From f6807e152c165bc7b08fa9cca7d1af003a67a79a Mon Sep 17 00:00:00 2001 From: hondacrx Date: Mon, 21 Aug 2023 07:22:33 -0400 Subject: [PATCH] Core: Update to 10.1.5 Port From (https://github.com/TrinityCore/TrinityCore/commit/0cea730fa23473a85c47451c3bd13df816f2b6e4) --- .../Framework/Constants/AchievementConst.cs | 21 + .../Framework/Constants/BattleGroundsConst.cs | 10 + Source/Framework/Constants/ChatConst.cs | 5 +- Source/Framework/Constants/CliDBConst.cs | 2 +- Source/Framework/Constants/MailConst.cs | 4 +- Source/Framework/Constants/Network/Opcodes.cs | 2004 +++++++++-------- Source/Framework/Constants/ObjectConst.cs | 2 + Source/Framework/Constants/PetConst.cs | 37 +- Source/Framework/Constants/QuestConst.cs | 26 +- Source/Framework/Constants/SharedConst.cs | 74 +- .../Constants/Spells/SpellAuraConst.cs | 4 + .../Framework/Constants/Spells/SpellConst.cs | 12 +- .../Database/Databases/HotfixDatabase.cs | 14 +- Source/Game/AI/CoreAI/PetAI.cs | 4 +- Source/Game/Achievements/CriteriaHandler.cs | 57 +- Source/Game/BattleGrounds/BattleGround.cs | 12 +- Source/Game/Chat/Commands/ModifyCommands.cs | 4 +- Source/Game/Conditions/Condition.cs | 3 +- Source/Game/Conditions/ConditionManager.cs | 9 +- Source/Game/DataStorage/CliDB.cs | 2 + Source/Game/DataStorage/DB2Manager.cs | 4 +- Source/Game/DataStorage/Structs/A_Records.cs | 2 +- Source/Game/DataStorage/Structs/C_Records.cs | 19 +- Source/Game/DataStorage/Structs/G_Records.cs | 3 + Source/Game/DataStorage/Structs/U_Records.cs | 3 +- .../Game/Entities/AreaTrigger/AreaTrigger.cs | 7 +- .../Entities/GameObject/GameObjectData.cs | 1 + Source/Game/Entities/Item/Item.cs | 16 + Source/Game/Entities/Item/ItemTemplate.cs | 3 +- Source/Game/Entities/Object/ObjectGuid.cs | 60 +- .../Entities/Object/Update/UpdateField.cs | 12 + .../Entities/Object/Update/UpdateFields.cs | 1729 ++++++++------ Source/Game/Entities/Player/Player.DB.cs | 73 +- Source/Game/Entities/Player/Player.Items.cs | 10 +- Source/Game/Entities/Player/Player.Map.cs | 13 + Source/Game/Entities/Player/Player.Quest.cs | 61 +- Source/Game/Entities/Player/Player.Spells.cs | 5 +- Source/Game/Entities/Player/Player.cs | 225 +- Source/Game/Entities/Unit/Unit.Pets.cs | 7 +- Source/Game/Entities/Unit/Unit.cs | 3 +- Source/Game/Globals/ObjectManager.cs | 39 +- Source/Game/Guilds/GuildManager.cs | 5 +- Source/Game/Handlers/CharacterHandler.cs | 46 +- Source/Game/Handlers/GuildHandler.cs | 2 +- Source/Game/Handlers/MiscHandler.cs | 3 + Source/Game/Handlers/NPCHandler.cs | 191 +- Source/Game/Handlers/PetHandler.cs | 3 - Source/Game/Handlers/SocialHandler.cs | 2 +- Source/Game/Handlers/SpellHandler.cs | 2 +- Source/Game/Miscellaneous/RaceMask.cs | 108 + .../Networking/Packets/AchievementPackets.cs | 8 +- .../Networking/Packets/AuctionHousePackets.cs | 6 +- .../Packets/AuthenticationPackets.cs | 17 + .../Networking/Packets/BattleGroundPackets.cs | 28 +- .../Networking/Packets/CharacterPackets.cs | 2 + .../Networking/Packets/CombatLogPackets.cs | 26 + Source/Game/Networking/Packets/DuelPackets.cs | 5 + .../Game/Networking/Packets/GuildPackets.cs | 19 +- Source/Game/Networking/Packets/ItemPackets.cs | 2 +- Source/Game/Networking/Packets/MailPackets.cs | 45 +- Source/Game/Networking/Packets/MiscPackets.cs | 2 +- Source/Game/Networking/Packets/NPCPackets.cs | 2 +- Source/Game/Networking/Packets/PetPackets.cs | 37 - .../Game/Networking/Packets/QuestPackets.cs | 13 +- .../Networking/Packets/ScenarioPackets.cs | 66 +- .../Game/Networking/Packets/SpellPackets.cs | 37 + .../Game/Networking/Packets/SystemPackets.cs | 2 + Source/Game/Networking/Packets/WhoPackets.cs | 5 +- Source/Game/Quest/Quest.cs | 17 +- Source/Game/Reputation/ReputationManager.cs | 15 +- Source/Game/Scenarios/Scenario.cs | 4 + Source/Game/Server/WorldSession.cs | 2 +- Source/Game/Spells/Auras/AuraEffect.cs | 24 +- Source/Game/Spells/Spell.cs | 2 +- Source/Game/Spells/SpellInfo.cs | 20 +- Source/Game/Spells/SpellManager.cs | 13 +- 76 files changed, 3149 insertions(+), 2233 deletions(-) create mode 100644 Source/Game/Miscellaneous/RaceMask.cs diff --git a/Source/Framework/Constants/AchievementConst.cs b/Source/Framework/Constants/AchievementConst.cs index aed1235ca..7e7f834b6 100644 --- a/Source/Framework/Constants/AchievementConst.cs +++ b/Source/Framework/Constants/AchievementConst.cs @@ -424,9 +424,29 @@ namespace Framework.Constants PlayerHasPerksProgramPendingReward = 350, PlayerCanUseItem = 351, // Player can use item {#Item} + PlayerSummonedBattlePetSpecies = 352, + PlayerSummonedBattlePetIsMaxLevel = 353, PlayerHasAtLeastProfPathRanks = 355, // Player has purchased or granted at least {#Count} ranks in {SkillLine} config PlayerHasAtLeastMissingProfPathRanks = 356, /*NYI*/ // Player is missing least {#Count} ranks in {SkillLine} config + + PlayerHasItemTransmogrifiedToItemModifiedAppearance = 358, // Player has item with {ItemModifiedAppearance} transmog + ItemHasBonusList = 359, /*NYI*/ // Item has {ItemBonusList} (used by ItemCondition) + ItemHasBonusListFromGroup = 360, /*NYI*/ // Item has a bonus list from {ItemBonusListGroup} (used by ItemCondition) + ItemHasContext = 361, /*NYI*/ // Item has {ItemContext} + ItemHasItemLevelBetween = 362, /*NYI*/ // Item has item level between {#Min} and {#Max} + ItemHasContentTuningID = 363, /*NYI*/ // Item has {ContentTuning} (modifier 28) + ItemHasInventoryType = 364, /*NYI*/ // Item has inventory type + ItemWasCraftedWithReagentInSlot = 365, /*NYI*/ // Item was crafted with reagent item {Item} in slot {ModifiedCraftingReagentSlot} + PlayerHasCompletedDungeonEncounterInDifficulty = 366, // Player has completed {DungeonEncounter} on {Difficulty} + PlayerCurrencyIsRelOpFromMax = 367, /*NYI*/ // Player {CurrencyTypes} is {RelOp} {#Amount} from currency limit + ItemHasModifiedCraftingReagentSlot = 368, /*NYI*/ // Item has {ModifiedCraftingReagentSlot} + PlayerIsBetweenQuests = 369, // Player has previously completed quest or is on "{QuestV2}" but not "{QuestV2}" (SecondaryAsset) + PlayerIsOnQuestWithLabel = 370, /*NYI*/ // Player is on quest with {QuestLabel} + PlayerScenarioStepID = 371, // Player is on scenario step number {ScenarioStep} + PlayerHasCompletedQuestWithLabel = 372, /*NYI*/ // Player has previously completed quest with {QuestLabel} + LegacyLootIsEnabled = 373, /*NYI*/ + PlayerZPositionBelow = 374, } public enum CriteriaFailEvent : byte @@ -723,6 +743,7 @@ namespace Framework.Constants FulfillCraftingOrderType = 246, /*NYI*/ // {CraftingOrderType} PerksProgramMonthComplete = 249, /*NYI*/ + CompleteTrackingQuest = 250, /*NYI*/ Count } diff --git a/Source/Framework/Constants/BattleGroundsConst.cs b/Source/Framework/Constants/BattleGroundsConst.cs index 02c69ed7b..4ccec721b 100644 --- a/Source/Framework/Constants/BattleGroundsConst.cs +++ b/Source/Framework/Constants/BattleGroundsConst.cs @@ -456,4 +456,14 @@ namespace Framework.Constants HordeCaptured = 4, AllianceCaptured = 5 } + + public enum PVPMatchState : byte + { + Waiting = 0, + StartUp = 1, + Engaged = 2, + PostRound = 3, + Inactive = 4, + Complete = 5 + } } diff --git a/Source/Framework/Constants/ChatConst.cs b/Source/Framework/Constants/ChatConst.cs index a9fe06f1e..bf172af6e 100644 --- a/Source/Framework/Constants/ChatConst.cs +++ b/Source/Framework/Constants/ChatConst.cs @@ -97,7 +97,8 @@ namespace Framework.Constants public enum ChatWhisperTargetStatus { CanWhisper = 0, - Offline = 1, - WrongFaction = 2 + CanWhisperGuild = 1, + Offline = 2, + WrongFaction = 3 } } diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index b15192f41..65a084db4 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -1904,7 +1904,7 @@ namespace Framework.Constants MonoValue = 0x400 // Skill always has value 1 } - public enum SpellCategoryFlags : sbyte + public enum SpellCategoryFlags : int { CooldownScalesWithWeaponSpeed = 0x01, // unused CooldownStartsOnEvent = 0x04, diff --git a/Source/Framework/Constants/MailConst.cs b/Source/Framework/Constants/MailConst.cs index a476e3fc8..35010e8b6 100644 --- a/Source/Framework/Constants/MailConst.cs +++ b/Source/Framework/Constants/MailConst.cs @@ -11,7 +11,9 @@ namespace Framework.Constants Gameobject = 4, Calendar = 5, Blackmarket = 6, - CommerceAuction = 7 + CommerceAuction = 7, + Auction2 = 8, + ArtisansConsortium = 9 } public enum MailCheckMask diff --git a/Source/Framework/Constants/Network/Opcodes.cs b/Source/Framework/Constants/Network/Opcodes.cs index 4b6246c52..d490777f3 100644 --- a/Source/Framework/Constants/Network/Opcodes.cs +++ b/Source/Framework/Constants/Network/Opcodes.cs @@ -5,51 +5,51 @@ namespace Framework.Constants { public enum ClientOpcodes : uint { - AbandonNpeResponse = 0x33eb, + AbandonNpeResponse = 0x33f0, AcceptGuildInvite = 0x35fd, - AcceptReturningPlayerPrompt = 0x3396, + AcceptReturningPlayerPrompt = 0x339b, AcceptSocialContract = 0x3744, AcceptTrade = 0x315a, AcceptWargameInvite = 0x35e0, AccountNotificationAcknowledged = 0x3733, - ActivateSoulbind = 0x33da, - ActivateTaxi = 0x34b1, + ActivateSoulbind = 0x33df, + ActivateTaxi = 0x34b2, AddonList = 0x35d8, - AddAccountCosmetic = 0x32b0, + AddAccountCosmetic = 0x32b6, AddBattlenetFriend = 0x3659, AddFriend = 0x36cd, AddIgnore = 0x36d1, - AddToy = 0x32af, - AdventureJournalOpenQuest = 0x3203, - AdventureJournalUpdateSuggestions = 0x33dd, - AdventureMapStartQuest = 0x3369, - AlterAppearance = 0x3503, - AreaSpiritHealerQuery = 0x34b6, - AreaSpiritHealerQueue = 0x34b7, - AreaTrigger = 0x31d7, - ArtifactAddPower = 0x31aa, - ArtifactSetAppearance = 0x31ac, - AssignEquipmentSetSpec = 0x320f, - AttackStop = 0x3262, - AttackSwing = 0x3261, + AddToy = 0x32b5, + AdventureJournalOpenQuest = 0x3202, + AdventureJournalUpdateSuggestions = 0x33e2, + AdventureMapStartQuest = 0x336e, + AlterAppearance = 0x3504, + AreaSpiritHealerQuery = 0x34b7, + AreaSpiritHealerQueue = 0x34b8, + AreaTrigger = 0x31d6, + ArtifactAddPower = 0x31a9, + ArtifactSetAppearance = 0x31ab, + AssignEquipmentSetSpec = 0x320e, + AttackStop = 0x3267, + AttackSwing = 0x3266, AuctionableTokenSell = 0x36e3, AuctionableTokenSellAtMarketPrice = 0x36e4, - AuctionBrowseQuery = 0x34d6, - AuctionCancelCommoditiesPurchase = 0x34de, - AuctionConfirmCommoditiesPurchase = 0x34dd, - AuctionGetCommodityQuote = 0x34dc, - AuctionHelloRequest = 0x34d1, - AuctionListBiddedItems = 0x34da, - AuctionListBucketsByBucketKeys = 0x34db, - AuctionListItemsByBucketKey = 0x34d7, - AuctionListItemsByItemId = 0x34d8, - AuctionListOwnedItems = 0x34d9, - AuctionPlaceBid = 0x34d5, - AuctionRemoveItem = 0x34d3, - AuctionReplicateItems = 0x34d4, + AuctionBrowseQuery = 0x34d7, + AuctionCancelCommoditiesPurchase = 0x34df, + AuctionConfirmCommoditiesPurchase = 0x34de, + AuctionGetCommodityQuote = 0x34dd, + AuctionHelloRequest = 0x34d2, + AuctionListBiddedItems = 0x34db, + AuctionListBucketsByBucketKeys = 0x34dc, + AuctionListItemsByBucketKey = 0x34d8, + AuctionListItemsByItemId = 0x34d9, + AuctionListOwnedItems = 0x34da, + AuctionPlaceBid = 0x34d6, + AuctionRemoveItem = 0x34d4, + AuctionReplicateItems = 0x34d5, AuctionRequestFavoriteList = 0x3735, - AuctionSellCommodity = 0x34df, - AuctionSellItem = 0x34d2, + AuctionSellCommodity = 0x34e0, + AuctionSellItem = 0x34d3, AuctionSetFavoriteItem = 0x3734, AuthContinuedSession = 0x3766, AuthSession = 0x3765, @@ -59,23 +59,23 @@ namespace Framework.Constants AutostoreBankReagent = 0x3998, AutoEquipItem = 0x399a, AutoEquipItemSlot = 0x399f, - AutoGuildBankItem = 0x34bd, + AutoGuildBankItem = 0x34be, AutoStoreBagItem = 0x399b, - AutoStoreGuildBankItem = 0x34c6, - AzeriteEmpoweredItemSelectPower = 0x3392, - AzeriteEmpoweredItemViewed = 0x3374, - AzeriteEssenceActivateEssence = 0x3394, - AzeriteEssenceUnlockMilestone = 0x3393, - BankerActivate = 0x34b9, - BattlefieldLeave = 0x3173, - BattlefieldList = 0x317e, - BattlefieldPort = 0x3538, - BattlemasterHello = 0x32cc, - BattlemasterJoin = 0x3530, - BattlemasterJoinArena = 0x3531, - BattlemasterJoinBrawl = 0x3536, - BattlemasterJoinRatedSoloShuffle = 0x3532, - BattlemasterJoinSkirmish = 0x3533, + AutoStoreGuildBankItem = 0x34c7, + AzeriteEmpoweredItemSelectPower = 0x3397, + AzeriteEmpoweredItemViewed = 0x3379, + AzeriteEssenceActivateEssence = 0x3399, + AzeriteEssenceUnlockMilestone = 0x3398, + BankerActivate = 0x34ba, + BattlefieldLeave = 0x3172, + BattlefieldList = 0x317d, + BattlefieldPort = 0x3539, + BattlemasterHello = 0x32d2, + BattlemasterJoin = 0x3531, + BattlemasterJoinArena = 0x3532, + BattlemasterJoinBrawl = 0x3537, + BattlemasterJoinRatedSoloShuffle = 0x3533, + BattlemasterJoinSkirmish = 0x3534, BattlenetChallengeResponse = 0x36d0, BattlenetRequest = 0x36f2, BattlePayAckFailedResponse = 0x36ca, @@ -98,21 +98,21 @@ namespace Framework.Constants BattlePetSetBattleSlot = 0x362c, BattlePetSetFlags = 0x362f, BattlePetSummon = 0x3628, - BattlePetUpdateDisplayNotify = 0x31e1, - BattlePetUpdateNotify = 0x31e0, + BattlePetUpdateDisplayNotify = 0x31e0, + BattlePetUpdateNotify = 0x31df, BeginTrade = 0x3157, - BinderActivate = 0x34b8, - BlackMarketBidOnItem = 0x3540, - BlackMarketOpen = 0x353e, - BlackMarketRequestItems = 0x353f, - BonusRoll = 0x3395, + BinderActivate = 0x34b9, + BlackMarketBidOnItem = 0x3541, + BlackMarketOpen = 0x353f, + BlackMarketRequestItems = 0x3540, + BonusRoll = 0x339a, BugReport = 0x3684, BusyTrade = 0x3158, - BuyBackItem = 0x34aa, - BuyBankSlot = 0x34ba, - BuyItem = 0x34a9, - BuyReagentBank = 0x34bb, - CageBattlePet = 0x31f3, + BuyBackItem = 0x34ab, + BuyBankSlot = 0x34bb, + BuyItem = 0x34aa, + BuyReagentBank = 0x34bc, + CageBattlePet = 0x31f2, CalendarAddEvent = 0x367c, CalendarCommunityInvite = 0x3670, CalendarComplain = 0x3678, @@ -128,24 +128,24 @@ namespace Framework.Constants CalendarRsvp = 0x3673, CalendarStatus = 0x3674, CalendarUpdateEvent = 0x367d, - CancelAura = 0x31ae, - CancelAutoRepeatSpell = 0x34f5, - CancelCast = 0x32b6, - CancelChannelling = 0x327a, - CancelGrowthAura = 0x3282, - CancelMasterLootRoll = 0x321b, - CancelModSpeedNoControlAuras = 0x31ad, - CancelMountAura = 0x3295, - CancelQueuedSpell = 0x317f, - CancelTempEnchantment = 0x3500, + CancelAura = 0x31ad, + CancelAutoRepeatSpell = 0x34f6, + CancelCast = 0x32bc, + CancelChannelling = 0x327f, + CancelGrowthAura = 0x3287, + CancelMasterLootRoll = 0x321a, + CancelModSpeedNoControlAuras = 0x31ac, + CancelMountAura = 0x329a, + CancelQueuedSpell = 0x317e, + CancelTempEnchantment = 0x3501, CancelTrade = 0x315c, CanDuel = 0x3661, CanRedeemTokenForBalance = 0x3705, - CastSpell = 0x32b3, + CastSpell = 0x32b9, ChallengeModeRequestLeaders = 0x308f, - ChangeBagSlotFlag = 0x334d, - ChangeBankBagSlotFlag = 0x334e, - ChangeMonumentAppearance = 0x332e, + ChangeBagSlotFlag = 0x3353, + ChangeBankBagSlotFlag = 0x3354, + ChangeMonumentAppearance = 0x3334, ChangeRealmTicket = 0x36f7, ChangeSubGroup = 0x364b, CharacterCheckUpgrade = 0x36c3, @@ -193,24 +193,25 @@ namespace Framework.Constants ChatReportIgnored = 0x37cb, ChatUnregisterAllAddonPrefixes = 0x37ce, CheckCharacterNameAvailability = 0x3644, - CheckIsAdventureMapPoiValid = 0x3253, - ChoiceResponse = 0x32bb, - ChromieTimeSelectExpansion = 0x33d9, - ClaimWeeklyReward = 0x33b5, - ClassTalentsDeleteConfig = 0x3411, - ClassTalentsNotifyEmptyConfig = 0x3213, - ClassTalentsNotifyValidationFailed = 0x3413, - ClassTalentsRenameConfig = 0x3410, - ClassTalentsRequestNewConfig = 0x340f, - ClassTalentsSetStarterBuildActive = 0x3414, - ClassTalentsSetUsesSharedActionBars = 0x3212, + CheckIsAdventureMapPoiValid = 0x3258, + ChoiceResponse = 0x32c1, + ChromieTimeSelectExpansion = 0x33de, + ClaimWeeklyReward = 0x33ba, + ClassTalentsDeleteConfig = 0x3417, + ClassTalentsNotifyEmptyConfig = 0x3212, + ClassTalentsNotifyValidationFailed = 0x3419, + ClassTalentsRenameConfig = 0x3416, + ClassTalentsRequestNewConfig = 0x3415, + ClassTalentsSetStarterBuildActive = 0x341a, + ClassTalentsSetUsesSharedActionBars = 0x3211, ClearNewAppearance = 0x3129, - ClearRaidMarker = 0x31a6, + ClearRaidMarker = 0x31a5, ClearTradeItem = 0x315e, - ClientPortGraveyard = 0x353a, + ClientPortGraveyard = 0x353b, CloseInteraction = 0x3499, - CloseRuneforgeInteraction = 0x33e1, - CloseTraitSystemInteraction = 0x3415, + CloseQuestChoice = 0x32c2, + CloseRuneforgeInteraction = 0x33e6, + CloseTraitSystemInteraction = 0x341b, ClubFinderApplicationResponse = 0x371c, ClubFinderGetApplicantsList = 0x371a, ClubFinderPost = 0x3717, @@ -235,41 +236,44 @@ namespace Framework.Constants CommerceTokenGetLog = 0x36eb, CommerceTokenGetMarketPrice = 0x36e2, Complaint = 0x366b, - CompleteCinematic = 0x3558, - CompleteMovie = 0x34eb, - ConfirmArtifactRespec = 0x31ab, - ConfirmRespecWipe = 0x3215, + CompleteCinematic = 0x3559, + CompleteMovie = 0x34ec, + ConfirmArtifactRespec = 0x31aa, + ConfirmRespecWipe = 0x3214, ConnectToFailed = 0x35d4, ConsumableTokenBuy = 0x36e6, ConsumableTokenBuyAtMarketPrice = 0x36e7, ConsumableTokenCanVeteranBuy = 0x36e5, ConsumableTokenRedeem = 0x36e9, ConsumableTokenRedeemConfirmation = 0x36ea, - ContributionContribute = 0x356c, - ContributionLastUpdateRequest = 0x356d, - ConversationCinematicReady = 0x355a, - ConversationLineStarted = 0x3559, + ContentTrackingStartTracking = 0x342b, + ContentTrackingStopTracking = 0x342c, + ContributionContribute = 0x356d, + ContributionLastUpdateRequest = 0x356e, + ConversationCinematicReady = 0x355b, + ConversationLineStarted = 0x355a, ConvertRaid = 0x364d, - CovenantRenownRequestCatchupState = 0x3580, - CraftingOrderCancel = 0x358b, - CraftingOrderClaim = 0x3588, - CraftingOrderCreate = 0x3585, - CraftingOrderFulfill = 0x358a, - CraftingOrderListCrafterOrders = 0x3587, - CraftingOrderListMyOrders = 0x3586, - CraftingOrderReject = 0x358c, - CraftingOrderRelease = 0x3589, - CraftingOrderUpdateIgnoreList = 0x358d, + CovenantRenownRequestCatchupState = 0x3581, + CraftingOrderCancel = 0x358c, + CraftingOrderClaim = 0x3589, + CraftingOrderCreate = 0x3586, + CraftingOrderFulfill = 0x358b, + CraftingOrderListCrafterOrders = 0x3588, + CraftingOrderListMyOrders = 0x3587, + CraftingOrderReject = 0x358d, + CraftingOrderRelease = 0x358a, + CraftingOrderReportPlayer = 0x358e, + CraftingOrderUpdateIgnoreList = 0x358f, CreateCharacter = 0x3643, - CreateShipment = 0x3319, + CreateShipment = 0x331f, DbQueryBulk = 0x35e4, - DeclineGuildInvites = 0x352d, - DeclinePetition = 0x3547, - DeleteEquipmentSet = 0x3519, + DeclineGuildInvites = 0x352e, + DeclinePetition = 0x3548, + DeleteEquipmentSet = 0x351a, DelFriend = 0x36ce, DelIgnore = 0x36d2, - DepositReagentBank = 0x3356, - DestroyItem = 0x32a9, + DepositReagentBank = 0x335c, + DestroyItem = 0x32af, DfBootPlayerVote = 0x3617, DfConfirmExpandSearch = 0x3609, DfGetJoinStatus = 0x3615, @@ -281,84 +285,84 @@ namespace Framework.Constants DfSetRoles = 0x3616, DfTeleport = 0x3618, DiscardedTimeSyncAcks = 0x3a41, - DismissCritter = 0x3507, + DismissCritter = 0x3508, DoCountdown = 0x3716, - DoMasterLootRoll = 0x321a, + DoMasterLootRoll = 0x3219, DoReadyCheck = 0x3633, - DuelResponse = 0x34f0, - EjectPassenger = 0x3248, - Emote = 0x3554, + DuelResponse = 0x34f1, + EjectPassenger = 0x324d, + Emote = 0x3555, EnableNagle = 0x376b, - EnableTaxiNode = 0x34af, + EnableTaxiNode = 0x34b0, EngineSurvey = 0x36e0, EnterEncryptedModeAck = 0x3767, EnumCharacters = 0x35e8, EnumCharactersDeletedByClient = 0x36da, - FarSight = 0x34f6, - GameEventDebugDisable = 0x31b2, - GameEventDebugEnable = 0x31b1, - GameObjReportUse = 0x34fd, - GameObjUse = 0x34fc, - GarrisonAddFollowerHealth = 0x3314, - GarrisonAssignFollowerToBuilding = 0x32fa, - GarrisonCancelConstruction = 0x32e7, - GarrisonCheckUpgradeable = 0x3349, - GarrisonCompleteMission = 0x333b, - GarrisonFullyHealAllFollowers = 0x3315, - GarrisonGenerateRecruits = 0x32fd, - GarrisonGetClassSpecCategoryInfo = 0x330c, - GarrisonGetMapData = 0x3313, - GarrisonGetMissionReward = 0x336d, - GarrisonLearnTalent = 0x3308, - GarrisonMissionBonusRoll = 0x333d, - GarrisonPurchaseBuilding = 0x32e3, - GarrisonRecruitFollower = 0x32ff, - GarrisonRemoveFollower = 0x3332, - GarrisonRemoveFollowerFromBuilding = 0x32fb, - GarrisonRenameFollower = 0x32fc, - GarrisonRequestBlueprintAndSpecializationData = 0x32e2, - GarrisonRequestShipmentInfo = 0x3317, - GarrisonResearchTalent = 0x3300, - GarrisonSetBuildingActive = 0x32e4, - GarrisonSetFollowerFavorite = 0x32f8, - GarrisonSetFollowerInactive = 0x32f0, - GarrisonSetRecruitmentPreferences = 0x32fe, - GarrisonSocketTalent = 0x33ee, - GarrisonStartMission = 0x333a, - GarrisonSwapBuildings = 0x32e8, + FarSight = 0x34f7, + GameEventDebugDisable = 0x31b1, + GameEventDebugEnable = 0x31b0, + GameObjReportUse = 0x34fe, + GameObjUse = 0x34fd, + GarrisonAddFollowerHealth = 0x331a, + GarrisonAssignFollowerToBuilding = 0x3300, + GarrisonCancelConstruction = 0x32ed, + GarrisonCheckUpgradeable = 0x334f, + GarrisonCompleteMission = 0x3341, + GarrisonFullyHealAllFollowers = 0x331b, + GarrisonGenerateRecruits = 0x3303, + GarrisonGetClassSpecCategoryInfo = 0x3312, + GarrisonGetMapData = 0x3319, + GarrisonGetMissionReward = 0x3372, + GarrisonLearnTalent = 0x330e, + GarrisonMissionBonusRoll = 0x3343, + GarrisonPurchaseBuilding = 0x32e9, + GarrisonRecruitFollower = 0x3305, + GarrisonRemoveFollower = 0x3338, + GarrisonRemoveFollowerFromBuilding = 0x3301, + GarrisonRenameFollower = 0x3302, + GarrisonRequestBlueprintAndSpecializationData = 0x32e8, + GarrisonRequestShipmentInfo = 0x331d, + GarrisonResearchTalent = 0x3306, + GarrisonSetBuildingActive = 0x32ea, + GarrisonSetFollowerFavorite = 0x32fe, + GarrisonSetFollowerInactive = 0x32f6, + GarrisonSetRecruitmentPreferences = 0x3304, + GarrisonSocketTalent = 0x33f3, + GarrisonStartMission = 0x3340, + GarrisonSwapBuildings = 0x32ee, GenerateRandomCharacterName = 0x35e7, GetAccountCharacterList = 0x36b3, GetAccountNotifications = 0x3732, - GetGarrisonInfo = 0x32dd, - GetItemPurchaseData = 0x3542, - GetLandingPageShipments = 0x3318, - GetMirrorImageData = 0x32ad, + GetGarrisonInfo = 0x32e3, + GetItemPurchaseData = 0x3543, + GetLandingPageShipments = 0x331e, + GetMirrorImageData = 0x32b3, GetPvpOptionsEnabled = 0x35ee, GetRafAccountInfo = 0x3720, GetRemainingGameTime = 0x36e8, - GetTrophyList = 0x332b, + GetTrophyList = 0x3331, GetUndeleteCharacterCooldownStatus = 0x36dc, GetVasAccountCharacterList = 0x36ed, GetVasTransferTargetRealmList = 0x36ee, GmTicketAcknowledgeSurvey = 0x368f, GmTicketGetCaseStatus = 0x368e, GmTicketGetSystemStatus = 0x368d, - GossipRefreshOptions = 0x357f, + GossipRefreshOptions = 0x3580, GossipSelectOption = 0x349a, GuildAddBattlenetFriend = 0x308d, GuildAddRank = 0x3065, GuildAssignMemberRank = 0x3060, GuildAutoDeclineInvitation = 0x3062, - GuildBankActivate = 0x34bc, - GuildBankBuyTab = 0x34ca, - GuildBankDepositMoney = 0x34cc, + GuildBankActivate = 0x34bd, + GuildBankBuyTab = 0x34cb, + GuildBankDepositMoney = 0x34cd, GuildBankLogQuery = 0x3083, - GuildBankQueryTab = 0x34c9, + GuildBankQueryTab = 0x34ca, GuildBankRemainingWithdrawMoneyQuery = 0x3084, GuildBankSetTabText = 0x3087, GuildBankTextQuery = 0x3088, - GuildBankUpdateTab = 0x34cb, - GuildBankWithdrawMoney = 0x34cd, + GuildBankUpdateTab = 0x34cc, + GuildBankWithdrawMoney = 0x34ce, GuildChallengeUpdateRequest = 0x307c, GuildChangeNameRequest = 0x307f, GuildDeclineInvitation = 0x3061, @@ -388,72 +392,72 @@ namespace Framework.Constants GuildShiftRank = 0x3067, GuildUpdateInfoText = 0x3076, GuildUpdateMotdText = 0x3075, - HearthAndResurrect = 0x3515, - HideQuestChoice = 0x32bd, + HearthAndResurrect = 0x3516, + HideQuestChoice = 0x32c3, HotfixRequest = 0x35e5, IgnoreTrade = 0x3159, InitiateRolePoll = 0x35da, InitiateTrade = 0x3156, - Inspect = 0x353c, - InstanceLockResponse = 0x351a, - IslandQueue = 0x33b1, - ItemPurchaseRefund = 0x3543, - ItemTextQuery = 0x334a, - JoinPetBattleQueue = 0x31de, - JoinRatedBattleground = 0x3179, + Inspect = 0x353d, + InstanceLockResponse = 0x351b, + IslandQueue = 0x33b6, + ItemPurchaseRefund = 0x3544, + ItemTextQuery = 0x3350, + JoinPetBattleQueue = 0x31dd, + JoinRatedBattleground = 0x3178, KeepAlive = 0x367e, - KeyboundOverride = 0x322d, + KeyboundOverride = 0x322f, LatencyReport = 0x3771, - LearnPvpTalents = 0x356b, - LearnTalents = 0x3569, + LearnPvpTalents = 0x356c, + LearnTalents = 0x356a, LeaveGroup = 0x3648, - LeavePetBattleQueue = 0x31df, + LeavePetBattleQueue = 0x31de, LfgListApplyToGroup = 0x360e, LfgListCancelApplication = 0x360f, LfgListDeclineApplicant = 0x3610, LfgListGetStatus = 0x360c, LfgListInviteApplicant = 0x3611, LfgListInviteResponse = 0x3612, - LfgListJoin = 0x3390, + LfgListJoin = 0x3395, LfgListLeave = 0x360b, LfgListSearch = 0x360d, - LfgListUpdateRequest = 0x3391, + LfgListUpdateRequest = 0x3396, ListInventory = 0x34a7, LiveRegionAccountRestore = 0x36b6, LiveRegionCharacterCopy = 0x36b5, LiveRegionGetAccountCharacterList = 0x36b4, LiveRegionKeyBindingsCopy = 0x36b7, LoadingScreenNotify = 0x35f8, - LoadSelectedTrophy = 0x332c, - LogoutCancel = 0x34e6, - LogoutInstant = 0x34e7, - LogoutRequest = 0x34e4, + LoadSelectedTrophy = 0x3332, + LogoutCancel = 0x34e7, + LogoutInstant = 0x34e8, + LogoutRequest = 0x34e5, LogDisconnect = 0x3769, LogStreamingError = 0x376d, - LootItem = 0x3218, - LootMoney = 0x3217, - LootRelease = 0x321c, - LootRoll = 0x321d, - LootUnit = 0x3216, + LootItem = 0x3217, + LootMoney = 0x3216, + LootRelease = 0x321b, + LootRoll = 0x321c, + LootUnit = 0x3215, LowLevelRaid1 = 0x369f, - LowLevelRaid2 = 0x3521, - MailCreateTextItem = 0x354e, - MailDelete = 0x322f, - MailGetList = 0x3549, - MailMarkAsRead = 0x354d, + LowLevelRaid2 = 0x3522, + MailCreateTextItem = 0x354f, + MailDelete = 0x3231, + MailGetList = 0x354a, + MailMarkAsRead = 0x354e, MailReturnToSender = 0x3654, - MailTakeItem = 0x354b, - MailTakeMoney = 0x354a, - MakeContitionalAppearancePermanent = 0x3231, - MasterLootItem = 0x3219, - MergeGuildBankItemWithGuildBankItem = 0x34c7, - MergeGuildBankItemWithItem = 0x34c4, - MergeItemWithGuildBankItem = 0x34c2, + MailTakeItem = 0x354c, + MailTakeMoney = 0x354b, + MakeContitionalAppearancePermanent = 0x3233, + MasterLootItem = 0x3218, + MergeGuildBankItemWithGuildBankItem = 0x34c8, + MergeGuildBankItemWithItem = 0x34c5, + MergeItemWithGuildBankItem = 0x34c3, MinimapPing = 0x364a, - MissileTrajectoryCollision = 0x318a, + MissileTrajectoryCollision = 0x3189, MountClearFanfare = 0x3127, MountSetFavorite = 0x3631, - MountSpecialAnim = 0x3296, + MountSpecialAnim = 0x329b, MoveAddImpulseAck = 0x3a50, MoveApplyInertiaAck = 0x3a4e, MoveApplyMovementForceAck = 0x3a15, @@ -481,7 +485,7 @@ namespace Framework.Constants MoveForceWalkSpeedChangeAck = 0x3a21, MoveGravityDisableAck = 0x3a35, MoveGravityEnableAck = 0x3a36, - MoveGuildBankItem = 0x34c1, + MoveGuildBankItem = 0x34c2, MoveHeartbeat = 0x3a10, MoveHoverAck = 0x3a13, MoveInertiaDisableAck = 0x3a37, @@ -544,45 +548,45 @@ namespace Framework.Constants MoveUpdateFallSpeed = 0x3a1a, MoveWaterWalkAck = 0x3a1d, MythicPlusRequestMapStats = 0x308e, - NeutralPlayerSelectFaction = 0x31d4, - NextCinematicCamera = 0x3557, - ObjectUpdateFailed = 0x3180, - ObjectUpdateRescued = 0x3181, - OfferPetition = 0x33d8, - OpeningCinematic = 0x3556, - OpenItem = 0x334b, - OpenMissionNpc = 0x330e, - OpenShipmentNpc = 0x3316, - OpenTradeskillNpc = 0x3321, - OptOutOfLoot = 0x3504, - OverrideScreenFlash = 0x352e, + NeutralPlayerSelectFaction = 0x31d3, + NextCinematicCamera = 0x3558, + ObjectUpdateFailed = 0x317f, + ObjectUpdateRescued = 0x3180, + OfferPetition = 0x33dd, + OpeningCinematic = 0x3557, + OpenItem = 0x3351, + OpenMissionNpc = 0x3314, + OpenShipmentNpc = 0x331c, + OpenTradeskillNpc = 0x3327, + OptOutOfLoot = 0x3505, + OverrideScreenFlash = 0x352f, PartyInvite = 0x3603, PartyInviteResponse = 0x3605, PartyUninvite = 0x3646, - PerformItemInteraction = 0x3239, + PerformItemInteraction = 0x323b, PerksProgramRequestPendingRewards = 0x3135, - PerksProgramRequestPurchase = 0x3401, - PerksProgramRequestRefund = 0x3402, - PerksProgramSetFrozenVendorItem = 0x3403, - PerksProgramStatusRequest = 0x3400, - PetitionBuy = 0x34cf, + PerksProgramRequestPurchase = 0x3406, + PerksProgramRequestRefund = 0x3407, + PerksProgramSetFrozenVendorItem = 0x3408, + PerksProgramStatusRequest = 0x3405, + PetitionBuy = 0x34d0, PetitionRenameGuild = 0x36c6, - PetitionShowList = 0x34ce, - PetitionShowSignatures = 0x34d0, + PetitionShowList = 0x34cf, + PetitionShowSignatures = 0x34d1, PetAbandon = 0x3493, PetAction = 0x3491, - PetBattleFinalNotify = 0x31e3, + PetBattleFinalNotify = 0x31e2, PetBattleInput = 0x3640, - PetBattleQueueProposeMatchResult = 0x322e, - PetBattleQuitNotify = 0x31e2, + PetBattleQueueProposeMatchResult = 0x3230, + PetBattleQuitNotify = 0x31e1, PetBattleReplaceFrontPet = 0x3641, - PetBattleRequestPvp = 0x31dc, - PetBattleRequestUpdate = 0x31dd, - PetBattleRequestWild = 0x31da, - PetBattleScriptErrorNotify = 0x31e4, - PetBattleWildLocationFail = 0x31db, + PetBattleRequestPvp = 0x31db, + PetBattleRequestUpdate = 0x31dc, + PetBattleRequestWild = 0x31d9, + PetBattleScriptErrorNotify = 0x31e3, + PetBattleWildLocationFail = 0x31da, PetCancelAura = 0x3494, - PetCastSpell = 0x32b2, + PetCastSpell = 0x32b8, PetRename = 0x3683, PetSetAction = 0x3490, PetSpellAutocast = 0x3495, @@ -590,48 +594,48 @@ namespace Framework.Constants Ping = 0x3768, PlayerLogin = 0x35ea, PushQuestToParty = 0x34a5, - PvpLogData = 0x317c, - QueryBattlePetName = 0x3289, + PvpLogData = 0x317b, + QueryBattlePetName = 0x328e, QueryCorpseLocationFromClient = 0x365f, QueryCorpseTransport = 0x3660, - QueryCountdownTimer = 0x31a9, - QueryCreature = 0x3283, - QueryGameObject = 0x3284, - QueryGarrisonPetName = 0x328a, + QueryCountdownTimer = 0x31a8, + QueryCreature = 0x3288, + QueryGameObject = 0x3289, + QueryGarrisonPetName = 0x328f, QueryGuildInfo = 0x3689, - QueryInspectAchievements = 0x350e, - QueryNextMailTime = 0x354c, - QueryNpcText = 0x3285, - QueryPageText = 0x3287, - QueryPetition = 0x328b, - QueryPetName = 0x3288, + QueryInspectAchievements = 0x350f, + QueryNextMailTime = 0x354d, + QueryNpcText = 0x328a, + QueryPageText = 0x328c, + QueryPetition = 0x3290, + QueryPetName = 0x328d, QueryPlayerNames = 0x3772, QueryPlayerNamesForCommunity = 0x3770, QueryPlayerNameByCommunityId = 0x376f, - QueryQuestCompletionNpcs = 0x3175, - QueryQuestInfo = 0x3286, - QueryQuestItemUsability = 0x3176, + QueryQuestCompletionNpcs = 0x3174, + QueryQuestInfo = 0x328b, + QueryQuestItemUsability = 0x3175, QueryRealmName = 0x3688, QueryScenarioPoi = 0x3655, - QueryTime = 0x34e3, - QueryTreasurePicker = 0x3370, - QueryVoidStorage = 0x31a2, + QueryTime = 0x34e4, + QueryTreasurePicker = 0x3375, + QueryVoidStorage = 0x31a1, QuestConfirmAccept = 0x34a4, QuestGiverAcceptQuest = 0x349e, QuestGiverChooseReward = 0x34a0, - QuestGiverCloseQuest = 0x355d, + QuestGiverCloseQuest = 0x355e, QuestGiverCompleteQuest = 0x349f, QuestGiverHello = 0x349c, QuestGiverQueryQuest = 0x349d, QuestGiverRequestReward = 0x34a1, QuestGiverStatusMultipleQuery = 0x34a3, QuestGiverStatusQuery = 0x34a2, - QuestGiverStatusTrackedQuery = 0x358f, - QuestLogRemoveQuest = 0x3541, + QuestGiverStatusTrackedQuery = 0x3591, + QuestLogRemoveQuest = 0x3542, QuestPoiQuery = 0x36ad, QuestPushResult = 0x34a6, - QuestSessionBeginResponse = 0x33c9, - QuestSessionRequestStart = 0x33c8, + QuestSessionBeginResponse = 0x33ce, + QuestSessionRequestStart = 0x33cd, QuestSessionRequestStop = 0x372b, QueuedMessagesEnd = 0x376c, QuickJoinAutoAcceptRequests = 0x3703, @@ -639,207 +643,209 @@ namespace Framework.Constants QuickJoinRequestInviteWithConfirmation = 0x3730, QuickJoinRespondToInvite = 0x3701, QuickJoinSignalToastDisplayed = 0x3700, - RafClaimActivityReward = 0x3512, + RafClaimActivityReward = 0x3513, RafClaimNextReward = 0x3721, RafGenerateRecruitmentLink = 0x3723, RafUpdateRecruitmentInfo = 0x3722, RandomRoll = 0x3653, ReadyCheckResponse = 0x3634, - ReadItem = 0x334c, - ReclaimCorpse = 0x34e9, - RemoveNewItem = 0x3373, + ReadItem = 0x3352, + ReclaimCorpse = 0x34ea, + RemoveNewItem = 0x3378, RemoveRafRecruit = 0x3724, ReorderCharacters = 0x35e9, - RepairItem = 0x34fa, - ReplaceTrophy = 0x332d, - RepopRequest = 0x3539, + RepairItem = 0x34fb, + ReplaceTrophy = 0x3333, + RepopRequest = 0x353a, ReportClientVariables = 0x36fd, ReportEnabledAddons = 0x36fc, ReportFrozenWhileLoadingMap = 0x36a5, ReportKeybindingExecutionCounts = 0x36fe, - ReportPvpPlayerAfk = 0x3502, - ReportServerLag = 0x33c1, - ReportStuckInCombat = 0x33c2, + ReportPvpPlayerAfk = 0x3503, + ReportServerLag = 0x33c6, + ReportStuckInCombat = 0x33c7, RequestAccountData = 0x3693, - RequestAreaPoiUpdate = 0x3372, + RequestAreaPoiUpdate = 0x3377, RequestBattlefieldStatus = 0x35dc, - RequestCemeteryList = 0x3177, + RequestCemeteryList = 0x3176, RequestCharacterGuildFollowInfo = 0x368a, - RequestConquestFormulaConstants = 0x32cf, - RequestCovenantCallings = 0x33b3, - RequestCrowdControlSpell = 0x353d, - RequestForcedReactions = 0x320d, - RequestGarrisonTalentWorldQuestUnlocks = 0x33ed, - RequestGuildPartyState = 0x31a8, - RequestGuildRewardsList = 0x31a7, - RequestLatestSplashScreen = 0x33c3, - RequestLfgListBlacklist = 0x32be, - RequestMythicPlusAffixes = 0x3207, - RequestMythicPlusSeasonData = 0x3208, + RequestConquestFormulaConstants = 0x32d5, + RequestCovenantCallings = 0x33b8, + RequestCrowdControlSpell = 0x353e, + RequestForcedReactions = 0x320c, + RequestGarrisonTalentWorldQuestUnlocks = 0x33f2, + RequestGuildPartyState = 0x31a7, + RequestGuildRewardsList = 0x31a6, + RequestLatestSplashScreen = 0x33c8, + RequestLfgListBlacklist = 0x32c4, + RequestMythicPlusAffixes = 0x3206, + RequestMythicPlusSeasonData = 0x3207, RequestPartyJoinUpdates = 0x35f7, RequestPartyMemberStats = 0x3652, RequestPetInfo = 0x3496, - RequestPlayedTime = 0x328e, - RequestPvpRewards = 0x3195, + RequestPlayedTime = 0x3293, + RequestPvpRewards = 0x3194, RequestRaidInfo = 0x36c7, RequestRatedPvpInfo = 0x35e3, RequestRealmGuildMasterInfo = 0x309a, - RequestResearchHistory = 0x3167, - RequestScheduledPvpInfo = 0x3196, + RequestScheduledPvpInfo = 0x3195, RequestStabledPets = 0x3497, - RequestVehicleExit = 0x3243, - RequestVehicleNextSeat = 0x3245, - RequestVehiclePrevSeat = 0x3244, - RequestVehicleSwitchSeat = 0x3246, - RequestWeeklyRewards = 0x33b6, - RequestWorldQuestUpdate = 0x3371, - ResetChallengeMode = 0x3205, - ResetChallengeModeCheat = 0x3206, + RequestVehicleExit = 0x3248, + RequestVehicleNextSeat = 0x324a, + RequestVehiclePrevSeat = 0x3249, + RequestVehicleSwitchSeat = 0x324b, + RequestWeeklyRewards = 0x33bb, + RequestWorldQuestUpdate = 0x3376, + ResetChallengeMode = 0x3204, + ResetChallengeModeCheat = 0x3205, ResetInstances = 0x3667, ResurrectResponse = 0x3682, - RevertMonumentAppearance = 0x332f, - RideVehicleInteract = 0x3247, + RevertMonumentAppearance = 0x3335, + RideVehicleInteract = 0x324c, + RpeResetCharacter = 0x374e, SaveAccountDataExport = 0x3748, - SaveCufProfiles = 0x318b, - SaveEquipmentSet = 0x3518, - SaveGuildEmblem = 0x32c2, - ScenePlaybackCanceled = 0x322a, - ScenePlaybackComplete = 0x3229, - SceneTriggerEvent = 0x322b, - SelfRes = 0x3544, + SaveCufProfiles = 0x318a, + SaveEquipmentSet = 0x3519, + SaveGuildEmblem = 0x32c8, + ScenePlaybackCanceled = 0x322c, + ScenePlaybackComplete = 0x322b, + SceneTriggerEvent = 0x322d, + SelfRes = 0x3545, + SellAllJunkItems = 0x34a9, SellItem = 0x34a8, SendCharacterClubInvitation = 0x36f6, SendContactList = 0x36cc, SendMail = 0x35fa, SendTextEmote = 0x348e, ServerTimeOffsetRequest = 0x369a, - SetAchievementsHidden = 0x3230, - SetActionBarToggles = 0x3545, + SetAchievementsHidden = 0x3232, + SetActionBarToggles = 0x3546, SetActionButton = 0x3635, SetActiveMover = 0x3a3c, - SetAdvancedCombatLogging = 0x32d0, + SetAdvancedCombatLogging = 0x32d6, SetAssistantLeader = 0x364e, - SetBackpackAutosortDisabled = 0x334f, - SetBankAutosortDisabled = 0x3350, + SetBackpackAutosortDisabled = 0x3355, + SetBankAutosortDisabled = 0x3356, SetContactNotes = 0x36cf, - SetCurrencyFlags = 0x3169, - SetDifficultyId = 0x322c, + SetCurrencyFlags = 0x3168, + SetDifficultyId = 0x322e, SetDungeonDifficulty = 0x3681, - SetEmpowerMinHoldStagePercent = 0x327d, + SetEmpowerMinHoldStagePercent = 0x3282, SetEveryoneIsAssistant = 0x3619, SetExcludedChatCensorSources = 0x3704, - SetFactionAtWar = 0x34ec, - SetFactionInactive = 0x34ee, - SetFactionNotAtWar = 0x34ed, - SetGameEventDebugViewState = 0x31b9, - SetInsertItemsLeftToRight = 0x3352, + SetFactionAtWar = 0x34ed, + SetFactionInactive = 0x34ef, + SetFactionNotAtWar = 0x34ee, + SetGameEventDebugViewState = 0x31b8, + SetInsertItemsLeftToRight = 0x3358, SetLootMethod = 0x3647, - SetLootSpecialization = 0x3552, + SetLootSpecialization = 0x3553, SetPartyAssignment = 0x3650, SetPartyLeader = 0x3649, - SetPetSlot = 0x3168, + SetPetSlot = 0x3167, SetPlayerDeclinedNames = 0x3687, - SetPreferredCemetery = 0x3178, - SetPvp = 0x32c6, + SetPreferredCemetery = 0x3177, + SetPvp = 0x32cc, SetRaidDifficulty = 0x36d8, SetRole = 0x35d9, SetSavedInstanceExtend = 0x3685, - SetSelection = 0x353b, + SetSelection = 0x353c, SetSheathed = 0x348f, - SetSortBagsRightToLeft = 0x3351, - SetTaxiBenchmarkMode = 0x3501, - SetTitle = 0x3294, + SetSortBagsRightToLeft = 0x3357, + SetTaxiBenchmarkMode = 0x3502, + SetTitle = 0x3299, SetTradeCurrency = 0x3160, SetTradeGold = 0x315f, SetTradeItem = 0x315d, - SetUsingPartyGarrison = 0x3310, - SetWarMode = 0x32c7, - SetWatchedFaction = 0x34ef, + SetUsingPartyGarrison = 0x3316, + SetWarMode = 0x32cd, + SetWatchedFaction = 0x34f0, ShowTradeSkill = 0x36bf, - SignPetition = 0x3546, + SignPetition = 0x3547, SilencePartyTalker = 0x3651, SocialContractRequest = 0x3743, - SocketGems = 0x34f9, - SortBags = 0x3353, - SortBankBags = 0x3354, - SortReagentBankBags = 0x3355, + SocketGems = 0x34fa, + SortBags = 0x3359, + SortBankBags = 0x335a, + SortReagentBankBags = 0x335b, + SpawnTrackingUpdate = 0x32ae, SpellClick = 0x349b, - SpellEmpowerRelease = 0x327b, - SpellEmpowerRestart = 0x327c, - SpiritHealerActivate = 0x34b5, - SplitGuildBankItem = 0x34c8, - SplitGuildBankItemToInventory = 0x34c5, + SpellEmpowerRelease = 0x3280, + SpellEmpowerRestart = 0x3281, + SpiritHealerActivate = 0x34b6, + SplitGuildBankItem = 0x34c9, + SplitGuildBankItemToInventory = 0x34c6, SplitItem = 0x399e, - SplitItemToGuildBank = 0x34c3, - StandStateChange = 0x3189, - StartChallengeMode = 0x355e, + SplitItemToGuildBank = 0x34c4, + StandStateChange = 0x3188, + StartChallengeMode = 0x355f, StartSpectatorWarGame = 0x35df, StartWarGame = 0x35de, - StoreGuildBankItem = 0x34be, + StoreGuildBankItem = 0x34bf, SubmitUserFeedback = 0x3692, - SubscriptionInterstitialResponse = 0x33e2, + SubscriptionInterstitialResponse = 0x33e7, SummonResponse = 0x3669, SupportTicketSubmitComplaint = 0x3645, - SurrenderArena = 0x3174, + SurrenderArena = 0x3173, SuspendCommsAck = 0x3764, SuspendTokenResponse = 0x376a, - SwapGuildBankItemWithGuildBankItem = 0x34c0, + SwapGuildBankItemWithGuildBankItem = 0x34c1, SwapInvItem = 0x399d, SwapItem = 0x399c, - SwapItemWithGuildBankItem = 0x34bf, + SwapItemWithGuildBankItem = 0x34c0, SwapSubGroups = 0x364c, - SwapVoidItem = 0x31a4, - TabardVendorActivate = 0x32c3, + SwapVoidItem = 0x31a3, + TabardVendorActivate = 0x32c9, TalkToGossip = 0x3498, - TaxiNodeStatusQuery = 0x34ae, - TaxiQueryAvailableNodes = 0x34b0, - TaxiRequestEarlyLanding = 0x34b2, + TaxiNodeStatusQuery = 0x34af, + TaxiQueryAvailableNodes = 0x34b1, + TaxiRequestEarlyLanding = 0x34b3, TimeAdjustmentResponse = 0x3a40, TimeSyncResponse = 0x3a3d, TimeSyncResponseDropped = 0x3a3f, TimeSyncResponseFailed = 0x3a3e, ToggleDifficulty = 0x3656, - TogglePvp = 0x32c5, - TotemDestroyed = 0x3506, + TogglePvp = 0x32cb, + TotemDestroyed = 0x3507, ToyClearFanfare = 0x3128, - TradeSkillSetFavorite = 0x336f, - TrainerBuySpell = 0x34b4, - TrainerList = 0x34b3, - TraitsCommitConfig = 0x3409, - TraitsTalentTestUnlearnSpells = 0x3407, - TransmogrifyItems = 0x3197, - TurnInPetition = 0x3548, + TradeSkillSetFavorite = 0x3374, + TrainerBuySpell = 0x34b5, + TrainerList = 0x34b4, + TraitsCommitConfig = 0x340f, + TraitsTalentTestUnlearnSpells = 0x340d, + TransmogrifyItems = 0x3196, + TurnInPetition = 0x3549, Tutorial = 0x36d9, - UiMapQuestLinesRequest = 0x33b2, + UiMapQuestLinesRequest = 0x33b7, UnacceptTrade = 0x315b, UndeleteCharacter = 0x36db, - UnlearnSkill = 0x34f3, - UnlearnSpecialization = 0x31a5, - UnlockVoidStorage = 0x31a1, + UnlearnSkill = 0x34f4, + UnlearnSpecialization = 0x31a4, + UnlockVoidStorage = 0x31a0, UpdateAadcStatus = 0x3737, UpdateAccountData = 0x3694, - UpdateAreaTriggerVisual = 0x32b5, + UpdateAreaTriggerVisual = 0x32bb, UpdateClientSettings = 0x3663, - UpdateCraftingNpcRecipes = 0x3322, + UpdateCraftingNpcRecipes = 0x3328, UpdateMissileTrajectory = 0x3a43, UpdateRaidTarget = 0x364f, - UpdateSpellVisual = 0x32b4, + UpdateSpellVisual = 0x32ba, UpdateVasPurchaseStates = 0x36f0, - UpgradeGarrison = 0x32d8, - UpgradeRuneforgeLegendary = 0x33e0, - UsedFollow = 0x3186, - UseCritterItem = 0x324d, + UpgradeGarrison = 0x32de, + UpgradeRuneforgeLegendary = 0x33e5, + UsedFollow = 0x3185, + UseCritterItem = 0x3252, UseEquipmentSet = 0x3995, - UseItem = 0x32ae, - UseToy = 0x32b1, + UseItem = 0x32b4, + UseToy = 0x32b7, VasCheckTransferOk = 0x3709, VasGetQueueMinutes = 0x3708, VasGetServiceStatus = 0x3707, - ViolenceLevel = 0x3184, + ViolenceLevel = 0x3183, VoiceChannelSttTokenRequest = 0x370d, VoiceChatJoinChannel = 0x370e, VoiceChatLogin = 0x370c, - VoidStorageTransfer = 0x31a3, + VoidStorageTransfer = 0x31a2, Warden3Data = 0x35ec, Who = 0x3680, WhoIs = 0x367f, @@ -852,90 +858,90 @@ namespace Framework.Constants public enum ServerOpcodes : uint { - AbortNewWorld = 0x259c, - AccountCosmeticAdded = 0x287a, - AccountCriteriaUpdate = 0x2860, - AccountDataTimes = 0x2704, - AccountExportResponse = 0x28b6, - AccountMountRemoved = 0x25b0, - AccountMountUpdate = 0x25af, - AccountNotificationsResponse = 0x2879, - AccountToyUpdate = 0x25b1, - AccountTransmogSetFavoritesUpdate = 0x25b4, - AccountTransmogUpdate = 0x25b3, - AchievementDeleted = 0x26e2, - AchievementEarned = 0x2640, + AbortNewWorld = 0x2597, + AccountCosmeticAdded = 0x2872, + AccountCriteriaUpdate = 0x2858, + AccountDataTimes = 0x2700, + AccountExportResponse = 0x28af, + AccountMountRemoved = 0x25ab, + AccountMountUpdate = 0x25aa, + AccountNotificationsResponse = 0x2871, + AccountToyUpdate = 0x25ac, + AccountTransmogSetFavoritesUpdate = 0x25b0, + AccountTransmogUpdate = 0x25af, + AchievementDeleted = 0x26de, + AchievementEarned = 0x263c, ActivateEssenceFailed = 0x3015, ActivateSoulbindFailed = 0x3017, - ActivateTaxiReply = 0x267a, + ActivateTaxiReply = 0x2676, ActiveGlyphs = 0x2c54, - ActiveScheduledWorldStateInfo = 0x2740, - AddonListRequest = 0x263f, - AddBattlenetFriendResponse = 0x263a, - AddItemPassive = 0x25ab, - AddLossOfControl = 0x266e, - AddRunePower = 0x26b4, - AdjustSplineDuration = 0x25d0, - AdvancedCombatLog = 0x2876, - AdventureJournalDataResponse = 0x2870, - AeLootTargets = 0x2615, - AeLootTargetAck = 0x2616, - AiReaction = 0x26b1, - AlliedRaceDetails = 0x27f4, + ActiveScheduledWorldStateInfo = 0x273c, + AddonListRequest = 0x263b, + AddBattlenetFriendResponse = 0x2636, + AddItemPassive = 0x25a6, + AddLossOfControl = 0x266a, + AddRunePower = 0x26b0, + AdjustSplineDuration = 0x25cc, + AdvancedCombatLog = 0x286e, + AdventureJournalDataResponse = 0x2868, + AeLootTargets = 0x2611, + AeLootTargetAck = 0x2612, + AiReaction = 0x26ad, + AlliedRaceDetails = 0x27ec, AllAccountCriteria = 0x2571, AllAchievementData = 0x2570, AllGuildAchievements = 0x29b8, - ApplyMountEquipmentResult = 0x284d, - ArchaeologySurveryCast = 0x2588, + ApplyMountEquipmentResult = 0x2845, + ArchaeologySurveryCast = 0x2586, AreaPoiUpdateResponse = 0x3010, - AreaSpiritHealerTime = 0x2739, + AreaSpiritHealerTime = 0x2735, AreaTriggerDenied = 0x2903, AreaTriggerForceSetPositionAndFacing = 0x2900, - AreaTriggerNoCorpse = 0x2710, + AreaTriggerNoCorpse = 0x270c, AreaTriggerPlaySpellVisual = 0x28fe, AreaTriggerRePath = 0x28fd, AreaTriggerReShape = 0x2902, AreaTriggerUnattach = 0x2901, AreaTriggerUpdateDecalProperties = 0x28ff, - ArenaClearOpponents = 0x2646, - ArenaCrowdControlSpellResult = 0x262f, - ArenaPrepOpponentSpecializations = 0x2645, - ArtifactEndgamePowersRefunded = 0x279e, - ArtifactForgeError = 0x279c, - ArtifactRespecPrompt = 0x279d, - ArtifactXpGain = 0x27e7, + ArenaClearOpponents = 0x2642, + ArenaCrowdControlSpellResult = 0x262b, + ArenaPrepOpponentSpecializations = 0x2641, + ArtifactEndgamePowersRefunded = 0x2797, + ArtifactForgeError = 0x2795, + ArtifactRespecPrompt = 0x2796, + ArtifactXpGain = 0x27df, AttackerStateUpdate = 0x294d, AttackStart = 0x2938, AttackStop = 0x2939, AttackSwingError = 0x2947, AttackSwingLandedLog = 0x2948, - AuctionableTokenAuctionSold = 0x27d0, - AuctionableTokenSellAtMarketPriceResponse = 0x27cf, - AuctionableTokenSellConfirmRequired = 0x27ce, - AuctionClosedNotification = 0x26ed, - AuctionCommandResult = 0x26ea, - AuctionDisableNewPostings = 0x2896, - AuctionFavoriteList = 0x2867, - AuctionGetCommodityQuoteResult = 0x285e, - AuctionHelloResponse = 0x26e8, - AuctionListBiddedItemsResult = 0x285d, - AuctionListBucketsResult = 0x285a, - AuctionListItemsResult = 0x285b, - AuctionListOwnedItemsResult = 0x285c, - AuctionOutbidNotification = 0x26ec, - AuctionOwnerBidNotification = 0x26ee, - AuctionReplicateResponse = 0x26e9, - AuctionWonNotification = 0x26eb, + AuctionableTokenAuctionSold = 0x27c8, + AuctionableTokenSellAtMarketPriceResponse = 0x27c7, + AuctionableTokenSellConfirmRequired = 0x27c6, + AuctionClosedNotification = 0x26e9, + AuctionCommandResult = 0x26e6, + AuctionDisableNewPostings = 0x288f, + AuctionFavoriteList = 0x285f, + AuctionGetCommodityQuoteResult = 0x2856, + AuctionHelloResponse = 0x26e4, + AuctionListBiddedItemsResult = 0x2855, + AuctionListBucketsResult = 0x2852, + AuctionListItemsResult = 0x2853, + AuctionListOwnedItemsResult = 0x2854, + AuctionOutbidNotification = 0x26e8, + AuctionOwnerBidNotification = 0x26ea, + AuctionReplicateResponse = 0x26e5, + AuctionWonNotification = 0x26e7, AuraPointsDepleted = 0x2c20, AuraUpdate = 0x2c1f, AuthChallenge = 0x3048, AuthFailed = 0x256c, AuthResponse = 0x256d, AvailableHotfixes = 0x290f, - BackpackDefaultSizeChanged = 0x289b, + BackpackDefaultSizeChanged = 0x2894, BagCleanupFinished = 0x2da7, - BarberShopResult = 0x26b9, - BatchPresenceSubscription = 0x283e, + BarberShopResult = 0x26b5, + BatchPresenceSubscription = 0x2836, BattlefieldList = 0x2927, BattlefieldPortDenied = 0x292d, BattlefieldStatusActive = 0x2923, @@ -951,217 +957,218 @@ namespace Framework.Constants BattlegroundPlayerLeft = 0x292c, BattlegroundPlayerPositions = 0x2928, BattlegroundPoints = 0x2949, - BattlenetChallengeAbort = 0x2783, - BattlenetChallengeStart = 0x2782, - BattlenetNotification = 0x2800, - BattlenetResponse = 0x27ff, - BattleNetConnectionStatus = 0x2801, - BattlePayAckFailed = 0x277d, - BattlePayBattlePetDelivered = 0x2772, - BattlePayCollectionItemDelivered = 0x2773, - BattlePayConfirmPurchase = 0x277c, - BattlePayDeliveryEnded = 0x2770, - BattlePayDeliveryStarted = 0x276f, - BattlePayDistributionAssignVasResponse = 0x287f, - BattlePayDistributionUnrevoked = 0x276d, - BattlePayDistributionUpdate = 0x276e, - BattlePayGetDistributionListResponse = 0x276c, - BattlePayGetProductListResponse = 0x276a, - BattlePayGetPurchaseListResponse = 0x276b, - BattlePayMountDelivered = 0x2771, - BattlePayPurchaseUpdate = 0x277b, - BattlePayStartCheckout = 0x281c, - BattlePayStartDistributionAssignToTargetResponse = 0x2779, - BattlePayStartPurchaseResponse = 0x2778, - BattlePayValidatePurchaseResponse = 0x2810, - BattlePetsHealed = 0x25f2, - BattlePetCageDateError = 0x2675, - BattlePetDeleted = 0x25ef, - BattlePetError = 0x2635, - BattlePetJournal = 0x25ee, - BattlePetJournalLockAcquired = 0x25ec, - BattlePetJournalLockDenied = 0x25ed, - BattlePetRestored = 0x25f1, - BattlePetRevoked = 0x25f0, - BattlePetTrapLevel = 0x25ea, - BattlePetUpdates = 0x25e9, + BattlenetChallengeAbort = 0x277f, + BattlenetChallengeStart = 0x277e, + BattlenetNotification = 0x27f8, + BattlenetResponse = 0x27f7, + BattleNetConnectionStatus = 0x27f9, + BattlePayAckFailed = 0x2779, + BattlePayBattlePetDelivered = 0x276e, + BattlePayCollectionItemDelivered = 0x276f, + BattlePayConfirmPurchase = 0x2778, + BattlePayDeliveryEnded = 0x276c, + BattlePayDeliveryStarted = 0x276b, + BattlePayDistributionAssignVasResponse = 0x2877, + BattlePayDistributionUnrevoked = 0x2769, + BattlePayDistributionUpdate = 0x276a, + BattlePayGetDistributionListResponse = 0x2768, + BattlePayGetProductListResponse = 0x2766, + BattlePayGetPurchaseListResponse = 0x2767, + BattlePayMountDelivered = 0x276d, + BattlePayPurchaseUpdate = 0x2777, + BattlePayStartCheckout = 0x2814, + BattlePayStartDistributionAssignToTargetResponse = 0x2775, + BattlePayStartPurchaseResponse = 0x2774, + BattlePayValidatePurchaseResponse = 0x2808, + BattlePetsHealed = 0x25ee, + BattlePetCageDateError = 0x2671, + BattlePetDeleted = 0x25eb, + BattlePetError = 0x2631, + BattlePetJournal = 0x25ea, + BattlePetJournalLockAcquired = 0x25e8, + BattlePetJournalLockDenied = 0x25e9, + BattlePetRestored = 0x25ed, + BattlePetRevoked = 0x25ec, + BattlePetTrapLevel = 0x25e6, + BattlePetUpdates = 0x25e5, BindPointUpdate = 0x257d, - BlackMarketBidOnItemResult = 0x2625, - BlackMarketOutbid = 0x2626, - BlackMarketRequestItemsResult = 0x2624, - BlackMarketWon = 0x2627, - BonusRollEmpty = 0x2642, + BlackMarketBidOnItemResult = 0x2621, + BlackMarketOutbid = 0x2622, + BlackMarketRequestItemsResult = 0x2620, + BlackMarketWon = 0x2623, + BonusRollEmpty = 0x263e, BossKill = 0x294c, BreakTarget = 0x2937, BroadcastAchievement = 0x2bbc, - BroadcastSummonCast = 0x2840, - BroadcastSummonResponse = 0x2841, - BuyFailed = 0x26c2, - BuySucceeded = 0x26c1, + BroadcastSummonCast = 0x2838, + BroadcastSummonResponse = 0x2839, + BuyFailed = 0x26be, + BuySucceeded = 0x26bd, CacheInfo = 0x291d, CacheVersion = 0x291c, - CalendarClearPendingAction = 0x269a, - CalendarCommandResult = 0x269b, - CalendarCommunityInvite = 0x268a, - CalendarEventRemovedAlert = 0x2692, - CalendarEventUpdatedAlert = 0x2693, - CalendarInviteAdded = 0x268b, - CalendarInviteAlert = 0x268f, - CalendarInviteNotes = 0x2694, - CalendarInviteNotesAlert = 0x2695, - CalendarInviteRemoved = 0x268c, - CalendarInviteRemovedAlert = 0x2691, - CalendarInviteStatus = 0x268d, - CalendarInviteStatusAlert = 0x2690, - CalendarModeratorStatus = 0x268e, - CalendarRaidLockoutAdded = 0x2696, - CalendarRaidLockoutRemoved = 0x2697, - CalendarRaidLockoutUpdated = 0x2698, - CalendarSendCalendar = 0x2688, - CalendarSendEvent = 0x2689, - CalendarSendNumPending = 0x2699, - CameraEffect = 0x271f, - CancelAutoRepeat = 0x26d8, + CalendarClearPendingAction = 0x2696, + CalendarCommandResult = 0x2697, + CalendarCommunityInvite = 0x2686, + CalendarEventRemovedAlert = 0x268e, + CalendarEventUpdatedAlert = 0x268f, + CalendarInviteAdded = 0x2687, + CalendarInviteAlert = 0x268b, + CalendarInviteNotes = 0x2690, + CalendarInviteNotesAlert = 0x2691, + CalendarInviteRemoved = 0x2688, + CalendarInviteRemovedAlert = 0x268d, + CalendarInviteStatus = 0x2689, + CalendarInviteStatusAlert = 0x268c, + CalendarModeratorStatus = 0x268a, + CalendarRaidLockoutAdded = 0x2692, + CalendarRaidLockoutRemoved = 0x2693, + CalendarRaidLockoutUpdated = 0x2694, + CalendarSendCalendar = 0x2684, + CalendarSendEvent = 0x2685, + CalendarSendNumPending = 0x2695, + CameraEffect = 0x271b, + CancelAutoRepeat = 0x26d4, CancelCombat = 0x2946, CancelOrphanSpellVisual = 0x2c46, - CancelPreloadWorld = 0x259a, - CancelScene = 0x2634, + CancelPreloadWorld = 0x2595, + CancelScene = 0x2630, CancelSpellVisual = 0x2c44, CancelSpellVisualKit = 0x2c48, CanDuelResult = 0x2942, - CanRedeemTokenForBalanceResponse = 0x280f, + CanRedeemTokenForBalanceResponse = 0x2807, CapturePointRemoved = 0x292a, CastFailed = 0x2c57, - ChainMissileBounce = 0x25c8, - ChallengeModeComplete = 0x2609, - ChallengeModeRequestLeadersResult = 0x260d, - ChallengeModeReset = 0x2608, - ChallengeModeStart = 0x2606, - ChallengeModeUpdateDeathCount = 0x2607, + ChainMissileBounce = 0x25c4, + ChallengeModeComplete = 0x2605, + ChallengeModeRequestLeadersResult = 0x2609, + ChallengeModeReset = 0x2604, + ChallengeModeStart = 0x2602, + ChallengeModeUpdateDeathCount = 0x2603, ChangePlayerDifficultyResult = 0x3004, - ChangeRealmTicketResponse = 0x2802, - ChannelList = 0x2bc3, - ChannelNotify = 0x2bc0, - ChannelNotifyJoined = 0x2bc1, - ChannelNotifyLeft = 0x2bc2, - CharacterCheckUpgradeResult = 0x27b9, - CharacterLoginFailed = 0x26ff, - CharacterObjectTestResponse = 0x2781, - CharacterRenameResult = 0x275c, - CharacterUpgradeAborted = 0x27b8, - CharacterUpgradeComplete = 0x27b7, - CharacterUpgradeManualUnrevokeResult = 0x27ba, - CharacterUpgradeStarted = 0x27b6, - CharCustomizeFailure = 0x26dc, - CharCustomizeSuccess = 0x26dd, - CharFactionChangeResult = 0x27a3, + ChangeRealmTicketResponse = 0x27fa, + ChannelList = 0x2bc4, + ChannelNotify = 0x2bc1, + ChannelNotifyJoined = 0x2bc2, + ChannelNotifyLeft = 0x2bc3, + CharacterCheckUpgradeResult = 0x27b2, + CharacterLoginFailed = 0x26fb, + CharacterObjectTestResponse = 0x277d, + CharacterRenameResult = 0x2758, + CharacterUpgradeAborted = 0x27b1, + CharacterUpgradeComplete = 0x27b0, + CharacterUpgradeManualUnrevokeResult = 0x27b3, + CharacterUpgradeStarted = 0x27af, + CharCustomizeFailure = 0x26d8, + CharCustomizeSuccess = 0x26d9, + CharFactionChangeResult = 0x279c, Chat = 0x2bad, ChatAutoResponded = 0x2bb8, - ChatCanLocalWhisperTargetResponse = 0x2bca, - ChatDown = 0x2bbd, + ChatCanLocalWhisperTargetResponse = 0x2bcb, + ChatDown = 0x2bbe, ChatIgnoredAccountMuted = 0x2bac, - ChatIsDown = 0x2bbe, + ChatIsDown = 0x2bbf, ChatNotInParty = 0x2bb2, ChatPlayerAmbiguous = 0x2bb0, ChatPlayerNotfound = 0x2bb7, - ChatReconnect = 0x2bbf, - ChatRegionalServiceStatus = 0x2bc5, + ChatReconnect = 0x2bc0, + ChatRegionalServiceStatus = 0x2bc6, ChatRestricted = 0x2bb3, - ChatServerMessage = 0x2bc4, + ChatServerMessage = 0x2bc5, CheatIgnoreDimishingReturns = 0x2c12, CheckAbandonNpe = 0x3018, CheckCharacterNameAvailabilityResult = 0x2584, - CheckWargameEntry = 0x2592, - ChromieTimeSelectExpansionSuccess = 0x286a, - ClaimRafRewardResponse = 0x2851, + CheckWargameEntry = 0x258f, + ChromieTimeSelectExpansionSuccess = 0x2862, + ClaimRafRewardResponse = 0x2849, ClearAllSpellCharges = 0x2c24, - ClearBossEmotes = 0x25bb, - ClearCooldown = 0x26b6, + ClearBossEmotes = 0x25b7, + ClearCooldown = 0x26b2, ClearCooldowns = 0x2c23, ClearResurrect = 0x257f, ClearSpellCharges = 0x2c25, ClearTarget = 0x2943, ClearTreasurePickerCache = 0x2aa1, - CloseArtifactForge = 0x279b, - ClubFinderErrorMessage = 0x2849, - ClubFinderGetClubPostingIdsResponse = 0x284c, - ClubFinderLookupClubPostingsList = 0x284a, - ClubFinderResponseCharacterApplicationList = 0x2847, - ClubFinderResponsePostRecruitmentMessage = 0x284b, - ClubFinderUpdateApplications = 0x2848, - ClubFinderWhisperApplicantResponse = 0x288d, - CoinRemoved = 0x2614, + CloseArtifactForge = 0x2794, + ClubFinderErrorMessage = 0x2841, + ClubFinderGetClubPostingIdsResponse = 0x2844, + ClubFinderLookupClubPostingsList = 0x2842, + ClubFinderResponseCharacterApplicationList = 0x283f, + ClubFinderResponsePostRecruitmentMessage = 0x2843, + ClubFinderUpdateApplications = 0x2840, + ClubFinderWhisperApplicantResponse = 0x2886, + CoinRemoved = 0x2610, CombatEventFailed = 0x293a, - CommentatorMapInfo = 0x2701, - CommentatorPlayerInfo = 0x2702, - CommentatorStateChanged = 0x2700, - CommerceTokenGetCountResponse = 0x27cb, - CommerceTokenGetLogResponse = 0x27d7, - CommerceTokenGetMarketPriceResponse = 0x27cd, - CommerceTokenUpdate = 0x27cc, - ComplaintResult = 0x26a8, - CompleteShipmentResponse = 0x2794, - ConfirmPartyInvite = 0x280e, + CommentatorMapInfo = 0x26fd, + CommentatorPlayerInfo = 0x26fe, + CommentatorStateChanged = 0x26fc, + CommerceTokenGetCountResponse = 0x27c3, + CommerceTokenGetLogResponse = 0x27cf, + CommerceTokenGetMarketPriceResponse = 0x27c5, + CommerceTokenUpdate = 0x27c4, + ComplaintResult = 0x26a4, + CompleteShipmentResponse = 0x278d, + ConfirmPartyInvite = 0x2806, ConnectTo = 0x304d, - ConquestFormulaConstants = 0x277e, - ConsoleWrite = 0x2632, - ConsumableTokenBuyAtMarketPriceResponse = 0x27d3, - ConsumableTokenBuyChoiceRequired = 0x27d2, - ConsumableTokenCanVeteranBuyResponse = 0x27d1, - ConsumableTokenRedeemConfirmRequired = 0x27d5, - ConsumableTokenRedeemResponse = 0x27d6, - ContactList = 0x277f, - ContributionLastUpdateResponse = 0x2815, - ControlUpdate = 0x2644, - ConvertItemsToCurrencyValue = 0x2873, - CooldownCheat = 0x2732, - CooldownEvent = 0x26b5, - CorpseLocation = 0x264c, - CorpseReclaimDelay = 0x2743, - CorpseTransportQuery = 0x270c, + ConquestFormulaConstants = 0x277a, + ConsoleWrite = 0x262e, + ConsumableTokenBuyAtMarketPriceResponse = 0x27cb, + ConsumableTokenBuyChoiceRequired = 0x27ca, + ConsumableTokenCanVeteranBuyResponse = 0x27c9, + ConsumableTokenRedeemConfirmRequired = 0x27cd, + ConsumableTokenRedeemResponse = 0x27ce, + ContactList = 0x277b, + ContributionLastUpdateResponse = 0x280d, + ControlUpdate = 0x2640, + ConvertItemsToCurrencyValue = 0x286b, + CooldownCheat = 0x272e, + CooldownEvent = 0x26b1, + CorpseLocation = 0x2648, + CorpseReclaimDelay = 0x273f, + CorpseTransportQuery = 0x2708, CovenantCallingsAvailabilityResponse = 0x2aa3, - CovenantPreviewOpenNpc = 0x27f7, - CovenantRenownSendCatchupState = 0x2874, - CraftingHouseHelloResponse = 0x28a9, - CraftingOrderCancelResult = 0x28a5, - CraftingOrderClaimResult = 0x28a1, - CraftingOrderCraftResult = 0x28a3, - CraftingOrderCreateResult = 0x289f, - CraftingOrderFulfillResult = 0x28a4, - CraftingOrderListOrdersResponse = 0x28a0, - CraftingOrderRejectResult = 0x28a7, - CraftingOrderReleaseResult = 0x28a2, - CraftingOrderUpdateState = 0x28aa, - CraftEnchantResult = 0x28a8, - CreateChar = 0x26fb, - CreateShipmentResponse = 0x2793, - CreatorVisualsOverride = 0x28ad, - CriteriaDeleted = 0x26e1, - CriteriaUpdate = 0x26db, - CrossedInebriationThreshold = 0x26bd, - CustomLoadScreen = 0x25cb, + CovenantPreviewOpenNpc = 0x27ef, + CovenantRenownSendCatchupState = 0x286c, + CraftingHouseHelloResponse = 0x28a2, + CraftingOrderCancelResult = 0x289e, + CraftingOrderClaimResult = 0x289a, + CraftingOrderCraftResult = 0x289c, + CraftingOrderCreateResult = 0x2898, + CraftingOrderFulfillResult = 0x289d, + CraftingOrderListOrdersResponse = 0x2899, + CraftingOrderRejectResult = 0x28a0, + CraftingOrderReleaseResult = 0x289b, + CraftingOrderUpdateState = 0x28a3, + CraftEnchantResult = 0x28a1, + CreateChar = 0x26f7, + CreateShipmentResponse = 0x278c, + CreatorVisualsOverride = 0x28a6, + CriteriaDeleted = 0x26dd, + CriteriaUpdate = 0x26d7, + CrossedInebriationThreshold = 0x26b9, + CustomLoadScreen = 0x25c7, DailyQuestsReset = 0x2a80, - DamageCalcLog = 0x27c0, + DamageCalcLog = 0x2c63, DbReply = 0x290e, - DeathReleaseLoc = 0x26ce, - DebugMenuManagerFullUpdate = 0x2652, + DeathReleaseLoc = 0x26ca, + DebugMenuManagerFullUpdate = 0x264e, DefenseMessage = 0x2bb6, - DeleteChar = 0x26fc, + DeleteChar = 0x26f8, DeleteExpiredMissionsResult = 0x2980, - DestroyArenaUnit = 0x273b, - DestructibleBuildingDamage = 0x26f3, - DifferentInstanceFromParty = 0x258c, - DisenchantCredit = 0x25a8, + DestroyArenaUnit = 0x2737, + DestructibleBuildingDamage = 0x26ef, + DifferentInstanceFromParty = 0x2589, + DisenchantCredit = 0x25a3, DismountResult = 0x257c, DispelFailed = 0x2c2d, - DisplayGameError = 0x25a1, + DisplayGameError = 0x259c, DisplayPlayerChoice = 0x2ffc, - DisplayPromotion = 0x2649, + DisplayPromotion = 0x2645, DisplayQuestPopup = 0x2a9e, - DisplaySoulbindUpdateMessage = 0x2878, - DisplayToast = 0x2621, - DisplayWorldText = 0x27e8, - DontAutoPushSpellsToActionBar = 0x25e0, + DisplaySoulbindUpdateMessage = 0x2870, + DisplayToast = 0x261d, + DisplayWorldText = 0x27e0, + DisplayWorldTextOnTarget = 0x2c62, + DontAutoPushSpellsToActionBar = 0x25dc, DropNewConnection = 0x304c, DuelArranged = 0x293c, DuelComplete = 0x2940, @@ -1170,50 +1177,51 @@ namespace Framework.Constants DuelOutOfBounds = 0x293d, DuelRequested = 0x293b, DuelWinner = 0x2941, - DurabilityDamageDeath = 0x273e, - Emote = 0x27c1, - EnableBarberShop = 0x26b8, - EnchantmentLog = 0x270d, - EncounterEnd = 0x2777, - EncounterStart = 0x2776, - EndLightningStorm = 0x26a5, - EnsureWorldLoaded = 0x2887, + DurabilityDamageDeath = 0x273a, + Emote = 0x27b9, + EnableBarberShop = 0x26b4, + EnchantmentLog = 0x2709, + EncounterEnd = 0x2773, + EncounterStart = 0x2772, + EndLightningStorm = 0x26a1, + EnsureWorldLoaded = 0x2880, EnterEncryptedMode = 0x3049, EnumCharactersResult = 0x2583, - EnumVasPurchaseStatesResponse = 0x27ed, + EnumVasPurchaseStatesResponse = 0x27e5, EnvironmentalDamageLog = 0x2c1e, - EquipmentSetId = 0x26ae, + EquipmentSetId = 0x26aa, ExpectedSpamRecords = 0x2bb1, - ExplorationExperience = 0x2758, - ExternalTransactionIdGenerated = 0x2871, - FactionBonusInfo = 0x271e, + ExplorationExperience = 0x2754, + ExternalTransactionIdGenerated = 0x2869, + FactionBonusInfo = 0x271a, FailedPlayerCondition = 0x2ffa, - FailedQuestTurnIn = 0x280b, - FeatureSystemStatus = 0x25bf, - FeatureSystemStatusGlueScreen = 0x25c0, - FeignDeathResisted = 0x273d, - FishEscaped = 0x26cb, - FishNotHooked = 0x26ca, + FailedQuestTurnIn = 0x2803, + FeatureSystemStatus = 0x25bb, + FeatureSystemStatusGlueScreen = 0x25bc, + FeignDeathResisted = 0x2739, + FishEscaped = 0x26c7, + FishNotHooked = 0x26c6, FlightSplineSync = 0x2e2b, - ForcedDeathUpdate = 0x26cf, - ForceAnim = 0x274a, - ForceAnimations = 0x274b, - ForceObjectRelink = 0x2648, - FriendStatus = 0x2780, - GainMawPower = 0x27dc, - GameObjectActivateAnimKit = 0x25c3, - GameObjectBase = 0x2822, - GameObjectCloseInteraction = 0x288b, - GameObjectCustomAnim = 0x25c4, - GameObjectDespawn = 0x25c5, - GameObjectInteraction = 0x288a, + ForcedDeathUpdate = 0x26cb, + ForceAnim = 0x2746, + ForceAnimations = 0x2747, + ForceObjectRelink = 0x2644, + ForceRandomTransmogToast = 0x25ae, + FriendStatus = 0x277c, + GainMawPower = 0x27d4, + GameObjectActivateAnimKit = 0x25bf, + GameObjectBase = 0x281a, + GameObjectCloseInteraction = 0x2884, + GameObjectCustomAnim = 0x25c0, + GameObjectDespawn = 0x25c1, + GameObjectInteraction = 0x2883, GameObjectPlaySpellVisual = 0x2c4b, GameObjectPlaySpellVisualKit = 0x2c4a, - GameObjectResetState = 0x2718, - GameObjectSetStateLocal = 0x27fe, - GameSpeedSet = 0x267e, - GameTimeSet = 0x2706, - GameTimeUpdate = 0x2705, + GameObjectResetState = 0x2714, + GameObjectSetStateLocal = 0x27f6, + GameSpeedSet = 0x267a, + GameTimeSet = 0x2702, + GameTimeUpdate = 0x2701, GarrisonActivateMissionBonusAbility = 0x2982, GarrisonAddEvent = 0x29a6, GarrisonAddFollowerResult = 0x2974, @@ -1285,35 +1293,36 @@ namespace Framework.Constants GarrisonUpgradeResult = 0x296b, GarrisonUseRecallPortalResult = 0x297d, GenerateRandomCharacterNameResult = 0x2585, - GenerateSsoTokenResponse = 0x2816, - GetAccountCharacterListResult = 0x275a, + GenerateSsoTokenResponse = 0x280e, + GetAccountCharacterListResult = 0x2756, GetGarrisonInfoResult = 0x295e, - GetLandingPageShipmentsResponse = 0x2796, - GetRemainingGameTimeResponse = 0x27d4, - GetSelectedTrophyIdResponse = 0x27be, - GetShipmentsOfTypeResponse = 0x2795, - GetShipmentInfoResponse = 0x2791, - GetTrophyListResponse = 0x27bd, - GetVasAccountCharacterListResult = 0x27e9, - GetVasTransferTargetRealmListResult = 0x27ea, + GetLandingPageShipmentsResponse = 0x278f, + GetRealmHiddenResult = 0x28b4, + GetRemainingGameTimeResponse = 0x27cc, + GetSelectedTrophyIdResponse = 0x27b7, + GetShipmentsOfTypeResponse = 0x278e, + GetShipmentInfoResponse = 0x278a, + GetTrophyListResponse = 0x27b6, + GetVasAccountCharacterListResult = 0x27e1, + GetVasTransferTargetRealmListResult = 0x27e2, GmPlayerInfo = 0x3005, GmRequestPlayerInfo = 0x2ffb, - GmTicketCaseStatus = 0x26a0, - GmTicketSystemStatus = 0x269f, - GodMode = 0x26f6, + GmTicketCaseStatus = 0x269c, + GmTicketSystemStatus = 0x269b, + GodMode = 0x26f2, GossipComplete = 0x2a97, GossipMessage = 0x2a98, GossipOptionNpcInteraction = 0x2aa7, - GossipPoi = 0x278e, + GossipPoi = 0x2787, GossipQuestUpdate = 0x2a99, GossipRefreshOptions = 0x2aa6, - GroupActionThrottled = 0x2590, - GroupAutoKick = 0x278b, - GroupDecline = 0x2787, - GroupDestroyed = 0x278a, - GroupNewLeader = 0x262a, - GroupRequestDecline = 0x2788, - GroupUninvite = 0x2789, + GroupActionThrottled = 0x258d, + GroupAutoKick = 0x2784, + GroupDecline = 0x2780, + GroupDestroyed = 0x2783, + GroupNewLeader = 0x2626, + GroupRequestDecline = 0x2781, + GroupUninvite = 0x2782, GuildAchievementDeleted = 0x29c5, GuildAchievementEarned = 0x29c4, GuildAchievementMembers = 0x29c7, @@ -1367,59 +1376,59 @@ namespace Framework.Constants GuildRoster = 0x29bb, GuildRosterUpdate = 0x29bc, GuildSendRankChange = 0x29b9, - HealthUpdate = 0x26cc, - HighestThreatUpdate = 0x26d4, + HealthUpdate = 0x26c8, + HighestThreatUpdate = 0x26d0, HotfixConnect = 0x2911, HotfixMessage = 0x2910, - InitializeFactions = 0x271d, + InitializeFactions = 0x2719, InitialSetup = 0x2580, - InitWorldStates = 0x273f, - InspectResult = 0x262e, - InstanceEncounterChangePriority = 0x27a9, - InstanceEncounterDisengageUnit = 0x27a8, - InstanceEncounterEnd = 0x27b1, - InstanceEncounterEngageUnit = 0x27a7, - InstanceEncounterGainCombatResurrectionCharge = 0x27b3, - InstanceEncounterInCombatResurrection = 0x27b2, - InstanceEncounterObjectiveComplete = 0x27ac, - InstanceEncounterObjectiveStart = 0x27ab, - InstanceEncounterObjectiveUpdate = 0x27b0, - InstanceEncounterPhaseShiftChanged = 0x27b4, - InstanceEncounterStart = 0x27ad, - InstanceEncounterTimerStart = 0x27aa, - InstanceEncounterUpdateAllowReleaseInProgress = 0x27af, - InstanceEncounterUpdateSuppressRelease = 0x27ae, - InstanceGroupSizeChanged = 0x26f4, - InstanceInfo = 0x2631, - InstanceReset = 0x2683, - InstanceResetFailed = 0x2684, - InstanceSaveCreated = 0x2775, + InitWorldStates = 0x273b, + InspectResult = 0x262a, + InstanceEncounterChangePriority = 0x27a2, + InstanceEncounterDisengageUnit = 0x27a1, + InstanceEncounterEnd = 0x27aa, + InstanceEncounterEngageUnit = 0x27a0, + InstanceEncounterGainCombatResurrectionCharge = 0x27ac, + InstanceEncounterInCombatResurrection = 0x27ab, + InstanceEncounterObjectiveComplete = 0x27a5, + InstanceEncounterObjectiveStart = 0x27a4, + InstanceEncounterObjectiveUpdate = 0x27a9, + InstanceEncounterPhaseShiftChanged = 0x27ad, + InstanceEncounterStart = 0x27a6, + InstanceEncounterTimerStart = 0x27a3, + InstanceEncounterUpdateAllowReleaseInProgress = 0x27a8, + InstanceEncounterUpdateSuppressRelease = 0x27a7, + InstanceGroupSizeChanged = 0x26f0, + InstanceInfo = 0x262d, + InstanceReset = 0x267f, + InstanceResetFailed = 0x2680, + InstanceSaveCreated = 0x2771, InterruptPowerRegen = 0x2c59, InvalidatePageText = 0x2918, InvalidatePlayer = 0x2fff, - InvalidPromotionCode = 0x274c, + InvalidPromotionCode = 0x2748, InventoryChangeFailure = 0x2da5, - InventoryFixupComplete = 0x280d, - InventoryFullOverflow = 0x281e, - IslandAzeriteGain = 0x2755, - IslandComplete = 0x2756, + InventoryFixupComplete = 0x2805, + InventoryFullOverflow = 0x2816, + IslandAzeriteGain = 0x2751, + IslandComplete = 0x2752, IsQuestCompleteResponse = 0x2a84, - ItemChanged = 0x26e5, - ItemCooldown = 0x27bf, - ItemEnchantTimeUpdate = 0x274e, - ItemExpirePurchaseRefund = 0x25a0, - ItemInteractionComplete = 0x2869, - ItemPurchaseRefundResult = 0x259e, - ItemPushResult = 0x2620, - ItemTimeUpdate = 0x274d, - KickReason = 0x2686, - LatencyReportPing = 0x287b, + ItemChanged = 0x26e1, + ItemCooldown = 0x27b8, + ItemEnchantTimeUpdate = 0x274a, + ItemExpirePurchaseRefund = 0x259b, + ItemInteractionComplete = 0x2861, + ItemPurchaseRefundResult = 0x2599, + ItemPushResult = 0x261c, + ItemTimeUpdate = 0x2749, + KickReason = 0x2682, + LatencyReportPing = 0x2873, LearnedSpells = 0x2c4d, - LearnPvpTalentFailed = 0x25d4, - LearnTalentFailed = 0x25d3, - LegacyLootRules = 0x2823, - LevelLinkingResult = 0x284f, - LevelUpInfo = 0x26e3, + LearnPvpTalentFailed = 0x25d0, + LearnTalentFailed = 0x25cf, + LegacyLootRules = 0x281b, + LevelLinkingResult = 0x2847, + LevelUpInfo = 0x26df, LfgBootPlayer = 0x2a35, LfgDisabled = 0x2a33, LfgExpandSearchPrompt = 0x2a3b, @@ -1447,48 +1456,48 @@ namespace Framework.Constants LfgSlotInvalid = 0x2a30, LfgTeleportDenied = 0x2a32, LfgUpdateStatus = 0x2a24, - LiveRegionAccountRestoreResult = 0x2767, - LiveRegionCharacterCopyResult = 0x2766, - LiveRegionGetAccountCharacterListResult = 0x275b, - LiveRegionKeyBindingsCopyResult = 0x2768, - LoadCufProfiles = 0x25bc, - LoadEquipmentSet = 0x2708, - LobbyMatchmakerPartyInfo = 0x288f, - LobbyMatchmakerPartyInviteRejected = 0x2890, - LobbyMatchmakerReceiveInvite = 0x2891, - LoginSetTimeSpeed = 0x2707, - LoginVerifyWorld = 0x259b, - LogoutCancelAck = 0x2682, - LogoutComplete = 0x2681, - LogoutResponse = 0x2680, - LogXpGain = 0x26df, - LootAllPassed = 0x261e, - LootList = 0x273a, - LootMoneyNotify = 0x2619, - LootRelease = 0x2618, - LootReleaseAll = 0x2617, - LootRemoved = 0x2613, - LootResponse = 0x2612, - LootRoll = 0x261b, - LootRollsComplete = 0x261d, - LootRollWon = 0x261f, - LossOfControlAuraUpdate = 0x266d, - MailCommandResult = 0x2638, - MailListResult = 0x274f, - MailQueryNextTimeResult = 0x2750, + LiveRegionAccountRestoreResult = 0x2763, + LiveRegionCharacterCopyResult = 0x2762, + LiveRegionGetAccountCharacterListResult = 0x2757, + LiveRegionKeyBindingsCopyResult = 0x2764, + LoadCufProfiles = 0x25b8, + LoadEquipmentSet = 0x2704, + LobbyMatchmakerPartyInfo = 0x2888, + LobbyMatchmakerPartyInviteRejected = 0x2889, + LobbyMatchmakerReceiveInvite = 0x288a, + LoginSetTimeSpeed = 0x2703, + LoginVerifyWorld = 0x2596, + LogoutCancelAck = 0x267e, + LogoutComplete = 0x267d, + LogoutResponse = 0x267c, + LogXpGain = 0x26db, + LootAllPassed = 0x261a, + LootList = 0x2736, + LootMoneyNotify = 0x2615, + LootRelease = 0x2614, + LootReleaseAll = 0x2613, + LootRemoved = 0x260f, + LootResponse = 0x260e, + LootRoll = 0x2617, + LootRollsComplete = 0x2619, + LootRollWon = 0x261b, + LossOfControlAuraUpdate = 0x2669, + MailCommandResult = 0x2634, + MailListResult = 0x274b, + MailQueryNextTimeResult = 0x274c, MapObjectivesInit = 0x294b, - MapObjEvents = 0x25c6, - MasterLootCandidateList = 0x261c, - MeetingStoneFailed = 0x2892, + MapObjEvents = 0x25c2, + MasterLootCandidateList = 0x2618, + MeetingStoneFailed = 0x288b, MessageBox = 0x2576, - MinimapPing = 0x26c9, + MinimapPing = 0x26c5, MirrorImageComponentedData = 0x2c14, MirrorImageCreatureData = 0x2c13, - MissileCancel = 0x25c7, - ModifyCooldown = 0x275d, + MissileCancel = 0x25c3, + ModifyCooldown = 0x2759, Motd = 0x2baf, MountResult = 0x257b, - MovementEnforcementAlert = 0x283f, + MovementEnforcementAlert = 0x2837, MoveAddImpulse = 0x2e32, MoveApplyInertia = 0x2e2e, MoveApplyMovementForce = 0x2e15, @@ -1596,84 +1605,83 @@ namespace Framework.Constants MoveUpdateTeleport = 0x2de1, MoveUpdateTurnRate = 0x2ddd, MoveUpdateWalkSpeed = 0x2dd8, - MultiFloorLeaveFloor = 0x27d9, - MultiFloorNewFloor = 0x27d8, - MythicPlusAllMapStats = 0x260a, - MythicPlusCurrentAffixes = 0x260c, - MythicPlusNewWeekRecord = 0x260f, - MythicPlusSeasonData = 0x260b, - NeutralPlayerFactionSelectResult = 0x25db, - NewTaxiPath = 0x267b, - NewWorld = 0x2598, + MultiFloorLeaveFloor = 0x27d1, + MultiFloorNewFloor = 0x27d0, + MythicPlusAllMapStats = 0x2606, + MythicPlusCurrentAffixes = 0x2608, + MythicPlusNewWeekRecord = 0x260b, + MythicPlusSeasonData = 0x2607, + NeutralPlayerFactionSelectResult = 0x25d7, + NewDataBuild = 0x28b3, + NewTaxiPath = 0x2677, + NewWorld = 0x2593, NotifyDestLocSpellCast = 0x2c43, - NotifyMissileTrajectoryCollision = 0x26a7, - NotifyMoney = 0x259d, - NotifyReceivedMail = 0x2639, - NpcInteractionOpenResult = 0x2889, - OfferPetitionError = 0x26b2, - OnCancelExpectedRideVehicleAura = 0x26e0, + NotifyMissileTrajectoryCollision = 0x26a3, + NotifyMoney = 0x2598, + NotifyReceivedMail = 0x2635, + NpcInteractionOpenResult = 0x2882, + OfferPetitionError = 0x26ae, + OnCancelExpectedRideVehicleAura = 0x26dc, OnMonsterMove = 0x2dd4, - OpenArtifactForge = 0x279a, + OpenArtifactForge = 0x2793, OpenContainer = 0x2da6, OpenLfgDungeonFinder = 0x2a31, - OpenShipmentNpcResult = 0x2792, - OverrideLight = 0x26b7, - PageText = 0x2713, - PartyCommandResult = 0x278c, - PartyInvite = 0x25bd, - PartyKillLog = 0x2753, - PartyMemberFullState = 0x2752, - PartyMemberPartialState = 0x2751, - PartyNotifyLfgLeaderChange = 0x286f, - PartyUpdate = 0x25f3, - PastTimeEvents = 0x25c2, - PauseMirrorTimer = 0x270a, - PendingRaidLock = 0x26f2, - PerksProgramActivityComplete = 0x2885, - PerksProgramActivityUpdate = 0x2881, - PerksProgramDisabled = 0x2886, - PerksProgramResult = 0x2882, - PerksProgramVendorUpdate = 0x2880, - PetitionAlreadySigned = 0x25a3, + OpenShipmentNpcResult = 0x278b, + OverrideLight = 0x26b3, + PageText = 0x270f, + PartyCommandResult = 0x2785, + PartyInvite = 0x25b9, + PartyKillLog = 0x274f, + PartyMemberFullState = 0x274e, + PartyMemberPartialState = 0x274d, + PartyNotifyLfgLeaderChange = 0x2867, + PartyUpdate = 0x25ef, + PastTimeEvents = 0x25be, + PauseMirrorTimer = 0x2706, + PendingRaidLock = 0x26ee, + PerksProgramActivityComplete = 0x287e, + PerksProgramActivityUpdate = 0x2879, + PerksProgramDisabled = 0x287f, + PerksProgramResult = 0x287b, + PerksProgramVendorPending = 0x287a, + PerksProgramVendorUpdate = 0x2878, + PetitionAlreadySigned = 0x259e, PetitionRenameGuildResponse = 0x29fa, - PetitionShowList = 0x26ba, - PetitionShowSignatures = 0x26bb, - PetitionSignResults = 0x2745, - PetActionFeedback = 0x2742, - PetActionSound = 0x269d, - PetAdded = 0x2595, - PetBattleChatRestricted = 0x2601, - PetBattleDebugQueueDumpResponse = 0x2672, - PetBattleFinalizeLocation = 0x25fa, - PetBattleFinalRound = 0x25ff, - PetBattleFinished = 0x2600, - PetBattleFirstRound = 0x25fc, - PetBattleInitialUpdate = 0x25fb, - PetBattleMaxGameLengthWarning = 0x2602, - PetBattlePvpChallenge = 0x25f9, - PetBattleQueueProposeMatch = 0x2636, - PetBattleQueueStatus = 0x2637, - PetBattleReplacementsMade = 0x25fe, - PetBattleRequestFailed = 0x25f8, - PetBattleRoundResult = 0x25fd, - PetBattleSlotUpdates = 0x25eb, + PetitionShowList = 0x26b6, + PetitionShowSignatures = 0x26b7, + PetitionSignResults = 0x2741, + PetActionFeedback = 0x273e, + PetActionSound = 0x2699, + PetBattleChatRestricted = 0x25fd, + PetBattleDebugQueueDumpResponse = 0x266e, + PetBattleFinalizeLocation = 0x25f6, + PetBattleFinalRound = 0x25fb, + PetBattleFinished = 0x25fc, + PetBattleFirstRound = 0x25f8, + PetBattleInitialUpdate = 0x25f7, + PetBattleMaxGameLengthWarning = 0x25fe, + PetBattlePvpChallenge = 0x25f5, + PetBattleQueueProposeMatch = 0x2632, + PetBattleQueueStatus = 0x2633, + PetBattleReplacementsMade = 0x25fa, + PetBattleRequestFailed = 0x25f4, + PetBattleRoundResult = 0x25f9, + PetBattleSlotUpdates = 0x25e7, PetCastFailed = 0x2c58, PetClearSpells = 0x2c21, - PetDismissSound = 0x269e, - PetGodMode = 0x2678, - PetGuids = 0x26fe, + PetDismissSound = 0x269a, + PetGodMode = 0x2674, + PetGuids = 0x26fa, PetLearnedSpells = 0x2c4f, - PetMode = 0x258b, - PetNameInvalid = 0x26bf, - PetNewlyTamed = 0x2589, - PetSlotUpdated = 0x258a, + PetMode = 0x2588, + PetNameInvalid = 0x26bb, + PetNewlyTamed = 0x2587, PetSpellsMessage = 0x2c22, - PetStableList = 0x2596, - PetStableResult = 0x2597, - PetTameFailure = 0x26af, + PetStableResult = 0x2592, + PetTameFailure = 0x26ab, PetUnlearnedSpells = 0x2c50, PhaseShiftChange = 0x2578, - PlayedTime = 0x26d0, + PlayedTime = 0x26cc, PlayerAckowledgeArrowCallout = 0x3022, PlayerAzeriteItemEquippedStatusChanged = 0x3014, PlayerAzeriteItemGains = 0x3013, @@ -1693,33 +1701,34 @@ namespace Framework.Constants PlayerSkinned = 0x3006, PlayerTutorialHighlightSpell = 0x300d, PlayerTutorialUnhighlightSpell = 0x300c, - PlayMusic = 0x2762, - PlayObjectSound = 0x2763, - PlayOneShotAnimKit = 0x272a, + PlayMusic = 0x275e, + PlayObjectSound = 0x275f, + PlayOneShotAnimKit = 0x2726, PlayOrphanSpellVisual = 0x2c47, - PlayScene = 0x2633, - PlaySound = 0x2761, - PlaySpeakerbotSound = 0x2764, + PlayScene = 0x262f, + PlaySound = 0x275d, + PlaySpeakerbotSound = 0x2760, PlaySpellVisual = 0x2c45, PlaySpellVisualKit = 0x2c49, - PlayTimeWarning = 0x26f8, + PlayTimeWarning = 0x26f4, Pong = 0x304e, - PowerUpdate = 0x26cd, + PowerUpdate = 0x26c9, PreloadChildMap = 0x2579, - PreloadWorld = 0x2599, - PrepopulateNameCache = 0x2842, - PreRessurect = 0x2760, - PrintNotification = 0x25ca, - ProcResist = 0x2754, - ProfessionGossip = 0x27f9, + PreloadWorld = 0x2594, + PrepopulateNameCache = 0x283a, + PreRessurect = 0x275c, + PrintNotification = 0x25c6, + ProcResist = 0x2750, + ProfessionGossip = 0x27f1, PushSpellToActionBar = 0x2c51, PvpCredit = 0x2945, - PvpMatchComplete = 0x294f, - PvpMatchInitialize = 0x2950, + PvpMatchComplete = 0x2950, + PvpMatchInitialize = 0x2951, + PvpMatchSetState = 0x294f, PvpMatchStart = 0x294e, PvpMatchStatistics = 0x2932, PvpOptionsEnabled = 0x2934, - PvpTierRecord = 0x287c, + PvpTierRecord = 0x2874, QueryBattlePetNameResponse = 0x291a, QueryCreatureResponse = 0x2914, QueryGameObjectResponse = 0x2915, @@ -1735,7 +1744,7 @@ namespace Framework.Constants QueryPlayerNameByCommunityIdResponse = 0x3002, QueryQuestInfoResponse = 0x2a96, QueryRealmGuildMasterInfoResponse = 0x29e6, - QueryTimeResponse = 0x26de, + QueryTimeResponse = 0x26da, QuestCompletionNpcResponse = 0x2a81, QuestConfirmAccept = 0x2a8f, QuestForceRemoved = 0x2a9c, @@ -1754,141 +1763,137 @@ namespace Framework.Constants QuestPoiQueryResponse = 0x2a9d, QuestPoiUpdateResponse = 0x2a9f, QuestPushResult = 0x2a90, - QuestSessionInfoResponse = 0x2865, - QuestSessionReadyCheck = 0x2853, - QuestSessionReadyCheckResponse = 0x2854, - QuestSessionResult = 0x2852, + QuestSessionInfoResponse = 0x285d, + QuestSessionReadyCheck = 0x284b, + QuestSessionReadyCheckResponse = 0x284c, + QuestSessionResult = 0x284a, QuestUpdateAddCredit = 0x2a8c, QuestUpdateAddCreditSimple = 0x2a8d, QuestUpdateAddPvpCredit = 0x2a8e, QuestUpdateComplete = 0x2a89, QuestUpdateFailed = 0x2a8a, QuestUpdateFailedTimer = 0x2a8b, - QueueSummaryUpdate = 0x280c, - RafAccountInfo = 0x2850, - RafActivityStateChanged = 0x2861, - RafDebugFriendMonths = 0x28b7, - RaidDifficultySet = 0x27a4, - RaidGroupOnly = 0x27a6, + QueueSummaryUpdate = 0x2804, + RafAccountInfo = 0x2848, + RafActivityStateChanged = 0x2859, + RafDebugFriendMonths = 0x28b0, + RaidDifficultySet = 0x279d, + RaidGroupOnly = 0x279f, RaidInstanceMessage = 0x2bb4, - RaidMarkersChanged = 0x25a4, - RandomRoll = 0x262d, + RaidMarkersChanged = 0x259f, + RandomRoll = 0x2629, RatedPvpInfo = 0x2931, - ReadyCheckCompleted = 0x25f7, - ReadyCheckResponse = 0x25f6, - ReadyCheckStarted = 0x25f5, - ReadItemResultFailed = 0x27a0, - ReadItemResultOk = 0x2797, - RealmLookupInfo = 0x27c4, + ReadyCheckCompleted = 0x25f3, + ReadyCheckResponse = 0x25f2, + ReadyCheckStarted = 0x25f1, + ReadItemResultFailed = 0x2799, + ReadItemResultOk = 0x2790, + RealmLookupInfo = 0x27bc, RealmQueryResponse = 0x2913, - ReattachResurrect = 0x2744, - RecraftItemResult = 0x28a6, - RecruitAFriendFailure = 0x26bc, - RefreshComponent = 0x264e, + ReattachResurrect = 0x2740, + RecraftItemResult = 0x289f, + RecruitAFriendFailure = 0x26b8, + RefreshComponent = 0x264a, RefreshSpellHistory = 0x2c29, - RemoveItemPassive = 0x25ac, + RemoveItemPassive = 0x25a7, RemoveSpellFromActionBar = 0x2c52, - ReplaceTrophyResponse = 0x27bc, + ReplaceTrophyResponse = 0x27b5, ReportPvpPlayerAfkResult = 0x3001, - RequestCemeteryListResponse = 0x2591, + RequestCemeteryListResponse = 0x258e, RequestPvpRewardsResponse = 0x2935, RequestScheduledPvpInfoResponse = 0x2936, - ResearchComplete = 0x2587, ResetCompressionContext = 0x304f, - ResetFailedNotify = 0x26b3, - ResetLastLoadedConfigCvars = 0x28ac, + ResetFailedNotify = 0x26af, + ResetLastLoadedConfigCvars = 0x28a5, ResetQuestPoi = 0x2aa0, ResetRangedCombatTimer = 0x2944, ResetWeeklyCurrency = 0x2575, - RespecWipeConfirm = 0x2610, + RespecWipeConfirm = 0x260c, RespondInspectAchievements = 0x2572, - ResponsePerkPendingRewards = 0x2883, - ResponsePerkRecentPurchases = 0x2884, + ResponsePerkPendingRewards = 0x287c, + ResponsePerkRecentPurchases = 0x287d, RestartGlobalCooldown = 0x2c61, - RestrictedAccountWarning = 0x25b9, + RestrictedAccountWarning = 0x25b5, ResumeCast = 0x2c3b, ResumeCastBar = 0x2c3e, ResumeComms = 0x304b, - ResumeToken = 0x25aa, + ResumeToken = 0x25a5, ResurrectRequest = 0x257e, ResyncRunes = 0x2c5f, - ReturningPlayerPrompt = 0x279f, - ReturnApplicantList = 0x2846, - ReturnRecruitingClubs = 0x2845, - RoleChangedInform = 0x258d, + ReturningPlayerPrompt = 0x2798, + ReturnApplicantList = 0x283e, + ReturnRecruitingClubs = 0x283d, + RoleChangedInform = 0x258a, RoleChosen = 0x2a39, - RolePollInform = 0x258e, - RuneforgeLegendaryCraftingOpenNpc = 0x27f8, - RuneRegenDebug = 0x25b6, - ScenarioCompleted = 0x27e6, - ScenarioPois = 0x2630, - ScenarioProgressUpdate = 0x2629, - ScenarioShowCriteria = 0x27fc, - ScenarioState = 0x2628, - ScenarioUiUpdate = 0x27fb, - ScenarioVacate = 0x27a1, - SceneObjectEvent = 0x25e1, - SceneObjectPetBattleFinalRound = 0x25e6, - SceneObjectPetBattleFinished = 0x25e7, - SceneObjectPetBattleFirstRound = 0x25e3, - SceneObjectPetBattleInitialUpdate = 0x25e2, - SceneObjectPetBattleReplacementsMade = 0x25e5, - SceneObjectPetBattleRoundResult = 0x25e4, + RolePollInform = 0x258b, + RuneforgeLegendaryCraftingOpenNpc = 0x27f0, + RuneRegenDebug = 0x25b2, + ScenarioCompleted = 0x27de, + ScenarioPois = 0x262c, + ScenarioProgressUpdate = 0x2625, + ScenarioShowCriteria = 0x27f4, + ScenarioState = 0x2624, + ScenarioUiUpdate = 0x27f3, + ScenarioVacate = 0x279a, + SceneObjectEvent = 0x25dd, + SceneObjectPetBattleFinalRound = 0x25e2, + SceneObjectPetBattleFinished = 0x25e3, + SceneObjectPetBattleFirstRound = 0x25df, + SceneObjectPetBattleInitialUpdate = 0x25de, + SceneObjectPetBattleReplacementsMade = 0x25e1, + SceneObjectPetBattleRoundResult = 0x25e0, ScriptCast = 0x2c56, - SeasonInfo = 0x25c1, - SellResponse = 0x26c0, - SendItemPassives = 0x25ad, + SeasonInfo = 0x25bd, + SellResponse = 0x26bc, + SendItemPassives = 0x25a8, SendKnownSpells = 0x2c27, - SendRaidTargetUpdateAll = 0x262b, - SendRaidTargetUpdateSingle = 0x262c, + SendRaidTargetUpdateAll = 0x2627, + SendRaidTargetUpdateSingle = 0x2628, SendSpellCharges = 0x2c2a, SendSpellHistory = 0x2c28, SendUnlearnSpells = 0x2c2b, - ServerFirstAchievements = 0x264b, - ServerTime = 0x267f, - ServerTimeOffset = 0x270e, + ServerFirstAchievements = 0x2647, + ServerTime = 0x267b, + ServerTimeOffset = 0x270a, SetupCurrency = 0x2573, - SetupResearchHistory = 0x2586, - SetAiAnimKit = 0x2729, - SetAllTaskProgress = 0x2785, - SetAnimTier = 0x272d, - SetChrUpgradeTier = 0x25de, + SetAiAnimKit = 0x2725, + SetAnimTier = 0x2729, + SetChrUpgradeTier = 0x25da, SetCurrency = 0x2574, SetDfFastLaunchResult = 0x2a2e, - SetDungeonDifficulty = 0x26a1, - SetFactionAtWar = 0x26fa, - SetFactionNotVisible = 0x2724, - SetFactionStanding = 0x2725, - SetFactionVisible = 0x2723, + SetDungeonDifficulty = 0x269d, + SetFactionAtWar = 0x26f6, + SetFactionNotVisible = 0x2720, + SetFactionStanding = 0x2721, + SetFactionVisible = 0x271f, SetFlatSpellModifier = 0x2c36, - SetForcedReactions = 0x2717, - SetItemPurchaseData = 0x259f, - SetLootMethodFailed = 0x27ca, - SetMaxWeeklyQuantity = 0x25a2, - SetMeleeAnimKit = 0x272c, - SetMovementAnimKit = 0x272b, + SetForcedReactions = 0x2713, + SetItemPurchaseData = 0x259a, + SetLootMethodFailed = 0x27c2, + SetMaxWeeklyQuantity = 0x259d, + SetMeleeAnimKit = 0x2728, + SetMovementAnimKit = 0x2727, SetPctSpellModifier = 0x2c37, - SetPetSpecialization = 0x2622, + SetPetSpecialization = 0x261e, SetPlayerDeclinedNamesResult = 0x3003, - SetPlayHoverAnim = 0x25ba, - SetProficiency = 0x272e, - SetQuestReplayCooldownOverride = 0x2859, + SetPlayHoverAnim = 0x25b6, + SetProficiency = 0x272a, + SetQuestReplayCooldownOverride = 0x2851, SetShipmentReadyResponse = 0x2998, SetSpellCharges = 0x2c26, - SetTaskComplete = 0x2786, - SetTimeZoneInformation = 0x2674, - SetVehicleRecId = 0x26f1, - ShadowlandsCapacitanceUpdate = 0x2888, + SetTimeZoneInformation = 0x2670, + SetVehicleRecId = 0x26ed, + ShadowlandsCapacitanceUpdate = 0x2881, ShipmentFactionUpdateResult = 0x2999, - ShowNeutralPlayerFactionSelectUi = 0x25da, + ShowNeutralPlayerFactionSelectUi = 0x25d6, ShowQuestCompletionText = 0x2a95, - ShowTaxiNodes = 0x26c8, - ShowTradeSkillResponse = 0x2769, - SocialContractRequestResponse = 0x2893, - SocketGemsFailure = 0x2721, - SocketGemsSuccess = 0x2720, - SpecialMountAnim = 0x269c, - SpecInvoluntarilyChanged = 0x2712, + ShowTaxiNodes = 0x26c4, + ShowTradeSkillResponse = 0x2765, + SocialContractRequestResponse = 0x288c, + SocketGemsFailure = 0x271d, + SocketGemsSuccess = 0x271c, + SpecialMountAnim = 0x2698, + SpecInvoluntarilyChanged = 0x270e, SpellAbsorbLog = 0x2c1c, SpellCategoryCooldown = 0x2c16, SpellChannelStart = 0x2c31, @@ -1916,94 +1921,93 @@ namespace Framework.Constants SpellPeriodicAuraLog = 0x2c18, SpellPrepare = 0x2c38, SpellStart = 0x2c3a, - SpellVisualLoadScreen = 0x25cc, - SplashScreenShowLatest = 0x286b, - StandStateUpdate = 0x2716, - StarterBuildActivateFailed = 0x25d2, - StartElapsedTimer = 0x2603, - StartElapsedTimers = 0x2605, - StartLightningStorm = 0x26a4, - StartLootRoll = 0x261a, - StartMirrorTimer = 0x2709, - StartTimer = 0x25a6, - StopElapsedTimer = 0x2604, - StopMirrorTimer = 0x270b, - StopSpeakerbotSound = 0x2765, - StopTimer = 0x25a7, - StreamingMovies = 0x25a5, - SuggestInviteInform = 0x278d, - SummonCancel = 0x26ad, - SummonRaidMemberValidateFailed = 0x258f, - SummonRequest = 0x271b, + SpellVisualLoadScreen = 0x25c8, + SplashScreenShowLatest = 0x2863, + StandStateUpdate = 0x2712, + StarterBuildActivateFailed = 0x25ce, + StartElapsedTimer = 0x25ff, + StartElapsedTimers = 0x2601, + StartLightningStorm = 0x26a0, + StartLootRoll = 0x2616, + StartMirrorTimer = 0x2705, + StartTimer = 0x25a1, + StopElapsedTimer = 0x2600, + StopMirrorTimer = 0x2707, + StopSpeakerbotSound = 0x2761, + StopTimer = 0x25a2, + StreamingMovies = 0x25a0, + SuggestInviteInform = 0x2786, + SummonCancel = 0x26a9, + SummonRaidMemberValidateFailed = 0x258c, + SummonRequest = 0x2717, SupercededSpells = 0x2c4c, SuspendComms = 0x304a, - SuspendToken = 0x25a9, - SyncWowEntitlements = 0x2863, - TalentsInvoluntarilyReset = 0x2711, - TaxiNodeStatus = 0x2679, - TextEmote = 0x2677, - ThreatClear = 0x26d7, - ThreatRemove = 0x26d6, - ThreatUpdate = 0x26d5, + SuspendToken = 0x25a4, + SyncWowEntitlements = 0x285b, + TalentsInvoluntarilyReset = 0x270d, + TaxiNodeStatus = 0x2675, + TextEmote = 0x2673, + ThreatClear = 0x26d3, + ThreatRemove = 0x26d2, + ThreatUpdate = 0x26d1, TimeAdjustment = 0x2dd3, TimeSyncRequest = 0x2dd2, - TitleEarned = 0x26d2, - TitleLost = 0x26d3, - TotemCreated = 0x26c3, - TotemDurationChanged = 0x26c4, - TotemMoved = 0x26c5, + TitleEarned = 0x26ce, + TitleLost = 0x26cf, + TotemCreated = 0x26bf, + TotemDurationChanged = 0x26c0, + TotemMoved = 0x26c1, TradeStatus = 0x2582, TradeUpdated = 0x2581, - TrainerBuyFailed = 0x26da, - TrainerList = 0x26d9, - TraitConfigCommitFailed = 0x25d1, - TransferAborted = 0x26fd, - TransferPending = 0x25cd, + TrainerBuyFailed = 0x26d6, + TrainerList = 0x26d5, + TraitConfigCommitFailed = 0x25cd, + TransferAborted = 0x26f9, + TransferPending = 0x25c9, TreasurePickerResponse = 0x291f, - TriggerCinematic = 0x27c2, - TriggerMovie = 0x26c6, - TurnInPetitionResult = 0x2747, - TutorialFlags = 0x27b5, + TriggerCinematic = 0x27ba, + TriggerMovie = 0x26c2, + TurnInPetitionResult = 0x2743, + TutorialFlags = 0x27ae, UiMapQuestLinesResponse = 0x2aa2, - UndeleteCharacterResponse = 0x27c5, - UndeleteCooldownStatusResponse = 0x27c6, + UndeleteCharacterResponse = 0x27bd, + UndeleteCooldownStatusResponse = 0x27be, UnlearnedSpells = 0x2c4e, UnloadChildMap = 0x257a, - UpdateAadcStatusResponse = 0x287d, - UpdateAccountData = 0x2703, - UpdateActionButtons = 0x25df, - UpdateBnetSessionKey = 0x281d, + UpdateAadcStatusResponse = 0x2875, + UpdateAccountData = 0x26ff, + UpdateActionButtons = 0x25db, + UpdateBnetSessionKey = 0x2815, UpdateCapturePoint = 0x2929, - UpdateCelestialBody = 0x2819, - UpdateCharacterFlags = 0x27bb, - UpdateChargeCategoryCooldown = 0x275f, - UpdateCooldown = 0x275e, + UpdateCelestialBody = 0x2811, + UpdateCharacterFlags = 0x27b4, + UpdateChargeCategoryCooldown = 0x275b, + UpdateCooldown = 0x275a, UpdateCraftingNpcRecipes = 0x2996, UpdateDailyMissionCounter = 0x297f, - UpdateExpansionLevel = 0x2643, - UpdateGameTimeState = 0x2820, - UpdateInstanceOwnership = 0x26a6, - UpdateLastInstance = 0x2685, - UpdateObject = 0x27c3, - UpdatePrimarySpec = 0x25d7, - UpdateRecentPlayerGuids = 0x25f4, - UpdateTalentData = 0x25d6, - UpdateTaskProgress = 0x2784, - UpdateWorldState = 0x2741, + UpdateExpansionLevel = 0x263f, + UpdateGameTimeState = 0x2818, + UpdateInstanceOwnership = 0x26a2, + UpdateLastInstance = 0x2681, + UpdateObject = 0x27bb, + UpdatePrimarySpec = 0x25d3, + UpdateRecentPlayerGuids = 0x25f0, + UpdateTalentData = 0x25d2, + UpdateWorldState = 0x273d, UserlistAdd = 0x2bb9, UserlistRemove = 0x2bba, UserlistUpdate = 0x2bbb, - UseEquipmentSetResult = 0x2748, - VasCheckTransferOkResponse = 0x2814, - VasGetQueueMinutesResponse = 0x2812, - VasGetServiceStatusResponse = 0x2811, - VasPurchaseComplete = 0x27ec, - VasPurchaseStateUpdate = 0x27eb, - VendorInventory = 0x25b8, + UseEquipmentSetResult = 0x2744, + VasCheckTransferOkResponse = 0x280c, + VasGetQueueMinutesResponse = 0x280a, + VasGetServiceStatusResponse = 0x2809, + VasPurchaseComplete = 0x27e4, + VasPurchaseStateUpdate = 0x27e3, + VendorInventory = 0x25b4, VignetteUpdate = 0x3008, - VoiceChannelInfoResponse = 0x2818, - VoiceChannelSttTokenResponse = 0x2877, - VoiceLoginResponse = 0x2817, + VoiceChannelInfoResponse = 0x2810, + VoiceChannelSttTokenResponse = 0x286f, + VoiceLoginResponse = 0x280f, VoidItemSwapResponse = 0x2da4, VoidStorageContents = 0x2da1, VoidStorageFailed = 0x2da0, @@ -2012,27 +2016,27 @@ namespace Framework.Constants WaitQueueFinish = 0x256f, WaitQueueUpdate = 0x256e, Warden3Data = 0x2577, - Warden3Disabled = 0x281b, - Warden3Enabled = 0x281a, - WarfrontComplete = 0x2757, + Warden3Disabled = 0x2813, + Warden3Enabled = 0x2812, + WarfrontComplete = 0x2753, WargameRequestSuccessfullySentToOpponent = 0x2933, - Weather = 0x26a3, - WeeklyRewardsProgressResult = 0x286e, - WeeklyRewardsResult = 0x286c, - WeeklyRewardClaimResult = 0x286d, + Weather = 0x269f, + WeeklyRewardsProgressResult = 0x2866, + WeeklyRewardsResult = 0x2864, + WeeklyRewardClaimResult = 0x2865, Who = 0x2bae, - WhoIs = 0x26a2, - WillBeKickedForAddedSubscriptionTime = 0x281f, + WhoIs = 0x269e, + WillBeKickedForAddedSubscriptionTime = 0x2817, WorldQuestUpdateResponse = 0x300f, - WorldServerInfo = 0x25ae, - WowEntitlementNotification = 0x2864, - XpAwardedFromCurrency = 0x28ab, - XpGainAborted = 0x25c9, - XpGainEnabled = 0x27a5, + WorldServerInfo = 0x25a9, + WowEntitlementNotification = 0x285c, + XpAwardedFromCurrency = 0x28a4, + XpGainAborted = 0x25c5, + XpGainEnabled = 0x279e, ZoneUnderAttack = 0x2bb5, // Opcodes That Are Not Generated Automatically - AccountHeirloomUpdate = 0x25b2, // No Client Handler + AccountHeirloomUpdate = 0x25AD, // No Client Handler CompressedPacket = 0x3052, MultiplePackets = 0x3051, diff --git a/Source/Framework/Constants/ObjectConst.cs b/Source/Framework/Constants/ObjectConst.cs index c4a2a689b..9e11f6d50 100644 --- a/Source/Framework/Constants/ObjectConst.cs +++ b/Source/Framework/Constants/ObjectConst.cs @@ -96,6 +96,8 @@ namespace Framework.Constants ToolsClient = 50, WorldLayer = 51, ArenaTeam = 52, + LMMParty = 53, + LMMLobby = 54, Count } diff --git a/Source/Framework/Constants/PetConst.cs b/Source/Framework/Constants/PetConst.cs index 20e844212..38d10e1d6 100644 --- a/Source/Framework/Constants/PetConst.cs +++ b/Source/Framework/Constants/PetConst.cs @@ -1,6 +1,8 @@ // Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. +using System; + namespace Framework.Constants { public enum CharmType @@ -29,6 +31,13 @@ namespace Framework.Constants NotInSlot = -1, // for avoid conflict with stable size grow will use negative value } + [Flags] + public enum PetStableFlags + { + Active = 0x1, + Inactive = 0x2 + } + public enum PetSpellState { Unchanged = 0, @@ -88,23 +97,6 @@ namespace Framework.Constants DeclensionDoesntMatchBaseName = 16 } - public enum PetStableinfo : byte - { - Active = 1, - Inactive = 2 - } - - public enum StableResult - { - 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" - } - public enum PetTameResult { Ok = 0, @@ -123,4 +115,15 @@ namespace Framework.Constants InvalidSlot = 13, EliteTooHighLevel = 14 } + + public enum StableResult + { + 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" + } } diff --git a/Source/Framework/Constants/QuestConst.cs b/Source/Framework/Constants/QuestConst.cs index 6a975d073..ee65d409f 100644 --- a/Source/Framework/Constants/QuestConst.cs +++ b/Source/Framework/Constants/QuestConst.cs @@ -67,9 +67,9 @@ namespace Framework.Constants public enum QuestSlotStateMask { - None = 0x0000, - Complete = 0x0001, - Fail = 0x0002 + None = 0x00, + Complete = 0x1, + Fail = 0x2 } public enum QuestType @@ -402,7 +402,7 @@ namespace Framework.Constants Max } - public enum QuestGiverStatus : uint + public enum QuestGiverStatus : ulong { None = 0x00, Future = 0x02, @@ -426,6 +426,16 @@ namespace Framework.Constants CovenantCallingQuest = 0x80000, CovenantCallingRewardCompleteNoPOI = 0x100000, CovenantCallingRewardCompletePOI = 0x200000, + TrivialLegendaryQuest = 0x400000, + FutureLegendaryQuest = 0x800000, + LegendaryReward = 0x1000000, + ImportantQuest = 0x2000000, + ImportantQuestReward = 0x4000000, + TrivialImportantQuest = 0x8000000, + ImportantQuestRewardCompleteNoPOI = 0x20000000, + ImportantQuestRewardCompletePOI = 0x40000000, + TrivialJourneyQuest = 0x80000000, + TrivialCovenantCallingQuest = 0x100000000, } [Flags] @@ -533,10 +543,10 @@ namespace Framework.Constants { None = 0x00, // Flags For Set Specialflags In Db If Required But Used Only At Server - Repeatable = 0x001, // Set by 1 in SpecialFlags from DB - AutoPushToParty = 0x002, // Set by 2 in SpecialFlags from DB will make quest be pushed to entire party when one member accepts it - AutoAccept = 0x004, // Set by 4 in SpecialFlags in DB if the quest is to be auto-accepted. - DfQuest = 0x008, // Set by 8 in SpecialFlags in DB if the quest is used by Dungeon Finder. + Repeatable = 0x01, // Set by 1 in SpecialFlags from DB + AutoPushToParty = 0x02, // Set by 2 in SpecialFlags from DB will make quest be pushed to entire party when one member accepts it + AutoAccept = 0x04, // Set by 4 in SpecialFlags in DB if the quest is to be auto-accepted. + DfQuest = 0x08, // Set by 8 in SpecialFlags in DB if the quest is used by Dungeon Finder. Monthly = 0x010, // Set by 16 in SpecialFlags in DB if the quest is reset at the begining of the month // Room For More Custom Flags diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index 239264f78..318142c78 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -294,18 +294,6 @@ namespace Framework.Constants 29, 30, 31, -1, 11, 12, 13, 14 }; - public static ulong RaceMaskAllPlayable = (ulong)(GetMaskForRace(Race.Human) | GetMaskForRace(Race.Orc) | GetMaskForRace(Race.Dwarf) | GetMaskForRace(Race.NightElf) | GetMaskForRace(Race.Undead) - | GetMaskForRace(Race.Tauren) | GetMaskForRace(Race.Gnome) | GetMaskForRace(Race.Troll) | GetMaskForRace(Race.BloodElf) | GetMaskForRace(Race.Draenei) - | GetMaskForRace(Race.Goblin) | GetMaskForRace(Race.Worgen) | GetMaskForRace(Race.PandarenNeutral) | GetMaskForRace(Race.PandarenAlliance) | GetMaskForRace(Race.PandarenHorde) - | GetMaskForRace(Race.Nightborne) | GetMaskForRace(Race.HighmountainTauren) | GetMaskForRace(Race.VoidElf) | GetMaskForRace(Race.LightforgedDraenei) | GetMaskForRace(Race.ZandalariTroll) - | GetMaskForRace(Race.KulTiran) | GetMaskForRace(Race.DarkIronDwarf) | GetMaskForRace(Race.Vulpera) | GetMaskForRace(Race.MagharOrc) | GetMaskForRace(Race.MechaGnome) | GetMaskForRace(Race.DracthyrAlliance) | GetMaskForRace(Race.DracthyrHorde)); - - public static ulong RaceMaskAlliance = (ulong)(GetMaskForRace(Race.Human) | GetMaskForRace(Race.Dwarf) | GetMaskForRace(Race.NightElf) | GetMaskForRace(Race.Gnome) - | GetMaskForRace(Race.Draenei) | GetMaskForRace(Race.Worgen) | GetMaskForRace(Race.PandarenAlliance) | GetMaskForRace(Race.VoidElf) | GetMaskForRace(Race.LightforgedDraenei) - | GetMaskForRace(Race.KulTiran) | GetMaskForRace(Race.DarkIronDwarf) | GetMaskForRace(Race.MechaGnome) | GetMaskForRace(Race.DracthyrAlliance)); - - public static ulong RaceMaskHorde = RaceMaskAllPlayable & ~RaceMaskAlliance; - //Todo move these else where /// /// Method Const @@ -418,55 +406,6 @@ namespace Framework.Constants CascLocaleBit.itIT }; - static int GetRaceBit(Race raceId) - { - switch (raceId) - { - case Race.Human: - case Race.Orc: - case Race.Dwarf: - case Race.NightElf: - case Race.Undead: - case Race.Tauren: - case Race.Gnome: - case Race.Troll: - case Race.Goblin: - case Race.BloodElf: - case Race.Draenei: - case Race.Worgen: - case Race.PandarenNeutral: - case Race.PandarenAlliance: - case Race.PandarenHorde: - case Race.Nightborne: - case Race.HighmountainTauren: - case Race.VoidElf: - case Race.LightforgedDraenei: - case Race.ZandalariTroll: - case Race.KulTiran: - return (int)raceId - 1; - case Race.DarkIronDwarf: - return 11; - case Race.Vulpera: - return 12; - case Race.MagharOrc: - return 13; - case Race.MechaGnome: - return 14; - case Race.DracthyrAlliance: - return 16; - case Race.DracthyrHorde: - return 15; - default: - return -1; - } - } - - public static long GetMaskForRace(Race raceId) - { - int raceBit = GetRaceBit(raceId); - return raceBit >= 0 && raceBit < sizeof(long) * 8 ? (1L << raceBit) : 0; - } - public static bool IsActivePetSlot(PetSaveMode slot) { return slot >= PetSaveMode.FirstActiveSlot && slot < PetSaveMode.LastActiveSlot; @@ -3054,12 +2993,13 @@ namespace Framework.Constants CrossFactionGroupJoined = 1114, CantTargetUnfriendlyInOverworld = 1115, EquipablespellsSlotsFull = 1116, - WowLabsPartyErrorTypePartyIsFull = 1117, - WowLabsPartyErrorTypeMaxInviteSent = 1118, - WowLabsPartyErrorTypePlayerAlreadyInvited = 1119, - WowLabsPartyErrorTypePartyInviteInvalid = 1120, - WowLabsLobbyMatchmakerErrorEnterQueueFailed = 1121, - WowLabsLobbyMatchmakerErrorLeaveQueueFailed = 1122, + ItemModAppearanceGroupAlreadyKnown = 1117, + WowLabsPartyErrorTypePartyIsFull = 1118, + WowLabsPartyErrorTypeMaxInviteSent = 1119, + WowLabsPartyErrorTypePlayerAlreadyInvited = 1120, + WowLabsPartyErrorTypePartyInviteInvalid = 1121, + WowLabsLobbyMatchmakerErrorEnterQueueFailed = 1122, + WowLabsLobbyMatchmakerErrorLeaveQueueFailed = 1123, } public enum SceneFlags diff --git a/Source/Framework/Constants/Spells/SpellAuraConst.cs b/Source/Framework/Constants/Spells/SpellAuraConst.cs index ed33d2bfc..861e0b27e 100644 --- a/Source/Framework/Constants/Spells/SpellAuraConst.cs +++ b/Source/Framework/Constants/Spells/SpellAuraConst.cs @@ -545,6 +545,10 @@ namespace Framework.Constants Unk535 = 535, IgnoreSpellCreatureTypeRequirements = 536, Unk537 = 537, + ModFakeInebriationMovementOnly = 538, + AllowMountInCombat = 539, + ModSupportStat = 540, // NYI + ModRequiredMountCapabilityFlags = 541, Total } diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 7f62eba3a..369e38984 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -20,7 +20,7 @@ namespace Framework.Constants public const float TrajectoryMissileSize = 3.0f; - public const int MaxPowersPerSpell = 4; + public const int MaxPowersPerSpell = 5; public const uint VisualKitFood = 406; public const uint VisualKitDrink = 438; @@ -763,7 +763,9 @@ namespace Framework.Constants CantBeRecrafted = 316, PassiveReplaced = 317, CantFlyHere = 318, - Unknown = 319, + DragonridingRidingRequirement = 319, + ItemModAppearanceGroupAlreadyKnown = 320, + Unknown = 321, // Ok Cast Value - Here In Case A Future Version Removes Success And We Need To Use A Custom Value (Not Sent To Client Either Way) SpellCastOk = Success @@ -1397,8 +1399,11 @@ namespace Framework.Constants RequiresADjaradinPillarShard = 831, // Requires A Djaradin Pillar Shard. RequiresAResilientStone = 832, // Requires A Resilient Stone. MyrritCannotCarryAnyMoreMaps = 835, // Myrrit Cannot Carry Any More Maps. Go On A Dig With Him! + SomeGiftsAreBetterLeftUndelivered = 836, // Some gifts are better left undelivered. RequiresNiffenCaveDiveKeyandShieldDisabled = 850, // Requires Niffen Cave Dive Key And Shield Disabled. ElusiveCreatureBaitWasRecentlyUsed = 851, // You Cannot Lure Anything In This Area For A Few Minutes. Elusive Creature Bait Was Recently Used. + MustBeInQuietPlaceWithinCaerDarrow = 852, // Must be in a suitably quiet place within Caer Darrow. + YouDontHaveAnyGlimmerOfLightsActive = 856, // You don't have any Glimmer of Lights active. YouDontHaveTheSwirlingMojoStone = 999, // You Don'T Have The Swirling Mojo Stone Equipped. YouMustBeNearADragonflightOathstone = 1000, // You Must Be Near One Of The Five Dragonflight Oathstones In The Dragon Isles. CanOnlyUseThisItemWhileAirborne = 1001, // You Can Only Use This Item While Airborne. @@ -2500,7 +2505,7 @@ namespace Framework.Constants CreateTraitTreeConfig = 303, // Miscvalue[0] = Traittreeid ChangeActiveCombatTraitConfig = 304, Unk305 = 305, - Unk306 = 306, + UpdateInteractions = 306, Unk307 = 307, CancelPreloadWorld = 308, PreloadWorld = 309, @@ -2509,6 +2514,7 @@ namespace Framework.Constants Unk312 = 312, ChangeItemBonuses2 = 313, // MiscValue[0] = ItemBonusTreeID to preserve AddSocketBonus = 314, // MiscValue[0] = required ItemBonusTreeID + LearnTransmogAppearanceFromItemModAppearanceGroup = 315, // MiscValue[0] = ItemModAppearanceGroupID (not in db2) TotalSpellEffects } diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index d357655a2..93a5aef5b 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -281,7 +281,7 @@ namespace Framework.Database " WHERE (`VerifiedBuild` > 0) = ? AND locale = ?"); // ChrCustomizationReq.db2 - PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ, "SELECT ID, ReqSource, Flags, ClassMask, AchievementID, QuestID, OverrideArchive, " + + PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ, "SELECT ID, RaceMask, ReqSource, Flags, ClassMask, AchievementID, QuestID, OverrideArchive, " + "ItemModifiedAppearanceID FROM chr_customization_req WHERE (`VerifiedBuild` > 0) = ?"); PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ_LOCALE, "SELECT ID, ReqSource_lang FROM chr_customization_req_locale WHERE (`VerifiedBuild` > 0) = ?" + " AND locale = ?"); @@ -331,6 +331,10 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_CINEMATIC_SEQUENCES, "SELECT ID, SoundID, Camera1, Camera2, Camera3, Camera4, Camera5, Camera6, Camera7, Camera8" + " FROM cinematic_sequences WHERE (`VerifiedBuild` > 0) = ?"); + // ConditionalChrModel.db2 + PrepareStatement(HotfixStatements.SEL_CONDITIONAL_CHR_MODEL, "SELECT ID, ChrModelID, ChrCustomizationReqID, PlayerConditionID, Flags, " + + "ChrCustomizationCategoryID FROM conditional_chr_model WHERE (`VerifiedBuild` > 0) = ?"); + // ConditionalContentTuning.db2 PrepareStatement(HotfixStatements.SEL_CONDITIONAL_CONTENT_TUNING, "SELECT ID, OrderIndex, RedirectContentTuningID, RedirectFlag, ParentContentTuningID" + " FROM conditional_content_tuning WHERE (`VerifiedBuild` > 0) = ?"); @@ -496,7 +500,8 @@ namespace Framework.Database // GameobjectDisplayInfo.db2 PrepareStatement(HotfixStatements.SEL_GAMEOBJECT_DISPLAY_INFO, "SELECT ID, GeoBoxMinX, GeoBoxMinY, GeoBoxMinZ, GeoBoxMaxX, GeoBoxMaxY, GeoBoxMaxZ, " + - "FileDataID, ObjectEffectPackageID, OverrideLootEffectScale, OverrideNameScale FROM gameobject_display_info WHERE (`VerifiedBuild` > 0) = ?"); + "FileDataID, ObjectEffectPackageID, OverrideLootEffectScale, OverrideNameScale, AlternateDisplayType, ClientCreatureDisplayInfoID, " + + "ClientItemID FROM gameobject_display_info WHERE (`VerifiedBuild` > 0) = ?"); // Gameobjects.db2 PrepareStatement(HotfixStatements.SEL_GAMEOBJECTS, "SELECT Name, PosX, PosY, PosZ, Rot1, Rot2, Rot3, Rot4, ID, OwnerID, DisplayID, Scale, TypeID, " + @@ -1496,7 +1501,8 @@ namespace Framework.Database // UiMap.db2 PrepareStatement(HotfixStatements.SEL_UI_MAP, "SELECT Name, ID, ParentUiMapID, Flags, `System`, Type, BountySetID, BountyDisplayLocation, " + - "VisibilityPlayerConditionID, HelpTextPosition, BkgAtlasID, AlternateUiMapGroup, ContentTuningID FROM ui_map WHERE (`VerifiedBuild` > 0) = ?"); + "VisibilityPlayerConditionID2, VisibilityPlayerConditionID, HelpTextPosition, BkgAtlasID, AlternateUiMapGroup, ContentTuningID FROM ui_map" + + " WHERE (`VerifiedBuild` > 0) = ?"); PrepareStatement(HotfixStatements.SEL_UI_MAP_LOCALE, "SELECT ID, Name_lang FROM ui_map_locale WHERE (`VerifiedBuild` > 0) = ? AND locale = ?"); // UiMapAssignment.db2 @@ -1725,6 +1731,8 @@ namespace Framework.Database SEL_CINEMATIC_SEQUENCES, + SEL_CONDITIONAL_CHR_MODEL, + SEL_CONDITIONAL_CONTENT_TUNING, SEL_CONTENT_TUNING, diff --git a/Source/Game/AI/CoreAI/PetAI.cs b/Source/Game/AI/CoreAI/PetAI.cs index 90ab88565..846334981 100644 --- a/Source/Game/AI/CoreAI/PetAI.cs +++ b/Source/Game/AI/CoreAI/PetAI.cs @@ -104,7 +104,7 @@ namespace Game.AI if (spellInfo.IsPositive()) { - if (spellInfo.CanBeUsedInCombat()) + if (spellInfo.CanBeUsedInCombat(me)) { // Check if we're in combat or commanded to attack if (!me.IsInCombat() && !me.GetCharmInfo().IsCommandAttack()) @@ -160,7 +160,7 @@ namespace Game.AI if (!spellUsed) spell.Dispose(); } - else if (me.GetVictim() && CanAttack(me.GetVictim()) && spellInfo.CanBeUsedInCombat()) + else if (me.GetVictim() && CanAttack(me.GetVictim()) && spellInfo.CanBeUsedInCombat(me)) { Spell spell = new(me, spellInfo, TriggerCastFlags.None); if (spell.CanAutoCast(me.GetVictim())) diff --git a/Source/Game/Achievements/CriteriaHandler.cs b/Source/Game/Achievements/CriteriaHandler.cs index 013c124ac..836cfc274 100644 --- a/Source/Game/Achievements/CriteriaHandler.cs +++ b/Source/Game/Achievements/CriteriaHandler.cs @@ -9,6 +9,7 @@ using Game.DataStorage; using Game.Entities; using Game.Garrisons; using Game.Maps; +using Game.Miscellaneous; using Game.Networking; using Game.Networking.Packets; using Game.Scenarios; @@ -3609,6 +3610,14 @@ namespace Game.Achievements return false; break; } + case ModifierTreeType.PlayerSummonedBattlePetSpecies: // 352 + if (referencePlayer.m_playerData.CurrentBattlePetSpeciesID != reqValue) + return false; + break; + case ModifierTreeType.PlayerSummonedBattlePetIsMaxLevel: // 353 + if (referencePlayer.m_unitData.WildBattlePetLevel != SharedConst.MaxBattlePetLevel) + return false; + break; case ModifierTreeType.PlayerHasAtLeastProfPathRanks: // 355 { uint ranks = 0; @@ -3629,6 +3638,50 @@ namespace Game.Achievements return false; break; } + case ModifierTreeType.PlayerHasItemTransmogrifiedToItemModifiedAppearance: // 358 + { + var itemModifiedAppearance = CliDB.ItemModifiedAppearanceStorage.LookupByKey(reqValue); + + bool bagScanReachedEnd = referencePlayer.ForEachItem(ItemSearchLocation.Inventory, item => + { + if (item.GetVisibleAppearanceModId(referencePlayer) == itemModifiedAppearance.Id) + return false; + + if (item.GetEntry() == itemModifiedAppearance.ItemID) + return false; + + return true; + }); + if (bagScanReachedEnd) + return false; + break; + } + case ModifierTreeType.PlayerHasCompletedDungeonEncounterInDifficulty: // 366 + if (!referencePlayer.IsLockedToDungeonEncounter(reqValue, (Difficulty)secondaryAsset)) + return false; + break; + case ModifierTreeType.PlayerIsBetweenQuests: // 369 + { + QuestStatus status = referencePlayer.GetQuestStatus(reqValue); + if (status == QuestStatus.None || status == QuestStatus.Failed) + return false; + if (referencePlayer.IsQuestRewarded((uint)secondaryAsset)) + return false; + break; + } + case ModifierTreeType.PlayerScenarioStepID: // 371 + { + Scenario scenario = referencePlayer.GetScenario(); + if (scenario == null) + return false; + if (scenario.GetStep().Id != reqValue) + return false; + break; + } + case ModifierTreeType.PlayerZPositionBelow: // 374 + if (referencePlayer.GetPositionZ() >= reqValue) + return false; + break; default: return false; } @@ -4274,7 +4327,7 @@ namespace Game.Achievements criteria.Id, criteria.Entry.Type, DataType, ClassRace.ClassId); return false; } - if (ClassRace.RaceId != 0 && (SharedConst.GetMaskForRace((Race)ClassRace.RaceId) & (long)SharedConst.RaceMaskAllPlayable) == 0) + if (!RaceMask.AllPlayable.HasRace((Race)ClassRace.RaceId)) { Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE ({2}) has non-existing race in value2 ({3}), ignored.", criteria.Id, criteria.Entry.Type, DataType, ClassRace.RaceId); @@ -4419,7 +4472,7 @@ namespace Game.Achievements criteria.Id, criteria.Entry.Type, DataType, ClassRace.ClassId); return false; } - if (ClassRace.RaceId != 0 && ((ulong)SharedConst.GetMaskForRace((Race)ClassRace.RaceId) & SharedConst.RaceMaskAllPlayable) == 0) + if (ClassRace.RaceId != 0 && !RaceMask.AllPlayable.HasRace((Race)ClassRace.RaceId)) { Log.outError(LogFilter.Sql, "Table `criteria_data` (Entry: {0} Type: {1}) for data type CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE ({2}) has non-existing race in value2 ({3}), ignored.", criteria.Id, criteria.Entry.Type, DataType, ClassRace.RaceId); diff --git a/Source/Game/BattleGrounds/BattleGround.cs b/Source/Game/BattleGrounds/BattleGround.cs index 5909d30ce..62c0d67d9 100644 --- a/Source/Game/BattleGrounds/BattleGround.cs +++ b/Source/Game/BattleGrounds/BattleGround.cs @@ -351,6 +351,8 @@ namespace Game.BattleGrounds SetStatus(BattlegroundStatus.InProgress); SetStartDelayTime(StartDelayTimes[BattlegroundConst.EventIdFourth]); + SendPacketToAll(new PVPMatchSetState(PVPMatchState.Engaged)); + foreach (var (guid, _) in GetPlayers()) { Player player = Global.ObjAccessor.FindPlayer(guid); @@ -954,14 +956,16 @@ namespace Game.BattleGrounds { case BattlegroundStatus.None: case BattlegroundStatus.WaitQueue: - pvpMatchInitialize.State = PVPMatchInitialize.MatchState.Inactive; + pvpMatchInitialize.State = PVPMatchState.Inactive; break; case BattlegroundStatus.WaitJoin: + pvpMatchInitialize.State = PVPMatchState.StartUp; + break; case BattlegroundStatus.InProgress: - pvpMatchInitialize.State = PVPMatchInitialize.MatchState.InProgress; + pvpMatchInitialize.State = PVPMatchState.Engaged; break; case BattlegroundStatus.WaitLeave: - pvpMatchInitialize.State = PVPMatchInitialize.MatchState.Complete; + pvpMatchInitialize.State = PVPMatchState.Complete; break; default: break; @@ -1226,7 +1230,7 @@ namespace Game.BattleGrounds { playerData.IsInWorld = true; playerData.PrimaryTalentTree = (int)player.GetPrimarySpecialization(); - playerData.Sex = (int)player.GetGender(); + playerData.Sex = (sbyte)player.GetGender(); playerData.PlayerRace = player.GetRace(); playerData.PlayerClass = (int)player.GetClass(); playerData.HonorLevel = (int)player.GetHonorLevel(); diff --git a/Source/Game/Chat/Commands/ModifyCommands.cs b/Source/Game/Chat/Commands/ModifyCommands.cs index a9894d0a4..5e114c5d7 100644 --- a/Source/Game/Chat/Commands/ModifyCommands.cs +++ b/Source/Game/Chat/Commands/ModifyCommands.cs @@ -580,7 +580,7 @@ namespace Game.Chat foreach (ChrCustomizationOptionRecord option in options) { ChrCustomizationReqRecord optionReq = CliDB.ChrCustomizationReqStorage.LookupByKey(option.ChrCustomizationReqID); - if (optionReq != null && !worldSession.MeetsChrCustomizationReq(optionReq, target.GetClass(), false, customizations)) + if (optionReq != null && !worldSession.MeetsChrCustomizationReq(optionReq, target.GetRace(), target.GetClass(), false, customizations)) continue; // Loop over the options until the first one fits @@ -588,7 +588,7 @@ namespace Game.Chat foreach (ChrCustomizationChoiceRecord choiceForOption in choicesForOption) { var choiceReq = CliDB.ChrCustomizationReqStorage.LookupByKey(choiceForOption.ChrCustomizationReqID); - if (choiceReq != null && !worldSession.MeetsChrCustomizationReq(choiceReq, target.GetClass(), false, customizations)) + if (choiceReq != null && !worldSession.MeetsChrCustomizationReq(choiceReq, target.GetRace(), target.GetClass(), false, customizations)) continue; ChrCustomizationChoiceRecord choiceEntry = choicesForOption[0]; diff --git a/Source/Game/Conditions/Condition.cs b/Source/Game/Conditions/Condition.cs index 15672c16a..17c7a358a 100644 --- a/Source/Game/Conditions/Condition.cs +++ b/Source/Game/Conditions/Condition.cs @@ -5,6 +5,7 @@ using Framework.Constants; using Game.DataStorage; using Game.Entities; using Game.Maps; +using Game.Miscellaneous; using Game.Scenarios; using System; using System.Collections.Generic; @@ -159,7 +160,7 @@ namespace Game.Conditions break; case ConditionTypes.Race: if (unit != null) - condMeets = Convert.ToBoolean(SharedConst.GetMaskForRace(unit.GetRace()) & ConditionValue1); + condMeets = new RaceMask(ConditionValue1).HasRace(unit.GetRace()); break; case ConditionTypes.Gender: if (player != null) diff --git a/Source/Game/Conditions/ConditionManager.cs b/Source/Game/Conditions/ConditionManager.cs index a15c82da3..a150b652b 100644 --- a/Source/Game/Conditions/ConditionManager.cs +++ b/Source/Game/Conditions/ConditionManager.cs @@ -10,6 +10,7 @@ using Game.Entities; using Game.Groups; using Game.Loots; using Game.Maps; +using Game.Miscellaneous; using Game.Spells; using System; using System.Collections.Generic; @@ -1445,9 +1446,10 @@ namespace Game } case ConditionTypes.Race: { - if (Convert.ToBoolean(cond.ConditionValue1 & ~SharedConst.RaceMaskAllPlayable)) + RaceMask invalidRaceMask = new RaceMask(cond.ConditionValue1 & ~RaceMask.AllPlayable.RawValue); + if (!invalidRaceMask.IsEmpty()) // uint32 works thanks to weird index remapping in racemask { - Log.outError(LogFilter.Sql, "{0} has non existing racemask ({1}), skipped.", cond.ToString(true), cond.ConditionValue1 & ~SharedConst.RaceMaskAllPlayable); + Log.outError(LogFilter.Sql, "{0} has non existing racemask ({1}), skipped.", cond.ToString(true), cond.ConditionValue1 & ~RaceMask.AllPlayable.RawValue); return false; } break; @@ -2022,7 +2024,8 @@ namespace Game } } - if (condition.RaceMask != 0 && !Convert.ToBoolean(SharedConst.GetMaskForRace(player.GetRace()) & condition.RaceMask)) + var raceMask = new RaceMask(condition.RaceMask); + if (!raceMask.IsEmpty() && raceMask.HasRace(player.GetRace())) return false; if (condition.ClassMask != 0 && !Convert.ToBoolean(player.GetClassMask() & condition.ClassMask)) diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 155da11fc..9badb58ce 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -107,6 +107,7 @@ namespace Game.DataStorage ChrSpecializationStorage = ReadDB2("ChrSpecialization.db2", HotfixStatements.SEL_CHR_SPECIALIZATION, HotfixStatements.SEL_CHR_SPECIALIZATION_LOCALE); CinematicCameraStorage = ReadDB2("CinematicCamera.db2", HotfixStatements.SEL_CINEMATIC_CAMERA); CinematicSequencesStorage = ReadDB2("CinematicSequences.db2", HotfixStatements.SEL_CINEMATIC_SEQUENCES); + ConditionalChrModelStorage = ReadDB2("ConditionalChrModel.db2", HotfixStatements.SEL_CONDITIONAL_CHR_MODEL); ConditionalContentTuningStorage = ReadDB2("ConditionalContentTuning.db2", HotfixStatements.SEL_CONDITIONAL_CONTENT_TUNING); ContentTuningStorage = ReadDB2("ContentTuning.db2", HotfixStatements.SEL_CONTENT_TUNING); ContentTuningXExpectedStorage = ReadDB2("ContentTuningXExpected.db2", HotfixStatements.SEL_CONTENT_TUNING_X_EXPECTED); @@ -539,6 +540,7 @@ namespace Game.DataStorage public static DB6Storage ChrSpecializationStorage; public static DB6Storage CinematicCameraStorage; public static DB6Storage CinematicSequencesStorage; + public static DB6Storage ConditionalChrModelStorage; public static DB6Storage ConditionalContentTuningStorage; public static DB6Storage ContentTuningStorage; public static DB6Storage ContentTuningXExpectedStorage; diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 195a1ee3d..85c2d0e98 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -3,6 +3,7 @@ using Framework.Constants; using Framework.Database; +using Game.Miscellaneous; using Game.Networking; using System; using System.Collections; @@ -1830,7 +1831,8 @@ namespace Game.DataStorage var bounds = _skillRaceClassInfoBySkill.LookupByKey(skill); foreach (var skllRaceClassInfo in bounds) { - if (skllRaceClassInfo.RaceMask != 0 && !Convert.ToBoolean(skllRaceClassInfo.RaceMask & SharedConst.GetMaskForRace(race))) + var raceMask = new RaceMask(skllRaceClassInfo.RaceMask); + if (!raceMask.IsEmpty() && !raceMask.HasRace(race)) continue; if (skllRaceClassInfo.ClassMask != 0 && !Convert.ToBoolean(skllRaceClassInfo.ClassMask & (1 << ((byte)class_ - 1)))) continue; diff --git a/Source/Game/DataStorage/Structs/A_Records.cs b/Source/Game/DataStorage/Structs/A_Records.cs index 28bb498e7..a25bef2cb 100644 --- a/Source/Game/DataStorage/Structs/A_Records.cs +++ b/Source/Game/DataStorage/Structs/A_Records.cs @@ -122,7 +122,7 @@ namespace Game.DataStorage public uint UwIntroSound; public byte FactionGroupMask; public float AmbientMultiplier; - public byte MountFlags; + public int MountFlags; public short PvpCombatWorldStateID; public byte WildBattlePetLevelMin; public byte WildBattlePetLevelMax; diff --git a/Source/Game/DataStorage/Structs/C_Records.cs b/Source/Game/DataStorage/Structs/C_Records.cs index 462392b0a..057571323 100644 --- a/Source/Game/DataStorage/Structs/C_Records.cs +++ b/Source/Game/DataStorage/Structs/C_Records.cs @@ -183,6 +183,7 @@ namespace Game.DataStorage public sealed class ChrCustomizationReqRecord { public uint Id; + public long RaceMask; public string ReqSource; public int Flags; public int ClassMask; @@ -329,6 +330,16 @@ namespace Game.DataStorage public ushort[] Camera = new ushort[8]; } + public sealed class ConditionalChrModelRecord + { + public uint Id; + public uint ChrModelID; // This is the PK + public int ChrCustomizationReqID; + public int PlayerConditionID; + public int Flags; + public int ChrCustomizationCategoryID; + } + public sealed class ConditionalContentTuningRecord { public uint Id; @@ -512,12 +523,12 @@ namespace Game.DataStorage public CriteriaType Type; public uint Asset; public uint ModifierTreeId; - public byte StartEvent; + public int StartEvent; public uint StartAsset; public ushort StartTimer; - public byte FailEvent; + public int FailEvent; public uint FailAsset; - public byte Flags; + public int Flags; public ushort EligibilityWorldStateID; public byte EligibilityWorldStateValue; @@ -530,7 +541,7 @@ namespace Game.DataStorage public string Description; public uint Parent; public uint Amount; - public sbyte Operator; + public int Operator; public uint CriteriaID; public int OrderIndex; public CriteriaTreeFlags Flags; diff --git a/Source/Game/DataStorage/Structs/G_Records.cs b/Source/Game/DataStorage/Structs/G_Records.cs index d2eaf97ce..4a2365ced 100644 --- a/Source/Game/DataStorage/Structs/G_Records.cs +++ b/Source/Game/DataStorage/Structs/G_Records.cs @@ -21,6 +21,9 @@ namespace Game.DataStorage public short ObjectEffectPackageID; public float OverrideLootEffectScale; public float OverrideNameScale; + public int AlternateDisplayType; + public int ClientCreatureDisplayInfoID; + public int ClientItemID; public Vector3 GeoBoxMin { diff --git a/Source/Game/DataStorage/Structs/U_Records.cs b/Source/Game/DataStorage/Structs/U_Records.cs index d25f8df14..ddd4f9b03 100644 --- a/Source/Game/DataStorage/Structs/U_Records.cs +++ b/Source/Game/DataStorage/Structs/U_Records.cs @@ -16,7 +16,8 @@ namespace Game.DataStorage public UiMapType Type; public int BountySetID; public uint BountyDisplayLocation; - public int VisibilityPlayerConditionID; + public int VisibilityPlayerConditionID2; // if not met then map is skipped when evaluating UiMapAssignment + public int VisibilityPlayerConditionID; // if not met then client checks other maps with the same AlternateUiMapGroup, not re-evaluating UiMapAssignment for them public sbyte HelpTextPosition; public int BkgAtlasID; public int AlternateUiMapGroup; diff --git a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs index 5f0a5ba6c..9664130a1 100644 --- a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs +++ b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs @@ -2,7 +2,6 @@ // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. using Framework.Constants; -using Framework.Dynamic; using Game.AI; using Game.Maps; using Game.Movement; @@ -11,6 +10,7 @@ using Game.Networking.Packets; using Game.Spells; using System; using System.Collections.Generic; +using System.Linq; using System.Numerics; namespace Game.Entities @@ -537,6 +537,9 @@ namespace Game.Entities _ai.OnUnitExit(leavingUnit); } } + + SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumUnitsInside), _insideUnits.Count); + SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.NumPlayersInside), _insideUnits.Count(guid => guid.IsPlayer())); } public AreaTriggerTemplate GetTemplate() @@ -815,6 +818,8 @@ namespace Game.Entities m_areaTriggerData.ClearChanged(m_areaTriggerData.TimeToTarget); }); + SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.OrbitPathTarget), orbit.PathTarget.GetValueOrDefault(ObjectGuid.Empty)); + _orbitInfo = orbit; _orbitInfo.TimeToTarget = timeToTarget; diff --git a/Source/Game/Entities/GameObject/GameObjectData.cs b/Source/Game/Entities/GameObject/GameObjectData.cs index 6bc334bd5..7edec4904 100644 --- a/Source/Game/Entities/GameObject/GameObjectData.cs +++ b/Source/Game/Entities/GameObject/GameObjectData.cs @@ -1044,6 +1044,7 @@ namespace Game.Entities public struct duelflag { public uint InteractRadiusOverride; // 0 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + public uint Willthisduelgountilaplayerdies; // 1 Will this duel go until a player dies?, enum { false, true, }; Default: false } public struct fishingnode diff --git a/Source/Game/Entities/Item/Item.cs b/Source/Game/Entities/Item/Item.cs index 740258b3f..f9a7c59db 100644 --- a/Source/Game/Entities/Item/Item.cs +++ b/Source/Game/Entities/Item/Item.cs @@ -2038,6 +2038,22 @@ namespace Game.Entities return (ushort)GetAppearanceModId(); } + uint GetVisibleModifiedAppearanceId(Player owner) + { + uint itemModifiedAppearanceId = GetModifier(ItemConst.AppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]); + if (itemModifiedAppearanceId == 0) + itemModifiedAppearanceId = GetModifier(ItemModifier.TransmogAppearanceAllSpecs); + + if (itemModifiedAppearanceId == 0) + { + var itemModifiedAppearance = GetItemModifiedAppearance(); + if (itemModifiedAppearance != null) + itemModifiedAppearanceId = itemModifiedAppearance.Id; + } + + return itemModifiedAppearanceId; + } + public uint GetVisibleSecondaryModifiedAppearanceId(Player owner) { uint itemModifiedAppearanceId = GetModifier(ItemConst.SecondaryAppearanceModifierSlotBySpec[owner.GetActiveTalentGroup()]); diff --git a/Source/Game/Entities/Item/ItemTemplate.cs b/Source/Game/Entities/Item/ItemTemplate.cs index ba2d39ed2..a1a85683e 100644 --- a/Source/Game/Entities/Item/ItemTemplate.cs +++ b/Source/Game/Entities/Item/ItemTemplate.cs @@ -3,6 +3,7 @@ using Framework.Constants; using Game.DataStorage; +using Game.Miscellaneous; using System; using System.Collections; using System.Collections.Generic; @@ -274,7 +275,7 @@ namespace Game.Entities public uint GetSellPrice() { return ExtendedData.SellPrice; } public InventoryType GetInventoryType() { return ExtendedData.inventoryType; } public int GetAllowableClass() { return ExtendedData.AllowableClass; } - public long GetAllowableRace() { return ExtendedData.AllowableRace; } + public RaceMask GetAllowableRace() { return new RaceMask(ExtendedData.AllowableRace); } public uint GetBaseItemLevel() { return ExtendedData.ItemLevel; } public int GetBaseRequiredLevel() { return ExtendedData.RequiredLevel; } public uint GetRequiredSkill() { return ExtendedData.RequiredSkill; } diff --git a/Source/Game/Entities/Object/ObjectGuid.cs b/Source/Game/Entities/Object/ObjectGuid.cs index ead7f77d8..db2dfaa2e 100644 --- a/Source/Game/Entities/Object/ObjectGuid.cs +++ b/Source/Game/Entities/Object/ObjectGuid.cs @@ -113,6 +113,7 @@ namespace Game.Entities case HighGuid.UniqUserClient: case HighGuid.ClientSession: case HighGuid.ClientConnection: + case HighGuid.LMMParty: return ObjectGuidFactory.CreateClient(type, 0, arg1, counter); default: return Empty; @@ -151,10 +152,13 @@ namespace Game.Entities case HighGuid.AILock: case HighGuid.AILockTicket: return ObjectGuidFactory.CreateWorldObject(type, 0, 0, (ushort)mapId, 0, entry, counter); + case HighGuid.ToolsClient: + return ObjectGuidFactory.CreateToolsClient(mapId, entry, counter); default: return Empty; } } + public static ObjectGuid Create(HighGuid type, SpellCastSource subType, uint mapId, uint entry, ulong counter) { switch (type) @@ -166,6 +170,22 @@ namespace Game.Entities } } + public static ObjectGuid Create(HighGuid type, uint arg1, ushort arg2, byte arg3, uint arg4) + { + if (type != HighGuid.WorldLayer) + return Empty; + + return ObjectGuidFactory.CreateWorldLayer(arg1, arg2, arg3, arg4); + } + + public static ObjectGuid Create(HighGuid type, uint arg2, byte arg3, byte arg4, ulong counter) + { + if (type != HighGuid.LMMLobby) + return Empty; + + return ObjectGuidFactory.CreateLMMLobby(0, arg2, arg3, arg4, counter); + } + public byte[] GetRawValue() { byte[] temp = new byte[16]; @@ -541,6 +561,16 @@ namespace Game.Entities return new ObjectGuid((ulong)(((ulong)HighGuid.WorldLayer << 58) | ((ulong)(arg1 & 0xFFFFFFFF) << 10) | (ulong)(arg2 & 0x1FFu)), (ulong)(((ulong)(arg3 & 0xFF) << 24) | (ulong)(arg4 & 0x7FFFFF))); } + public static ObjectGuid CreateLMMLobby(uint realmId, uint arg2, byte arg3, byte arg4, ulong counter) + { + return new ObjectGuid((ulong)(((ulong)HighGuid.LMMLobby << 58) + | ((ulong)GetRealmIdForObjectGuid(realmId) << 42) + | ((ulong)(arg2 & 0xFFFFFFFF) << 26) + | ((ulong)(arg3 & 0xFF) << 18) + | ((ulong)(arg4 & 0xFF) << 10)), + counter); + } + static uint GetRealmIdForObjectGuid(uint realmId) { if (realmId != 0) @@ -608,6 +638,11 @@ namespace Game.Entities SET_GUID_INFO(HighGuid.Cast, FormatWorldObject, ParseWorldObject); SET_GUID_INFO(HighGuid.ClientConnection, FormatClient, ParseClient); SET_GUID_INFO(HighGuid.ClubFinder, FormatClubFinder, ParseClubFinder); + SET_GUID_INFO(HighGuid.ToolsClient, FormatToolsClient, ParseToolsClient); + SET_GUID_INFO(HighGuid.WorldLayer, FormatWorldLayer, ParseWorldLayer); + SET_GUID_INFO(HighGuid.ArenaTeam, FormatGuild, ParseGuild); + SET_GUID_INFO(HighGuid.LMMParty, FormatClient, ParseClient); + SET_GUID_INFO(HighGuid.LMMLobby, FormatLMMLobby, ParseLMMLobby); } static void SET_GUID_INFO(HighGuid type, Func format, Func parse) @@ -993,12 +1028,12 @@ namespace Game.Entities return ObjectGuidFactory.CreateClubFinder(realmId, typeNum, clubFinderId, dbId); } - string FormatToolsClient(HighGuid typeName, ObjectGuid guid) + static string FormatToolsClient(HighGuid typeName, ObjectGuid guid) { return $"{typeName}-{guid.GetMapId()}-{(uint)(guid.GetLowValue() >> 40) & 0xFFFFFF}-{guid.GetCounter():X10}"; } - ObjectGuid ParseToolsClient(HighGuid type, string guidString) + static ObjectGuid ParseToolsClient(HighGuid type, string guidString) { string[] split = guidString.Split('-'); if (split.Length != 3) @@ -1010,12 +1045,12 @@ namespace Game.Entities return ObjectGuidFactory.CreateToolsClient(mapId, serverId, counter); } - string FormatWorldLayer(HighGuid typeName, ObjectGuid guid) + static string FormatWorldLayer(HighGuid typeName, ObjectGuid guid) { return $"{typeName}-{(uint)((guid.GetHighValue() >> 10) & 0xFFFFFFFF)}-{(uint)(guid.GetHighValue() & 0x1FF)}-{(uint)((guid.GetLowValue() >> 24) & 0xFF)}-{(uint)(guid.GetLowValue() & 0x7FFFFF)}"; } - ObjectGuid ParseWorldLayer(HighGuid type, string guidString) + static ObjectGuid ParseWorldLayer(HighGuid type, string guidString) { string[] split = guidString.Split('-'); if (split.Length != 4) @@ -1026,6 +1061,23 @@ namespace Game.Entities return ObjectGuidFactory.CreateWorldLayer(arg1, arg2, arg3, arg4); } + + static string FormatLMMLobby(HighGuid typeName, ObjectGuid guid) + { + return $"{typeName}-{guid.GetRealmId()}-{(uint)(guid.GetHighValue() >> 26) & 0xFFFFFF}-{(uint)(guid.GetHighValue() >> 18) & 0xFF}-{(uint)(guid.GetHighValue() >> 10) & 0xFF}-{guid.GetLowValue():X}"; + } + + static ObjectGuid ParseLMMLobby(HighGuid type, string guidString) + { + string[] split = guidString.Split('-'); + if (split.Length != 5) + return ObjectGuid.FromStringFailed; + + if (!uint.TryParse(split[0], out uint realmId) || !uint.TryParse(split[1], out uint arg2) || !byte.TryParse(split[2], out byte arg3) || !byte.TryParse(split[0], out byte arg4) || !ulong.TryParse(split[0], out ulong arg5)) + return ObjectGuid.FromStringFailed; + + return ObjectGuidFactory.CreateLMMLobby(realmId, arg2, arg3, arg4, arg5); + } } public class Legacy diff --git a/Source/Game/Entities/Object/Update/UpdateField.cs b/Source/Game/Entities/Object/Update/UpdateField.cs index 135e7d955..bf5de1b96 100644 --- a/Source/Game/Entities/Object/Update/UpdateField.cs +++ b/Source/Game/Entities/Object/Update/UpdateField.cs @@ -423,6 +423,12 @@ namespace Game.Entities return updateField; } + public OptionalUpdateField ModifyValue(OptionalUpdateField updateField) where U : new() + { + MarkChanged(updateField); + return updateField; + } + public UpdateFieldString ModifyValue(UpdateFieldString updateField) { MarkChanged(updateField); @@ -464,6 +470,12 @@ namespace Game.Entities _changesMask.Set(updateField.Bit); } + public void MarkChanged(OptionalUpdateField updateField) where U : new() + { + _changesMask.Set(updateField.BlockBit); + _changesMask.Set(updateField.Bit); + } + public void MarkChanged(UpdateFieldString updateField) { _changesMask.Set(updateField.BlockBit); diff --git a/Source/Game/Entities/Object/Update/UpdateFields.cs b/Source/Game/Entities/Object/Update/UpdateFields.cs index 9cd18a445..394fe5300 100644 --- a/Source/Game/Entities/Object/Update/UpdateFields.cs +++ b/Source/Game/Entities/Object/Update/UpdateFields.cs @@ -247,7 +247,7 @@ namespace Game.Entities public class ItemModList : BaseUpdateData { - public DynamicUpdateField Values = new(0, 0); + public DynamicUpdateField Values = new(-1, 0); public ItemModList() : base(1) { } @@ -271,27 +271,21 @@ namespace Game.Entities 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 (int i = 0; i < Values.Size(); ++i) { - for (int 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); } - } + } } data.FlushBits(); } @@ -1126,6 +1120,8 @@ namespace Game.Entities public class UnitData : BaseUpdateData { + static int ChangeMaskLength = 217; + public UpdateField> StateWorldEffectIDs = new(0, 1); public DynamicUpdateField PassiveSpells = new(0, 2); public DynamicUpdateField WorldEffects = new(0, 3); @@ -1213,53 +1209,59 @@ namespace Game.Entities public UpdateField AttackPowerModPos = new(64, 87); public UpdateField AttackPowerModNeg = new(64, 88); public UpdateField AttackPowerMultiplier = new(64, 89); - public UpdateField RangedAttackPower = new(64, 90); - public UpdateField RangedAttackPowerModPos = new(64, 91); - public UpdateField RangedAttackPowerModNeg = new(64, 92); - public UpdateField RangedAttackPowerMultiplier = new(64, 93); - public UpdateField MainHandWeaponAttackPower = new(64, 94); - public UpdateField OffHandWeaponAttackPower = new(64, 95); - public UpdateField RangedWeaponAttackPower = new(96, 97); - public UpdateField SetAttackSpeedAura = new(96, 98); - public UpdateField Lifesteal = new(96, 99); - public UpdateField MinRangedDamage = new(96, 100); - public UpdateField MaxRangedDamage = new(96, 101); - public UpdateField ManaCostMultiplier = new(96, 102); - public UpdateField MaxHealthModifier = new(96, 103); - public UpdateField HoverHeight = new(96, 104); - public UpdateField MinItemLevelCutoff = new(96, 105); - public UpdateField MinItemLevel = new(96, 106); - public UpdateField MaxItemLevel = new(96, 107); - public UpdateField AzeriteItemLevel = new(96, 108); - public UpdateField WildBattlePetLevel = new(96, 109); - public UpdateField BattlePetCompanionExperience = new(96, 110); - public UpdateField BattlePetCompanionNameTimestamp = new(96, 111); - public UpdateField InteractSpellID = new(96, 112); - public UpdateField ScaleDuration = new(96, 113); - public UpdateField LooksLikeMountID = new(96, 114); - public UpdateField LooksLikeCreatureID = new(96, 115); - public UpdateField LookAtControllerID = new(96, 116); - public UpdateField PerksVendorItemID = new(96, 117); - public UpdateField TaxiNodesID = new(96, 118); - public UpdateField GuildGUID = new(96, 119); - public UpdateField FlightCapabilityID = new(96, 120); - public UpdateField SilencedSchoolMask = new(96, 121); - public UpdateField NameplateAttachToGUID = new(96, 122); // When set, nameplate of this unit will instead appear on that object - public UpdateFieldArray NpcFlags = new(2, 123, 124); - public UpdateFieldArray Power = new(10, 126, 127); - public UpdateFieldArray MaxPower = new(10, 126, 137); - public UpdateFieldArray PowerRegenFlatModifier = new(10, 126, 147); - public UpdateFieldArray PowerRegenInterruptedFlatModifier = new(10, 126, 157); - public UpdateFieldArray VirtualItems = new(3, 167, 168); - public UpdateFieldArray AttackRoundBaseTime = new(2, 171, 172); - public UpdateFieldArray Stats = new(4, 174, 175); - public UpdateFieldArray StatPosBuff = new(4, 174, 179); - public UpdateFieldArray StatNegBuff = new(4, 174, 183); - public UpdateFieldArray Resistances = new(7, 187, 188); - public UpdateFieldArray BonusResistanceMods = new(7, 187, 195); - public UpdateFieldArray ManaCostModifier = new(7, 187, 202); + public UpdateField AttackPowerModSupport = new(64, 90); + public UpdateField RangedAttackPower = new(64, 91); + public UpdateField RangedAttackPowerModPos = new(64, 92); + public UpdateField RangedAttackPowerModNeg = new(64, 93); + public UpdateField RangedAttackPowerMultiplier = new(64, 94); + public UpdateField RangedAttackPowerModSupport = new(64, 95); + public UpdateField MainHandWeaponAttackPower = new(96, 97); + public UpdateField OffHandWeaponAttackPower = new(96, 98); + public UpdateField RangedWeaponAttackPower = new(96, 99); + public UpdateField SetAttackSpeedAura = new(96, 100); + public UpdateField Lifesteal = new(96, 101); + public UpdateField MinRangedDamage = new(96, 102); + public UpdateField MaxRangedDamage = new(96, 103); + public UpdateField ManaCostMultiplier = new(96, 104); + public UpdateField MaxHealthModifier = new(96, 105); + public UpdateField HoverHeight = new(96, 106); + public UpdateField MinItemLevelCutoff = new(96, 107); + public UpdateField MinItemLevel = new(96, 108); + public UpdateField MaxItemLevel = new(96, 109); + public UpdateField AzeriteItemLevel = new(96, 110); + public UpdateField WildBattlePetLevel = new(96, 111); + public UpdateField BattlePetCompanionExperience = new(96, 112); + public UpdateField BattlePetCompanionNameTimestamp = new(96, 113); + public UpdateField InteractSpellID = new(96, 114); + public UpdateField ScaleDuration = new(96, 115); + public UpdateField LooksLikeMountID = new(96, 116); + public UpdateField LooksLikeCreatureID = new(96, 117); + public UpdateField LookAtControllerID = new(96, 118); + public UpdateField PerksVendorItemID = new(96, 119); + public UpdateField TaxiNodesID = new(96, 120); + public UpdateField GuildGUID = new(96, 121); + public UpdateField FlightCapabilityID = new(96, 122); + public UpdateField GlideEventSpeedDivisor = new(96, 123); // Movement speed gets divided by this value when evaluating what GlideEvents to use + public UpdateField SilencedSchoolMask = new(96, 124); + public UpdateField CurrentAreaID = new(96, 125); + public UpdateField NameplateAttachToGUID = new(96, 126); // When set, nameplate of this unit will instead appear on that object + public UpdateFieldArray NpcFlags = new(2, 127, 128); + public UpdateFieldArray Power = new(10, 130, 131); + public UpdateFieldArray MaxPower = new(10, 130, 141); + public UpdateFieldArray PowerRegenFlatModifier = new(10, 130, 151); + public UpdateFieldArray PowerRegenInterruptedFlatModifier = new(10, 130, 161); + public UpdateFieldArray VirtualItems = new(3, 171, 172); + public UpdateFieldArray AttackRoundBaseTime = new(2, 175, 176); + public UpdateFieldArray Stats = new(4, 178, 179); + public UpdateFieldArray StatPosBuff = new(4, 178, 183); + public UpdateFieldArray StatNegBuff = new(4, 178, 187); + public UpdateFieldArray StatSupportBuff = new(4, 178, 191); + public UpdateFieldArray Resistances = new(7, 195, 196); + public UpdateFieldArray BonusResistanceMods = new(7, 195, 203); + public UpdateFieldArray ManaCostModifier = new(7, 195, 210); - public UnitData() : base(0, TypeId.Unit, 209) { } + + public UnitData() : base(0, TypeId.Unit, ChangeMaskLength) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { @@ -1376,6 +1378,7 @@ namespace Game.Entities data.WriteInt32(Stats[i]); data.WriteInt32(StatPosBuff[i]); data.WriteInt32(StatNegBuff[i]); + data.WriteInt32(StatSupportBuff[i]); } } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner) || fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) @@ -1407,10 +1410,12 @@ namespace Game.Entities data.WriteInt32(AttackPowerModPos); data.WriteInt32(AttackPowerModNeg); data.WriteFloat(AttackPowerMultiplier); + data.WriteInt32(AttackPowerModSupport); data.WriteInt32(RangedAttackPower); data.WriteInt32(RangedAttackPowerModPos); data.WriteInt32(RangedAttackPowerModNeg); data.WriteFloat(RangedAttackPowerMultiplier); + data.WriteInt32(RangedAttackPowerModSupport); data.WriteInt32(MainHandWeaponAttackPower); data.WriteInt32(OffHandWeaponAttackPower); data.WriteInt32(RangedWeaponAttackPower); @@ -1441,7 +1446,9 @@ namespace Game.Entities data.WriteInt32(WorldEffects.Size()); data.WriteInt32(ChannelObjects.Size()); data.WriteInt32(FlightCapabilityID); + data.WriteFloat(GlideEventSpeedDivisor); data.WriteUInt32(SilencedSchoolMask); + data.WriteUInt32(CurrentAreaID); data.WritePackedGuid(NameplateAttachToGUID); for (int i = 0; i < PassiveSpells.Size(); ++i) @@ -1456,7 +1463,7 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { - UpdateMask allowedMaskForTarget = new(209, new uint[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0x0007FFFFu, 0x00003F80u, 0x00000000u }); + UpdateMask allowedMaskForTarget = new(ChangeMaskLength, new uint[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFC01u, 0x007FFFFFu, 0x0003F800u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1464,16 +1471,16 @@ namespace Game.Entities public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) - allowedMaskForTarget.OR(new UpdateMask(209, new uint[] { 0x00002000u, 0x3C010000u, 0xFFC20000u, 0x400000FEu, 0xFFF80000u, 0xFFFFC07Fu, 0x0001FFFFu })); + allowedMaskForTarget.OR(new UpdateMask(ChangeMaskLength, new uint[] { 0x00002000u, 0x3C010000u, 0xFFC20000u, 0x000003FEu, 0xFF800004u, 0xFFFC07FFu, 0x01FFFFFFu })); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.UnitAll)) - allowedMaskForTarget.OR(new UpdateMask(209, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x40000000u, 0xFFF80000u, 0x0000007Fu, 0x00000000u })); + allowedMaskForTarget.OR(new UpdateMask(ChangeMaskLength, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xFF800004u, 0x000007FFu, 0x00000000u })); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) - allowedMaskForTarget.OR(new UpdateMask(209, new uint[] { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0xF8000000u, 0x00000007u })); + allowedMaskForTarget.OR(new UpdateMask(ChangeMaskLength, new uint[] { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000007F8u })); } public void FilterDisallowedFieldsMaskForFlag(UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags) { - UpdateMask allowedMaskForTarget = new(209, new[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0x0007FFFFu, 0x00003F80u, 0x00000000u }); + UpdateMask allowedMaskForTarget = new(ChangeMaskLength, new[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFC01u, 0x007FFFFFu, 0x0003F800u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask.AND(allowedMaskForTarget); } @@ -1894,219 +1901,235 @@ namespace Game.Entities } if (changesMask[90]) { - data.WriteInt32(RangedAttackPower); + data.WriteInt32(AttackPowerModSupport); } if (changesMask[91]) { - data.WriteInt32(RangedAttackPowerModPos); + data.WriteInt32(RangedAttackPower); } if (changesMask[92]) { - data.WriteInt32(RangedAttackPowerModNeg); + data.WriteInt32(RangedAttackPowerModPos); } if (changesMask[93]) { - data.WriteFloat(RangedAttackPowerMultiplier); + data.WriteFloat(RangedAttackPowerModNeg); } if (changesMask[94]) { - data.WriteInt32(MainHandWeaponAttackPower); + data.WriteFloat(RangedAttackPowerMultiplier); } if (changesMask[95]) { - data.WriteInt32(OffHandWeaponAttackPower); + data.WriteInt32(RangedAttackPowerModSupport); } } if (changesMask[96]) { if (changesMask[97]) { - data.WriteInt32(RangedWeaponAttackPower); + data.WriteInt32(MainHandWeaponAttackPower); } if (changesMask[98]) { - data.WriteInt32(SetAttackSpeedAura); + data.WriteInt32(OffHandWeaponAttackPower); } if (changesMask[99]) { - data.WriteFloat(Lifesteal); + data.WriteFloat(RangedWeaponAttackPower); } if (changesMask[100]) { - data.WriteFloat(MinRangedDamage); + data.WriteFloat(SetAttackSpeedAura); } if (changesMask[101]) { - data.WriteFloat(MaxRangedDamage); + data.WriteFloat(Lifesteal); } if (changesMask[102]) { - data.WriteFloat(ManaCostMultiplier); + data.WriteFloat(MinRangedDamage); } if (changesMask[103]) { - data.WriteFloat(MaxHealthModifier); + data.WriteFloat(MaxRangedDamage); } if (changesMask[104]) { - data.WriteFloat(HoverHeight); + data.WriteFloat(ManaCostMultiplier); } if (changesMask[105]) { - data.WriteUInt32(MinItemLevelCutoff); + data.WriteFloat(MaxHealthModifier); } if (changesMask[106]) { - data.WriteUInt32(MinItemLevel); + data.WriteFloat(HoverHeight); } if (changesMask[107]) { - data.WriteUInt32(MaxItemLevel); + data.WriteUInt32(MinItemLevelCutoff); } if (changesMask[108]) { - data.WriteInt32(AzeriteItemLevel); + data.WriteUInt32(MinItemLevel); } if (changesMask[109]) { - data.WriteUInt32(WildBattlePetLevel); + data.WriteUInt32(MaxItemLevel); } if (changesMask[110]) { - data.WriteUInt32(BattlePetCompanionExperience); + data.WriteInt32(AzeriteItemLevel); } if (changesMask[111]) { - data.WriteUInt32(BattlePetCompanionNameTimestamp); + data.WriteUInt32(WildBattlePetLevel); } if (changesMask[112]) { - data.WriteInt32(InteractSpellID); + data.WriteUInt32(BattlePetCompanionExperience); } if (changesMask[113]) { - data.WriteInt32(ScaleDuration); + data.WriteUInt32(BattlePetCompanionNameTimestamp); } if (changesMask[114]) { - data.WriteInt32(LooksLikeMountID); + data.WriteInt32(InteractSpellID); } if (changesMask[115]) { - data.WriteInt32(LooksLikeCreatureID); + data.WriteInt32(ScaleDuration); } if (changesMask[116]) { - data.WriteInt32(LookAtControllerID); + data.WriteInt32(LooksLikeMountID); } if (changesMask[117]) { - data.WriteInt32(PerksVendorItemID); + data.WriteInt32(LooksLikeCreatureID); } if (changesMask[118]) { - data.WriteInt32(TaxiNodesID); + data.WriteInt32(LookAtControllerID); } if (changesMask[119]) { - data.WritePackedGuid(GuildGUID); + data.WriteInt32(PerksVendorItemID); } if (changesMask[120]) { - data.WriteInt32(FlightCapabilityID); + data.WriteInt32(TaxiNodesID); } if (changesMask[121]) { - data.WriteUInt32(SilencedSchoolMask); + data.WritePackedGuid(GuildGUID); } if (changesMask[122]) + { + data.WriteInt32(FlightCapabilityID); + } + if (changesMask[123]) + { + data.WriteFloat(GlideEventSpeedDivisor); + } + if (changesMask[124]) + { + data.WriteUInt32(SilencedSchoolMask); + } + if (changesMask[125]) + { + data.WriteUInt32(CurrentAreaID); + } + if (changesMask[126]) { data.WritePackedGuid(NameplateAttachToGUID); } } - if (changesMask[123]) + if (changesMask[127]) { for (int i = 0; i < 2; ++i) { - if (changesMask[124 + i]) + if (changesMask[128 + i]) { data.WriteUInt32(GetViewerDependentNpcFlags(this, i, owner, receiver)); } } } - if (changesMask[126]) + if (changesMask[130]) { for (int i = 0; i < 10; ++i) { - if (changesMask[127 + i]) + if (changesMask[131 + i]) { data.WriteInt32(Power[i]); } - if (changesMask[137 + i]) + if (changesMask[141 + i]) { data.WriteUInt32(MaxPower[i]); } - if (changesMask[147 + i]) + if (changesMask[151 + i]) { data.WriteFloat(PowerRegenFlatModifier[i]); } - if (changesMask[157 + i]) + if (changesMask[161 + i]) { data.WriteFloat(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[167]) + if (changesMask[171]) { for (int 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 (int i = 0; i < 2; ++i) { - if (changesMask[172 + i]) + if (changesMask[176 + i]) { data.WriteUInt32(AttackRoundBaseTime[i]); } } } - if (changesMask[174]) + if (changesMask[178]) { for (int i = 0; i < 4; ++i) { - if (changesMask[175 + i]) + if (changesMask[179 + i]) { data.WriteInt32(Stats[i]); } - if (changesMask[179 + i]) + if (changesMask[183 + i]) { data.WriteInt32(StatPosBuff[i]); } - if (changesMask[183 + i]) + if (changesMask[187 + i]) { data.WriteInt32(StatNegBuff[i]); } } } - if (changesMask[187]) + if (changesMask[195]) { for (int i = 0; i < 7; ++i) { - if (changesMask[188 + i]) + if (changesMask[196 + i]) { data.WriteInt32(Resistances[i]); } - if (changesMask[195 + i]) + if (changesMask[203 + i]) { data.WriteInt32(BonusResistanceMods[i]); } - if (changesMask[202 + i]) + if (changesMask[210 + i]) { data.WriteInt32(ManaCostModifier[i]); } @@ -2203,10 +2226,12 @@ namespace Game.Entities ClearChangesMask(AttackPowerModPos); ClearChangesMask(AttackPowerModNeg); ClearChangesMask(AttackPowerMultiplier); + ClearChangesMask(AttackPowerModSupport); ClearChangesMask(RangedAttackPower); ClearChangesMask(RangedAttackPowerModPos); ClearChangesMask(RangedAttackPowerModNeg); ClearChangesMask(RangedAttackPowerMultiplier); + ClearChangesMask(RangedAttackPowerModSupport); ClearChangesMask(MainHandWeaponAttackPower); ClearChangesMask(OffHandWeaponAttackPower); ClearChangesMask(RangedWeaponAttackPower); @@ -2233,7 +2258,9 @@ namespace Game.Entities ClearChangesMask(TaxiNodesID); ClearChangesMask(GuildGUID); ClearChangesMask(FlightCapabilityID); + ClearChangesMask(GlideEventSpeedDivisor); ClearChangesMask(SilencedSchoolMask); + ClearChangesMask(CurrentAreaID); ClearChangesMask(NameplateAttachToGUID); ClearChangesMask(NpcFlags); ClearChangesMask(Power); @@ -2245,6 +2272,7 @@ namespace Game.Entities ClearChangesMask(Stats); ClearChangesMask(StatPosBuff); ClearChangesMask(StatNegBuff); + ClearChangesMask(StatSupportBuff); ClearChangesMask(Resistances); ClearChangesMask(BonusResistanceMods); ClearChangesMask(ManaCostModifier); @@ -2380,21 +2408,21 @@ namespace Game.Entities public class QuestLog : BaseUpdateData { - public UpdateField QuestID = new(0, 1); - public UpdateField StateFlags = new(0, 2); - public UpdateField EndTime = new(0, 3); - public UpdateField AcceptTime = new(0, 4); - public UpdateField ObjectiveFlags = new(0, 5); - public UpdateFieldArray ObjectiveProgress = new(24, 6, 7); + static int changeMaskLength = 30; - public QuestLog() : base(31) { } + public UpdateField EndTime = new(0, 1); + public UpdateField QuestID = new(0, 2); + public UpdateField StateFlags = new(0, 3); + public UpdateField ObjectiveFlags = new(0, 4); + public UpdateFieldArray ObjectiveProgress = new(24, 5, 6); + + public QuestLog() : base(changeMaskLength) { } public void WriteCreate(WorldPacket data, Player owner, Player receiver) { + data.WriteInt64(EndTime); data.WriteUInt32(QuestID); data.WriteUInt32(StateFlags); - data.WriteUInt32(EndTime); - data.WriteUInt32(AcceptTime); data.WriteUInt32(ObjectiveFlags); for (int i = 0; i < 24; ++i) { @@ -2417,30 +2445,26 @@ namespace Game.Entities { if (changesMask[1]) { - data.WriteUInt32(QuestID); + data.WriteInt64(EndTime); } if (changesMask[2]) { - data.WriteUInt32(StateFlags); + data.WriteUInt32(QuestID); } if (changesMask[3]) { - data.WriteUInt32(EndTime); + data.WriteUInt32(StateFlags); } if (changesMask[4]) - { - data.WriteUInt32(AcceptTime); - } - if (changesMask[5]) { data.WriteUInt32(ObjectiveFlags); } } - if (changesMask[6]) + if (changesMask[5]) { for (int i = 0; i < 24; ++i) { - if (changesMask[7 + i]) + if (changesMask[6 + i]) { data.WriteUInt16(ObjectiveProgress[i]); } @@ -2450,10 +2474,9 @@ namespace Game.Entities public override void ClearChangesMask() { + ClearChangesMask(EndTime); ClearChangesMask(QuestID); ClearChangesMask(StateFlags); - ClearChangesMask(EndTime); - ClearChangesMask(AcceptTime); ClearChangesMask(ObjectiveFlags); ClearChangesMask(ObjectiveProgress); _changesMask.ResetAll(); @@ -3376,21 +3399,112 @@ namespace Game.Entities } } - public class Research + public class CompletedProject : BaseUpdateData { - public short ResearchProjectID; + public UpdateField ProjectID = new(0, 1); + public UpdateField FirstCompleted = new(0, 2); + public UpdateField CompletionCount = new(0, 3); + + public CompletedProject() : base(4) { } public void WriteCreate(WorldPacket data, Player owner, Player receiver) { - data.WriteInt16(ResearchProjectID); + data.WriteUInt32(ProjectID); + data.WriteInt64(FirstCompleted); + data.WriteUInt32(CompletionCount); } public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) { - data.WriteInt16(ResearchProjectID); + UpdateMask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 4); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteUInt32(ProjectID); + } + if (changesMask[2]) + { + data.WriteInt64(FirstCompleted); + } + if (changesMask[3]) + { + data.WriteUInt32(CompletionCount); + } + } + } + + public override void ClearChangesMask() + { + ClearChangesMask(ProjectID); + ClearChangesMask(FirstCompleted); + ClearChangesMask(CompletionCount); + _changesMask.ResetAll(); } } + public class ResearchHistory : BaseUpdateData + { + public DynamicUpdateField CompletedProjects = new(0, 1); + + public ResearchHistory() : base(2) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(CompletedProjects.Size()); + for (int i = 0; i < CompletedProjects.Size(); ++i) + { + CompletedProjects[i].WriteCreate(data, owner, receiver); + } + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + UpdateMask 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 (int i = 0; i < CompletedProjects.Size(); ++i) + { + if (CompletedProjects.HasChanged(i) || ignoreChangesMask) + { + CompletedProjects[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + } + } + + public override void ClearChangesMask() + { + ClearChangesMask(CompletedProjects); + _changesMask.ResetAll(); + } + } + public class MawPower { public int Field_0; @@ -3797,6 +3911,7 @@ namespace Game.Entities data.WriteUInt32(Quantity); data.WriteInt32(ReagentQuality); data.WriteBits(DataSlotIndex.HasValue(), 1); + data.FlushBits(); if (DataSlotIndex.HasValue()) { data.WriteUInt8(DataSlotIndex); @@ -3837,6 +3952,7 @@ namespace Game.Entities data.WriteInt32(ReagentQuality); } data.WriteBits(DataSlotIndex.HasValue(), 1); + data.FlushBits(); if (changesMask[6]) { if (DataSlotIndex.HasValue()) @@ -3904,6 +4020,7 @@ namespace Game.Entities data.WriteBits(CustomerNotes.GetValue().GetByteCount(), 10); data.WriteBits(OutputItem.HasValue(), 1); data.WriteBits(OutputItemData.HasValue(), 1); + data.FlushBits(); for (int i = 0; i < Reagents.Size(); ++i) { Reagents[i].WriteCreate(data, owner, receiver); @@ -4030,6 +4147,7 @@ namespace Game.Entities } data.WriteBits(OutputItem.HasValue(), 1); data.WriteBits(OutputItemData.HasValue(), 1); + data.FlushBits(); if (changesMask[22]) { if (OutputItem.HasValue()) @@ -4090,6 +4208,7 @@ namespace Game.Entities data.WriteBits(RecraftItemInfo.HasValue(), 1); data.WriteBits(Enchantments.Size(), 4); data.WriteBits(Gems.Size(), 2); + data.FlushBits(); if (RecraftItemInfo.HasValue()) { RecraftItemInfo.GetValue().Write(data); @@ -4154,6 +4273,7 @@ namespace Game.Entities Data.GetValue().WriteUpdate(data, ignoreChangesMask, owner, receiver); } data.WriteBits(RecraftItemInfo.HasValue(), 1); + data.FlushBits(); if (changesMask[3]) { if (RecraftItemInfo.HasValue()) @@ -4232,6 +4352,166 @@ namespace Game.Entities data.WriteUInt8(Uses); } } + + public class StablePetInfo : BaseUpdateData + { + public UpdateField PetSlot = new(0, 1); + public UpdateField PetNumber = new(0, 2); + public UpdateField CreatureID = new(0, 3); + public UpdateField DisplayID = new(0, 4); + public UpdateField ExperienceLevel = new(0, 5); + public UpdateFieldString Name = new(0, 6); + public UpdateField PetFlags = new(0, 7); + + public StablePetInfo() : base(8) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteUInt32(PetSlot); + data.WriteUInt32(PetNumber); + data.WriteUInt32(CreatureID); + data.WriteUInt32(DisplayID); + data.WriteUInt32(ExperienceLevel); + data.WriteUInt8(PetFlags); + data.WriteBits(Name.GetValue().GetByteCount(), 8); + data.WriteString(Name); + data.FlushBits(); + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + UpdateMask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 8); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteUInt32(PetSlot); + } + if (changesMask[2]) + { + data.WriteUInt32(PetNumber); + } + if (changesMask[3]) + { + data.WriteUInt32(CreatureID); + } + if (changesMask[4]) + { + data.WriteUInt32(DisplayID); + } + if (changesMask[5]) + { + data.WriteUInt32(ExperienceLevel); + } + if (changesMask[7]) + { + data.WriteUInt8(PetFlags); + } + if (changesMask[6]) + { + data.WriteBits(Name.GetValue().GetByteCount(), 8); + data.WriteString(Name); + } + } + data.FlushBits(); + } + + public override void ClearChangesMask() + { + ClearChangesMask(PetSlot); + ClearChangesMask(PetNumber); + ClearChangesMask(CreatureID); + ClearChangesMask(DisplayID); + ClearChangesMask(ExperienceLevel); + ClearChangesMask(Name); + ClearChangesMask(PetFlags); + _changesMask.ResetAll(); + } + } + + public class StableInfo : BaseUpdateData + { + public DynamicUpdateField Pets = new(0, 1); + public UpdateField StableMaster = new(0, 2); + + public StableInfo() : base(3) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(Pets.Size()); + data.WritePackedGuid(StableMaster); + for (int i = 0; i < Pets.Size(); ++i) + { + Pets[i].WriteCreate(data, owner, receiver); + } + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + UpdateMask 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 (int i = 0; i < Pets.Size(); ++i) + { + if (Pets.HasChanged(i) || ignoreChangesMask) + { + Pets[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + if (changesMask[2]) + { + data.WritePackedGuid(StableMaster); + } + } + } + + public override void ClearChangesMask() + { + ClearChangesMask(Pets); + ClearChangesMask(StableMaster); + _changesMask.ResetAll(); + } + } + + public struct Research + { + public short ResearchProjectID; + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt16(ResearchProjectID); + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + data.WriteInt16(ResearchProjectID); + } + } public class ActivePlayerData : BaseUpdateData { @@ -4239,145 +4519,157 @@ namespace Game.Entities public static int ExploredZonesBits; public static int QuestCompletedBitsSize; public static int QuestCompletedBitsPerBlock; + + static int changeMaskLength = 1618; public UpdateField BackpackAutoSortDisabled = new(0, 1); public UpdateField BankAutoSortDisabled = new(0, 2); public UpdateField SortBagsRightToLeft = new(0, 3); public UpdateField InsertItemsLeftToRight = new(0, 4); public UpdateField HasPerksProgramPendingReward = new(0, 5); - public UpdateFieldArray> Research = new(1, 35, 36); + public UpdateFieldArray> ResearchSites = new(1, 35, 36); + public UpdateFieldArray> ResearchSiteProgress = new(1, 37, 38); + public UpdateFieldArray> Research = new(1, 39, 40); public DynamicUpdateField KnownTitles = new(0, 6); - public DynamicUpdateField ResearchSites = new(0, 8); - public DynamicUpdateField ResearchSiteProgress = new(0, 9); - public DynamicUpdateField DailyQuestsCompleted = new(0, 10); - public DynamicUpdateField AvailableQuestLineXQuestIDs = new(0, 11); - public DynamicUpdateField Heirlooms = new(0, 12); - public DynamicUpdateField HeirloomFlags = new(0, 13); - public DynamicUpdateField Toys = new(0, 14); - public DynamicUpdateField ToyFlags = new(0, 15); - public DynamicUpdateField Transmog = new(0, 16); - public DynamicUpdateField ConditionalTransmog = new(0, 17); - public DynamicUpdateField SelfResSpells = new(0, 18); - public DynamicUpdateField RuneforgePowers = new(0, 19); - public DynamicUpdateField TransmogIllusions = new(0, 20); - public DynamicUpdateField SpellPctModByLabel = new(0, 22); - public DynamicUpdateField SpellFlatModByLabel = new(0, 23); - public DynamicUpdateField MawPowers = new(0, 24); - public DynamicUpdateField MultiFloorExploration = new(0, 25); - public DynamicUpdateField RecipeProgression = new(0, 26); - public DynamicUpdateField ReplayedQuests = new(0, 27); - public DynamicUpdateField DisabledSpells = new(0, 28); - public DynamicUpdateField PersonalCraftingOrderCounts = new(0, 31); - public DynamicUpdateField CategoryCooldownMods = new(32, 33); - public DynamicUpdateField WeeklySpellUses = new(32, 34); + public DynamicUpdateField DailyQuestsCompleted = new(0, 8); + public DynamicUpdateField AvailableQuestLineXQuestIDs = new(0, 9); + public DynamicUpdateField Heirlooms = new(0, 10); + public DynamicUpdateField HeirloomFlags = new(0, 11); + public DynamicUpdateField Toys = new(0, 12); + public DynamicUpdateField ToyFlags = new(0, 13); + public DynamicUpdateField Transmog = new(0, 14); + public DynamicUpdateField ConditionalTransmog = new(0, 15); + public DynamicUpdateField SelfResSpells = new(0, 16); + public DynamicUpdateField RuneforgePowers = new(0, 17); + public DynamicUpdateField TransmogIllusions = new(0, 18); + public DynamicUpdateField SpellPctModByLabel = new(0, 20); + public DynamicUpdateField SpellFlatModByLabel = new(0, 21); + public DynamicUpdateField MawPowers = new(0, 22); + public DynamicUpdateField MultiFloorExploration = new(0, 23); + public DynamicUpdateField RecipeProgression = new(0, 24); + public DynamicUpdateField ReplayedQuests = new(0, 25); + public DynamicUpdateField TaskQuests = new(0, 26); + public DynamicUpdateField DisabledSpells = new(0, 27); + public DynamicUpdateField PersonalCraftingOrderCounts = new(0, 30); + public DynamicUpdateField CategoryCooldownMods = new(0, 31); + public DynamicUpdateField WeeklySpellUses = new(32, 33); + public DynamicUpdateField TrackedCollectableSources = new(32, 34); public DynamicUpdateField PvpInfo = new(0, 7); - public DynamicUpdateField CharacterRestrictions = new(0, 21); - public DynamicUpdateField TraitConfigs = new(0, 29); - public DynamicUpdateField CraftingOrders = new(0, 30); - public UpdateField FarsightObject = new(32, 37); - public UpdateField SummonedBattlePetGUID = new(32, 38); - public UpdateField Coinage = new(32, 39); - public UpdateField XP = new(32, 40); - public UpdateField NextLevelXP = new(32, 41); - public UpdateField TrialXP = new(32, 42); - public UpdateField Skill = new(32, 43); - public UpdateField CharacterPoints = new(32, 44); - public UpdateField MaxTalentTiers = new(32, 45); - public UpdateField TrackCreatureMask = new(32, 46); - public UpdateField MainhandExpertise = new(32, 47); - public UpdateField OffhandExpertise = new(32, 48); - public UpdateField RangedExpertise = new(32, 49); - public UpdateField CombatRatingExpertise = new(32, 50); - public UpdateField BlockPercentage = new(32, 51); - public UpdateField DodgePercentage = new(32, 52); - public UpdateField DodgePercentageFromAttribute = new(32, 53); - public UpdateField ParryPercentage = new(32, 54); - public UpdateField ParryPercentageFromAttribute = new(32, 55); - public UpdateField CritPercentage = new(32, 56); - public UpdateField RangedCritPercentage = new(32, 57); - public UpdateField OffhandCritPercentage = new(32, 58); - public UpdateField SpellCritPercentage = new(32, 59); - public UpdateField ShieldBlock = new(32, 60); - public UpdateField ShieldBlockCritPercentage = new(32, 61); - public UpdateField Mastery = new(32, 62); - public UpdateField Speed = new(32, 63); - public UpdateField Avoidance = new(32, 64); - public UpdateField Sturdiness = new(32, 65); - public UpdateField Versatility = new(66, 67); - public UpdateField VersatilityBonus = new(66, 68); - public UpdateField PvpPowerDamage = new(66, 69); - public UpdateField PvpPowerHealing = new(66, 70); - public UpdateField ModHealingDonePos = new(66, 71); - public UpdateField ModHealingPercent = new(66, 72); - public UpdateField ModPeriodicHealingDonePercent = new(66, 73); - public UpdateField ModSpellPowerPercent = new(66, 74); - public UpdateField ModResiliencePercent = new(66, 75); - public UpdateField OverrideSpellPowerByAPPercent = new(66, 76); - public UpdateField OverrideAPBySpellPowerPercent = new(66, 77); - public UpdateField ModTargetResistance = new(66, 78); - public UpdateField ModTargetPhysicalResistance = new(66, 79); - public UpdateField LocalFlags = new(66, 80); - public UpdateField GrantableLevels = new(66, 81); - public UpdateField MultiActionBars = new(66, 82); - public UpdateField LifetimeMaxRank = new(66, 83); - public UpdateField NumRespecs = new(66, 84); - public UpdateField PvpMedals = new(66, 85); - public UpdateField TodayHonorableKills = new(66, 86); - public UpdateField YesterdayHonorableKills = new(66, 87); - public UpdateField LifetimeHonorableKills = new(66, 88); - public UpdateField WatchedFactionIndex = new(66, 89); - public UpdateField MaxLevel = new(66, 90); - public UpdateField ScalingPlayerLevelDelta = new(66, 91); - public UpdateField MaxCreatureScalingLevel = new(66, 92); - public UpdateField PetSpellPower = new(66, 93); - public UpdateField UiHitModifier = new(66, 94); - public UpdateField UiSpellHitModifier = new(66, 95); - public UpdateField HomeRealmTimeOffset = new(66, 96); - public UpdateField ModPetHaste = new(66, 97); - public UpdateField JailersTowerLevelMax = new(98, 99); - public UpdateField JailersTowerLevel = new(98, 100); - public UpdateField LocalRegenFlags = new(98, 101); - public UpdateField AuraVision = new(98, 102); - public UpdateField NumBackpackSlots = new(98, 103); - public UpdateField OverrideSpellsID = new(98, 104); - public UpdateField LootSpecID = new(98, 105); - public UpdateField OverrideZonePVPType = new(98, 106); - public UpdateField BnetAccount = new(98, 107); - public UpdateField GuildClubMemberID = new(98, 108); - public UpdateField Honor = new(98, 109); - public UpdateField HonorNextLevel = new(98, 110); - public UpdateField PerksProgramCurrency = new(98, 111); - public UpdateField NumBankSlots = new(98, 112); - public UpdateField FrozenPerksVendorItem = new(98, 113); - public UpdateField Field_1410 = new(98, 115); - public OptionalUpdateField QuestSession = new(98, 114); - public UpdateField UiChromieTimeExpansionID = new(98, 116); - public UpdateField TransportServerTime = new(98, 117); - public UpdateField WeeklyRewardsPeriodSinceOrigin = new(98, 118); // week count since Cfg_RegionsEntry::ChallengeOrigin - public UpdateField DEBUGSoulbindConduitRank = new(98, 119); - public UpdateField DungeonScore = new(98, 120); - public UpdateField ActiveCombatTraitConfigID = new(98, 121); - public UpdateField LootHistoryInstanceID = new(98, 122); - public UpdateFieldArray InvSlots = new(227, 123, 124); - public UpdateFieldArray ExploredZones = new(240, 351, 352); - public UpdateFieldArray RestInfo = new(2, 592, 593); - public UpdateFieldArray ModDamageDonePos = new(7, 595, 596); - public UpdateFieldArray ModDamageDoneNeg = new(7, 595, 603); - public UpdateFieldArray ModDamageDonePercent = new(7, 595, 610); - public UpdateFieldArray ModHealingDonePercent = new(7, 595, 617); - public UpdateFieldArray WeaponDmgMultipliers = new(3, 624, 625); - public UpdateFieldArray WeaponAtkSpeedMultipliers = new(3, 624, 628); - public UpdateFieldArray BuybackPrice = new(12, 631, 632); - public UpdateFieldArray BuybackTimestamp = new(12, 631, 644); - public UpdateFieldArray CombatRatings = new(32, 656, 657); - public UpdateFieldArray NoReagentCostMask = new(4, 689, 690); - public UpdateFieldArray ProfessionSkillLine = new(2, 694, 695); - public UpdateFieldArray BagSlotFlags = new(5, 697, 698); - public UpdateFieldArray BankBagSlotFlags = new(7, 703, 704); - public UpdateFieldArray QuestCompleted = new(875, 711, 712); - public UpdateFieldArray ItemUpgradeHighWatermark = new(17, 1587, 1588); + public DynamicUpdateField CharacterRestrictions = new(0, 19); + public DynamicUpdateField TraitConfigs = new(0, 28); + public DynamicUpdateField CraftingOrders = new(0, 29); + public UpdateField FarsightObject = new(32, 41); + public UpdateField SummonedBattlePetGUID = new(32, 42); + public UpdateField Coinage = new(32, 43); + public UpdateField XP = new(32, 44); + public UpdateField NextLevelXP = new(32, 45); + public UpdateField TrialXP = new(32, 46); + public UpdateField Skill = new(32, 47); + public UpdateField CharacterPoints = new(32, 48); + public UpdateField MaxTalentTiers = new(32, 49); + public UpdateField TrackCreatureMask = new(32, 50); + public UpdateField MainhandExpertise = new(32, 51); + public UpdateField OffhandExpertise = new(32, 52); + public UpdateField RangedExpertise = new(32, 53); + public UpdateField CombatRatingExpertise = new(32, 54); + public UpdateField BlockPercentage = new(32, 55); + public UpdateField DodgePercentage = new(32, 56); + public UpdateField DodgePercentageFromAttribute = new(32, 57); + public UpdateField ParryPercentage = new(32, 58); + public UpdateField ParryPercentageFromAttribute = new(32, 59); + public UpdateField CritPercentage = new(32, 60); + public UpdateField RangedCritPercentage = new(32, 61); + public UpdateField OffhandCritPercentage = new(32, 62); + public UpdateField SpellCritPercentage = new(32, 63); + public UpdateField ShieldBlock = new(32, 64); + public UpdateField ShieldBlockCritPercentage = new(32, 65); + public UpdateField Mastery = new(32, 66); + public UpdateField Speed = new(32, 67); + public UpdateField Avoidance = new(32, 68); + public UpdateField Sturdiness = new(32, 69); + public UpdateField Versatility = new(70, 71); + public UpdateField VersatilityBonus = new(70, 72); + public UpdateField PvpPowerDamage = new(70, 73); + public UpdateField PvpPowerHealing = new(70, 74); + public UpdateField ModHealingDonePos = new(70, 75); + public UpdateField ModHealingPercent = new(70, 76); + public UpdateField ModPeriodicHealingDonePercent = new(70, 77); + public UpdateField ModSpellPowerPercent = new(70, 78); + public UpdateField ModResiliencePercent = new(70, 79); + public UpdateField OverrideSpellPowerByAPPercent = new(70, 80); + public UpdateField OverrideAPBySpellPowerPercent = new(70, 81); + public UpdateField ModTargetResistance = new(70, 82); + public UpdateField ModTargetPhysicalResistance = new(70, 83); + public UpdateField LocalFlags = new(70, 84); + public UpdateField GrantableLevels = new(70, 85); + public UpdateField MultiActionBars = new(70, 86); + public UpdateField LifetimeMaxRank = new(70, 87); + public UpdateField NumRespecs = new(70, 88); + public UpdateField PvpMedals = new(70, 89); + public UpdateField TodayHonorableKills = new(70, 90); + public UpdateField YesterdayHonorableKills = new(70, 91); + public UpdateField LifetimeHonorableKills = new(70, 92); + public UpdateField WatchedFactionIndex = new(70, 93); + public UpdateField MaxLevel = new(70, 94); + public UpdateField ScalingPlayerLevelDelta = new(70, 95); + public UpdateField MaxCreatureScalingLevel = new(70, 96); + public UpdateField PetSpellPower = new(70, 97); + public UpdateField UiHitModifier = new(70, 98); + public UpdateField UiSpellHitModifier = new(70, 99); + public UpdateField HomeRealmTimeOffset = new(70, 100); + public UpdateField ModPetHaste = new(70, 101); + public UpdateField JailersTowerLevelMax = new(102, 103); + public UpdateField JailersTowerLevel = new(102, 104); + public UpdateField LocalRegenFlags = new(102, 105); + public UpdateField AuraVision = new(102, 106); + public UpdateField NumBackpackSlots = new(102, 107); + public UpdateField OverrideSpellsID = new(102, 108); + public UpdateField LootSpecID = new(102, 109); + public UpdateField OverrideZonePVPType = new(102, 110); + public UpdateField BnetAccount = new(102, 111); + public UpdateField GuildClubMemberID = new(102, 112); + public UpdateField Honor = new(102, 113); + public UpdateField HonorNextLevel = new(102, 114); + public UpdateField PerksProgramCurrency = new(102, 115); + public UpdateField NumBankSlots = new(102, 116); + public UpdateField ResearchHistory = new(102, 117); + public UpdateField FrozenPerksVendorItem = new(102, 118); + public UpdateField Field_1410 = new(102, 120); + public OptionalUpdateField QuestSession = new(102, 119); + public UpdateField UiChromieTimeExpansionID = new(102, 121); + public UpdateField TransportServerTime = new(102, 122); + public UpdateField WeeklyRewardsPeriodSinceOrigin = new(102, 123); // week count since Cfg_RegionsEntry::ChallengeOrigin + public UpdateField DEBUGSoulbindConduitRank = new(102, 124); + public UpdateField DungeonScore = new(102, 125); + public UpdateField ActiveCombatTraitConfigID = new(102, 126); + public UpdateField ItemUpgradeHighOnehandWeaponItemID = new(102, 127); + public UpdateField ItemUpgradeHighFingerItemID = new(102, 128); + public UpdateField ItemUpgradeHighFingerWatermark = new(102, 129); + public UpdateField ItemUpgradeHighTrinketItemID = new(102, 130); + public UpdateField ItemUpgradeHighTrinketWatermark = new(102, 131); + public UpdateField LootHistoryInstanceID = new(102, 132); + public OptionalUpdateField PetStable = new(102, 133); + public UpdateField RequiredMountCapabilityFlags = new(134, 135); + public UpdateFieldArray InvSlots = new(227, 136, 137); + public UpdateFieldArray ExploredZones = new(240, 364, 365); + public UpdateFieldArray RestInfo = new(2, 605, 606); + public UpdateFieldArray ModDamageDonePos = new(7, 608, 609); + public UpdateFieldArray ModDamageDoneNeg = new(7, 608, 616); + public UpdateFieldArray ModDamageDonePercent = new(7, 608, 623); + public UpdateFieldArray ModHealingDonePercent = new(7, 608, 630); + public UpdateFieldArray WeaponDmgMultipliers = new(3, 637, 638); + public UpdateFieldArray WeaponAtkSpeedMultipliers = new(3, 637, 641); + public UpdateFieldArray BuybackPrice = new(12, 644, 645); + public UpdateFieldArray BuybackTimestamp = new(12, 644, 657); + public UpdateFieldArray CombatRatings = new(32, 669, 670); + public UpdateFieldArray NoReagentCostMask = new(4, 702, 703); + public UpdateFieldArray ProfessionSkillLine = new(2, 707, 708); + public UpdateFieldArray BagSlotFlags = new(5, 710, 711); + public UpdateFieldArray BankBagSlotFlags = new(7, 716, 717); + public UpdateFieldArray QuestCompleted = new(875, 724, 725); + public UpdateFieldArray ItemUpgradeHighWatermark = new(17, 1600, 1601); - public ActivePlayerData() : base(0, TypeId.ActivePlayer, 1605) + public ActivePlayerData() : base(0, TypeId.ActivePlayer, changeMaskLength) { ExploredZonesSize = ExploredZones.GetSize(); ExploredZonesBits = sizeof(ulong) * 8; @@ -4399,7 +4691,7 @@ namespace Game.Entities data.WriteUInt32(XP); data.WriteUInt32(NextLevelXP); data.WriteInt32(TrialXP); - ((SkillInfo)Skill).WriteCreate(data, owner, receiver); + Skill.GetValue().WriteCreate(data, owner, receiver); data.WriteUInt32(CharacterPoints); data.WriteUInt32(MaxTalentTiers); data.WriteUInt32(TrackCreatureMask); @@ -4464,7 +4756,7 @@ namespace Game.Entities for (int i = 0; i < 12; ++i) { data.WriteUInt32(BuybackPrice[i]); - data.WriteUInt64(BuybackTimestamp[i]); + data.WriteInt64(BuybackTimestamp[i]); } data.WriteUInt16(TodayHonorableKills); data.WriteUInt16(YesterdayHonorableKills); @@ -4517,8 +4809,24 @@ namespace Game.Entities data.WriteUInt32(HonorNextLevel); data.WriteInt32(PerksProgramCurrency); data.WriteUInt8(NumBankSlots); - data.WriteInt32(ResearchSites.Size()); - data.WriteInt32(ResearchSiteProgress.Size()); + for (int i = 0; i < 1; ++i) + { + data.WriteInt32(ResearchSites[i].Size()); + data.WriteInt32(ResearchSiteProgress[i].Size()); + data.WriteInt32(Research[i].Size()); + for (int j = 0; j < ResearchSites[i].Size(); ++j) + { + data.WriteUInt16(ResearchSites[i][j]); + } + for (int j = 0; j < ResearchSiteProgress[i].Size(); ++j) + { + data.WriteUInt32(ResearchSiteProgress[i][j]); + } + for (int j = 0; j < Research[i].Size(); ++j) + { + Research[i][j].WriteCreate(data, owner, receiver); + } + } data.WriteInt32(DailyQuestsCompleted.Size()); data.WriteInt32(AvailableQuestLineXQuestIDs.Size()); data.WriteInt32(Heirlooms.Size()); @@ -4533,18 +4841,11 @@ namespace Game.Entities data.WriteInt32(CharacterRestrictions.Size()); data.WriteInt32(SpellPctModByLabel.Size()); data.WriteInt32(SpellFlatModByLabel.Size()); - for (int i = 0; i < 1; ++i) - { - data.WriteInt32(Research[i].Size()); - for (int j = 0; j < Research[i].Size(); ++j) - { - Research[i][j].WriteCreate(data, owner, receiver); - } - } data.WriteInt32(MawPowers.Size()); data.WriteInt32(MultiFloorExploration.Size()); data.WriteInt32(RecipeProgression.Size()); data.WriteInt32(ReplayedQuests.Size()); + data.WriteInt32(TaskQuests.Size()); data.WriteInt32(DisabledSpells.Size()); data.WriteInt32(UiChromieTimeExpansionID); data.WriteInt32(TransportServerTime); @@ -4560,19 +4861,18 @@ namespace Game.Entities { data.WriteFloat(ItemUpgradeHighWatermark[i]); } + data.WriteInt32(ItemUpgradeHighOnehandWeaponItemID); + data.WriteInt32(ItemUpgradeHighFingerItemID); + data.WriteFloat(ItemUpgradeHighFingerWatermark); + data.WriteInt32(ItemUpgradeHighTrinketItemID); + data.WriteFloat(ItemUpgradeHighTrinketWatermark); data.WriteUInt64(LootHistoryInstanceID); + data.WriteInt32(TrackedCollectableSources.Size()); + data.WriteUInt8(RequiredMountCapabilityFlags); for (int i = 0; i < KnownTitles.Size(); ++i) { data.WriteUInt64(KnownTitles[i]); } - for (int i = 0; i < ResearchSites.Size(); ++i) - { - data.WriteUInt16(ResearchSites[i]); - } - for (int i = 0; i < ResearchSiteProgress.Size(); ++i) - { - data.WriteUInt32(ResearchSiteProgress[i]); - } for (int i = 0; i < DailyQuestsCompleted.Size(); ++i) { data.WriteUInt32(DailyQuestsCompleted[i]); @@ -4641,6 +4941,10 @@ namespace Game.Entities { ReplayedQuests[i].WriteCreate(data, owner, receiver); } + for (int i = 0; i < TaskQuests.Size(); ++i) + { + TaskQuests[i].WriteCreate(data, owner, receiver); + } for (int i = 0; i < DisabledSpells.Size(); ++i) { data.WriteInt32(DisabledSpells[i]); @@ -4657,6 +4961,10 @@ namespace Game.Entities { WeeklySpellUses[i].WriteCreate(data, owner, receiver); } + for (int i = 0; i < TrackedCollectableSources.Size(); ++i) + { + data.WriteInt64(TrackedCollectableSources[i]); + } data.FlushBits(); data.WriteBit(BackpackAutoSortDisabled); data.WriteBit(BankAutoSortDisabled); @@ -4664,11 +4972,14 @@ namespace Game.Entities data.WriteBit(InsertItemsLeftToRight); data.WriteBit(HasPerksProgramPendingReward); data.WriteBits(QuestSession.HasValue(), 1); - FrozenPerksVendorItem.GetValue().Write(data); + data.WriteBits(PetStable.HasValue(), 1); + data.FlushBits(); + ResearchHistory.GetValue().WriteCreate(data, owner, receiver); if (QuestSession.HasValue()) { QuestSession.GetValue().WriteCreate(data, owner, receiver); } + FrozenPerksVendorItem.GetValue().Write(data); ((ActivePlayerUnk901)Field_1410).WriteCreate(data, owner, receiver); DungeonScore._value.Write(data); for (int i = 0; i < PvpInfo.Size(); ++i) @@ -4687,6 +4998,10 @@ namespace Game.Entities { CraftingOrders[i].WriteCreate(data, owner, receiver); } + if (PetStable.HasValue()) + { + PetStable.GetValue().WriteCreate(data, owner, receiver); + } data.FlushBits(); } @@ -4740,129 +5055,84 @@ namespace Game.Entities else WriteCompleteDynamicFieldUpdateMask(PvpInfo.Size(), data); } - if (changesMask[8]) - { - if (!ignoreNestedChangesMask) - ResearchSites.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSites.Size(), data); - } - if (changesMask[9]) - { - if (!ignoreNestedChangesMask) - ResearchSiteProgress.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress.Size(), data); - } - if (changesMask[10]) - { - if (!ignoreNestedChangesMask) - DailyQuestsCompleted.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.Size(), data); - } - if (changesMask[11]) - { - if (!ignoreNestedChangesMask) - AvailableQuestLineXQuestIDs.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.Size(), data); - } - if (changesMask[12]) - { - if (!ignoreNestedChangesMask) - Heirlooms.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Heirlooms.Size(), data); - } - if (changesMask[13]) - { - if (!ignoreNestedChangesMask) - HeirloomFlags.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.Size(), data); - } - if (changesMask[14]) - { - if (!ignoreNestedChangesMask) - Toys.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Toys.Size(), data); - } - if (changesMask[15]) - { - if (!ignoreNestedChangesMask) - ToyFlags.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ToyFlags.Size(), data); - } - if (changesMask[16]) - { - if (!ignoreNestedChangesMask) - Transmog.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(Transmog.Size(), data); - } - if (changesMask[17]) - { - if (!ignoreNestedChangesMask) - ConditionalTransmog.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.Size(), data); - } - if (changesMask[18]) - { - if (!ignoreNestedChangesMask) - SelfResSpells.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SelfResSpells.Size(), data); - } - if (changesMask[19]) - { - if (!ignoreNestedChangesMask) - RuneforgePowers.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.Size(), data); - } - if (changesMask[20]) - { - if (!ignoreNestedChangesMask) - TransmogIllusions.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.Size(), data); - } - if (changesMask[21]) - { - if (!ignoreNestedChangesMask) - CharacterRestrictions.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.Size(), data); - } - if (changesMask[22]) - { - if (!ignoreNestedChangesMask) - SpellPctModByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.Size(), data); - } - if (changesMask[23]) - { - if (!ignoreNestedChangesMask) - SpellFlatModByLabel.WriteUpdateMask(data); - else - WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.Size(), data); - } } if (changesMask[35]) { for (int i = 0; i < 1; ++i) { if (changesMask[36 + i]) + { + if (!ignoreNestedChangesMask) + ResearchSites[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSites[i].Size(), data); + } + } + } + if (changesMask[37]) + { + for (int i = 0; i < 1; ++i) + { + if (changesMask[38 + i]) + { + if (!ignoreNestedChangesMask) + ResearchSiteProgress[i].WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress[i].Size(), data); + } + } + } + if (changesMask[39]) + { + for (int 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 (int i = 0; i < 1; ++i) + { + if (changesMask[36 + i]) + { + for (int j = 0; j < ResearchSites[i].Size(); ++j) + { + if (ResearchSites[i].HasChanged(j) || ignoreNestedChangesMask) + { + data.WriteUInt16(ResearchSites[i][j]); + } + } + } + } + } + if (changesMask[37]) + { + for (int i = 0; i < 1; ++i) + { + if (changesMask[38 + i]) + { + for (int j = 0; j < ResearchSiteProgress[i].Size(); ++j) + { + if (ResearchSiteProgress[i].HasChanged(j) || ignoreNestedChangesMask) + { + data.WriteUInt32(ResearchSiteProgress[i][j]); + } + } + } + } + } + if (changesMask[39]) + { + for (int i = 0; i < 1; ++i) + { + if (changesMask[40 + i]) + { for (int j = 0; j < Research[i].Size(); ++j) { if (Research[i].HasChanged(j) || ignoreNestedChangesMask) @@ -4876,78 +5146,190 @@ namespace Game.Entities data.FlushBits(); if (changesMask[0]) { - if (changesMask[24]) + if (changesMask[8]) + { + if (!ignoreNestedChangesMask) + DailyQuestsCompleted.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.Size(), data); + } + if (changesMask[9]) + { + if (!ignoreNestedChangesMask) + AvailableQuestLineXQuestIDs.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.Size(), data); + } + if (changesMask[10]) + { + if (!ignoreNestedChangesMask) + Heirlooms.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Heirlooms.Size(), data); + } + if (changesMask[11]) + { + if (!ignoreNestedChangesMask) + HeirloomFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.Size(), data); + } + if (changesMask[12]) + { + if (!ignoreNestedChangesMask) + Toys.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Toys.Size(), data); + } + if (changesMask[13]) + { + if (!ignoreNestedChangesMask) + ToyFlags.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ToyFlags.Size(), data); + } + if (changesMask[14]) + { + if (!ignoreNestedChangesMask) + Transmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Transmog.Size(), data); + } + if (changesMask[15]) + { + if (!ignoreNestedChangesMask) + ConditionalTransmog.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.Size(), data); + } + if (changesMask[16]) + { + if (!ignoreNestedChangesMask) + SelfResSpells.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SelfResSpells.Size(), data); + } + if (changesMask[17]) + { + if (!ignoreNestedChangesMask) + RuneforgePowers.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.Size(), data); + } + if (changesMask[18]) + { + if (!ignoreNestedChangesMask) + TransmogIllusions.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.Size(), data); + } + if (changesMask[19]) + { + if (!ignoreNestedChangesMask) + CharacterRestrictions.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.Size(), data); + } + if (changesMask[20]) + { + if (!ignoreNestedChangesMask) + SpellPctModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.Size(), data); + } + if (changesMask[21]) + { + if (!ignoreNestedChangesMask) + SpellFlatModByLabel.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.Size(), data); + } + 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(); @@ -4964,26 +5346,6 @@ namespace Game.Entities } } if (changesMask[8]) - { - for (int i = 0; i < ResearchSites.Size(); ++i) - { - if (ResearchSites.HasChanged(i) || ignoreNestedChangesMask) - { - data.WriteUInt16(ResearchSites[i]); - } - } - } - if (changesMask[9]) - { - for (int i = 0; i < ResearchSiteProgress.Size(); ++i) - { - if (ResearchSiteProgress.HasChanged(i) || ignoreNestedChangesMask) - { - data.WriteUInt32(ResearchSiteProgress[i]); - } - } - } - if (changesMask[10]) { for (int i = 0; i < DailyQuestsCompleted.Size(); ++i) { @@ -4993,7 +5355,7 @@ namespace Game.Entities } } } - if (changesMask[11]) + if (changesMask[9]) { for (int i = 0; i < AvailableQuestLineXQuestIDs.Size(); ++i) { @@ -5003,7 +5365,7 @@ namespace Game.Entities } } } - if (changesMask[12]) + if (changesMask[10]) { for (int i = 0; i < Heirlooms.Size(); ++i) { @@ -5013,7 +5375,7 @@ namespace Game.Entities } } } - if (changesMask[13]) + if (changesMask[11]) { for (int i = 0; i < HeirloomFlags.Size(); ++i) { @@ -5023,7 +5385,7 @@ namespace Game.Entities } } } - if (changesMask[14]) + if (changesMask[12]) { for (int i = 0; i < Toys.Size(); ++i) { @@ -5033,7 +5395,7 @@ namespace Game.Entities } } } - if (changesMask[15]) + if (changesMask[13]) { for (int i = 0; i < ToyFlags.Size(); ++i) { @@ -5043,7 +5405,7 @@ namespace Game.Entities } } } - if (changesMask[16]) + if (changesMask[14]) { for (int i = 0; i < Transmog.Size(); ++i) { @@ -5053,7 +5415,7 @@ namespace Game.Entities } } } - if (changesMask[17]) + if (changesMask[15]) { for (int i = 0; i < ConditionalTransmog.Size(); ++i) { @@ -5063,7 +5425,7 @@ namespace Game.Entities } } } - if (changesMask[18]) + if (changesMask[16]) { for (int i = 0; i < SelfResSpells.Size(); ++i) { @@ -5073,7 +5435,7 @@ namespace Game.Entities } } } - if (changesMask[19]) + if (changesMask[17]) { for (int i = 0; i < RuneforgePowers.Size(); ++i) { @@ -5083,7 +5445,7 @@ namespace Game.Entities } } } - if (changesMask[20]) + if (changesMask[18]) { for (int i = 0; i < TransmogIllusions.Size(); ++i) { @@ -5093,7 +5455,7 @@ namespace Game.Entities } } } - if (changesMask[22]) + if (changesMask[20]) { for (int i = 0; i < SpellPctModByLabel.Size(); ++i) { @@ -5103,7 +5465,7 @@ namespace Game.Entities } } } - if (changesMask[23]) + if (changesMask[21]) { for (int i = 0; i < SpellFlatModByLabel.Size(); ++i) { @@ -5113,7 +5475,7 @@ namespace Game.Entities } } } - if (changesMask[24]) + if (changesMask[22]) { for (int i = 0; i < MawPowers.Size(); ++i) { @@ -5123,7 +5485,7 @@ namespace Game.Entities } } } - if (changesMask[25]) + if (changesMask[23]) { for (int i = 0; i < MultiFloorExploration.Size(); ++i) { @@ -5133,7 +5495,7 @@ namespace Game.Entities } } } - if (changesMask[26]) + if (changesMask[24]) { for (int i = 0; i < RecipeProgression.Size(); ++i) { @@ -5143,7 +5505,7 @@ namespace Game.Entities } } } - if (changesMask[27]) + if (changesMask[25]) { for (int i = 0; i < ReplayedQuests.Size(); ++i) { @@ -5153,7 +5515,17 @@ namespace Game.Entities } } } - if (changesMask[28]) + if (changesMask[26]) + { + for (int i = 0; i < TaskQuests.Size(); ++i) + { + if (TaskQuests.HasChanged(i) || ignoreNestedChangesMask) + { + TaskQuests[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[27]) { for (int i = 0; i < DisabledSpells.Size(); ++i) { @@ -5163,7 +5535,7 @@ namespace Game.Entities } } } - if (changesMask[31]) + if (changesMask[30]) { for (int i = 0; i < PersonalCraftingOrderCounts.Size(); ++i) { @@ -5173,10 +5545,7 @@ namespace Game.Entities } } } - } - if (changesMask[32]) - { - if (changesMask[33]) + if (changesMask[31]) { for (int i = 0; i < CategoryCooldownMods.Size(); ++i) { @@ -5186,7 +5555,10 @@ namespace Game.Entities } } } - if (changesMask[34]) + } + if (changesMask[32]) + { + if (changesMask[33]) { for (int i = 0; i < WeeklySpellUses.Size(); ++i) { @@ -5196,6 +5568,16 @@ namespace Game.Entities } } } + if (changesMask[34]) + { + for (int i = 0; i < TrackedCollectableSources.Size(); ++i) + { + if (TrackedCollectableSources.HasChanged(i) || ignoreNestedChangesMask) + { + data.WriteInt64(TrackedCollectableSources[i]); + } + } + } } if (changesMask[0]) { @@ -5209,7 +5591,7 @@ namespace Game.Entities } } } - if (changesMask[21]) + if (changesMask[19]) { for (int i = 0; i < CharacterRestrictions.Size(); ++i) { @@ -5219,7 +5601,7 @@ namespace Game.Entities } } } - if (changesMask[29]) + if (changesMask[28]) { for (int i = 0; i < TraitConfigs.Size(); ++i) { @@ -5229,7 +5611,7 @@ namespace Game.Entities } } } - if (changesMask[30]) + if (changesMask[29]) { for (int i = 0; i < CraftingOrders.Size(); ++i) { @@ -5242,501 +5624,541 @@ namespace Game.Entities } if (changesMask[32]) { - if (changesMask[37]) + if (changesMask[41]) { data.WritePackedGuid(FarsightObject); } - if (changesMask[38]) + if (changesMask[42]) { data.WritePackedGuid(SummonedBattlePetGUID); } - if (changesMask[39]) + if (changesMask[43]) { data.WriteUInt64(Coinage); } - if (changesMask[40]) + if (changesMask[44]) { data.WriteUInt32(XP); } - if (changesMask[41]) + if (changesMask[45]) { data.WriteUInt32(NextLevelXP); } - if (changesMask[42]) + if (changesMask[46]) { data.WriteInt32(TrialXP); } - if (changesMask[43]) - { - ((SkillInfo)Skill).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); - } - if (changesMask[44]) - { - data.WriteUInt32(CharacterPoints); - } - if (changesMask[45]) - { - data.WriteUInt32(MaxTalentTiers); - } - if (changesMask[46]) - { - data.WriteUInt32(TrackCreatureMask); - } if (changesMask[47]) { - data.WriteFloat(MainhandExpertise); + Skill.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[48]) { - data.WriteFloat(OffhandExpertise); + data.WriteUInt32(CharacterPoints); } if (changesMask[49]) { - data.WriteFloat(RangedExpertise); + data.WriteUInt32(MaxTalentTiers); } if (changesMask[50]) { - data.WriteFloat(CombatRatingExpertise); + data.WriteUInt32(TrackCreatureMask); } if (changesMask[51]) { - data.WriteFloat(BlockPercentage); + data.WriteFloat(MainhandExpertise); } if (changesMask[52]) { - data.WriteFloat(DodgePercentage); + data.WriteFloat(OffhandExpertise); } if (changesMask[53]) { - data.WriteFloat(DodgePercentageFromAttribute); + data.WriteFloat(RangedExpertise); } if (changesMask[54]) { - data.WriteFloat(ParryPercentage); + data.WriteFloat(CombatRatingExpertise); } if (changesMask[55]) { - data.WriteFloat(ParryPercentageFromAttribute); + data.WriteFloat(BlockPercentage); } if (changesMask[56]) { - data.WriteFloat(CritPercentage); + data.WriteFloat(DodgePercentage); } if (changesMask[57]) { - data.WriteFloat(RangedCritPercentage); + data.WriteFloat(DodgePercentageFromAttribute); } if (changesMask[58]) { - data.WriteFloat(OffhandCritPercentage); + data.WriteFloat(ParryPercentage); } if (changesMask[59]) { - data.WriteFloat(SpellCritPercentage); + data.WriteFloat(ParryPercentageFromAttribute); } if (changesMask[60]) { - data.WriteUInt32(ShieldBlock); + data.WriteFloat(CritPercentage); } if (changesMask[61]) { - data.WriteFloat(ShieldBlockCritPercentage); + data.WriteFloat(RangedCritPercentage); } if (changesMask[62]) { - data.WriteFloat(Mastery); + data.WriteFloat(OffhandCritPercentage); } if (changesMask[63]) { - data.WriteFloat(Speed); + data.WriteFloat(SpellCritPercentage); } if (changesMask[64]) { - data.WriteFloat(Avoidance); + data.WriteUInt32(ShieldBlock); } if (changesMask[65]) + { + data.WriteFloat(ShieldBlockCritPercentage); + } + if (changesMask[66]) + { + data.WriteFloat(Mastery); + } + if (changesMask[67]) + { + data.WriteFloat(Speed); + } + if (changesMask[68]) + { + data.WriteFloat(Avoidance); + } + if (changesMask[69]) { data.WriteFloat(Sturdiness); } } - if (changesMask[66]) + if (changesMask[70]) { - if (changesMask[67]) + if (changesMask[71]) { data.WriteInt32(Versatility); } - if (changesMask[68]) + if (changesMask[72]) { data.WriteFloat(VersatilityBonus); } - if (changesMask[69]) + if (changesMask[73]) { data.WriteFloat(PvpPowerDamage); } - if (changesMask[70]) + if (changesMask[74]) { data.WriteFloat(PvpPowerHealing); } - if (changesMask[71]) + if (changesMask[75]) { data.WriteInt32(ModHealingDonePos); } - if (changesMask[72]) + if (changesMask[76]) { data.WriteFloat(ModHealingPercent); } - if (changesMask[73]) + if (changesMask[77]) { data.WriteFloat(ModPeriodicHealingDonePercent); } - if (changesMask[74]) + if (changesMask[78]) { data.WriteFloat(ModSpellPowerPercent); } - if (changesMask[75]) + if (changesMask[79]) { data.WriteFloat(ModResiliencePercent); } - if (changesMask[76]) + if (changesMask[80]) { data.WriteFloat(OverrideSpellPowerByAPPercent); } - if (changesMask[77]) + if (changesMask[81]) { data.WriteFloat(OverrideAPBySpellPowerPercent); } - if (changesMask[78]) + if (changesMask[82]) { data.WriteInt32(ModTargetResistance); } - if (changesMask[79]) + if (changesMask[83]) { data.WriteInt32(ModTargetPhysicalResistance); } - if (changesMask[80]) + if (changesMask[84]) { data.WriteUInt32(LocalFlags); } - if (changesMask[81]) + if (changesMask[85]) { data.WriteUInt8(GrantableLevels); } - if (changesMask[82]) + if (changesMask[86]) { data.WriteUInt8(MultiActionBars); } - if (changesMask[83]) + if (changesMask[87]) { data.WriteUInt8(LifetimeMaxRank); } - if (changesMask[84]) + if (changesMask[88]) { data.WriteUInt8(NumRespecs); } - if (changesMask[85]) + if (changesMask[89]) { data.WriteUInt32(PvpMedals); } - if (changesMask[86]) + if (changesMask[90]) { data.WriteUInt16(TodayHonorableKills); } - if (changesMask[87]) + if (changesMask[91]) { data.WriteUInt16(YesterdayHonorableKills); } - if (changesMask[88]) + if (changesMask[92]) { data.WriteUInt32(LifetimeHonorableKills); } - if (changesMask[89]) + if (changesMask[93]) { data.WriteUInt32(WatchedFactionIndex); } - if (changesMask[90]) + if (changesMask[94]) { data.WriteInt32(MaxLevel); } - if (changesMask[91]) + if (changesMask[95]) { data.WriteInt32(ScalingPlayerLevelDelta); } - if (changesMask[92]) + if (changesMask[96]) { data.WriteInt32(MaxCreatureScalingLevel); } - if (changesMask[93]) + if (changesMask[97]) { data.WriteUInt32(PetSpellPower); } - if (changesMask[94]) + if (changesMask[98]) { data.WriteFloat(UiHitModifier); } - if (changesMask[95]) + if (changesMask[99]) { data.WriteFloat(UiSpellHitModifier); } - if (changesMask[96]) + if (changesMask[100]) { data.WriteInt32(HomeRealmTimeOffset); } - if (changesMask[97]) + if (changesMask[101]) { data.WriteFloat(ModPetHaste); } } - if (changesMask[98]) + if (changesMask[102]) { - if (changesMask[99]) + if (changesMask[103]) { data.WriteInt8(JailersTowerLevelMax); } - if (changesMask[100]) + if (changesMask[104]) { data.WriteInt8(JailersTowerLevel); } - if (changesMask[101]) + if (changesMask[105]) { data.WriteUInt8(LocalRegenFlags); } - if (changesMask[102]) + if (changesMask[106]) { data.WriteUInt8(AuraVision); } - if (changesMask[103]) + if (changesMask[107]) { data.WriteUInt8(NumBackpackSlots); } - if (changesMask[104]) + if (changesMask[108]) { data.WriteUInt32(OverrideSpellsID); } - if (changesMask[105]) + if (changesMask[109]) { data.WriteUInt16(LootSpecID); } - if (changesMask[106]) + if (changesMask[110]) { data.WriteUInt32(OverrideZonePVPType); } - if (changesMask[107]) + if (changesMask[111]) { data.WritePackedGuid(BnetAccount); } - if (changesMask[108]) + if (changesMask[112]) { data.WriteUInt64(GuildClubMemberID); } - if (changesMask[109]) + if (changesMask[113]) { data.WriteUInt32(Honor); } - if (changesMask[110]) + if (changesMask[114]) { data.WriteUInt32(HonorNextLevel); } - if (changesMask[111]) + if (changesMask[115]) { data.WriteInt32(PerksProgramCurrency); } - if (changesMask[112]) - { - data.WriteInt32(NumBankSlots); - } if (changesMask[116]) { - data.WriteInt32(UiChromieTimeExpansionID); - } - if (changesMask[117]) - { - data.WriteInt32(TransportServerTime); - } - if (changesMask[118]) - { - data.WriteUInt32(WeeklyRewardsPeriodSinceOrigin); - } - if (changesMask[119]) - { - data.WriteInt16(DEBUGSoulbindConduitRank); + data.WriteUInt8(NumBankSlots); } if (changesMask[121]) { - data.WriteUInt32(ActiveCombatTraitConfigID); + data.WriteInt32(UiChromieTimeExpansionID); } if (changesMask[122]) + { + data.WriteInt32(TransportServerTime); + } + if (changesMask[123]) + { + data.WriteUInt32(WeeklyRewardsPeriodSinceOrigin); + } + if (changesMask[124]) + { + data.WriteInt16(DEBUGSoulbindConduitRank); + } + if (changesMask[126]) + { + data.WriteUInt32(ActiveCombatTraitConfigID); + } + if (changesMask[127]) + { + data.WriteInt32(ItemUpgradeHighOnehandWeaponItemID); + } + if (changesMask[128]) + { + data.WriteInt32(ItemUpgradeHighFingerItemID); + } + if (changesMask[129]) + { + data.WriteFloat(ItemUpgradeHighFingerWatermark); + } + if (changesMask[130]) + { + data.WriteInt32(ItemUpgradeHighTrinketItemID); + } + if (changesMask[131]) + { + data.WriteFloat(ItemUpgradeHighTrinketWatermark); + } + if (changesMask[132]) { data.WriteUInt64(LootHistoryInstanceID); } } - if (changesMask[98]) + if (changesMask[134]) + { + if (changesMask[135]) + { + data.WriteUInt8(RequiredMountCapabilityFlags); + } + } + if (changesMask[102]) { data.WriteBits(QuestSession.HasValue(), 1); - if (changesMask[113]) + data.WriteBits(PetStable.HasValue(), 1); + data.FlushBits(); + if (changesMask[117]) { - FrozenPerksVendorItem.GetValue().Write(data); + ResearchHistory.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[114]) + if (changesMask[119]) { if (QuestSession.HasValue()) { QuestSession.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[115]) + if (changesMask[118]) { - ((ActivePlayerUnk901)Field_1410).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + FrozenPerksVendorItem.GetValue().Write(data); } if (changesMask[120]) + { + Field_1410.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[125]) { DungeonScore.GetValue().Write(data); } + if (changesMask[133]) + { + if (PetStable.HasValue()) + { + PetStable.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } - if (changesMask[123]) + if (changesMask[136]) { for (int i = 0; i < 227; ++i) { - if (changesMask[124 + i]) + if (changesMask[137 + i]) { data.WritePackedGuid(InvSlots[i]); } } } - if (changesMask[351]) + if (changesMask[364]) { for (int i = 0; i < 240; ++i) { - if (changesMask[352 + i]) + if (changesMask[365 + i]) { data.WriteUInt64(ExploredZones[i]); } } } - if (changesMask[592]) + if (changesMask[605]) { for (int 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 (int i = 0; i < 7; ++i) { - if (changesMask[596 + i]) + if (changesMask[609 + i]) { data.WriteInt32(ModDamageDonePos[i]); } - if (changesMask[603 + i]) + if (changesMask[616 + i]) { data.WriteInt32(ModDamageDoneNeg[i]); } - if (changesMask[610 + i]) + if (changesMask[623 + i]) { data.WriteFloat(ModDamageDonePercent[i]); } - if (changesMask[617 + i]) + if (changesMask[630 + i]) { data.WriteFloat(ModHealingDonePercent[i]); } } } - if (changesMask[624]) + if (changesMask[637]) { for (int i = 0; i < 3; ++i) { - if (changesMask[625 + i]) + if (changesMask[638 + i]) { data.WriteFloat(WeaponDmgMultipliers[i]); } - if (changesMask[628 + i]) + if (changesMask[641 + i]) { data.WriteFloat(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[631]) + if (changesMask[644]) { for (int i = 0; i < 12; ++i) { - if (changesMask[632 + i]) + if (changesMask[645 + i]) { data.WriteUInt32(BuybackPrice[i]); } - if (changesMask[644 + i]) + if (changesMask[657 + i]) { - data.WriteUInt64(BuybackTimestamp[i]); + data.WriteInt64(BuybackTimestamp[i]); } } } - if (changesMask[656]) + if (changesMask[669]) { for (int i = 0; i < 32; ++i) { - if (changesMask[657 + i]) + if (changesMask[670 + i]) { data.WriteUInt32(CombatRatings[i]); } } } - if (changesMask[689]) + if (changesMask[702]) { for (int i = 0; i < 4; ++i) { - if (changesMask[690 + i]) + if (changesMask[703 + i]) { data.WriteUInt32(NoReagentCostMask[i]); } } } - if (changesMask[694]) + if (changesMask[707]) { for (int i = 0; i < 2; ++i) { - if (changesMask[695 + i]) + if (changesMask[708 + i]) { data.WriteUInt32(ProfessionSkillLine[i]); } } } - if (changesMask[697]) + if (changesMask[710]) { for (int i = 0; i < 5; ++i) { - if (changesMask[698 + i]) + if (changesMask[711 + i]) { data.WriteUInt32(BagSlotFlags[i]); } } } - if (changesMask[703]) + if (changesMask[716]) { for (int i = 0; i < 7; ++i) { - if (changesMask[704 + i]) + if (changesMask[717 + i]) { data.WriteUInt32(BankBagSlotFlags[i]); } } } - if (changesMask[711]) + if (changesMask[724]) { for (int i = 0; i < 875; ++i) { - if (changesMask[712 + i]) + if (changesMask[725 + i]) { data.WriteUInt64(QuestCompleted[i]); } } } - if (changesMask[1587]) + if (changesMask[1600]) { for (int i = 0; i < 17; ++i) { - if (changesMask[1588 + i]) + if (changesMask[1601 + i]) { data.WriteFloat(ItemUpgradeHighWatermark[i]); } @@ -5752,10 +6174,10 @@ namespace Game.Entities ClearChangesMask(SortBagsRightToLeft); ClearChangesMask(InsertItemsLeftToRight); ClearChangesMask(HasPerksProgramPendingReward); - ClearChangesMask(Research); - ClearChangesMask(KnownTitles); ClearChangesMask(ResearchSites); ClearChangesMask(ResearchSiteProgress); + ClearChangesMask(Research); + ClearChangesMask(KnownTitles); ClearChangesMask(DailyQuestsCompleted); ClearChangesMask(AvailableQuestLineXQuestIDs); ClearChangesMask(Heirlooms); @@ -5773,10 +6195,12 @@ namespace Game.Entities ClearChangesMask(MultiFloorExploration); ClearChangesMask(RecipeProgression); ClearChangesMask(ReplayedQuests); + ClearChangesMask(TaskQuests); ClearChangesMask(DisabledSpells); ClearChangesMask(PersonalCraftingOrderCounts); ClearChangesMask(CategoryCooldownMods); ClearChangesMask(WeeklySpellUses); + ClearChangesMask(TrackedCollectableSources); ClearChangesMask(PvpInfo); ClearChangesMask(CharacterRestrictions); ClearChangesMask(TraitConfigs); @@ -5855,6 +6279,7 @@ namespace Game.Entities ClearChangesMask(HonorNextLevel); ClearChangesMask(PerksProgramCurrency); ClearChangesMask(NumBankSlots); + ClearChangesMask(ResearchHistory); ClearChangesMask(FrozenPerksVendorItem); ClearChangesMask(Field_1410); ClearChangesMask(QuestSession); @@ -5864,7 +6289,14 @@ namespace Game.Entities ClearChangesMask(DEBUGSoulbindConduitRank); ClearChangesMask(DungeonScore); ClearChangesMask(ActiveCombatTraitConfigID); + ClearChangesMask(ItemUpgradeHighOnehandWeaponItemID); + ClearChangesMask(ItemUpgradeHighFingerItemID); + ClearChangesMask(ItemUpgradeHighFingerWatermark); + ClearChangesMask(ItemUpgradeHighTrinketItemID); + ClearChangesMask(ItemUpgradeHighTrinketWatermark); ClearChangesMask(LootHistoryInstanceID); + ClearChangesMask(PetStable); + ClearChangesMask(RequiredMountCapabilityFlags); ClearChangesMask(InvSlots); ClearChangesMask(ExploredZones); ClearChangesMask(RestInfo); @@ -6517,33 +6949,34 @@ namespace Game.Entities public class AreaTriggerFieldData : BaseUpdateData { - public UpdateField Field_260 = new(0, 1); + public UpdateField HeightIgnoresScale = new(0, 1); public UpdateField Field_261 = new(0, 2); public UpdateField OverrideScaleCurve = new(0, 3); public UpdateField ExtraScaleCurve = new(0, 4); - public UpdateField Field_C38 = new(0, 5); - public UpdateField Field_C54 = new(0, 6); - public UpdateField Field_C70 = new(0, 7); + public UpdateField OverrideMoveCurveX = new(0, 5); + public UpdateField OverrideMoveCurveY = new(0, 6); + public UpdateField OverrideMoveCurveZ = new(0, 7); public UpdateField Caster = new(0, 8); public UpdateField Duration = new(0, 9); public UpdateField TimeToTarget = new(0, 10); public UpdateField TimeToTargetScale = new(0, 11); public UpdateField TimeToTargetExtraScale = new(0, 12); - public UpdateField Field_B0 = new(0, 13); + public UpdateField TimeToTargetPos = new(0, 13); // Linked to m_overrideMoveCurve public UpdateField SpellID = new(0, 14); public UpdateField SpellForVisuals = new(0, 15); public UpdateField SpellVisual = new(0, 16); public UpdateField BoundsRadius2D = new(0, 17); public UpdateField DecalPropertiesID = new(0, 18); public UpdateField CreatingEffectGUID = new(0, 19); - public UpdateField Field_80 = new(0, 20); - public UpdateField Field_84 = new(0, 21); - public UpdateField Field_88 = new(0, 22); - public UpdateField Field_F8 = new(0, 23); - public UpdateField VisualAnim = new(0, 24); + public UpdateField NumUnitsInside = new(0, 20); + public UpdateField NumPlayersInside = new(0, 21); // When not 0 this causes SpellVisualEvent 14 to trigger, playing alternate visuals, typically used by "SOAK THIS" areatriggers + public UpdateField OrbitPathTarget = new(0, 22); + public UpdateField RollPitchYaw = new(0, 23); + public UpdateField PositionalSoundKitID = new(0, 24); + public UpdateField VisualAnim = new(0, 25); - public AreaTriggerFieldData() : base(0, TypeId.AreaTrigger, 25) { } + public AreaTriggerFieldData() : base(0, TypeId.AreaTrigger, 26) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { @@ -6553,7 +6986,7 @@ namespace Game.Entities data.WriteUInt32(TimeToTarget); data.WriteUInt32(TimeToTargetScale); data.WriteUInt32(TimeToTargetExtraScale); - data.WriteUInt32(Field_B0); + data.WriteUInt32(TimeToTargetPos); data.WriteUInt32(SpellID); data.WriteUInt32(SpellForVisuals); @@ -6562,16 +6995,17 @@ namespace Game.Entities data.WriteFloat(BoundsRadius2D); data.WriteUInt32(DecalPropertiesID); data.WritePackedGuid(CreatingEffectGUID); - data.WriteUInt32(Field_80); - data.WriteUInt32(Field_84); - data.WritePackedGuid(Field_88); - data.WriteVector3(Field_F8); + data.WriteInt32(NumUnitsInside); + data.WriteInt32(NumPlayersInside); + data.WritePackedGuid(OrbitPathTarget); + data.WriteVector3(RollPitchYaw); ExtraScaleCurve.GetValue().WriteCreate(data, owner, receiver); - data.WriteBit(Field_260); + data.FlushBits(); + data.WriteBit(HeightIgnoresScale); data.WriteBit(Field_261); - Field_C38.GetValue().WriteCreate(data, owner, receiver); - Field_C54.GetValue().WriteCreate(data, owner, receiver); - Field_C70.GetValue().WriteCreate(data, owner, receiver); + OverrideMoveCurveX.GetValue().WriteCreate(data, owner, receiver); + OverrideMoveCurveY.GetValue().WriteCreate(data, owner, receiver); + OverrideMoveCurveZ.GetValue().WriteCreate(data, owner, receiver); VisualAnim.GetValue().WriteCreate(data, owner, receiver); data.FlushBits(); } @@ -6583,13 +7017,13 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateMask changesMask, bool ignoreNestedChangesMask, AreaTrigger owner, Player receiver) { - 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]) { @@ -6625,7 +7059,7 @@ namespace Game.Entities } if (_changesMask[13]) { - data.WriteUInt32(Field_B0); + data.WriteUInt32(TimeToTargetPos); } if (changesMask[14]) { @@ -6653,19 +7087,23 @@ namespace Game.Entities } if (changesMask[20]) { - data.WriteUInt32(Field_80); + data.WriteInt32(NumUnitsInside); } if (changesMask[21]) { - data.WriteUInt32(Field_84); + data.WriteInt32(NumPlayersInside); } if (changesMask[22]) { - data.WritePackedGuid(Field_88); + data.WritePackedGuid(OrbitPathTarget); } if (changesMask[23]) { - data.WriteVector3(Field_F8); + data.WriteVector3(RollPitchYaw); + } + if (changesMask[24]) + { + data.WriteInt32(PositionalSoundKitID); } if (_changesMask[4]) { @@ -6673,17 +7111,17 @@ namespace Game.Entities } if (changesMask[5]) { - Field_C38.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveX.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[6]) { - Field_C54.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveY.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[7]) { - Field_C70.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + OverrideMoveCurveZ.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[24]) + if (changesMask[25]) { VisualAnim.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } @@ -6693,29 +7131,30 @@ namespace Game.Entities public override void ClearChangesMask() { - ClearChangesMask(Field_260); + ClearChangesMask(HeightIgnoresScale); ClearChangesMask(Field_261); ClearChangesMask(OverrideScaleCurve); ClearChangesMask(ExtraScaleCurve); - ClearChangesMask(Field_C38); - ClearChangesMask(Field_C54); - ClearChangesMask(Field_C70); + ClearChangesMask(OverrideMoveCurveX); + ClearChangesMask(OverrideMoveCurveY); + ClearChangesMask(OverrideMoveCurveZ); ClearChangesMask(Caster); ClearChangesMask(Duration); ClearChangesMask(TimeToTarget); ClearChangesMask(TimeToTargetScale); ClearChangesMask(TimeToTargetExtraScale); - ClearChangesMask(Field_B0); + ClearChangesMask(TimeToTargetPos); ClearChangesMask(SpellID); ClearChangesMask(SpellForVisuals); ClearChangesMask(SpellVisual); ClearChangesMask(BoundsRadius2D); ClearChangesMask(DecalPropertiesID); ClearChangesMask(CreatingEffectGUID); - ClearChangesMask(Field_80); - ClearChangesMask(Field_84); - ClearChangesMask(Field_88); - ClearChangesMask(Field_F8); + ClearChangesMask(NumUnitsInside); + ClearChangesMask(NumPlayersInside); + ClearChangesMask(OrbitPathTarget); + ClearChangesMask(RollPitchYaw); + ClearChangesMask(PositionalSoundKitID); ClearChangesMask(VisualAnim); _changesMask.ResetAll(); } diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index 7665f876a..f85c71d27 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -756,7 +756,7 @@ namespace Game.Entities SetQuestSlot(slot, questId); SetQuestSlotEndTime(slot, endTime); - SetQuestSlotAcceptTime(slot, acceptTime); + questStatusData.AcceptTime = acceptTime; if (questStatusData.Status == QuestStatus.Complete) SetQuestSlotState(slot, QuestSlotStateMask.Complete); @@ -1624,42 +1624,49 @@ namespace Game.Entities // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // SELECT id, entry, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType, specialization FROM character_pet WHERE owner = ? - if (!result.IsEmpty()) - { - do - { - PetStable.PetInfo petInfo = new(); - petInfo.PetNumber = result.Read(0); - petInfo.CreatureId = result.Read(1); - petInfo.DisplayId = result.Read(2); - petInfo.Level = result.Read(3); - petInfo.Experience = result.Read(4); - petInfo.ReactState = (ReactStates)result.Read(5); - PetSaveMode slot = (PetSaveMode)result.Read(6); - petInfo.Name = result.Read(7); - petInfo.WasRenamed = result.Read(8); - petInfo.Health = result.Read(9); - petInfo.Mana = result.Read(10); - petInfo.ActionBar = result.Read(11); - petInfo.LastSaveTime = result.Read(12); - petInfo.CreatedBySpellId = result.Read(13); - petInfo.Type = (PetType)result.Read(14); - petInfo.SpecializationId = result.Read(15); - if (slot >= PetSaveMode.FirstActiveSlot && slot < PetSaveMode.LastActiveSlot) - m_petStable.ActivePets[(int)slot] = petInfo; - else if (slot >= PetSaveMode.FirstStableSlot && slot < PetSaveMode.LastStableSlot) - m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot] = petInfo; - else if (slot == PetSaveMode.NotInSlot) - m_petStable.UnslottedPets.Add(petInfo); - } while (result.NextRow()); - } + do + { + PetStable.PetInfo petInfo = new(); + petInfo.PetNumber = result.Read(0); + petInfo.CreatureId = result.Read(1); + petInfo.DisplayId = result.Read(2); + petInfo.Level = result.Read(3); + petInfo.Experience = result.Read(4); + petInfo.ReactState = (ReactStates)result.Read(5); + PetSaveMode slot = (PetSaveMode)result.Read(6); + petInfo.Name = result.Read(7); + petInfo.WasRenamed = result.Read(8); + petInfo.Health = result.Read(9); + petInfo.Mana = result.Read(10); + petInfo.ActionBar = result.Read(11); + petInfo.LastSaveTime = result.Read(12); + petInfo.CreatedBySpellId = result.Read(13); + petInfo.Type = (PetType)result.Read(14); + petInfo.SpecializationId = result.Read(15); + if (slot >= PetSaveMode.FirstActiveSlot && slot < PetSaveMode.LastActiveSlot) + { + m_petStable.ActivePets[(int)slot] = petInfo; + + if (m_petStable.ActivePets[(int)slot].Type == PetType.Hunter) + AddPetToUpdateFields(m_petStable.ActivePets[(int)slot], slot, PetStableFlags.Active); + } + else if (slot >= PetSaveMode.FirstStableSlot && slot < PetSaveMode.LastStableSlot) + { + m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot] = petInfo; + + if (m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot].Type == PetType.Hunter) + AddPetToUpdateFields(m_petStable.StabledPets[slot - PetSaveMode.FirstStableSlot], slot, PetStableFlags.Inactive); + } + else if (slot == PetSaveMode.NotInSlot) + m_petStable.UnslottedPets.Add(petInfo); + + } while (result.NextRow()); if (Pet.GetLoadPetInfo(m_petStable, 0, summonedPetNumber, null).Item1 != null) m_temporaryUnsummonedPetNumber = summonedPetNumber; } - void _SaveInventory(SQLTransaction trans) { PreparedStatement stmt; @@ -2121,8 +2128,8 @@ namespace Game.Entities stmt.AddValue(1, save.Key); stmt.AddValue(2, (byte)data.Status); stmt.AddValue(3, data.Explored); - stmt.AddValue(4, (long)GetQuestSlotAcceptTime(data.Slot)); - stmt.AddValue(5, (long)GetQuestSlotEndTime(data.Slot)); + stmt.AddValue(4, data.AcceptTime); + stmt.AddValue(5, GetQuestSlotEndTime(data.Slot)); trans.Append(stmt); // Save objectives diff --git a/Source/Game/Entities/Player/Player.Items.cs b/Source/Game/Entities/Player/Player.Items.cs index eb0e254a1..24f1a15a9 100644 --- a/Source/Game/Entities/Player/Player.Items.cs +++ b/Source/Game/Entities/Player/Player.Items.cs @@ -1447,7 +1447,7 @@ namespace Game.Entities if (proto.HasFlag(ItemFlags2.FactionAlliance) && GetTeam() != Team.Alliance) return InventoryResult.CantEquipEver; - if ((proto.GetAllowableClass() & GetClassMask()) == 0 || (proto.GetAllowableRace() & (long)SharedConst.GetMaskForRace(GetRace())) == 0) + if ((proto.GetAllowableClass() & GetClassMask()) == 0 || !proto.GetAllowableRace().HasRace(GetRace())) return InventoryResult.CantEquipEver; if (proto.GetRequiredSkill() != 0) @@ -2967,7 +2967,7 @@ namespace Game.Entities return InventoryResult.ItemNotFound; // Used by group, function GroupLoot, to know if a prototype can be used by a player - if ((proto.GetAllowableClass() & GetClassMask()) == 0 || (proto.GetAllowableRace() & (long)SharedConst.GetMaskForRace(GetRace())) == 0) + if ((proto.GetAllowableClass() & GetClassMask()) == 0 || !proto.GetAllowableRace().HasRace(GetRace())) return InventoryResult.CantEquipEver; if (proto.GetRequiredSpell() != 0 && !HasSpell(proto.GetRequiredSpell())) @@ -3002,7 +3002,7 @@ namespace Game.Entities // if current back slot non-empty search oldest or free if (m_items[slot] != null) { - ulong oldest_time = m_activePlayerData.BuybackTimestamp[0]; + long oldest_time = m_activePlayerData.BuybackTimestamp[0]; uint oldest_slot = InventorySlots.BuyBackStart; for (byte i = InventorySlots.BuyBackStart + 1; i < InventorySlots.BuyBackEnd; ++i) @@ -3014,7 +3014,7 @@ namespace Game.Entities break; } - ulong i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart]; + long i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart]; if (oldest_time > i_time) { oldest_time = i_time; @@ -3466,7 +3466,7 @@ namespace Game.Entities DB.Characters.CommitTransaction(trans); } public void SetBuybackPrice(uint slot, uint price) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackPrice, (int)slot), price); } - public void SetBuybackTimestamp(uint slot, ulong timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); } + public void SetBuybackTimestamp(uint slot, long timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); } public Item GetItemFromBuyBackSlot(uint slot) { diff --git a/Source/Game/Entities/Player/Player.Map.cs b/Source/Game/Entities/Player/Player.Map.cs index ab0fe8777..6182f5bcc 100644 --- a/Source/Game/Entities/Player/Player.Map.cs +++ b/Source/Game/Entities/Player/Player.Map.cs @@ -560,6 +560,19 @@ namespace Game.Entities return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0; } + + public bool IsLockedToDungeonEncounter(uint dungeonEncounterId, Difficulty difficulty) + { + var dungeonEncounter = CliDB.DungeonEncounterStorage.LookupByKey(dungeonEncounterId); + if (dungeonEncounter == null) + return false; + + InstanceLock instanceLock = Global.InstanceLockMgr.FindActiveInstanceLock(GetGUID(), new MapDb2Entries((uint)dungeonEncounter.MapID, difficulty)); + if (instanceLock == null) + return false; + + return (instanceLock.GetData().CompletedEncountersMask & (1u << dungeonEncounter.Bit)) != 0; + } public override void ProcessTerrainStatusUpdate(ZLiquidStatus oldLiquidStatus, LiquidData newLiquidData) { diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index d1e3e2889..a18671bf9 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -798,7 +798,7 @@ namespace Game.Entities AdjustQuestObjectiveProgress(quest); long endTime = 0; - uint limittime = quest.LimitTime; + uint limittime = (uint)quest.LimitTime; if (limittime != 0) { // shared timed quest @@ -833,7 +833,7 @@ namespace Game.Entities } SetQuestSlotEndTime(logSlot, endTime); - SetQuestSlotAcceptTime(logSlot, GameTime.GetGameTime()); + questStatusData.AcceptTime = GameTime.GetGameTime(); m_QuestStatusSave[questId] = QuestSaveType.Default; @@ -1591,17 +1591,12 @@ namespace Game.Entities public bool SatisfyQuestRace(Quest qInfo, bool msg) { - long reqraces = qInfo.AllowableRaces; - if (reqraces == -1) - return true; - - if ((reqraces & (long)SharedConst.GetMaskForRace(GetRace())) == 0) + if (!qInfo.AllowableRaces.HasRace(GetRace())) { if (msg) { SendCanTakeQuestResponse(QuestFailedReasons.FailedWrongRace); - Log.outDebug(LogFilter.Server, "SatisfyQuestRace: Sent QuestFailedReasons.FailedWrongRace (questId: {0}) because player does not have required race.", qInfo.Id); - + Log.outDebug(LogFilter.Server, $"SatisfyQuestRace: Sent QuestFailedReasons.FailedWrongRace (questId: {qInfo.Id}) because player '{GetName()}' ({GetGUID()}) does not have required race."); } return false; } @@ -2068,7 +2063,9 @@ namespace Game.Entities switch (GetQuestStatus(questId)) { case QuestStatus.Complete: - if (quest.GetQuestTag() == QuestTagType.CovenantCalling) + if (quest.IsImportant()) + result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.ImportantQuestRewardCompleteNoPOI : QuestGiverStatus.ImportantQuestRewardCompletePOI; + else if (quest.GetQuestTag() == QuestTagType.CovenantCalling) result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.CovenantCallingRewardCompleteNoPOI : QuestGiverStatus.CovenantCallingRewardCompletePOI; else if (quest.HasFlagEx(QuestFlagsEx.Legendary)) result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.LegendaryRewardCompleteNoPOI : QuestGiverStatus.LegendaryRewardCompletePOI; @@ -2076,8 +2073,12 @@ namespace Game.Entities result |= quest.HasFlag(QuestFlags.HideRewardPoi) ? QuestGiverStatus.RewardCompleteNoPOI : QuestGiverStatus.RewardCompletePOI; break; case QuestStatus.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(QuestFlagsEx.Legendary)) + result |= QuestGiverStatus.LegendaryReward; else result |= QuestGiverStatus.Reward; break; @@ -2109,22 +2110,20 @@ namespace Game.Entities { if (SatisfyQuestLevel(quest, false)) { - if (GetLevel() <= (GetQuestLevel(quest) + WorldConfig.GetIntValue(WorldCfg.QuestLowLevelHideDiff))) - { - if (quest.GetQuestTag() == QuestTagType.CovenantCalling) - result |= QuestGiverStatus.CovenantCallingQuest; - else if (quest.HasFlagEx(QuestFlagsEx.Legendary)) - result |= QuestGiverStatus.LegendaryQuest; - else if (quest.IsDaily()) - result |= QuestGiverStatus.DailyQuest; - else - result |= QuestGiverStatus.Quest; - } + bool isTrivial = GetLevel() <= (GetQuestLevel(quest) + WorldConfig.GetIntValue(WorldCfg.QuestLowLevelHideDiff)); + 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(QuestFlagsEx.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(QuestFlagsEx.Legendary)) + result |= QuestGiverStatus.FutureLegendaryQuest; else result |= QuestGiverStatus.Future; } @@ -2201,16 +2200,11 @@ namespace Game.Entities return 0; } - public uint GetQuestSlotEndTime(ushort slot) + public long GetQuestSlotEndTime(ushort slot) { return m_playerData.QuestLog[slot].EndTime; } - public uint GetQuestSlotAcceptTime(ushort slot) - { - return m_playerData.QuestLog[slot].AcceptTime; - } - bool GetQuestSlotObjectiveFlag(ushort slot, sbyte objectiveIndex) { if (objectiveIndex < SharedConst.MaxQuestCounts) @@ -2244,7 +2238,6 @@ namespace Game.Entities SetUpdateFieldValue(questLogField.ModifyValue(questLogField.QuestID), quest_id); SetUpdateFieldValue(questLogField.ModifyValue(questLogField.StateFlags), 0u); SetUpdateFieldValue(questLogField.ModifyValue(questLogField.EndTime), 0u); - SetUpdateFieldValue(questLogField.ModifyValue(questLogField.AcceptTime), 0u); SetUpdateFieldValue(questLogField.ModifyValue(questLogField.ObjectiveFlags), 0u); for (int i = 0; i < SharedConst.MaxQuestCounts; ++i) @@ -2279,12 +2272,6 @@ namespace Game.Entities SetUpdateFieldValue(questLog.ModifyValue(questLog.EndTime), (uint)endTime); } - public void SetQuestSlotAcceptTime(ushort slot, long acceptTime) - { - QuestLog questLog = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot); - SetUpdateFieldValue(questLog.ModifyValue(questLog.AcceptTime), (uint)acceptTime); - } - void SetQuestSlotObjectiveFlag(ushort slot, sbyte objectiveIndex) { QuestLog questLog = m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.QuestLog, slot); diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index cccfe3b52..59756c889 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -4,6 +4,7 @@ using Framework.Constants; using Framework.Dynamic; using Game.DataStorage; +using Game.Miscellaneous; using Game.Networking.Packets; using Game.Spells; using System; @@ -1627,7 +1628,6 @@ namespace Game.Entities public void LearnSkillRewardedSpells(uint skillId, uint skillValue, Race race) { - long raceMask = SharedConst.GetMaskForRace(race); uint classMask = GetClassMask(); List skillLineAbilities = Global.DB2Mgr.GetSkillLineAbilitiesBySkill(skillId); @@ -1659,7 +1659,8 @@ namespace Game.Entities continue; // Check race if set - if (ability.RaceMask != 0 && !Convert.ToBoolean(ability.RaceMask & raceMask)) + var raceMask = new RaceMask(ability.RaceMask); + if (!raceMask.IsEmpty() && !raceMask.HasRace(race)) continue; // Check class if set diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index fd49dde5e..2286afa06 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -19,6 +19,7 @@ using Game.Loots; using Game.Mails; using Game.Maps; using Game.Misc; +using Game.Miscellaneous; using Game.Networking; using Game.Networking.Packets; using Game.Spells; @@ -859,6 +860,194 @@ namespace Game.Entities return m_petStable; } + public void AddPetToUpdateFields(PetStable.PetInfo pet, PetSaveMode slot, PetStableFlags flags) + { + StableInfo ufStable = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable); + StablePetInfo ufPet = new(); + ufPet.ModifyValue(ufPet.PetSlot).SetValue((uint)slot); + ufPet.ModifyValue(ufPet.PetNumber).SetValue(pet.PetNumber); + ufPet.ModifyValue(ufPet.CreatureID).SetValue(pet.CreatureId); + ufPet.ModifyValue(ufPet.DisplayID).SetValue(pet.DisplayId); + ufPet.ModifyValue(ufPet.ExperienceLevel).SetValue(pet.Level); + ufPet.ModifyValue(ufPet.PetFlags).SetValue((byte)flags); + ufPet.ModifyValue(ufPet.Name).SetValue(pet.Name); + AddDynamicUpdateFieldValue(ufStable.ModifyValue(ufStable.Pets), ufPet); + } + + public void SetPetSlot(uint petNumber, PetSaveMode dstPetSlot) + { + RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting); + + WorldSession sess = GetSession(); + PetStable petStable = GetPetStable(); + if (petStable == null) + { + sess.SendPetStableResult(StableResult.InternalError); + return; + } + + var (srcPet, srcPetSlot) = Pet.GetLoadPetInfo(petStable, 0, petNumber, null); + PetStable.PetInfo dstPet = Pet.GetLoadPetInfo(petStable, 0, 0, dstPetSlot).Item1; + + if (srcPet == null || srcPet.Type != PetType.Hunter) + { + sess.SendPetStableResult(StableResult.InternalError); + return; + } + + if (dstPet != null && dstPet.Type != PetType.Hunter) + { + sess.SendPetStableResult(StableResult.InternalError); + return; + } + + PetStable.PetInfo src = null; + PetStable.PetInfo dst = null; + uint? newActivePetIndex = null; + + if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot)) + { + // active<.active: only swap ActivePets and CurrentPetIndex (do not despawn pets) + src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot]; + dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot]; + + if (petStable.GetCurrentActivePetIndex() == (uint)srcPetSlot) + newActivePetIndex = (uint)dstPetSlot; + else if (petStable.GetCurrentActivePetIndex() == (uint)dstPetSlot) + newActivePetIndex = (uint)srcPetSlot; + } + else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot)) + { + // stabled<.stabled: only swap StabledPets + src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot]; + dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot]; + } + else if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot)) + { + // active<.stabled: swap petStable contents and despawn active pet if it is involved in swap + if (petStable.CurrentPetIndex == (uint)srcPetSlot) + { + Pet oldPet = GetPet(); + if (oldPet && !oldPet.IsAlive()) + { + sess.SendPetStableResult(StableResult.InternalError); + return; + } + + RemovePet(oldPet, PetSaveMode.NotInSlot); + } + + if (dstPet != null) + { + CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(dstPet.CreatureId); + if (creatureInfo == null || !creatureInfo.IsTameable(CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None))) + { + sess.SendPetStableResult(StableResult.CantControlExotic); + return; + } + } + + src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot]; + dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot]; + } + else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot)) + { + // stabled<.active: swap petStable contents and despawn active pet if it is involved in swap + if (petStable.CurrentPetIndex == (uint)dstPetSlot) + { + Pet oldPet = GetPet(); + if (oldPet != null && !oldPet.IsAlive()) + { + sess.SendPetStableResult(StableResult.InternalError); + return; + } + + RemovePet(oldPet, PetSaveMode.NotInSlot); + } + + CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(srcPet.CreatureId); + if (creatureInfo == null || !creatureInfo.IsTameable(CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None))) + { + sess.SendPetStableResult(StableResult.CantControlExotic); + return; + } + + src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot]; + dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot]; + } + + SQLTransaction trans = new SQLTransaction(); + + PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID); + stmt.AddValue(0, (short)dstPetSlot); + stmt.AddValue(1, GetGUID().GetCounter()); + stmt.AddValue(2, srcPet.PetNumber); + trans.Append(stmt); + + if (dstPet != null) + { + stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID); + stmt.AddValue(0, (short)srcPetSlot); + stmt.AddValue(1, GetGUID().GetCounter()); + stmt.AddValue(2, dstPet.PetNumber); + trans.Append(stmt); + } + + + GetSession().AddTransactionCallback(DB.Characters.AsyncCommitTransaction(trans)).AfterComplete(success => + { + if (sess.GetPlayer() == this) + { + if (success) + { + Extensions.Swap(ref src, ref dst); + if (newActivePetIndex.HasValue) + sess.GetPlayer().GetPetStable().SetCurrentActivePetIndex(newActivePetIndex.Value); + + int srcPetIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetSlot == (uint)srcPetSlot); + int dstPetIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetSlot == (uint)dstPetSlot); + + if (srcPetIndex >= 0) + { + StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable); + StablePetInfo stablePetInfo = stableInfo.ModifyValue(stableInfo.Pets, srcPetIndex); + SetUpdateFieldValue(stablePetInfo.ModifyValue(stablePetInfo.PetSlot), (uint)dstPetSlot); + } + + if (dstPetIndex >= 0) + { + StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable); + StablePetInfo stablePetInfo = stableInfo.ModifyValue(stableInfo.Pets, dstPetIndex); + SetUpdateFieldValue(stablePetInfo.ModifyValue(stablePetInfo.PetSlot), (uint)srcPetSlot); + } + + sess.SendPetStableResult(StableResult.StableSuccess); + } + else + { + sess.SendPetStableResult(StableResult.InternalError); + } + } + }); + } + + public ObjectGuid GetStableMaster() + { + if (!m_activePlayerData.PetStable.HasValue()) + return ObjectGuid.Empty; + + return m_activePlayerData.PetStable.GetValue().StableMaster; + } + + public void SetStableMaster(ObjectGuid stableMaster) + { + if (!m_activePlayerData.PetStable.HasValue()) + return; + + StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable); + SetUpdateFieldValue(stableInfo.ModifyValue(stableInfo.StableMaster), stableMaster); + } + // last used pet number (for BG's) public uint GetLastPetNumber() { return m_lastpetnumber; } public void SetLastPetNumber(uint petnumber) { m_lastpetnumber = petnumber; } @@ -2568,7 +2757,8 @@ namespace Game.Entities SendRespecWipeConfirm(guid, WorldConfig.GetBoolValue(WorldCfg.NoResetTalentCost) ? 0 : GetNextResetTalentsCost(), SpecResetType.Talents); break; case GossipOptionNpc.Stablemaster: - GetSession().SendStablePet(guid); + SetStableMaster(guid); + handled = false; break; case GossipOptionNpc.PetSpecializationMaster: PlayerTalkClass.SendCloseGossip(); @@ -3578,7 +3768,7 @@ namespace Game.Entities public static bool IsValidGender(Gender _gender) { return _gender <= Gender.Female; } public static bool IsValidClass(Class _class) { return Convert.ToBoolean((1 << ((int)_class - 1)) & (int)Class.ClassMaskAllPlayable); } - public static bool IsValidRace(Race _race) { return Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(_race) & SharedConst.RaceMaskAllPlayable); } + public static bool IsValidRace(Race _race) { return RaceMask.AllPlayable.HasRace(_race); } void LeaveLFGChannel() { @@ -4506,8 +4696,26 @@ namespace Game.Entities PetStable.PetInfo currentPet = m_petStable.GetCurrentPet(); Cypher.Assert(currentPet != null && currentPet.PetNumber == pet.GetCharmInfo().GetPetNumber()); - if (mode == PetSaveMode.NotInSlot || mode == PetSaveMode.AsDeleted) + if (mode == PetSaveMode.NotInSlot) m_petStable.CurrentPetIndex = null; + else if (mode == PetSaveMode.AsDeleted) + { + if (m_activePlayerData.PetStable.HasValue()) + { + int ufIndex = m_activePlayerData.PetStable.GetValue().Pets.FindIndexIf(p => p.PetNumber == currentPet.PetNumber); + if (ufIndex >= 0) + { + StableInfo stableInfo = m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.PetStable); + RemoveDynamicUpdateFieldValue(stableInfo.ModifyValue(stableInfo.Pets), ufIndex); + } + } + + var petIndex = m_petStable.GetCurrentActivePetIndex(); + if (petIndex.HasValue) + m_petStable.ActivePets[petIndex.Value] = null; + + m_petStable.CurrentPetIndex = null; + } // else if (stable slots) handled in opcode handlers due to required swaps // else (current pet) doesnt need to do anything @@ -5083,7 +5291,7 @@ namespace Game.Entities if (pet) pet.SynchronizeLevelWithOwner(); - MailLevelReward mailReward = ObjectMgr.GetMailLevelReward(level, (uint)SharedConst.GetMaskForRace(GetRace())); + MailLevelReward mailReward = ObjectMgr.GetMailLevelReward(level, GetRace()); if (mailReward != null) { //- TODO: Poor design of mail system @@ -7014,7 +7222,6 @@ namespace Game.Entities } public bool IsSpellFitByClassAndRace(uint spell_id) { - long racemask = SharedConst.GetMaskForRace(GetRace()); uint classmask = GetClassMask(); var bounds = SpellMgr.GetSkillLineAbilityMapBounds(spell_id); @@ -7025,7 +7232,8 @@ namespace Game.Entities foreach (var _spell_idx in bounds) { // skip wrong race skills - if (_spell_idx.RaceMask != 0 && (_spell_idx.RaceMask & racemask) == 0) + var raceMask = new RaceMask(_spell_idx.RaceMask); + if (!raceMask.IsEmpty() && !raceMask.HasRace(GetRace())) continue; // skip wrong class skills @@ -7409,7 +7617,10 @@ namespace Game.Entities public void RemoveAuraVision(PlayerFieldByte2Flags flags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.AuraVision), (byte)flags); } public void SetTransportServerTime(int transportServerTime) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.TransportServerTime), transportServerTime); } - + + public void SetRequiredMountCapabilityFlag(byte flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flag); } + public void ReplaceAllRequiredMountCapabilityFlags(byte flags) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.RequiredMountCapabilityFlags), flags); } + public bool CanTameExoticPets() { return IsGameMaster() || HasAuraType(AuraType.AllowTamePetType); } void SendAttackSwingCantAttack() { SendPacket(new AttackSwingError(AttackSwingErr.CantAttack)); } diff --git a/Source/Game/Entities/Unit/Unit.Pets.cs b/Source/Game/Entities/Unit/Unit.Pets.cs index ea24dac27..e426c2bc4 100644 --- a/Source/Game/Entities/Unit/Unit.Pets.cs +++ b/Source/Game/Entities/Unit/Unit.Pets.cs @@ -768,10 +768,8 @@ namespace Game.Entities pet.SetCreatorGUID(GetGUID()); pet.SetFaction(GetFaction()); - pet.SetCreatedBySpell(spell_id); - - if (IsTypeId(TypeId.Player)) - pet.SetUnitFlag(UnitFlags.PlayerControlled); + pet.SetCreatedBySpell(spell_id); + pet.SetUnitFlag(UnitFlags.PlayerControlled); if (!pet.InitStatsForLevel(level)) { @@ -790,6 +788,7 @@ namespace Game.Entities PetStable.PetInfo petInfo = new(); pet.FillPetInfo(petInfo); + player.AddPetToUpdateFields(petInfo, (PetSaveMode)petStable.GetCurrentActivePetIndex(), PetStableFlags.Active); petStable.ActivePets[freeActiveSlot] = petInfo; return true; } diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index 6a713fb3e..138ca7551 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -1431,7 +1431,7 @@ namespace Game.Entities if (displayInfo != null) { ChrCustomizationReqRecord choiceReq = CliDB.ChrCustomizationReqStorage.LookupByKey(formModelData.Choices[i].ChrCustomizationReqID); - if (choiceReq == null || thisPlayer.GetSession().MeetsChrCustomizationReq(choiceReq, GetClass(), false, thisPlayer.m_playerData.Customizations)) + if (choiceReq == null || thisPlayer.GetSession().MeetsChrCustomizationReq(choiceReq, GetRace(), GetClass(), false, thisPlayer.m_playerData.Customizations)) displayIds.Add(displayInfo.DisplayID); } } @@ -1877,6 +1877,7 @@ namespace Game.Entities public Race GetRace() { return (Race)(byte)m_unitData.Race; } public void SetRace(Race race) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.Race), (byte)race); } + public ulong GetRaceMask() { return 1UL << ((int)GetRace() - 1); } public Class GetClass() { return (Class)(byte)m_unitData.ClassId; } public void SetClass(Class classId) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.ClassId), (byte)classId); } public uint GetClassMask() { return (uint)(1 << ((int)GetClass() - 1)); } diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 30ccc3802..8ef32db73 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -12,6 +12,7 @@ using Game.Loots; using Game.Mails; using Game.Maps; using Game.Misc; +using Game.Miscellaneous; using Game.Movement; using Game.Scripting; using Game.Spells; @@ -6048,9 +6049,12 @@ namespace Game if (items.Empty()) continue; + var raceMask = new RaceMask(characterLoadout.RaceMask); + for (var raceIndex = Race.Human; raceIndex < Race.Max; ++raceIndex) { - if (!characterLoadout.RaceMask.HasAnyFlag(SharedConst.GetMaskForRace(raceIndex))) + + if (!raceMask.HasRace(raceIndex)) continue; var playerInfo = _playerInfo.LookupByKey(Tuple.Create((Race)raceIndex, (Class)characterLoadout.ChrClassID)); @@ -6159,9 +6163,10 @@ namespace Game { if (rcInfo.Availability == 1) { + var raceMask = new RaceMask(rcInfo.RaceMask); for (Race raceIndex = Race.Human; raceIndex < Race.Max; ++raceIndex) { - if (rcInfo.RaceMask == -1 || Convert.ToBoolean(SharedConst.GetMaskForRace(raceIndex) & rcInfo.RaceMask)) + if (raceMask.HasRace(raceIndex)) { for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { @@ -6194,11 +6199,11 @@ namespace Game uint count = 0; do { - ulong raceMask = result.Read(0); + RaceMask raceMask = new(result.Read(0)); uint classMask = result.Read(1); uint spellId = result.Read(2); - if (raceMask != 0 && !Convert.ToBoolean(raceMask & SharedConst.RaceMaskAllPlayable)) + if (!raceMask.IsEmpty() && (raceMask & RaceMask.AllPlayable).IsEmpty()) { Log.outError(LogFilter.Sql, "Wrong race mask {0} in `playercreateinfo_spell_custom` table, ignoring.", raceMask); continue; @@ -6212,7 +6217,7 @@ namespace Game for (Race raceIndex = Race.Human; raceIndex < Race.Max; ++raceIndex) { - if (raceMask == 0 || Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(raceIndex) & raceMask)) + if (raceMask.IsEmpty() || raceMask.HasRace(raceIndex)) { for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { @@ -6252,12 +6257,12 @@ namespace Game do { - ulong raceMask = result.Read(0); + RaceMask raceMask = new(result.Read(0)); uint classMask = result.Read(1); uint spellId = result.Read(2); sbyte playerCreateMode = result.Read(3); - if (raceMask != 0 && (raceMask & SharedConst.RaceMaskAllPlayable) == 0) + if (!raceMask.IsEmpty() && (raceMask & RaceMask.AllPlayable).IsEmpty()) { Log.outError(LogFilter.Sql, $"Wrong race mask {raceMask} in `playercreateinfo_cast_spell` table, ignoring."); continue; @@ -6277,7 +6282,7 @@ namespace Game for (Race raceIndex = Race.Human; raceIndex < Race.Max; ++raceIndex) { - if (raceMask == 0 || Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(raceIndex) & raceMask)) + if (raceMask.IsEmpty() || raceMask.HasRace(raceIndex)) { for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { @@ -7387,12 +7392,12 @@ namespace Game } } // AllowableRaces, can be -1/RACEMASK_ALL_PLAYABLE to allow any race - if (qinfo.AllowableRaces != -1) + if (qinfo.AllowableRaces.RawValue != 0xFFFFFFFFFFFFFFFF) { - if (qinfo.AllowableRaces > 0 && !Convert.ToBoolean(qinfo.AllowableRaces & (long)SharedConst.RaceMaskAllPlayable)) + if (!qinfo.AllowableRaces.IsEmpty() && (qinfo.AllowableRaces & RaceMask.AllPlayable).IsEmpty()) { Log.outError(LogFilter.Sql, "Quest {0} does not contain any playable races in `RequiredRaces` ({1}), value set to 0 (all races).", qinfo.Id, qinfo.AllowableRaces); - qinfo.AllowableRaces = -1; + qinfo.AllowableRaces = new(0xFFFFFFFFFFFFFFFF); } } // RequiredSkillId, can be 0 @@ -9287,7 +9292,7 @@ namespace Game do { byte level = result.Read(0); - ulong raceMask = result.Read(1); + RaceMask raceMask = new(result.Read(1)); uint mailTemplateId = result.Read(2); uint senderEntry = result.Read(3); @@ -9297,7 +9302,7 @@ namespace Game continue; } - if (!Convert.ToBoolean(raceMask & SharedConst.RaceMaskAllPlayable)) + if ((raceMask & RaceMask.AllPlayable).IsEmpty()) { Log.outError(LogFilter.Sql, "Table `mail_level_reward` have raceMask ({0}) for level {1} that not include any player races, ignoring.", raceMask, level); continue; @@ -10221,14 +10226,14 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} phase names in {Time.GetMSTimeDiffToNow(oldMSTime)} ms."); } - public MailLevelReward GetMailLevelReward(uint level, ulong raceMask) + public MailLevelReward GetMailLevelReward(uint level, Race race) { var mailList = _mailLevelRewardStorage.LookupByKey((byte)level); if (mailList.Empty()) return null; foreach (var mailReward in mailList) - if (Convert.ToBoolean(mailReward.raceMask & raceMask)) + if (mailReward.raceMask.HasRace(race)) return mailReward; return null; @@ -11531,14 +11536,14 @@ namespace Game public class MailLevelReward { - public MailLevelReward(ulong _raceMask = 0, uint _mailTemplateId = 0, uint _senderEntry = 0) + public MailLevelReward(RaceMask _raceMask, uint _mailTemplateId = 0, uint _senderEntry = 0) { raceMask = _raceMask; mailTemplateId = _mailTemplateId; senderEntry = _senderEntry; } - public ulong raceMask; + public RaceMask raceMask; public uint mailTemplateId; public uint senderEntry; } diff --git a/Source/Game/Guilds/GuildManager.cs b/Source/Game/Guilds/GuildManager.cs index 66af3fb31..a78a6dc01 100644 --- a/Source/Game/Guilds/GuildManager.cs +++ b/Source/Game/Guilds/GuildManager.cs @@ -6,6 +6,7 @@ using Framework.Database; using Game.DataStorage; using Game.Entities; using Game.Guilds; +using Game.Miscellaneous; using System.Collections.Generic; using System.Linq; @@ -436,7 +437,7 @@ namespace Game reward.ItemID = result.Read(0); reward.MinGuildRep = result.Read(1); - reward.RaceMask = result.Read(2); + reward.RaceMask = new RaceMask(result.Read(2)); reward.Cost = result.Read(3); if (Global.ObjectMgr.GetItemTemplate(reward.ItemID) == null) @@ -497,7 +498,7 @@ namespace Game { public uint ItemID; public byte MinGuildRep; - public ulong RaceMask; + public RaceMask RaceMask; public ulong Cost; public List AchievementsRequired = new(); } diff --git a/Source/Game/Handlers/CharacterHandler.cs b/Source/Game/Handlers/CharacterHandler.cs index e60e3162b..f72726677 100644 --- a/Source/Game/Handlers/CharacterHandler.cs +++ b/Source/Game/Handlers/CharacterHandler.cs @@ -11,6 +11,7 @@ using Game.Entities; using Game.Groups; using Game.Guilds; using Game.Maps; +using Game.Miscellaneous; using Game.Networking; using Game.Networking.Packets; using Game.Spells; @@ -85,7 +86,7 @@ namespace Game charInfo.Customizations.Clear(); - if (charInfo.Flags2 != CharacterCustomizeFlags.Customize) + if (!charInfo.Flags2.HasAnyFlag(CharacterCustomizeFlags.Customize | CharacterCustomizeFlags.Faction | CharacterCustomizeFlags.Race)) { PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_ADD_AT_LOGIN_FLAG); stmt.AddValue(0, (ushort)AtLoginFlags.Customize); @@ -165,7 +166,7 @@ namespace Game SendPacket(charEnum); } - public bool MeetsChrCustomizationReq(ChrCustomizationReqRecord req, Class playerClass, bool checkRequiredDependentChoices, List selectedChoices) + public bool MeetsChrCustomizationReq(ChrCustomizationReqRecord req, Race race, Class playerClass, bool checkRequiredDependentChoices, List selectedChoices) { if (!req.GetFlags().HasFlag(ChrCustomizationReqFlag.HasRequirements)) return true; @@ -173,6 +174,10 @@ namespace Game if (req.ClassMask != 0 && (req.ClassMask & (1 << ((int)playerClass - 1))) == 0) return false; + var raceMask = new RaceMask(req.RaceMask); + if (race != Race.None && !raceMask.IsEmpty() && raceMask.RawValue != -1 && !raceMask.HasRace(race)) + return false; + if (req.AchievementID != 0 /*&& !HasAchieved(req->AchievementID)*/) return false; @@ -240,7 +245,7 @@ namespace Game ChrCustomizationReqRecord req = CliDB.ChrCustomizationReqStorage.LookupByKey(customizationOptionData.ChrCustomizationReqID); if (req != null) - if (!MeetsChrCustomizationReq(req, playerClass, false, customizations)) + if (!MeetsChrCustomizationReq(req, race, playerClass, false, customizations)) return false; var choicesForOption = Global.DB2Mgr.GetCustomiztionChoices(playerChoice.ChrCustomizationOptionID); @@ -255,7 +260,7 @@ namespace Game ChrCustomizationReqRecord reqEntry = CliDB.ChrCustomizationReqStorage.LookupByKey(customizationChoiceData.ChrCustomizationReqID); if (reqEntry != null) - if (!MeetsChrCustomizationReq(reqEntry, playerClass, true, customizations)) + if (!MeetsChrCustomizationReq(reqEntry, race, playerClass, true, customizations)) return false; } @@ -374,8 +379,8 @@ namespace Game return; } - ulong raceMaskDisabled = WorldConfig.GetUInt64Value(WorldCfg.CharacterCreatingDisabledRacemask); - if (Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(charCreate.CreateInfo.RaceId) & raceMaskDisabled)) + RaceMask raceMaskDisabled = new(WorldConfig.GetUInt64Value(WorldCfg.CharacterCreatingDisabledRacemask)); + if (raceMaskDisabled.HasRace(charCreate.CreateInfo.RaceId)) { SendCharCreate(ResponseCodes.CharCreateDisabled); return; @@ -839,10 +844,6 @@ namespace Game pCurrChar.SetGuildLevel(0); } - // Send stable contents to display icons on Call Pet spells - if (pCurrChar.HasSpell(SharedConst.CallPetSpellId)) - SendStablePet(ObjectGuid.Empty); - pCurrChar.GetSession().GetBattlePetMgr().SendJournalLockStatus(); pCurrChar.SendInitialPacketsBeforeAddToMap(); @@ -1382,6 +1383,23 @@ namespace Game [WorldPacketHandler(ClientOpcodes.AlterAppearance)] void HandleAlterAppearance(AlterApperance packet) { + if (packet.CustomizedChrModelID != 0) + { + var conditionalChrModel = CliDB.ConditionalChrModelStorage.LookupByKey(packet.CustomizedChrModelID); + if (conditionalChrModel == null) + return; + + var req = CliDB.ChrCustomizationReqStorage.LookupByKey(conditionalChrModel.ChrCustomizationReqID); + if (req != null) + if (!MeetsChrCustomizationReq(req, (Race)packet.CustomizedRace, _player.GetClass(), false, packet.Customizations)) + return; + + var condition = CliDB.PlayerConditionStorage.LookupByKey(conditionalChrModel.PlayerConditionID); + if (condition != null) + if (!ConditionManager.IsPlayerMeetingCondition(_player, condition)) + return; + } + if (!ValidateAppearance(_player.GetRace(), _player.GetClass(), (Gender)packet.NewSex, packet.Customizations)) return; @@ -1766,8 +1784,8 @@ namespace Game if (!HasPermission(RBACPermissions.SkipCheckCharacterCreationRacemask)) { - ulong raceMaskDisabled = WorldConfig.GetUInt64Value(WorldCfg.CharacterCreatingDisabledRacemask); - if (Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(factionChangeInfo.RaceID) & raceMaskDisabled)) + RaceMask raceMaskDisabled = new(WorldConfig.GetUInt64Value(WorldCfg.CharacterCreatingDisabledRacemask)); + if (raceMaskDisabled.HasRace(factionChangeInfo.RaceID)) { SendCharFactionChange(ResponseCodes.CharCreateError, factionChangeInfo); return; @@ -2078,8 +2096,8 @@ namespace Game var questTemplates = Global.ObjectMgr.GetQuestTemplates(); foreach (Quest quest in questTemplates.Values) { - long newRaceMask = (long)(newTeamId == TeamId.Alliance ? SharedConst.RaceMaskAlliance : SharedConst.RaceMaskHorde); - if (quest.AllowableRaces != -1 && !Convert.ToBoolean(quest.AllowableRaces & newRaceMask)) + RaceMask newRaceMask = newTeamId == TeamId.Alliance ? RaceMask.Alliance : RaceMask.Horde; + if (quest.AllowableRaces.RawValue != unchecked((ulong)-1) && (quest.AllowableRaces & newRaceMask).IsEmpty()) { stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST); stmt.AddValue(0, lowGuid); diff --git a/Source/Game/Handlers/GuildHandler.cs b/Source/Game/Handlers/GuildHandler.cs index e390c39f6..258cbf89a 100644 --- a/Source/Game/Handlers/GuildHandler.cs +++ b/Source/Game/Handlers/GuildHandler.cs @@ -614,7 +614,7 @@ namespace Game { GuildRewardItem rewardItem = new(); rewardItem.ItemID = rewards[i].ItemID; - rewardItem.RaceMask = (uint)rewards[i].RaceMask; + rewardItem.RaceMask = rewards[i].RaceMask; rewardItem.MinGuildLevel = 0; rewardItem.MinGuildRep = rewards[i].MinGuildRep; rewardItem.AchievementsRequired = rewards[i].AchievementsRequired; diff --git a/Source/Game/Handlers/MiscHandler.cs b/Source/Game/Handlers/MiscHandler.cs index 730a8219b..f5757b0c3 100644 --- a/Source/Game/Handlers/MiscHandler.cs +++ b/Source/Game/Handlers/MiscHandler.cs @@ -465,6 +465,9 @@ namespace Game { if (_player.PlayerTalkClass.GetInteractionData().SourceGuid == closeInteraction.SourceGuid) _player.PlayerTalkClass.GetInteractionData().Reset(); + + if (_player.GetStableMaster() == closeInteraction.SourceGuid) + _player.SetStableMaster(ObjectGuid.Empty); } [WorldPacketHandler(ClientOpcodes.ConversationLineStarted)] diff --git a/Source/Game/Handlers/NPCHandler.cs b/Source/Game/Handlers/NPCHandler.cs index 0174de3d8..3066ae34e 100644 --- a/Source/Game/Handlers/NPCHandler.cs +++ b/Source/Game/Handlers/NPCHandler.cs @@ -324,61 +324,10 @@ namespace Game if (GetPlayer().IsMounted()) GetPlayer().RemoveAurasByType(AuraType.Mounted); - SendStablePet(packet.StableMaster); + _player.SetStableMaster(packet.StableMaster); } - public void SendStablePet(ObjectGuid guid) - { - PetStableList packet = new(); - packet.StableMaster = guid; - - PetStable petStable = GetPlayer().GetPetStable(); - if (petStable == null) - { - SendPacket(packet); - return; - } - - for (uint petSlot = 0; petSlot < petStable.ActivePets.Length; ++petSlot) - { - if (petStable.ActivePets[petSlot] == null) - continue; - - PetStable.PetInfo pet = petStable.ActivePets[petSlot]; - PetStableInfo stableEntry; - stableEntry.PetSlot = petSlot + (int)PetSaveMode.FirstActiveSlot; - stableEntry.PetNumber = pet.PetNumber; - stableEntry.CreatureID = pet.CreatureId; - stableEntry.DisplayID = pet.DisplayId; - stableEntry.ExperienceLevel = pet.Level; - stableEntry.PetFlags = PetStableinfo.Active; - stableEntry.PetName = pet.Name; - - packet.Pets.Add(stableEntry); - } - - for (uint petSlot = 0; petSlot < petStable.StabledPets.Length; ++petSlot) - { - if (petStable.StabledPets[petSlot] == null) - continue; - - PetStable.PetInfo pet = petStable.StabledPets[petSlot]; - PetStableInfo stableEntry; - stableEntry.PetSlot = petSlot + (int)PetSaveMode.FirstStableSlot; - stableEntry.PetNumber = pet.PetNumber; - stableEntry.CreatureID = pet.CreatureId; - stableEntry.DisplayID = pet.DisplayId; - stableEntry.ExperienceLevel = pet.Level; - stableEntry.PetFlags = PetStableinfo.Inactive; - stableEntry.PetName = pet.Name; - - packet.Pets.Add(stableEntry); - } - - SendPacket(packet); - } - - void SendPetStableResult(StableResult result) + public void SendPetStableResult(StableResult result) { PetStableResult petStableResult = new(); petStableResult.Result = result; @@ -394,141 +343,7 @@ namespace Game return; } - GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting); - - PetStable petStable = GetPlayer().GetPetStable(); - if (petStable == null) - { - SendPetStableResult(StableResult.InternalError); - return; - } - - (PetStable.PetInfo srcPet, PetSaveMode srcPetSlot) = Pet.GetLoadPetInfo(petStable, 0, setPetSlot.PetNumber, null); - PetSaveMode dstPetSlot = (PetSaveMode)setPetSlot.DestSlot; - PetStable.PetInfo dstPet = Pet.GetLoadPetInfo(petStable, 0, 0, dstPetSlot).Item1; - - if (srcPet == null || srcPet.Type != PetType.Hunter) - { - SendPetStableResult(StableResult.InternalError); - return; - } - - if (dstPet != null && dstPet.Type != PetType.Hunter) - { - SendPetStableResult(StableResult.InternalError); - return; - } - - PetStable.PetInfo src = null; - PetStable.PetInfo dst = null; - PetSaveMode? newActivePetIndex = null; - - if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot)) - { - // active<.active: only swap ActivePets and CurrentPetIndex (do not despawn pets) - src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot]; - dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot]; - - if (petStable.GetCurrentActivePetIndex().Value == (uint)srcPetSlot) - newActivePetIndex = dstPetSlot; - else if (petStable.GetCurrentActivePetIndex().Value == (uint)dstPetSlot) - newActivePetIndex = srcPetSlot; - } - else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot)) - { - // stabled<.stabled: only swap StabledPets - src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot]; - dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot]; - } - else if (SharedConst.IsActivePetSlot(srcPetSlot) && SharedConst.IsStabledPetSlot(dstPetSlot)) - { - // active<.stabled: swap petStable contents and despawn active pet if it is involved in swap - if (petStable.CurrentPetIndex.Value == (uint)srcPetSlot) - { - Pet oldPet = _player.GetPet(); - if (oldPet != null && !oldPet.IsAlive()) - { - SendPetStableResult(StableResult.InternalError); - return; - } - - _player.RemovePet(oldPet, PetSaveMode.NotInSlot); - } - - if (dstPet != null) - { - CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(dstPet.CreatureId); - if (creatureInfo == null || !creatureInfo.IsTameable(_player.CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None))) - { - SendPetStableResult(StableResult.CantControlExotic); - return; - } - } - - src = petStable.ActivePets[srcPetSlot - PetSaveMode.FirstActiveSlot]; - dst = petStable.StabledPets[dstPetSlot - PetSaveMode.FirstStableSlot]; - } - else if (SharedConst.IsStabledPetSlot(srcPetSlot) && SharedConst.IsActivePetSlot(dstPetSlot)) - { - // stabled<.active: swap petStable contents and despawn active pet if it is involved in swap - if (petStable.CurrentPetIndex.Value == (uint)dstPetSlot) - { - Pet oldPet = _player.GetPet(); - if (oldPet != null && !oldPet.IsAlive()) - { - SendPetStableResult(StableResult.InternalError); - return; - } - - _player.RemovePet(oldPet, PetSaveMode.NotInSlot); - } - - CreatureTemplate creatureInfo = Global.ObjectMgr.GetCreatureTemplate(srcPet.CreatureId); - if (creatureInfo == null || !creatureInfo.IsTameable(_player.CanTameExoticPets(), creatureInfo.GetDifficulty(Difficulty.None))) - { - SendPetStableResult(StableResult.CantControlExotic); - return; - } - - src = petStable.StabledPets[srcPetSlot - PetSaveMode.FirstStableSlot]; - dst = petStable.ActivePets[dstPetSlot - PetSaveMode.FirstActiveSlot]; - } - - SQLTransaction trans = new(); - - PreparedStatement stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID); - stmt.AddValue(0, (short)dstPetSlot); - stmt.AddValue(1, _player.GetGUID().GetCounter()); - stmt.AddValue(2, srcPet.PetNumber); - trans.Append(stmt); - - if (dstPet != null) - { - stmt = CharacterDatabase.GetPreparedStatement(CharStatements.UPD_CHAR_PET_SLOT_BY_ID); - stmt.AddValue(0, (short)srcPetSlot); - stmt.AddValue(1, _player.GetGUID().GetCounter()); - stmt.AddValue(2, dstPet.PetNumber); - trans.Append(stmt); - } - - AddTransactionCallback(DB.Characters.AsyncCommitTransaction(trans)).AfterComplete(success => - { - var currentPlayerGuid = _player.GetGUID(); - if (_player && _player.GetGUID() == currentPlayerGuid) - { - if (success) - { - Extensions.Swap(ref src, ref dst); - if (newActivePetIndex.HasValue) - GetPlayer().GetPetStable().SetCurrentActivePetIndex((uint)newActivePetIndex.Value); - SendPetStableResult(StableResult.StableSuccess); - } - else - { - SendPetStableResult(StableResult.InternalError); - } - } - }); + _player.SetPetSlot(setPetSlot.PetNumber, (PetSaveMode)setPetSlot.DestSlot); } [WorldPacketHandler(ClientOpcodes.RepairItem, Processing = PacketProcessing.Inplace)] diff --git a/Source/Game/Handlers/PetHandler.cs b/Source/Game/Handlers/PetHandler.cs index 081db4042..fce5dd454 100644 --- a/Source/Game/Handlers/PetHandler.cs +++ b/Source/Game/Handlers/PetHandler.cs @@ -582,9 +582,6 @@ namespace Game [WorldPacketHandler(ClientOpcodes.PetAbandon)] void HandlePetAbandon(PetAbandon packet) { - if (!GetPlayer().IsInWorld) - return; - // pet/charmed Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(GetPlayer(), packet.Pet); if (pet && pet.ToPet() && pet.ToPet().GetPetType() == PetType.Hunter) diff --git a/Source/Game/Handlers/SocialHandler.cs b/Source/Game/Handlers/SocialHandler.cs index 15bc47302..0a5dea490 100644 --- a/Source/Game/Handlers/SocialHandler.cs +++ b/Source/Game/Handlers/SocialHandler.cs @@ -80,7 +80,7 @@ namespace Game continue; // check if race matches racemask - if (!Convert.ToBoolean(request.RaceFilter & (1 << target.Race))) + if (!request.RaceFilter.HasRace((Race)target.Race)) continue; if (!whoRequest.Areas.Empty()) diff --git a/Source/Game/Handlers/SpellHandler.cs b/Source/Game/Handlers/SpellHandler.cs index 9f846230a..280c4fd6c 100644 --- a/Source/Game/Handlers/SpellHandler.cs +++ b/Source/Game/Handlers/SpellHandler.cs @@ -81,7 +81,7 @@ namespace Game SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo((uint)effect.SpellID, user.GetMap().GetDifficultyID()); if (spellInfo != null) { - if (!spellInfo.CanBeUsedInCombat()) + if (!spellInfo.CanBeUsedInCombat(user)) { user.SendEquipError(InventoryResult.NotInCombat, item); return; diff --git a/Source/Game/Miscellaneous/RaceMask.cs b/Source/Game/Miscellaneous/RaceMask.cs new file mode 100644 index 000000000..ac2118168 --- /dev/null +++ b/Source/Game/Miscellaneous/RaceMask.cs @@ -0,0 +1,108 @@ +// Copyright (c) CypherCore All rights reserved. +// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. + +using Framework.Constants; +using System.Runtime.InteropServices; + +namespace Game.Miscellaneous +{ + public struct RaceMask + { + public static RaceMask AllPlayable = new RaceMask( + RaceMask.GetMaskForRace(Race.Human) | RaceMask.GetMaskForRace(Race.Orc) | RaceMask.GetMaskForRace(Race.Dwarf) | RaceMask.GetMaskForRace(Race.NightElf) | + RaceMask.GetMaskForRace(Race.Undead) | RaceMask.GetMaskForRace(Race.Tauren) | RaceMask.GetMaskForRace(Race.Gnome) | RaceMask.GetMaskForRace(Race.Troll) | + RaceMask.GetMaskForRace(Race.BloodElf) | RaceMask.GetMaskForRace(Race.Draenei) | RaceMask.GetMaskForRace(Race.Goblin) | RaceMask.GetMaskForRace(Race.Worgen) | + RaceMask.GetMaskForRace(Race.PandarenNeutral) | RaceMask.GetMaskForRace(Race.PandarenAlliance) | RaceMask.GetMaskForRace(Race.PandarenHorde) | RaceMask.GetMaskForRace(Race.Nightborne) | + RaceMask.GetMaskForRace(Race.HighmountainTauren) | RaceMask.GetMaskForRace(Race.VoidElf) | RaceMask.GetMaskForRace(Race.LightforgedDraenei) | RaceMask.GetMaskForRace(Race.ZandalariTroll) | + RaceMask.GetMaskForRace(Race.KulTiran) | RaceMask.GetMaskForRace(Race.DarkIronDwarf) | RaceMask.GetMaskForRace(Race.Vulpera) | RaceMask.GetMaskForRace(Race.MagharOrc) | + RaceMask.GetMaskForRace(Race.MechaGnome) | RaceMask.GetMaskForRace(Race.DracthyrAlliance) | RaceMask.GetMaskForRace(Race.DracthyrHorde)); + + public static RaceMask Neutral = new(RaceMask.GetMaskForRace(Race.PandarenNeutral)); + + public static RaceMask Alliance = new( + RaceMask.GetMaskForRace(Race.Human) | RaceMask.GetMaskForRace(Race.Dwarf) | RaceMask.GetMaskForRace(Race.NightElf) | + RaceMask.GetMaskForRace(Race.Gnome) | RaceMask.GetMaskForRace(Race.Draenei) | RaceMask.GetMaskForRace(Race.Worgen) | + RaceMask.GetMaskForRace(Race.PandarenAlliance) | RaceMask.GetMaskForRace(Race.VoidElf) | RaceMask.GetMaskForRace(Race.LightforgedDraenei) | + RaceMask.GetMaskForRace(Race.KulTiran) | RaceMask.GetMaskForRace(Race.DarkIronDwarf) | RaceMask.GetMaskForRace(Race.MechaGnome) | RaceMask.GetMaskForRace(Race.DracthyrAlliance)); + + public static RaceMask Horde = new(AllPlayable.RawValue & ~(Neutral | Alliance).RawValue); + } + + public struct RaceMask where T : unmanaged + { + public T RawValue; + + public RaceMask(T rawValue) + { + RawValue = rawValue; + } + + public bool HasRace(Race raceId) + { + return ((dynamic)RawValue & GetMaskForRace(raceId)) != 0; + } + + public bool IsEmpty() + { + return RawValue == (dynamic)0; + } + + public static RaceMask operator &(RaceMask left, RaceMask right) { return new RaceMask((dynamic)left.RawValue & right.RawValue); } + public static RaceMask operator |(RaceMask left, RaceMask right) { return new RaceMask((dynamic)left.RawValue | right.RawValue); } + + public static explicit operator T(RaceMask raceMask) + { + return raceMask.RawValue; + } + + public static dynamic GetMaskForRace(Race raceId) + { + int raceBit = GetRaceBit(raceId); + return (raceBit >= 0 && (uint)raceBit < Marshal.SizeOf() * 8 ? (1 << raceBit) : 0); + } + + static int GetRaceBit(Race raceId) + { + switch (raceId) + { + case Race.Human: + case Race.Orc: + case Race.Dwarf: + case Race.NightElf: + case Race.Undead: + case Race.Tauren: + case Race.Gnome: + case Race.Troll: + case Race.Goblin: + case Race.BloodElf: + case Race.Draenei: + case Race.Worgen: + case Race.PandarenNeutral: + case Race.PandarenAlliance: + case Race.PandarenHorde: + case Race.Nightborne: + case Race.HighmountainTauren: + case Race.VoidElf: + case Race.LightforgedDraenei: + case Race.ZandalariTroll: + case Race.KulTiran: + return (int)raceId - 1; + case Race.DarkIronDwarf: + return 11; + case Race.Vulpera: + return 12; + case Race.MagharOrc: + return 13; + case Race.MechaGnome: + return 14; + case Race.DracthyrAlliance: + return 16; + case Race.DracthyrHorde: + return 15; + default: + break; + } + return -1; + } + } +} \ No newline at end of file diff --git a/Source/Game/Networking/Packets/AchievementPackets.cs b/Source/Game/Networking/Packets/AchievementPackets.cs index bf72b2464..7271d58ed 100644 --- a/Source/Game/Networking/Packets/AchievementPackets.cs +++ b/Source/Game/Networking/Packets/AchievementPackets.cs @@ -58,6 +58,7 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(CriteriaID); _worldPacket.WriteUInt64(Quantity); _worldPacket.WritePackedGuid(PlayerGUID); + _worldPacket.WriteUInt32(Unused_10_1_5); _worldPacket.WriteUInt32(Flags); _worldPacket.WritePackedTime(CurrentTime); _worldPacket.WriteInt64(ElapsedTime); @@ -72,6 +73,7 @@ namespace Game.Networking.Packets public uint CriteriaID; public ulong Quantity; public ObjectGuid PlayerGUID; + public uint Unused_10_1_5; public uint Flags; public long CurrentTime; public long ElapsedTime; @@ -178,6 +180,7 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(0); // this is a hack. this is a packed time written as int64 (progress.DateUpdated) _worldPacket.WriteUInt64(progress.Quantity); _worldPacket.WritePackedGuid(progress.PlayerGUID); + _worldPacket.WriteInt32(progress.Unused_10_1_5); _worldPacket.WriteInt32(progress.Flags); } } @@ -318,10 +321,11 @@ namespace Game.Networking.Packets data.WriteUInt32(Id); data.WriteUInt64(Quantity); data.WritePackedGuid(Player); + data.WriteUInt32(Unused_10_1_5); + data.WriteUInt32(Flags); data.WritePackedTime(Date); data.WriteInt64(TimeFromStart); data.WriteInt64(TimeFromCreate); - data.WriteBits(Flags, 4); data.WriteBit(RafAcceptanceID.HasValue); data.FlushBits(); @@ -332,6 +336,7 @@ namespace Game.Networking.Packets public uint Id; public ulong Quantity; public ObjectGuid Player; + public uint Unused_10_1_5; public uint Flags; public long Date; public long TimeFromStart; @@ -347,6 +352,7 @@ namespace Game.Networking.Packets public long DateUpdated; public ulong Quantity; public ObjectGuid PlayerGUID; + public int Unused_10_1_5; public int Flags; } diff --git a/Source/Game/Networking/Packets/AuctionHousePackets.cs b/Source/Game/Networking/Packets/AuctionHousePackets.cs index 401647df6..718ec2411 100644 --- a/Source/Game/Networking/Packets/AuctionHousePackets.cs +++ b/Source/Game/Networking/Packets/AuctionHousePackets.cs @@ -517,7 +517,8 @@ namespace Game.Networking.Packets class AuctionHelloResponse : ServerPacket { public ObjectGuid Guid; - public uint DeliveryDelay; + public uint PurchasedItemDeliveryDelay; + public uint CancelledItemDeliveryDelay; public bool OpenForBusiness = true; public AuctionHelloResponse() : base(ServerOpcodes.AuctionHelloResponse) { } @@ -525,7 +526,8 @@ namespace Game.Networking.Packets public override void Write() { _worldPacket.WritePackedGuid(Guid); - _worldPacket.WriteUInt32(DeliveryDelay); + _worldPacket.WriteUInt32(PurchasedItemDeliveryDelay); + _worldPacket.WriteUInt32(CancelledItemDeliveryDelay); _worldPacket.WriteBit(OpenForBusiness); _worldPacket.FlushBits(); } diff --git a/Source/Game/Networking/Packets/AuthenticationPackets.cs b/Source/Game/Networking/Packets/AuthenticationPackets.cs index f2b58eaa5..967d5236d 100644 --- a/Source/Game/Networking/Packets/AuthenticationPackets.cs +++ b/Source/Game/Networking/Packets/AuthenticationPackets.cs @@ -133,6 +133,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(SuccessInfo.NumPlayersHorde.HasValue); _worldPacket.WriteBit(SuccessInfo.NumPlayersAlliance.HasValue); _worldPacket.WriteBit(SuccessInfo.ExpansionTrialExpiration.HasValue); + _worldPacket.WriteBit(SuccessInfo.NewBuildKeys != null); _worldPacket.FlushBits(); { @@ -155,6 +156,15 @@ namespace Game.Networking.Packets if(SuccessInfo.ExpansionTrialExpiration.HasValue) _worldPacket.WriteInt64(SuccessInfo.ExpansionTrialExpiration.Value); + if (SuccessInfo.NewBuildKeys != null) + { + for (int i = 0; i < 16; ++i) + { + _worldPacket.WriteUInt8(SuccessInfo.NewBuildKeys.NewBuildKey[i]); + _worldPacket.WriteUInt8(SuccessInfo.NewBuildKeys.SomeKey[i]); + } + } + foreach (VirtualRealmInfo virtualRealm in SuccessInfo.VirtualRealms) virtualRealm.Write(_worldPacket); @@ -208,6 +218,7 @@ namespace Game.Networking.Packets public ushort? NumPlayersHorde; // number of horde players in this realm. @todo implement public ushort? NumPlayersAlliance; // number of alliance players in this realm. @todo implement public long? ExpansionTrialExpiration; // expansion trial expiration unix timestamp + public NewBuild NewBuildKeys; public struct GameTime { @@ -216,6 +227,12 @@ namespace Game.Networking.Packets public uint Unknown735; public bool InGameRoom; } + + public class NewBuild + { + public Array NewBuildKey = new Array(16); + public Array SomeKey = new Array(16); + } } } diff --git a/Source/Game/Networking/Packets/BattleGroundPackets.cs b/Source/Game/Networking/Packets/BattleGroundPackets.cs index 8f9b0b4a9..b0faafcb7 100644 --- a/Source/Game/Networking/Packets/BattleGroundPackets.cs +++ b/Source/Game/Networking/Packets/BattleGroundPackets.cs @@ -485,15 +485,8 @@ namespace Game.Networking.Packets DeserterPenalty.Write(_worldPacket); } - public enum MatchState - { - InProgress = 1, - Complete = 3, - Inactive = 4 - } - public uint MapID; - public MatchState State = MatchState.Inactive; + public PVPMatchState State = PVPMatchState.Inactive; public long StartTime; public int Duration; public RatedMatchDeserterPenalty DeserterPenalty; @@ -503,6 +496,21 @@ namespace Game.Networking.Packets public bool AffectsRating; } + class PVPMatchSetState : ServerPacket + { + public PVPMatchSetState(PVPMatchState state) : base(ServerOpcodes.PvpMatchSetState) + { + State = state; + } + + public override void Write() + { + _worldPacket.WriteUInt8((byte)State); + } + + PVPMatchState State; + } + class PVPMatchComplete : ServerPacket { public PVPMatchComplete() : base(ServerOpcodes.PvpMatchComplete, ConnectionType.Instance) { } @@ -685,7 +693,7 @@ namespace Game.Networking.Packets data.WriteUInt32(HealingDone); data.WriteInt32(Stats.Count); data.WriteInt32(PrimaryTalentTree); - data.WriteInt32(Sex); + data.WriteInt8(Sex); data.WriteUInt32((uint)PlayerRace); data.WriteInt32(PlayerClass); data.WriteInt32(CreatureID); @@ -738,7 +746,7 @@ namespace Game.Networking.Packets public uint? PostMatchMMR; public List Stats = new(); public int PrimaryTalentTree; - public int Sex; + public sbyte Sex; public Race PlayerRace; public int PlayerClass; public int CreatureID; diff --git a/Source/Game/Networking/Packets/CharacterPackets.cs b/Source/Game/Networking/Packets/CharacterPackets.cs index 5b6bb8e5d..faecb7865 100644 --- a/Source/Game/Networking/Packets/CharacterPackets.cs +++ b/Source/Game/Networking/Packets/CharacterPackets.cs @@ -868,6 +868,7 @@ namespace Game.Networking.Packets var customizationCount = _worldPacket.ReadUInt32(); NewSex = _worldPacket.ReadUInt8(); CustomizedRace = _worldPacket.ReadInt32(); + CustomizedChrModelID = _worldPacket.ReadInt32(); for (var i = 0; i < customizationCount; ++i) { @@ -884,6 +885,7 @@ namespace Game.Networking.Packets public byte NewSex; public Array Customizations = new(125); public int CustomizedRace; + public int CustomizedChrModelID; } public class BarberShopResult : ServerPacket diff --git a/Source/Game/Networking/Packets/CombatLogPackets.cs b/Source/Game/Networking/Packets/CombatLogPackets.cs index 537c006e7..62fa99ebd 100644 --- a/Source/Game/Networking/Packets/CombatLogPackets.cs +++ b/Source/Game/Networking/Packets/CombatLogPackets.cs @@ -62,6 +62,11 @@ namespace Game.Networking.Packets _worldPacket.WriteInt32(Absorbed); _worldPacket.WriteInt32(Resisted); _worldPacket.WriteInt32(ShieldBlock); + _worldPacket.WriteInt32(WorldTextViewers.Count); + _worldPacket.WriteInt32(Supporters.Count); + + foreach (SpellSupportInfo supportInfo in Supporters) + supportInfo.Write(_worldPacket); _worldPacket.WriteBit(Periodic); _worldPacket.WriteBits(Flags, 7); @@ -69,6 +74,10 @@ namespace Game.Networking.Packets WriteLogDataBit(); _worldPacket.WriteBit(ContentTuning != null); FlushBits(); + + foreach (CombatWorldTextViewerInfo worldTextViewer in WorldTextViewers) + worldTextViewer.Write(_worldPacket); + WriteLogData(); if (ContentTuning != null) ContentTuning.Write(_worldPacket); @@ -90,6 +99,8 @@ namespace Game.Networking.Packets public int Flags; // Optional DebugInfo; public ContentTuningParams ContentTuning; + public List WorldTextViewers = new(); + public List Supporters = new(); } class EnvironmentalDamageLog : CombatLogServerPacket @@ -193,6 +204,10 @@ namespace Game.Networking.Packets _worldPacket.WriteInt32(OriginalHeal); _worldPacket.WriteUInt32(OverHeal); _worldPacket.WriteUInt32(Absorbed); + _worldPacket.WriteInt32(Supporters.Count); + + foreach (SpellSupportInfo supportInfo in Supporters) + supportInfo.Write(_worldPacket); _worldPacket.WriteBit(Crit); @@ -225,6 +240,7 @@ namespace Game.Networking.Packets public float? CritRollMade; public float? CritRollNeeded; public ContentTuningParams ContentTuning; + public List Supporters = new(); } class SpellPeriodicAuraLog : CombatLogServerPacket @@ -267,6 +283,10 @@ namespace Game.Networking.Packets data.WriteUInt32(SchoolMaskOrPower); data.WriteUInt32(AbsorbedOrAmplitude); data.WriteUInt32(Resisted); + data.WriteInt32(Supporters.Count); + + foreach (SpellSupportInfo supportInfo in Supporters) + supportInfo.Write(data); data.WriteBit(Crit); data.WriteBit(DebugInfo.HasValue); @@ -293,6 +313,7 @@ namespace Game.Networking.Packets public bool Crit; public PeriodicalAuraLogEffectDebugInfo? DebugInfo; public ContentTuningParams ContentTuning; + public List Supporters = new(); } } @@ -594,6 +615,10 @@ namespace Game.Networking.Packets _worldPacket.WritePackedGuid(Caster); _worldPacket.WriteInt32(Absorbed); _worldPacket.WriteUInt32(OriginalDamage); + _worldPacket.WriteInt32(Supporters.Count); + + foreach (SpellSupportInfo supportInfo in Supporters) + supportInfo.Write(_worldPacket); _worldPacket.WriteBit(Unk); WriteLogDataBit(); @@ -610,6 +635,7 @@ namespace Game.Networking.Packets public int Absorbed; public uint OriginalDamage; public bool Unk; + public List Supporters = new(); } class SpellHealAbsorbLog : ServerPacket diff --git a/Source/Game/Networking/Packets/DuelPackets.cs b/Source/Game/Networking/Packets/DuelPackets.cs index e953a3667..32963c7d4 100644 --- a/Source/Game/Networking/Packets/DuelPackets.cs +++ b/Source/Game/Networking/Packets/DuelPackets.cs @@ -14,9 +14,11 @@ namespace Game.Networking.Packets public override void Read() { TargetGUID = _worldPacket.ReadPackedGuid(); + ToTheDeath = _worldPacket.HasBit(); } public ObjectGuid TargetGUID; + public bool ToTheDeath; } public class CanDuelResult : ServerPacket @@ -85,11 +87,14 @@ namespace Game.Networking.Packets _worldPacket.WritePackedGuid(ArbiterGUID); _worldPacket.WritePackedGuid(RequestedByGUID); _worldPacket.WritePackedGuid(RequestedByWowAccount); + _worldPacket.WriteBit(ToTheDeath); + _worldPacket.FlushBits(); } public ObjectGuid ArbiterGUID; public ObjectGuid RequestedByGUID; public ObjectGuid RequestedByWowAccount; + public bool ToTheDeath; } public class DuelResponse : ClientPacket diff --git a/Source/Game/Networking/Packets/GuildPackets.cs b/Source/Game/Networking/Packets/GuildPackets.cs index 7aff26823..b6c1eb6aa 100644 --- a/Source/Game/Networking/Packets/GuildPackets.cs +++ b/Source/Game/Networking/Packets/GuildPackets.cs @@ -4,6 +4,7 @@ using Framework.Constants; using Framework.Dynamic; using Game.Entities; +using Game.Miscellaneous; using System; using System.Collections.Generic; @@ -1705,12 +1706,20 @@ namespace Game.Networking.Packets public class GuildRewardItem { + public uint ItemID; + public uint Unk4; + public List AchievementsRequired = new(); + public RaceMask RaceMask; + public int MinGuildLevel; + public int MinGuildRep; + public ulong Cost; + public void Write(WorldPacket data) { data.WriteUInt32(ItemID); data.WriteUInt32(Unk4); data.WriteInt32(AchievementsRequired.Count); - data.WriteUInt64(RaceMask); + data.WriteUInt64(RaceMask.RawValue); data.WriteInt32(MinGuildLevel); data.WriteInt32(MinGuildRep); data.WriteUInt64(Cost); @@ -1718,14 +1727,6 @@ namespace Game.Networking.Packets foreach (var achievementId in AchievementsRequired) data.WriteUInt32(achievementId); } - - public uint ItemID; - public uint Unk4; - public List AchievementsRequired = new(); - public ulong RaceMask; - public int MinGuildLevel; - public int MinGuildRep; - public ulong Cost; } public class GuildBankItemInfo diff --git a/Source/Game/Networking/Packets/ItemPackets.cs b/Source/Game/Networking/Packets/ItemPackets.cs index b3569c551..cb32e89c4 100644 --- a/Source/Game/Networking/Packets/ItemPackets.cs +++ b/Source/Game/Networking/Packets/ItemPackets.cs @@ -38,8 +38,8 @@ namespace Game.Networking.Packets Quantity = _worldPacket.ReadInt32(); Muid = _worldPacket.ReadUInt32(); Slot = _worldPacket.ReadUInt32(); + ItemType = (ItemVendorType)_worldPacket.ReadInt32(); Item.Read(_worldPacket); - ItemType = (ItemVendorType)_worldPacket.ReadBits(3); } public ObjectGuid VendorGUID; diff --git a/Source/Game/Networking/Packets/MailPackets.cs b/Source/Game/Networking/Packets/MailPackets.cs index 23aa4104c..5311f9d10 100644 --- a/Source/Game/Networking/Packets/MailPackets.cs +++ b/Source/Game/Networking/Packets/MailPackets.cs @@ -250,6 +250,10 @@ namespace Game.Networking.Packets case MailMessageType.Creature: case MailMessageType.Gameobject: case MailMessageType.Calendar: + case MailMessageType.Blackmarket: + case MailMessageType.CommerceAuction: + case MailMessageType.Auction2: + case MailMessageType.ArtisansConsortium: AltSenderID = (int)mail.sender; break; } @@ -353,7 +357,7 @@ namespace Game.Networking.Packets public MailListEntry(Mail mail, Player player) { MailID = mail.messageID; - SenderType = (byte)mail.messageType; + SenderType = mail.messageType; switch (mail.messageType) { @@ -364,6 +368,10 @@ namespace Game.Networking.Packets case MailMessageType.Gameobject: case MailMessageType.Auction: case MailMessageType.Calendar: + case MailMessageType.Blackmarket: + case MailMessageType.CommerceAuction: + case MailMessageType.Auction2: + case MailMessageType.ArtisansConsortium: AltSenderID = (uint)mail.sender; break; } @@ -388,7 +396,7 @@ namespace Game.Networking.Packets public void Write(WorldPacket data) { data.WriteUInt64(MailID); - data.WriteUInt8(SenderType); + data.WriteUInt32((uint)SenderType); data.WriteUInt64(Cod); data.WriteInt32(StationeryID); data.WriteUInt64(SentMoney); @@ -397,28 +405,39 @@ namespace Game.Networking.Packets data.WriteInt32(MailTemplateID); data.WriteInt32(Attachments.Count); - data.WriteBit(SenderCharacter.HasValue); - data.WriteBit(AltSenderID.HasValue); + switch (SenderType) + { + case MailMessageType.Normal: + data.WritePackedGuid(SenderCharacter); + break; + case MailMessageType.Auction: + case MailMessageType.Creature: + case MailMessageType.Gameobject: + case MailMessageType.Calendar: + case MailMessageType.Blackmarket: + case MailMessageType.CommerceAuction: + case MailMessageType.Auction2: + case MailMessageType.ArtisansConsortium: + data.WriteUInt32(AltSenderID); + break; + default: + break; + } + data.WriteBits(Subject.GetByteCount(), 8); data.WriteBits(Body.GetByteCount(), 13); data.FlushBits(); Attachments.ForEach(p => p.Write(data)); - if (SenderCharacter.HasValue) - data.WritePackedGuid(SenderCharacter.Value); - - if (AltSenderID.HasValue) - data.WriteUInt32(AltSenderID.Value); - data.WriteString(Subject); data.WriteString(Body); } public ulong MailID; - public byte SenderType; - public ObjectGuid? SenderCharacter; - public uint? AltSenderID; + public MailMessageType SenderType; + public ObjectGuid SenderCharacter; + public uint AltSenderID; public ulong Cod; public int StationeryID; public ulong SentMoney; diff --git a/Source/Game/Networking/Packets/MiscPackets.cs b/Source/Game/Networking/Packets/MiscPackets.cs index 94d9ae311..33efef8f1 100644 --- a/Source/Game/Networking/Packets/MiscPackets.cs +++ b/Source/Game/Networking/Packets/MiscPackets.cs @@ -1338,7 +1338,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(BonusRoll); Item.Write(_worldPacket); _worldPacket.WriteInt32(LootSpec); - _worldPacket.WriteInt32((int)Gender); + _worldPacket.WriteInt8((sbyte)Gender); break; case DisplayToastType.NewCurrency: _worldPacket.WriteUInt32(CurrencyID); diff --git a/Source/Game/Networking/Packets/NPCPackets.cs b/Source/Game/Networking/Packets/NPCPackets.cs index db52acae7..c9b04f914 100644 --- a/Source/Game/Networking/Packets/NPCPackets.cs +++ b/Source/Game/Networking/Packets/NPCPackets.cs @@ -394,12 +394,12 @@ namespace Game.Networking.Packets { data.WriteUInt64(Price); data.WriteInt32(MuID); + data.WriteInt32(Type); data.WriteInt32(Durability); data.WriteInt32(StackCount); data.WriteInt32(Quantity); data.WriteInt32(ExtendedCostID); data.WriteInt32(PlayerConditionFailed); - data.WriteBits(Type, 3); data.WriteBit(Locked); data.WriteBit(DoNotFilterOnVendor); data.WriteBit(Refundable); diff --git a/Source/Game/Networking/Packets/PetPackets.cs b/Source/Game/Networking/Packets/PetPackets.cs index d8e30318b..81b709b06 100644 --- a/Source/Game/Networking/Packets/PetPackets.cs +++ b/Source/Game/Networking/Packets/PetPackets.cs @@ -124,32 +124,6 @@ namespace Game.Networking.Packets public List SpellHistory = new(); } - class PetStableList : ServerPacket - { - public PetStableList() : base(ServerOpcodes.PetStableList, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(StableMaster); - - _worldPacket.WriteInt32(Pets.Count); - foreach (PetStableInfo pet in Pets) - { - _worldPacket.WriteUInt32(pet.PetSlot); - _worldPacket.WriteUInt32(pet.PetNumber); - _worldPacket.WriteUInt32(pet.CreatureID); - _worldPacket.WriteUInt32(pet.DisplayID); - _worldPacket.WriteUInt32(pet.ExperienceLevel); - _worldPacket.WriteUInt8((byte)pet.PetFlags); - _worldPacket.WriteBits(pet.PetName.GetByteCount(), 8); - _worldPacket.WriteString(pet.PetName); - } - } - - public ObjectGuid StableMaster; - public List Pets = new(); - } - class PetStableResult : ServerPacket { public PetStableResult() : base(ServerOpcodes.PetStableResult, ConnectionType.Instance) { } @@ -382,17 +356,6 @@ namespace Game.Networking.Packets public sbyte ConsumedCharges; } - struct PetStableInfo - { - public uint PetSlot; - public uint PetNumber; - public uint CreatureID; - public uint DisplayID; - public uint ExperienceLevel; - public PetStableinfo PetFlags; - public string PetName; - } - struct PetRenameData { public ObjectGuid PetGUID; diff --git a/Source/Game/Networking/Packets/QuestPackets.cs b/Source/Game/Networking/Packets/QuestPackets.cs index f914689f3..caa6249a9 100644 --- a/Source/Game/Networking/Packets/QuestPackets.cs +++ b/Source/Game/Networking/Packets/QuestPackets.cs @@ -4,6 +4,7 @@ using Framework.Constants; using Framework.Dynamic; using Game.Entities; +using Game.Miscellaneous; using System; using System.Collections.Generic; @@ -53,7 +54,7 @@ namespace Game.Networking.Packets public override void Write() { _worldPacket.WritePackedGuid(QuestGiver.Guid); - _worldPacket.WriteUInt32((uint)QuestGiver.Status); + _worldPacket.WriteUInt64((ulong)QuestGiver.Status); } public QuestGiverInfo QuestGiver; @@ -69,7 +70,7 @@ namespace Game.Networking.Packets foreach (QuestGiverInfo questGiver in QuestGiver) { _worldPacket.WritePackedGuid(questGiver.Guid); - _worldPacket.WriteUInt32((uint)questGiver.Status); + _worldPacket.WriteUInt64((ulong)questGiver.Status); } } @@ -190,10 +191,10 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(Info.CompleteSoundKitID); _worldPacket.WriteUInt32(Info.AreaGroupID); - _worldPacket.WriteUInt32(Info.TimeAllowed); + _worldPacket.WriteInt64(Info.TimeAllowed); _worldPacket.WriteInt32(Info.Objectives.Count); - _worldPacket.WriteInt64(Info.AllowableRaces); + _worldPacket.WriteUInt64(Info.AllowableRaces.RawValue); _worldPacket.WriteInt32(Info.TreasurePickerID); _worldPacket.WriteInt32(Info.Expansion); _worldPacket.WriteInt32(Info.ManagedWorldStateID); @@ -1037,7 +1038,7 @@ namespace Game.Networking.Packets public float POIx; public float POIy; public uint POIPriority; - public long AllowableRaces = -1; + public RaceMask AllowableRaces = new (0xFFFFFFFFFFFFFFFF); public string LogTitle; public string LogDescription; public string QuestDescription; @@ -1059,7 +1060,7 @@ namespace Game.Networking.Packets public uint AcceptedSoundKitID; public uint CompleteSoundKitID; public uint AreaGroupID; - public uint TimeAllowed; + public long TimeAllowed; public int TreasurePickerID; public int Expansion; public int ManagedWorldStateID; diff --git a/Source/Game/Networking/Packets/ScenarioPackets.cs b/Source/Game/Networking/Packets/ScenarioPackets.cs index 53dfd2da6..a30072d07 100644 --- a/Source/Game/Networking/Packets/ScenarioPackets.cs +++ b/Source/Game/Networking/Packets/ScenarioPackets.cs @@ -10,10 +10,25 @@ namespace Game.Networking.Packets { class ScenarioState : ServerPacket { + public ObjectGuid ScenarioGUID; + public int ScenarioID; + public int CurrentStep = -1; + public uint DifficultyID; + public uint WaveCurrent; + public uint WaveMax; + public uint TimerDuration; + public List CriteriaProgress = new(); + public List BonusObjectives = new(); + public List PickedSteps = new(); + public List Spells = new(); + public ObjectGuid PlayerGUID; + public bool ScenarioComplete; + public ScenarioState() : base(ServerOpcodes.ScenarioState, ConnectionType.Instance) { } public override void Write() { + _worldPacket.WritePackedGuid(ScenarioGUID); _worldPacket.WriteInt32(ScenarioID); _worldPacket.WriteInt32(CurrentStep); _worldPacket.WriteUInt32(DifficultyID); @@ -41,35 +56,24 @@ namespace Game.Networking.Packets foreach (ScenarioSpellUpdate spell in Spells) spell.Write(_worldPacket); } - - public int ScenarioID; - public int CurrentStep = -1; - public uint DifficultyID; - public uint WaveCurrent; - public uint WaveMax; - public uint TimerDuration; - public List CriteriaProgress = new(); - public List BonusObjectives = new(); - public List PickedSteps = new(); - public List Spells = new(); - public ObjectGuid PlayerGUID; - public bool ScenarioComplete = false; } class ScenarioProgressUpdate : ServerPacket { + public CriteriaProgressPkt CriteriaProgress; + public ScenarioProgressUpdate() : base(ServerOpcodes.ScenarioProgressUpdate, ConnectionType.Instance) { } public override void Write() { CriteriaProgress.Write(_worldPacket); } - - public CriteriaProgressPkt CriteriaProgress; } class ScenarioCompleted : ServerPacket { + public uint ScenarioID; + public ScenarioCompleted(uint scenarioId) : base(ServerOpcodes.ScenarioCompleted, ConnectionType.Instance) { ScenarioID = scenarioId; @@ -79,29 +83,31 @@ namespace Game.Networking.Packets { _worldPacket.WriteUInt32(ScenarioID); } - - public uint ScenarioID; } class ScenarioVacate : ServerPacket { + public ObjectGuid ScenarioGUID; + public int ScenarioID; + public int Unk1; + public byte Unk2; + public ScenarioVacate() : base(ServerOpcodes.ScenarioVacate, ConnectionType.Instance) { } public override void Write() { + _worldPacket.WritePackedGuid(ScenarioGUID); _worldPacket.WriteInt32(ScenarioID); _worldPacket.WriteInt32(Unk1); _worldPacket.WriteBits(Unk2, 2); _worldPacket.FlushBits(); } - - public int ScenarioID; - public int Unk1; - public byte Unk2; } class QueryScenarioPOI : ClientPacket { + public Array MissingScenarioPOIs = new(50); + public QueryScenarioPOI(WorldPacket packet) : base(packet) { } public override void Read() @@ -110,12 +116,12 @@ namespace Game.Networking.Packets for (var i = 0; i < count; ++i) MissingScenarioPOIs[i] = _worldPacket.ReadInt32(); } - - public Array MissingScenarioPOIs = new(50); } class ScenarioPOIs : ServerPacket { + public List ScenarioPOIDataStats = new(); + public ScenarioPOIs() : base(ServerOpcodes.ScenarioPois) { } public override void Write() @@ -148,34 +154,32 @@ namespace Game.Networking.Packets } } } - - public List ScenarioPOIDataStats = new(); } struct BonusObjectiveData { + public int BonusObjectiveID; + public bool ObjectiveComplete; + public void Write(WorldPacket data) { data.WriteInt32(BonusObjectiveID); data.WriteBit(ObjectiveComplete); data.FlushBits(); } - - public int BonusObjectiveID; - public bool ObjectiveComplete; } class ScenarioSpellUpdate { + public uint SpellID; + public bool Usable = true; + public void Write(WorldPacket data) { data.WriteUInt32(SpellID); data.WriteBit(Usable); data.FlushBits(); } - - public uint SpellID; - public bool Usable = true; } struct ScenarioPOIData diff --git a/Source/Game/Networking/Packets/SpellPackets.cs b/Source/Game/Networking/Packets/SpellPackets.cs index c65ae7621..2a6e7ae0d 100644 --- a/Source/Game/Networking/Packets/SpellPackets.cs +++ b/Source/Game/Networking/Packets/SpellPackets.cs @@ -1371,6 +1371,43 @@ namespace Game.Networking.Packets } } + struct CombatWorldTextViewerInfo + { + public ObjectGuid ViewerGUID; + public byte? ColorType; + public byte? ScaleType; + + public void Write(WorldPacket data) + { + data.WritePackedGuid(ViewerGUID); + data.WriteBit(ColorType.HasValue); + data.WriteBit(ScaleType.HasValue); + data.FlushBits(); + + if (ColorType.HasValue) + data.WriteUInt8(ColorType.Value); + + if (ScaleType.HasValue) + data.WriteUInt8(ScaleType.Value); + } + } + + public struct SpellSupportInfo + { + public ObjectGuid CasterGUID; + public int SpellID; + public int Amount; + public float Percentage; + + public void Write(WorldPacket data) + { + data.WritePackedGuid(CasterGUID); + data.WriteInt32(SpellID); + data.WriteInt32(Amount); + data.WriteFloat(Percentage); + } + } + public struct SpellCastVisual { public uint SpellXSpellVisualID; diff --git a/Source/Game/Networking/Packets/SystemPackets.cs b/Source/Game/Networking/Packets/SystemPackets.cs index 5a5f3030d..6bca6fcb3 100644 --- a/Source/Game/Networking/Packets/SystemPackets.cs +++ b/Source/Game/Networking/Packets/SystemPackets.cs @@ -84,6 +84,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(LFGListCustomRequiresAuthenticator); _worldPacket.WriteBit(AddonsDisabled); _worldPacket.WriteBit(Unused1000); + _worldPacket.WriteBit(ContentTrackingEnabled); _worldPacket.FlushBits(); @@ -176,6 +177,7 @@ namespace Game.Networking.Packets public bool LFGListCustomRequiresAuthenticator; public bool AddonsDisabled; public bool Unused1000; + public bool ContentTrackingEnabled; public SocialQueueConfig QuickJoinConfig; public SquelchInfo Squelch; diff --git a/Source/Game/Networking/Packets/WhoPackets.cs b/Source/Game/Networking/Packets/WhoPackets.cs index c0c64f501..dba782179 100644 --- a/Source/Game/Networking/Packets/WhoPackets.cs +++ b/Source/Game/Networking/Packets/WhoPackets.cs @@ -4,6 +4,7 @@ using Framework.Constants; using Framework.Dynamic; using Game.Entities; +using Game.Miscellaneous; using System; using System.Collections.Generic; @@ -91,7 +92,7 @@ namespace Game.Networking.Packets { MinLevel = data.ReadInt32(); MaxLevel = data.ReadInt32(); - RaceFilter = data.ReadInt64(); + RaceFilter = new RaceMask(data.ReadInt64()); ClassFilter = data.ReadInt32(); uint nameLength = data.ReadBits(6); @@ -129,7 +130,7 @@ namespace Game.Networking.Packets public string VirtualRealmName; public string Guild; public string GuildVirtualRealmName; - public long RaceFilter; + public RaceMask RaceFilter; public int ClassFilter = -1; public List Words = new(); public bool ShowEnemies; diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index b0dda2672..e16fb1160 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -6,6 +6,7 @@ using Framework.Constants; using Framework.Database; using Game.DataStorage; using Game.Entities; +using Game.Miscellaneous; using Game.Networking.Packets; using System; using System.Collections; @@ -101,7 +102,7 @@ namespace Game SoundTurnIn = fields.Read(99); AreaGroupID = fields.Read(100); LimitTime = fields.Read(101); - AllowableRaces = (long)fields.Read(102); + AllowableRaces = new(fields.Read(102)); TreasurePickerID = fields.Read(103); Expansion = fields.Read(104); ManagedWorldStateID = fields.Read(105); @@ -472,6 +473,15 @@ namespace Game return null; } + public bool IsImportant() + { + var questInfo = CliDB.QuestInfoStorage.LookupByKey(QuestInfoID); + if (questInfo != null) + return (questInfo.Modifiers & 0x400) != 0; + + return false; + } + public void BuildQuestRewards(QuestRewards rewards, Player player) { rewards.ChoiceItemCount = GetRewChoiceItemsCount(); @@ -864,8 +874,8 @@ namespace Game public uint SoundAccept { get; set; } public uint SoundTurnIn { get; set; } public uint AreaGroupID; - public uint LimitTime; - public long AllowableRaces { get; set; } + public long LimitTime; + public RaceMask AllowableRaces { get; set; } public int TreasurePickerID; public int Expansion; public int ManagedWorldStateID; @@ -946,6 +956,7 @@ namespace Game { public ushort Slot = SharedConst.MaxQuestLogSize; public QuestStatus Status; + public long AcceptTime; public uint Timer; public bool Explored; } diff --git a/Source/Game/Reputation/ReputationManager.cs b/Source/Game/Reputation/ReputationManager.cs index dfd140ed0..3f89e91e9 100644 --- a/Source/Game/Reputation/ReputationManager.cs +++ b/Source/Game/Reputation/ReputationManager.cs @@ -5,6 +5,7 @@ using Framework.Constants; using Framework.Database; using Game.DataStorage; using Game.Entities; +using Game.Miscellaneous; using Game.Networking.Packets; using System; using System.Collections.Generic; @@ -593,7 +594,7 @@ namespace Game var factionEntry = CliDB.FactionStorage.LookupByKey(factionTemplateEntry.Faction); if (factionEntry.Id != 0) // Never show factions of the opposing team - if (!Convert.ToBoolean(factionEntry.ReputationRaceMask[1] & SharedConst.GetMaskForRace(_player.GetRace())) && factionEntry.ReputationBase[1] == SharedConst.ReputationBottom) + if (!(new RaceMask(factionEntry.ReputationRaceMask[1]).HasRace(_player.GetRace()) && factionEntry.ReputationBase[1] == SharedConst.ReputationBottom)) SetVisible(factionEntry); } @@ -798,13 +799,12 @@ namespace Game if (factionEntry == null) return -1; - long raceMask = SharedConst.GetMaskForRace(_player.GetRace()); short classMask = (short)_player.GetClassMask(); + for (int i = 0; i < 4; i++) { - if ((factionEntry.ReputationRaceMask[i].HasAnyFlag(raceMask) || (factionEntry.ReputationRaceMask[i] == 0 && factionEntry.ReputationClassMask[i] != 0)) - && (factionEntry.ReputationClassMask[i].HasAnyFlag(classMask) || factionEntry.ReputationClassMask[i] == 0)) - + var raceMask = new RaceMask(factionEntry.ReputationRaceMask[i]); + if ((raceMask.HasRace(_player.GetRace()) || (raceMask.IsEmpty() && factionEntry.ReputationClassMask[i] != 0)) && (factionEntry.ReputationClassMask[i].HasAnyFlag(classMask) || factionEntry.ReputationClassMask[i] == 0)) return i; } @@ -862,13 +862,12 @@ namespace Game if (factionEntry == null) return 0; - long raceMask = SharedConst.GetMaskForRace(race); uint classMask = (1u << ((int)playerClass - 1)); for (int i = 0; i < 4; i++) { - if ((factionEntry.ReputationClassMask[i] == 0 || factionEntry.ReputationClassMask[i].HasAnyFlag((short)classMask)) - && (factionEntry.ReputationRaceMask[i] == 0 || factionEntry.ReputationRaceMask[i].HasAnyFlag(raceMask))) + var raceMask = new RaceMask(factionEntry.ReputationRaceMask[i]); + if ((factionEntry.ReputationClassMask[i] == 0 || factionEntry.ReputationClassMask[i].HasAnyFlag((short)classMask)) && (raceMask.IsEmpty() || raceMask.HasRace(race))) return factionEntry.ReputationBase[i]; } diff --git a/Source/Game/Scenarios/Scenario.cs b/Source/Game/Scenarios/Scenario.cs index 2b3725525..73bcd000c 100644 --- a/Source/Game/Scenarios/Scenario.cs +++ b/Source/Game/Scenarios/Scenario.cs @@ -19,6 +19,7 @@ namespace Game.Scenarios { _map = map; _data = scenarioData; + _guid = ObjectGuid.Create(HighGuid.Scenario, map.GetId(), scenarioData.Entry.Id, map.GenerateLowGuid(HighGuid.Scenario)); _currentstep = null; //ASSERT(_data); @@ -229,6 +230,7 @@ namespace Game.Scenarios void BuildScenarioState(ScenarioState scenarioState) { + scenarioState.ScenarioGUID = _guid; scenarioState.ScenarioID = (int)_data.Entry.Id; ScenarioStepRecord step = GetStep(); if (step != null) @@ -343,6 +345,7 @@ namespace Game.Scenarios void SendBootPlayer(Player player) { ScenarioVacate scenarioBoot = new(); + scenarioBoot.ScenarioGUID = _guid; scenarioBoot.ScenarioID = (int)_data.Entry.Id; player.SendPacket(scenarioBoot); } @@ -362,6 +365,7 @@ namespace Game.Scenarios protected Map _map; List _players = new(); protected ScenarioData _data; + ObjectGuid _guid; ScenarioStepRecord _currentstep; Dictionary _stepStates = new(); } diff --git a/Source/Game/Server/WorldSession.cs b/Source/Game/Server/WorldSession.cs index 64b482f0f..6162f8a9a 100644 --- a/Source/Game/Server/WorldSession.cs +++ b/Source/Game/Server/WorldSession.cs @@ -702,7 +702,7 @@ namespace Game _queryHolderProcessor.ProcessReadyCallbacks(); } - TransactionCallback AddTransactionCallback(TransactionCallback callback) + public TransactionCallback AddTransactionCallback(TransactionCallback callback) { return _transactionCallbacks.AddCallback(callback); } diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index 379c818c8..fc7968131 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -4841,7 +4841,7 @@ namespace Game.Spells return; if (apply) - target.ToPlayer().GetSession().SendStablePet(target.GetGUID()); + target.ToPlayer().SetStableMaster(target.GetGUID()); // client auto close stable dialog at !apply aura } @@ -5959,6 +5959,28 @@ namespace Game.Spells playerTarget.SendMovementSetCollisionHeight(playerTarget.GetCollisionHeight(), UpdateCollisionHeightReason.Force); } + [AuraEffectHandler(AuraType.ModRequiredMountCapabilityFlags)] + void HandleModRequiredMountCapabilityFlags(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply) + { + if (!mode.HasAnyFlag(AuraEffectHandleModes.Real)) + return; + + Player playerTarget = aurApp.GetTarget().ToPlayer(); + if (playerTarget == null) + return; + + if (apply) + playerTarget.SetRequiredMountCapabilityFlag((byte)GetMiscValue()); + else + { + int mountCapabilityFlags = 0; + foreach (AuraEffect otherAura in playerTarget.GetAuraEffectsByType(GetAuraType())) + mountCapabilityFlags |= otherAura.GetMiscValue(); + + playerTarget.ReplaceAllRequiredMountCapabilityFlags((byte)mountCapabilityFlags); + } + } + [AuraEffectHandler(AuraType.SuppressItemPassiveEffectBySpellLabel)] void HandleSuppressItemPassiveEffectBySpellLabel(AuraApplication aurApp, AuraEffectHandleModes mode, bool apply) { diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index a46dce1e6..8f771b667 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4829,7 +4829,7 @@ namespace Game.Spells if (m_spellInfo.ExcludeCasterAuraType != 0 && unitCaster.HasAuraType(m_spellInfo.ExcludeCasterAuraType)) return SpellCastResult.CasterAurastate; - if (reqCombat && unitCaster.IsInCombat() && !m_spellInfo.CanBeUsedInCombat()) + if (reqCombat && unitCaster.IsInCombat() && !m_spellInfo.CanBeUsedInCombat(unitCaster)) return SpellCastResult.AffectingCombat; } diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index 4a3fcbfae..924908948 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -518,9 +518,10 @@ namespace Game.Spells return false; } - public bool CanBeUsedInCombat() + public bool CanBeUsedInCombat(Unit caster) { - return !HasAttribute(SpellAttr0.NotInCombatOnlyPeaceful); + return !HasAttribute(SpellAttr0.NotInCombatOnlyPeaceful) + || (caster.HasAuraType(AuraType.AllowMountInCombat) && HasAura(AuraType.Mounted)); } public bool IsPositive() @@ -3144,7 +3145,7 @@ namespace Game.Spells } case SpellProcsPerMinuteModType.Race: { - if (SharedConst.GetMaskForRace(caster.GetRace()).HasAnyFlag((int)mod.Param)) + if ((caster.GetRaceMask() & mod.Param) != 0) ppm *= 1.0f + mod.Coeff; break; } @@ -4822,15 +4823,16 @@ namespace Game.Spells new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 303 SPELL_EFFECT_CREATE_TRAIT_TREE_CONFIG new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 304 SPELL_EFFECT_CHANGE_ACTIVE_COMBAT_TRAIT_CONFIG new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 305 SPELL_EFFECT_305 - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 306 SPELL_EFFECT_306 + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 306 SPELL_EFFECT_UPDATE_INTERACTIONS new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 307 SPELL_EFFECT_307 - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 308 SPELL_EFFECT_308 - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 309 SPELL_EFFECT_309 + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 308 SPELL_EFFECT_CANCEL_PRELOAD_WORLD + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 309 SPELL_EFFECT_PRELOAD_WORLD new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 310 SPELL_EFFECT_310 - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 311 SPELL_EFFECT_311 + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 311 SPELL_EFFECT_ENSURE_WORLD_LOADED new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 312 SPELL_EFFECT_312 - new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 313 SPELL_EFFECT_313 - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 314 SPELL_EFFECT_314 + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 313 SPELL_EFFECT_CHANGE_ITEM_BONUSES_2 + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 314 SPELL_EFFECT_ADD_SOCKET_BONUS + new StaticData(SpellEffectImplicitTargetTypes.Caster, SpellTargetObjectTypes.Unit), // 315 SPELL_EFFECT_LEARN_TRANSMOG_APPEARANCE_FROM_ITEM_MOD_APPEARANCE_GROUP }; #region Fields diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index e301fa682..2659aa8f4 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -8,6 +8,7 @@ using Game.BattleFields; using Game.BattleGrounds; using Game.BattlePets; using Game.DataStorage; +using Game.Miscellaneous; using Game.Movement; using Game.Spells; using System; @@ -1987,7 +1988,7 @@ namespace Game.Entities spellArea.questEndStatus = result.Read(4); spellArea.questEnd = result.Read(5); spellArea.auraSpell = result.Read(6); - spellArea.raceMask = result.Read(7); + spellArea.raceMask = new RaceMask(result.Read(7)); spellArea.gender = (Gender)result.Read(8); spellArea.flags = (SpellAreaFlag)result.Read(9); @@ -2016,7 +2017,7 @@ namespace Game.Entities continue; if (spellArea.auraSpell != bound.auraSpell) continue; - if ((spellArea.raceMask & bound.raceMask) == 0) + if ((spellArea.raceMask & bound.raceMask).IsEmpty()) continue; if (spellArea.gender != bound.gender) continue; @@ -2107,7 +2108,7 @@ namespace Game.Entities } } - if (spellArea.raceMask != 0 && (spellArea.raceMask & SharedConst.RaceMaskAllPlayable) == 0) + if (!spellArea.raceMask.IsEmpty() && (spellArea.raceMask & RaceMask.AllPlayable).IsEmpty()) { Log.outError(LogFilter.Sql, "Spell {0} listed in `spell_area` have wrong race mask ({1}) requirement", spell, spellArea.raceMask); continue; @@ -4913,7 +4914,7 @@ namespace Game.Entities public uint questStart; // quest start (quest must be active or rewarded for spell apply) public uint questEnd; // quest end (quest must not be rewarded for spell apply) public int auraSpell; // spell aura must be applied for spell apply)if possitive) and it must not be applied in other case - public ulong raceMask; // can be applied only to races + public RaceMask raceMask; // can be applied only to races public Gender gender; // can be applied only to gender public uint questStartStatus; // QuestStatus that quest_start must have in order to keep the spell public uint questEndStatus; // QuestStatus that the quest_end must have in order to keep the spell (if the quest_end's status is different than this, the spell will be dropped) @@ -4926,8 +4927,8 @@ namespace Game.Entities if (player == null || gender != player.GetNativeGender()) return false; - if (raceMask != 0) // not in expected race - if (player == null || !Convert.ToBoolean(raceMask & (ulong)SharedConst.GetMaskForRace(player.GetRace()))) + if (!raceMask.IsEmpty()) // not in expected race + if (player == null || !raceMask.HasRace(player.GetRace())) return false; if (areaId != 0) // not in expected zone