From 989b80b0563f68c0206c7deb9450b7a2d5668838 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 28 Dec 2022 15:25:15 -0500 Subject: [PATCH] Core: Updated to 10.0.2 Port From (https://github.com/TrinityCore/TrinityCore/commit/e98e1283ea0034baf6be9aa2ffb386eb5582801b) --- .../Framework/Constants/AchievementConst.cs | 23 +- .../Constants/Authentication/AuthConst.cs | 106 +- Source/Framework/Constants/CliDBConst.cs | 99 +- Source/Framework/Constants/GossipConst.cs | 40 +- Source/Framework/Constants/GroupConst.cs | 6 +- Source/Framework/Constants/ItemConst.cs | 137 +- Source/Framework/Constants/LootConst.cs | 11 + .../Constants/Movement/MovementFlags.cs | 2 + Source/Framework/Constants/Network/Opcodes.cs | 2196 ++++++++------- Source/Framework/Constants/PlayerConst.cs | 16 +- Source/Framework/Constants/SharedConst.cs | 2234 ++++++++------- .../Constants/Spells/SpellAuraConst.cs | 28 +- .../Framework/Constants/Spells/SpellConst.cs | 71 +- Source/Framework/Constants/UnitConst.cs | 3 +- .../Database/Databases/HotfixDatabase.cs | 131 +- Source/Game/Achievements/CriteriaHandler.cs | 113 +- Source/Game/AuctionHouse/AuctionManager.cs | 4 +- .../Game/BattleGrounds/BattleGroundManager.cs | 4 +- Source/Game/Conditions/ConditionManager.cs | 41 +- Source/Game/DataStorage/CliDB.cs | 26 +- Source/Game/DataStorage/DB2Manager.cs | 14 +- Source/Game/DataStorage/Structs/B_Records.cs | 7 +- Source/Game/DataStorage/Structs/C_Records.cs | 19 +- Source/Game/DataStorage/Structs/D_Records.cs | 1 - Source/Game/DataStorage/Structs/F_Records.cs | 20 +- Source/Game/DataStorage/Structs/G_Records.cs | 22 +- .../DataStorage/Structs/GameTablesRecords.cs | 5 + Source/Game/DataStorage/Structs/I_Records.cs | 7 +- Source/Game/DataStorage/Structs/J_Records.cs | 1 - Source/Game/DataStorage/Structs/M_Records.cs | 5 +- Source/Game/DataStorage/Structs/P_Records.cs | 17 +- Source/Game/DataStorage/Structs/Q_Records.cs | 3 +- Source/Game/DataStorage/Structs/S_Records.cs | 29 +- Source/Game/DataStorage/Structs/U_Records.cs | 1 + Source/Game/Entities/Corpse.cs | 7 +- Source/Game/Entities/Creature/Gossip.cs | 245 +- Source/Game/Entities/GameObject/GameObject.cs | 25 +- .../Entities/GameObject/GameObjectData.cs | 20 +- .../Entities/Item/AzeriteEmpoweredItem.cs | 2 +- Source/Game/Entities/Item/Item.cs | 42 +- .../Entities/Object/Update/UpdateField.cs | 25 + .../Entities/Object/Update/UpdateFields.cs | 2464 +++++++++++------ Source/Game/Entities/Object/WorldObject.cs | 51 +- .../Game/Entities/Player/CollectionManager.cs | 2 +- Source/Game/Entities/Player/Player.DB.cs | 27 +- Source/Game/Entities/Player/Player.Fields.cs | 1 + Source/Game/Entities/Player/Player.Items.cs | 94 +- Source/Game/Entities/Player/Player.Quest.cs | 9 - Source/Game/Entities/Player/Player.Spells.cs | 16 +- Source/Game/Entities/Player/Player.Talents.cs | 5 + Source/Game/Entities/Player/Player.cs | 280 +- Source/Game/Entities/StatSystem.cs | 12 +- Source/Game/Entities/Unit/Unit.Spells.cs | 5 + Source/Game/Globals/ObjectManager.cs | 264 +- Source/Game/Handlers/AuthenticationHandler.cs | 1 + Source/Game/Handlers/AzeriteHandler.cs | 6 +- Source/Game/Handlers/BankHandler.cs | 9 +- Source/Game/Handlers/BlackMarketHandlers.cs | 9 +- Source/Game/Handlers/CharacterHandler.cs | 100 +- Source/Game/Handlers/ItemHandler.cs | 4 +- Source/Game/Handlers/MailHandler.cs | 8 +- Source/Game/Handlers/NPCHandler.cs | 28 +- .../Handlers/TransmogrificationHandler.cs | 6 +- Source/Game/Handlers/VoidStorageHandler.cs | 2 +- Source/Game/Maps/TransportManager.cs | 22 +- .../Networking/Packets/AuctionHousePackets.cs | 4 +- .../Packets/AuthenticationPackets.cs | 5 +- .../Game/Networking/Packets/AzeritePackets.cs | 34 - .../Networking/Packets/BattleGroundPackets.cs | 10 +- .../Networking/Packets/BlackMarketPackets.cs | 15 - .../Networking/Packets/CharacterPackets.cs | 51 +- Source/Game/Networking/Packets/ChatPackets.cs | 12 +- .../Networking/Packets/CraftingPackets.cs | 88 + .../Networking/Packets/GameObjectPackets.cs | 45 +- .../Networking/Packets/GarrisonPackets.cs | 16 - .../Game/Networking/Packets/InspectPackets.cs | 31 +- Source/Game/Networking/Packets/ItemPackets.cs | 76 +- Source/Game/Networking/Packets/LootPackets.cs | 6 + Source/Game/Networking/Packets/MailPackets.cs | 12 - Source/Game/Networking/Packets/MiscPackets.cs | 52 +- .../Networking/Packets/MovementPackets.cs | 48 +- Source/Game/Networking/Packets/NPCPackets.cs | 155 +- .../Game/Networking/Packets/QuestPackets.cs | 69 +- .../Networking/Packets/ReputationPackets.cs | 6 +- .../Game/Networking/Packets/SpellPackets.cs | 96 +- .../Game/Networking/Packets/SystemPackets.cs | 29 +- .../Networking/Packets/TraitPacketsCommon.cs | 84 + .../Packets/TransmogrificationPackets.cs | 15 - Source/Game/Quest/Quest.cs | 121 + Source/Game/Reputation/ReputationManager.cs | 1 - Source/Game/Scripting/CoreScripts.cs | 4 +- Source/Game/Server/WorldConfig.cs | 12 +- Source/Game/Spells/Spell.cs | 33 +- Source/Game/Spells/SpellEffects.cs | 116 +- Source/Game/Spells/SpellHistory.cs | 35 +- Source/Game/Spells/SpellInfo.cs | 61 +- Source/Game/Spells/SpellManager.cs | 98 +- Source/Game/World/WorldManager.cs | 3 - Source/Scripts/Spells/Generic.cs | 6 +- Source/WorldServer/WorldServer.conf.dist | 21 +- 100 files changed, 6591 insertions(+), 4112 deletions(-) create mode 100644 Source/Game/Networking/Packets/CraftingPackets.cs create mode 100644 Source/Game/Networking/Packets/TraitPacketsCommon.cs diff --git a/Source/Framework/Constants/AchievementConst.cs b/Source/Framework/Constants/AchievementConst.cs index 5ef9d0899..628692b14 100644 --- a/Source/Framework/Constants/AchievementConst.cs +++ b/Source/Framework/Constants/AchievementConst.cs @@ -421,10 +421,21 @@ namespace Framework.Constants PlayerBestWeeklyWinPvpTierInBracketEqualOrGreaterThan = 325, // (Mainline) Player has best weekly win at or above "{@PVP_TIER_ENUM}" for "{@PVP_BRACKET}" PlayerHasVanillaCollectorsEdition = 326, // Player has Vanilla Collector's Edition PlayerHasItemWithKeystoneLevelModifierEqualOrGreaterThan = 327, - PlayerMythicPlusRatingInDisplaySeasonEqualOrGreaterThan = 329, /*NYI*/ // Player has Mythic+ Rating of at least "{#DungeonScore}" in {DisplaySeason} - - MythicPlusRatingIsInTop01Percent = 334, // top 0.1% rating + PlayerMythicPlusLadderRatingInDisplaySeasonEqualOrGreaterThan = 333, /*NYI*/ // Player has Mythic+ Ladder Rating of at least "{#DungeonScore}" in {DisplaySeason} + MythicPlusRatingIsInTop01Percent = 334, /*NYI*/ // top 0.1% rating + PlayerAuraWithLabelStackCountEqualOrGreaterThan = 335, // Player has at least {#Stacks} stacks of aura "{Label}" + PlayerAuraWithLabelStackCountEqual = 336, // Target has exactly {#Stacks} stacks of aura with label "{Label}" + PlayerAuraWithLabelStackCountEqualOrLessThan = 337, // Player has at most {#Stacks} stacks of aura "{Label}" + PlayerIsInCrossFactionGroup = 338, // Player is in a cross faction group + PlayerHasTraitNodeEntryInActiveConfig = 340, // Player has {TraitNodeEntry} node in currently active config + PlayerHasTraitNodeEntryInActiveConfigRankGreaterOrEqualThan = 341, // Player has at least {#Rank} for {TraitNodeEntry} node in currently active config + PlayerHasPurchasedCombatTraitRanks = 342, /*NYI*/ // Player has purchased at least {#Count} talent points in active combat config + PlayerHasPurchasedTraitRanksInTraitTree = 343, /*NYI*/ // Player has purchased at least {#Count} ranks in {#TraitTree} + PlayerDaysSinceLogout = 344, + CraftingOrderSkillLineAbility = 347, /*NYI*/ + CraftingOrderProfession = 348, /*NYI*/ // ProfessionEnum + PlayerCanUseItem = 351, // Player can use item {#Item} } public enum CriteriaFailEvent : byte @@ -714,7 +725,11 @@ namespace Framework.Constants MythicPlusRatingAttained = 230, /*NYI*/ // (Player) Mythic+ Rating "{#DungeonScore}" attained SpentTalentPoint = 231, /*NYI*/ // (Player) spent talent point MythicPlusDisplaySeasonEnded = 234, /*NYI*/ // {DisplaySeason} - + WinRatedSoloShuffleRound = 239, /*NYI*/ + ParticipateInRatedSoloShuffleRound = 240, /*NYI*/ + ReputationAmountGained = 243, /*NYI*/ // Gain reputation amount with {FactionID}; accumulate, not highest + FulfillAnyCraftingOrder = 245, /*NYI*/ + FulfillCraftingOrderType = 246, /*NYI*/ // {CraftingOrderType} Count } diff --git a/Source/Framework/Constants/Authentication/AuthConst.cs b/Source/Framework/Constants/Authentication/AuthConst.cs index 077dd8938..b3546226f 100644 --- a/Source/Framework/Constants/Authentication/AuthConst.cs +++ b/Source/Framework/Constants/Authentication/AuthConst.cs @@ -77,60 +77,64 @@ namespace Framework.Constants CharCreateNewPlayer = 50, CharCreateNameReservationFull = 51, - CharCreateClassTrialNewcomer = 52, - CharCreateClassTrialThrottleHour = 53, - CharCreateClassTrialThrottleDay = 54, - CharCreateClassTrialThrottleWeek = 55, - CharCreateClassTrialThrottleAccount = 56, + CharCreateDracthyrDuplicate = 52, + CharCreateDracthyrLevelRequirement = 53, + CharCreateDeathknightDuplicate = 54, + CharCreateDeathknightLevelRequirement = 55, + CharCreateClassTrialNewcomer = 56, + CharCreateClassTrialThrottleHour = 57, + CharCreateClassTrialThrottleDay = 58, + CharCreateClassTrialThrottleWeek = 59, + CharCreateClassTrialThrottleAccount = 60, - CharDeleteInProgress = 57, - CharDeleteSuccess = 58, - CharDeleteFailed = 59, - CharDeleteFailedLockedForTransfer = 60, - CharDeleteFailedGuildLeader = 61, - CharDeleteFailedArenaCaptain = 62, - CharDeleteFailedHasHeirloomOrMail = 63, - CharDeleteFailedUpgradeInProgress = 64, - CharDeleteFailedHasWowToken = 65, - CharDeleteFailedVasTransactionInProgress = 66, - CharDeleteFailedCommunityOwner = 67, + CharDeleteInProgress = 61, + CharDeleteSuccess = 62, + CharDeleteFailed = 63, + CharDeleteFailedLockedForTransfer = 64, + CharDeleteFailedGuildLeader = 65, + CharDeleteFailedArenaCaptain = 66, + CharDeleteFailedHasHeirloomOrMail = 67, + CharDeleteFailedUpgradeInProgress = 68, + CharDeleteFailedHasWowToken = 69, + CharDeleteFailedVasTransactionInProgress = 70, + CharDeleteFailedCommunityOwner = 71, - CharLoginInProgress = 68, - CharLoginSuccess = 69, - CharLoginNoWorld = 70, - CharLoginDuplicateCharacter = 71, - CharLoginNoInstances = 72, - CharLoginFailed = 73, - CharLoginDisabled = 74, - CharLoginNoCharacter = 75, - CharLoginLockedForTransfer = 76, - CharLoginLockedByBilling = 77, - CharLoginLockedByMobileAh = 78, - CharLoginTemporaryGmLock = 79, - CharLoginLockedByCharacterUpgrade = 80, - CharLoginLockedByRevokedCharacterUpgrade = 81, - CharLoginLockedByRevokedVasTransaction = 82, - CharLoginLockedByRestriction = 83, - CharLoginLockedForRealmPlaytype = 84, + CharLoginInProgress = 72, + CharLoginSuccess = 73, + CharLoginNoWorld = 74, + CharLoginDuplicateCharacter = 75, + CharLoginNoInstances = 76, + CharLoginFailed = 77, + CharLoginDisabled = 78, + CharLoginNoCharacter = 79, + CharLoginLockedForTransfer = 80, + CharLoginLockedByBilling = 81, + CharLoginLockedByMobileAh = 82, + CharLoginTemporaryGmLock = 83, + CharLoginLockedByCharacterUpgrade = 84, + CharLoginLockedByRevokedCharacterUpgrade = 85, + CharLoginLockedByRevokedVasTransaction = 86, + CharLoginLockedByRestriction = 87, + CharLoginLockedForRealmPlaytype = 88, - CharNameSuccess = 85, - CharNameFailure = 86, - CharNameNoName = 87, - CharNameTooShort = 88, - CharNameTooLong = 89, - CharNameInvalidCharacter = 90, - CharNameMixedLanguages = 91, - CharNameProfane = 92, - CharNameReserved = 93, - CharNameInvalidApostrophe = 94, - CharNameMultipleApostrophes = 95, - CharNameThreeConsecutive = 96, - CharNameInvalidSpace = 97, - CharNameConsecutiveSpaces = 98, - CharNameRussianConsecutiveSilentCharacters = 99, - CharNameRussianSilentCharacterAtBeginningOrEnd = 100, - CharNameDeclensionDoesntMatchBaseName = 101, - CharNameSpacesDisallowed = 102, + CharNameSuccess = 89, + CharNameFailure = 90, + CharNameNoName = 91, + CharNameTooShort = 92, + CharNameTooLong = 93, + CharNameInvalidCharacter = 94, + CharNameMixedLanguages = 95, + CharNameProfane = 96, + CharNameReserved = 97, + CharNameInvalidApostrophe = 98, + CharNameMultipleApostrophes = 99, + CharNameThreeConsecutive = 100, + CharNameInvalidSpace = 101, + CharNameConsecutiveSpaces = 102, + CharNameRussianConsecutiveSilentCharacters = 103, + CharNameRussianSilentCharacterAtBeginningOrEnd = 104, + CharNameDeclensionDoesntMatchBaseName = 105, + CharNameSpacesDisallowed = 106 } public enum CharacterUndeleteResult diff --git a/Source/Framework/Constants/CliDBConst.cs b/Source/Framework/Constants/CliDBConst.cs index 7e2e0c317..3f0f6f44b 100644 --- a/Source/Framework/Constants/CliDBConst.cs +++ b/Source/Framework/Constants/CliDBConst.cs @@ -1491,7 +1491,13 @@ namespace Framework.Constants OneshotStandVar0 = 991, OneshotFlycustomspell01 = 992, OneshotSpelleffectDecay = 993, - CreatureSpecial = 994, + StateCreatureSpecial = 994, + OneshotWareact01 = 1001, + OneshotFlycustomspell04 = 1004, + OneshotTalkSubdued = 1005, + StateEmotetalk = 1006, + StateWainteraction = 1007, + OneshotTakeOffStart = 1009, } public enum GlyphSlotType @@ -1715,6 +1721,75 @@ namespace Framework.Constants GearDiff = 8 } + public enum PlayerInteractionType + { + None = 0, + TradePartner = 1, + Item = 2, + Gossip = 3, + QuestGiver = 4, + Merchant = 5, + TaxiNode = 6, + Trainer = 7, + Banker = 8, + AlliedRaceDetailsGiver = 9, + GuildBanker = 10, + Registrar = 11, + Vendor = 12, + PetitionVendor = 13, + TabardVendor = 14, + TalentMaster = 15, + SpecializationMaster = 16, + MailInfo = 17, + SpiritHealer = 18, + AreaSpiritHealer = 19, + Binder = 20, + Auctioneer = 21, + StableMaster = 22, + BattleMaster = 23, + Transmogrifier = 24, + LFGDungeon = 25, + VoidStorageBanker = 26, + BlackMarketAuctioneer = 27, + AdventureMap = 28, + WorldMap = 29, + GarrArchitect = 30, + GarrTradeskill = 31, + GarrMission = 32, + ShipmentCrafter = 33, + GarrRecruitment = 34, + GarrTalent = 35, + Trophy = 36, + PlayerChoice = 37, + ArtifactForge = 38, + ObliterumForge = 39, + ScrappingMachine = 40, + ContributionCollector = 41, + AzeriteRespec = 42, + IslandQueue = 43, + ItemInteraction = 44, + ChromieTime = 45, + CovenantPreview = 46, + AnimaDiversion = 47, + LegendaryCrafting = 48, + WeeklyRewards = 49, + Soulbind = 50, + CovenantSanctum = 51, + NewPlayerGuide = 52, + ItemUpgrade = 53, + AdventureJournal = 54, + Renown = 55, + AzeriteForge = 56, + PerksProgramVendor = 57, + ProfessionsCraftingOrder = 58, + Professions = 59, + ProfessionsCustomerOrder = 60, + TraitSystem = 61, + BarbersChoice = 62, + JailersTowerBuffs = 63, + MajorFactionRenown = 64 + } + public enum PrestigeLevelInfoFlags : byte { Disabled = 0x01 // Prestige levels with this flag won't be included to calculate max prestigelevel. @@ -2129,6 +2204,23 @@ namespace Framework.Constants CreatureSpellDamage = 9 } + [Flags] + public enum TraitCombatConfigFlags + { + None = 0x0, + ActiveForSpec = 0x1, + StarterBuild = 0x2, + SharedActionBars = 0x4 + } + + public enum TraitConfigType + { + Invalid = 0, + Combat = 1, + Profession = 2, + Generic = 3 + } + public enum UiMapFlag { None = 0x00, @@ -2426,7 +2518,7 @@ namespace Framework.Constants ContentTuningPvpItemLevelDamageScaling = 15, } - public enum BattlePetSpeciesFlags : ushort + public enum BattlePetSpeciesFlags : int { NoRename = 0x01, WellKnown = 0x02, @@ -2443,7 +2535,8 @@ namespace Framework.Constants NoLicenseRequired = 0x1000, AddsAllowedWithBoss = 0x2000, HideUntilLearned = 0x4000, - MatchPlayerHighPetLevel = 0x8000 + MatchPlayerHighPetLevel = 0x8000, + NoWildPetAddsAllowed = 0x10000, } public enum SpellVisualEffectNameType diff --git a/Source/Framework/Constants/GossipConst.cs b/Source/Framework/Constants/GossipConst.cs index ac200231d..2891f106e 100644 --- a/Source/Framework/Constants/GossipConst.cs +++ b/Source/Framework/Constants/GossipConst.cs @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ + */ namespace Framework.Constants { @@ -48,24 +48,24 @@ namespace Framework.Constants { None = 0, // White chat bubble. Default Vendor = 1, // Brown bag - TaxiNode = 2, // White wing + Taxinode = 2, // White wing Trainer = 3, // Brown book SpiritHealer = 4, // Golden interaction wheel (with red center) Binder = 5, // Golden interaction wheel Banker = 6, // Brown bag (with gold coin in lower corner) PetitionVendor = 7, // White chat bubble (with "..." inside) TabardVendor = 8, // White tabard - BattleMaster = 9, // Two crossed swords + Battlemaster = 9, // Two crossed swords Auctioneer = 10, // Stack of gold coins TalentMaster = 11, // White chat bubble - StableMaster = 12, // White chat bubble + Stablemaster = 12, // White chat bubble PetSpecializationMaster = 13, /*DEPRECATED*/ // White chat bubble - GuildBanker = 14, /*NYI*/ // White chat bubble - SpellClick = 15, /*NYI*/ // White chat bubble + GuildBanker = 14, // White chat bubble + Spellclick = 15, // White chat bubble DisableXPGain = 16, // White chat bubble EnableXPGain = 17, // White chat bubble Mailbox = 18, // White chat bubble - WorldPVPQueue = 19, /*NYI*/ // White chat bubble + WorldPvPQueue = 19, /*NYI*/ // White chat bubble LFGDungeon = 20, /*NYI*/ // White chat bubble ArtifactRespec = 21, /*NYI*/ // White chat bubble CemeterySelect = 22, /*DEPRECATED*/ // White chat bubble @@ -73,25 +73,33 @@ namespace Framework.Constants GlyphMaster = 24, /*DEPRECATED*/ // White chat bubble QueueScenario = 25, /*NYI*/ // White chat bubble GarrisonArchitect = 26, /*NYI*/ // White chat bubble - GarrisonMission = 27, /*NYI*/ // White chat bubble + GarrisonMissionNpc = 27, /*NYI*/ // White chat bubble ShipmentCrafter = 28, /*NYI*/ // Brown document - GarrisonTradeskill = 29, /*NYI*/ // White chat bubble + GarrisonTradeskillNpc = 29, /*NYI*/ // White chat bubble GarrisonRecruitment = 30, /*NYI*/ // White chat bubble AdventureMap = 31, /*NYI*/ // White chat bubble GarrisonTalent = 32, // White chat bubble ContributionCollector = 33, /*NYI*/ // White chat bubble Transmogrify = 34, // Purple helm AzeriteRespec = 35, // White chat bubble - IslandsMission = 36, /*NYI*/ // White chat bubble + IslandsMissionNpc = 36, /*NYI*/ // White chat bubble UIItemInteraction = 37, /*NYI*/ // White chat bubble WorldMap = 38, /*NYI*/ // White chat bubble Soulbind = 39, /*NYI*/ // White chat bubble - ChromieTime = 40, /*NYI*/ // White chat bubble - CovenantPreview = 41, /*NYI*/ // White chat bubble + ChromieTimeNpc = 40, /*NYI*/ // White chat bubble + CovenantPreviewNpc = 41, /*NYI*/ // White chat bubble RuneforgeLegendaryCrafting = 42, /*NYI*/ // White chat bubble NewPlayerGuide = 43, /*NYI*/ // White chat bubble RuneforgeLegendaryUpgrade = 44, /*NYI*/ // White chat bubble - CovenantRenown = 45, /*NYI*/ // White chat bubble + CovenantRenownNpc = 45, /*NYI*/ // White chat bubble + BlackMarketAuctionHouse = 46, + PerksProgramVendor = 47, + ProfessionsCraftingOrder = 48, + ProfessionsOpen = 49, + ProfessionsCustomerOrder = 50, + TraitSystem = 51, + BarbersChoice = 52, + MajorFactionRenown = 53, Max } @@ -162,4 +170,10 @@ namespace Framework.Constants Item = 0, Currency = 1 } + + public enum GossipOptionFlags + { + None = 0x0, + QuestLabelPrepend = 0x1 + } } diff --git a/Source/Framework/Constants/GroupConst.cs b/Source/Framework/Constants/GroupConst.cs index 77ccdc91e..e62a67135 100644 --- a/Source/Framework/Constants/GroupConst.cs +++ b/Source/Framework/Constants/GroupConst.cs @@ -13,7 +13,9 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - */ + */ + +using System; namespace Framework.Constants { @@ -60,6 +62,7 @@ namespace Framework.Constants WorldPvp = 4, } + [Flags] public enum GroupFlags { None = 0x00, @@ -71,6 +74,7 @@ namespace Framework.Constants OnePersonParty = 0x020, // Script_IsOnePersonParty() EveryoneAssistant = 0x040, // Script_IsEveryoneAssistant() GuildGroup = 0x100, + CrossFaction = 0x200, MaskBgRaid = FakeRaid | Raid } diff --git a/Source/Framework/Constants/ItemConst.cs b/Source/Framework/Constants/ItemConst.cs index 104ebf767..26f3b2a12 100644 --- a/Source/Framework/Constants/ItemConst.cs +++ b/Source/Framework/Constants/ItemConst.cs @@ -102,29 +102,65 @@ namespace Framework.Constants }; } + public struct ProfessionSlots + { + public const byte Profession1Tool = 19; + public const byte Profession1Gear1 = 20; + public const byte Profession1Gear2 = 21; + public const byte Profession2Tool = 22; + public const byte Profession2Gear1 = 23; + public const byte Profession2Gear2 = 24; + public const byte CookingTool = 25; + public const byte CookingGear1 = 26; + public const byte FishingTool = 27; + public const byte FishingGear1 = 28; + public const byte FishingGear2 = 29; + + public const byte End = 30; + public const byte Start = Profession1Tool; + } + public struct InventorySlots { - public const byte BagStart = 19; - public const byte BagEnd = 23; - public const byte ItemStart = 23; - public const byte ItemEnd = 51; + public const byte BagStart = 30; + public const byte BagEnd = 34; - public const byte BankItemStart = 51; - public const byte BankItemEnd = 79; - public const byte BankBagStart = 79; - public const byte BankBagEnd = 86; + public const byte ReagentBagStart = 34; + public const byte ReagentBagEnd = 35; - public const byte BuyBackStart = 86; - public const byte BuyBackEnd = 98; - public const byte ReagentStart = 98; - public const byte ReagentEnd = 196; - public const byte ChildEquipmentStart = 196; - public const byte ChildEquipmentEnd = 199; + public const byte ItemStart = 35; + public const byte ItemEnd = 63; + + public const byte BankItemStart = 63; + public const byte BankItemEnd = 91; + + public const byte BankBagStart = 91; + public const byte BankBagEnd = 98; + + public const byte BuyBackStart = 98; + public const byte BuyBackEnd = 110; + + public const byte ReagentStart = 110; + public const byte ReagentEnd = 208; + + public const byte ChildEquipmentStart = 208; + public const byte ChildEquipmentEnd = 211; public const byte Bag0 = 255; public const byte DefaultSize = 16; } + enum EquipableSpellSlots + { + OffensiveSlot1 = 211, + OffensiveSlot2 = 212, + OffensiveSlot3 = 213, + OffensiveSlot4 = 214, + UtilitySlot1 = 215, + DefensiveSlot1 = 216, + MobilitySlot1 = 217 + } + public struct EquipmentSlot { public const byte Start = 0; @@ -462,6 +498,20 @@ namespace Framework.Constants RaidHeroicExtended = 84, RaidMythicExtended = 85, CharacterTemplate91 = 86, + ChallengeMode4 = 87, + PvpRanked9 = 88, + RaidNormalExtended2 = 89, + RaidFinderExtended2 = 90, + RaidHeroicExtended2 = 91, + RaidMythicExtended2 = 92, + RaidNormalExtended3 = 93, + RaidFinderExtended3 = 94, + RaidHeroicExtended3 = 95, + RaidMythicExtended3 = 96, + TemplateCharacter1 = 97, + TemplateCharacter2 = 98, + TemplateCharacter3 = 99, + TemplateCharacter4 = 100, Max } @@ -537,7 +587,13 @@ namespace Framework.Constants RangedRight = 26, Quiver = 27, Relic = 28, - Max = 29 + ProfessionTool = 29, + ProfessionGear = 30, + EquipableSpellOffensive = 31, + EquipableSpellUtility = 32, + EquipableSpellDefensive = 33, + EquipableSpellMobility = 34, + Max } public enum VisibleEquipmentSlot @@ -586,7 +642,8 @@ namespace Framework.Constants Glyph = 16, BattlePets = 17, WowToken = 18, - Max = 19 + Profession = 19, + Max } public enum ItemSubClassConsumable @@ -601,7 +658,7 @@ namespace Framework.Constants Bandage = 7, ConsumableOther = 8, VantusRune = 9, - Max = 10 + Max } public enum ItemSubClassContainer @@ -617,7 +674,8 @@ namespace Framework.Constants InscriptionContainer = 8, TackleContainer = 9, CookingContainer = 10, - Max = 11 + ReagentContainer = 11, + Max } public enum ItemSubClassWeapon @@ -664,7 +722,7 @@ namespace Framework.Constants Other = 9, MultipleStats = 10, ArtifactRelic = 11, - Max = 12 + Max } public enum ItemSubClassArmor @@ -681,14 +739,15 @@ namespace Framework.Constants Totem = 9, Sigil = 10, Relic = 11, - Max = 12 + Max } public enum ItemSubClassReagent { Reagent = 0, Keystone = 1, - Max = 2 + ContextToken = 2, + Max } public enum ItemSubClassProjectile @@ -698,7 +757,7 @@ namespace Framework.Constants Arrow = 2, Bullet = 3, Thrown = 4, // Obsolete - Max = 5 + Max } public enum ItemSubClassTradeGoods @@ -721,7 +780,9 @@ namespace Framework.Constants WeaponEnchantment = 15, Inscription = 16, ExplosivesDevices = 17, - Max = 18 + OptionalReagent = 18, + FinishingReagent = 19, + Max } public enum ItemSubclassItemEnhancement @@ -740,7 +801,8 @@ namespace Framework.Constants Weapon = 11, TwoHandedWeapon = 12, ShieldOffHand = 13, - Max = 14 + Misc = 14, + Max } public enum ItemSubClassRecipe @@ -804,7 +866,8 @@ namespace Framework.Constants Holiday = 3, Other = 4, Mount = 5, - Max = 6 + MountEquipment = 6, + Max } public enum ItemSubClassGlyph @@ -836,6 +899,25 @@ namespace Framework.Constants Max = 1 } + public enum ItemSubclassPorfession + { + Blacksmithing = 0, + Leatherworking = 1, + Alchemy = 2, + Herbalism = 3, + Cooking = 4, + Mining = 5, + Tailoring = 6, + Engineering = 7, + Enchanting = 8, + Fishing = 9, + Skinning = 10, + Jewelcrafting = 11, + Inscription = 12, + Archaeology = 13, + Max + } + public enum ItemQuality { Poor = 0, //Grey @@ -1144,6 +1226,11 @@ namespace Framework.Constants NotInNPE = 110,// Not available during the tutorial ItemCooldown = 111,// Item is not ready yet. NotInRatedBattleground = 112,// You can't do that in a rated battleground. + EquipableSpellsSlotsFull = 113, + CantBeRecrafted = 114,// You can't recraft that itemv + ReagentBagWrongSlot = 115,// Reagent Bags can only be placed in the reagent bag slot. + SlotOnlyReagentBag = 116,// Only Reagent Bags can be placed in the reagent bag slot. + ReagentBagItemType = 117,// Only Reagents can be placed in Reagent Bags. } public enum BuyResult diff --git a/Source/Framework/Constants/LootConst.cs b/Source/Framework/Constants/LootConst.cs index e7405ff52..087f78577 100644 --- a/Source/Framework/Constants/LootConst.cs +++ b/Source/Framework/Constants/LootConst.cs @@ -111,4 +111,15 @@ namespace Framework.Constants Master = 3, // Item Can Only Be Distributed By Group Loot Master. Owner = 4 // Ignore Binding Confirmation And Etc, For Single Player Looting } + + public enum LootRollIneligibilityReason + { + None = 0, + UnusableByClass = 1, // Your class may not roll need on this item. + MaxUniqueItemCount = 2, // You already have the maximum amount of this item. + CannotBeDisenchanted = 3, // This item may not be disenchanted. + EnchantingSkillTooLow = 4, // You do not have an Enchanter of skill %d in your group. + NeedDisabled = 5, // Need rolls are disabled for this item. + OwnBetterItem = 6 // You already have a powerful version of this item. + } } diff --git a/Source/Framework/Constants/Movement/MovementFlags.cs b/Source/Framework/Constants/Movement/MovementFlags.cs index 72e9f5360..1e8847c97 100644 --- a/Source/Framework/Constants/Movement/MovementFlags.cs +++ b/Source/Framework/Constants/Movement/MovementFlags.cs @@ -99,5 +99,7 @@ namespace Framework.Constants { None = 0x00, DisableInertia = 0x01, + CanAdvFly = 0x02, + AdvFlying = 0x04, } } diff --git a/Source/Framework/Constants/Network/Opcodes.cs b/Source/Framework/Constants/Network/Opcodes.cs index 36be7422c..f3bc15664 100644 --- a/Source/Framework/Constants/Network/Opcodes.cs +++ b/Source/Framework/Constants/Network/Opcodes.cs @@ -19,34 +19,35 @@ namespace Framework.Constants { public enum ClientOpcodes : uint { - AbandonNpeResponse = 0x33e1, + AbandonNpeResponse = 0x33eb, AcceptGuildInvite = 0x35fc, - AcceptSocialContract = 0x373b, + AcceptReturningPlayerPrompt = 0x3395, + AcceptSocialContract = 0x373e, AcceptTrade = 0x315a, AcceptWargameInvite = 0x35e0, - AccountNotificationAcknowledged = 0x3731, - ActivateSoulbind = 0x33d0, + AccountNotificationAcknowledged = 0x3733, + ActivateSoulbind = 0x33da, ActivateTaxi = 0x34b1, AddonList = 0x35d8, - AddAccountCosmetic = 0x32a9, - AddBattlenetFriend = 0x3659, - AddFriend = 0x36cc, - AddIgnore = 0x36d0, - AddToy = 0x32a8, - AdventureJournalOpenQuest = 0x3205, - AdventureJournalUpdateSuggestions = 0x33d3, - AdventureMapStartQuest = 0x3360, + AddAccountCosmetic = 0x32b1, + AddBattlenetFriend = 0x365a, + AddFriend = 0x36ce, + AddIgnore = 0x36d2, + AddToy = 0x32b0, + AdventureJournalOpenQuest = 0x3204, + AdventureJournalUpdateSuggestions = 0x33dd, + AdventureMapStartQuest = 0x3369, AlterAppearance = 0x3503, AreaSpiritHealerQuery = 0x34b6, AreaSpiritHealerQueue = 0x34b7, AreaTrigger = 0x31d8, ArtifactAddPower = 0x31ab, ArtifactSetAppearance = 0x31ad, - AssignEquipmentSetSpec = 0x3211, - AttackStop = 0x3260, - AttackSwing = 0x325f, - AuctionableTokenSell = 0x36e2, - AuctionableTokenSellAtMarketPrice = 0x36e3, + AssignEquipmentSetSpec = 0x3210, + AttackStop = 0x3263, + AttackSwing = 0x3262, + AuctionableTokenSell = 0x36e4, + AuctionableTokenSellAtMarketPrice = 0x36e5, AuctionBrowseQuery = 0x34d6, AuctionCancelCommoditiesPurchase = 0x34de, AuctionConfirmCommoditiesPurchase = 0x34dd, @@ -60,10 +61,10 @@ namespace Framework.Constants AuctionPlaceBid = 0x34d5, AuctionRemoveItem = 0x34d3, AuctionReplicateItems = 0x34d4, - AuctionRequestFavoriteList = 0x3733, + AuctionRequestFavoriteList = 0x3735, AuctionSellCommodity = 0x34df, AuctionSellItem = 0x34d2, - AuctionSetFavoriteItem = 0x3732, + AuctionSetFavoriteItem = 0x3734, AuthContinuedSession = 0x3766, AuthSession = 0x3765, AutobankItem = 0x3997, @@ -75,32 +76,33 @@ namespace Framework.Constants AutoGuildBankItem = 0x34bd, AutoStoreBagItem = 0x399b, AutoStoreGuildBankItem = 0x34c6, - AzeriteEmpoweredItemSelectPower = 0x3388, - AzeriteEmpoweredItemViewed = 0x336b, - AzeriteEssenceActivateEssence = 0x338a, - AzeriteEssenceUnlockMilestone = 0x3389, + AzeriteEmpoweredItemSelectPower = 0x3391, + AzeriteEmpoweredItemViewed = 0x3374, + AzeriteEssenceActivateEssence = 0x3393, + AzeriteEssenceUnlockMilestone = 0x3392, BankerActivate = 0x34b9, BattlefieldLeave = 0x3173, BattlefieldList = 0x317f, - BattlefieldPort = 0x3537, - BattlemasterHello = 0x32c5, + BattlefieldPort = 0x3538, + BattlemasterHello = 0x32cd, BattlemasterJoin = 0x3530, BattlemasterJoinArena = 0x3531, - BattlemasterJoinBrawl = 0x3535, - BattlemasterJoinSkirmish = 0x3532, - BattlenetChallengeResponse = 0x36cf, - BattlenetRequest = 0x36f1, - BattlePayAckFailedResponse = 0x36c9, - BattlePayCancelOpenCheckout = 0x370f, - BattlePayConfirmPurchaseResponse = 0x36c8, - BattlePayDistributionAssignToTarget = 0x36bf, - BattlePayDistributionAssignVas = 0x3736, - BattlePayGetProductList = 0x36b7, - BattlePayGetPurchaseList = 0x36b8, - BattlePayOpenCheckout = 0x3708, - BattlePayRequestPriceInfo = 0x3704, - BattlePayStartPurchase = 0x36c7, - BattlePayStartVasPurchase = 0x36ee, + BattlemasterJoinBrawl = 0x3536, + BattlemasterJoinRatedSoloShuffle = 0x3532, + BattlemasterJoinSkirmish = 0x3533, + BattlenetChallengeResponse = 0x36d1, + BattlenetRequest = 0x36f3, + BattlePayAckFailedResponse = 0x36cb, + BattlePayCancelOpenCheckout = 0x3711, + BattlePayConfirmPurchaseResponse = 0x36ca, + BattlePayDistributionAssignToTarget = 0x36c1, + BattlePayDistributionAssignVas = 0x3738, + BattlePayGetProductList = 0x36b9, + BattlePayGetPurchaseList = 0x36ba, + BattlePayOpenCheckout = 0x370a, + BattlePayRequestPriceInfo = 0x3706, + BattlePayStartPurchase = 0x36c9, + BattlePayStartVasPurchase = 0x36f0, BattlePetClearFanfare = 0x312c, BattlePetDeletePet = 0x3625, BattlePetDeletePetCheat = 0x3626, @@ -114,59 +116,59 @@ namespace Framework.Constants BattlePetUpdateNotify = 0x31e1, BeginTrade = 0x3157, BinderActivate = 0x34b8, - BlackMarketBidOnItem = 0x353f, - BlackMarketOpen = 0x353d, - BlackMarketRequestItems = 0x353e, - BonusRoll = 0x338b, - BugReport = 0x3684, + BlackMarketBidOnItem = 0x3540, + BlackMarketOpen = 0x353e, + BlackMarketRequestItems = 0x353f, + BonusRoll = 0x3394, + BugReport = 0x3685, BusyTrade = 0x3158, BuyBackItem = 0x34aa, BuyBankSlot = 0x34ba, BuyItem = 0x34a9, BuyReagentBank = 0x34bb, CageBattlePet = 0x31f4, - CalendarAddEvent = 0x367c, - CalendarCommunityInvite = 0x3670, - CalendarComplain = 0x3678, - CalendarCopyEvent = 0x3677, - CalendarEventSignUp = 0x367a, - CalendarGet = 0x366e, - CalendarGetEvent = 0x366f, - CalendarGetNumPending = 0x3679, - CalendarInvite = 0x3671, - CalendarModeratorStatus = 0x3675, - CalendarRemoveEvent = 0x3676, - CalendarRemoveInvite = 0x3672, - CalendarRsvp = 0x3673, - CalendarStatus = 0x3674, - CalendarUpdateEvent = 0x367d, + CalendarAddEvent = 0x367d, + CalendarCommunityInvite = 0x3671, + CalendarComplain = 0x3679, + CalendarCopyEvent = 0x3678, + CalendarEventSignUp = 0x367b, + CalendarGet = 0x366f, + CalendarGetEvent = 0x3670, + CalendarGetNumPending = 0x367a, + CalendarInvite = 0x3672, + CalendarModeratorStatus = 0x3676, + CalendarRemoveEvent = 0x3677, + CalendarRemoveInvite = 0x3673, + CalendarRsvp = 0x3674, + CalendarStatus = 0x3675, + CalendarUpdateEvent = 0x367e, CancelAura = 0x31af, CancelAutoRepeatSpell = 0x34f5, - CancelCast = 0x32af, - CancelChannelling = 0x3278, - CancelGrowthAura = 0x327d, - CancelMasterLootRoll = 0x3219, + CancelCast = 0x32b7, + CancelChannelling = 0x327b, + CancelGrowthAura = 0x3283, + CancelMasterLootRoll = 0x321c, CancelModSpeedNoControlAuras = 0x31ae, - CancelMountAura = 0x3290, + CancelMountAura = 0x3296, CancelQueuedSpell = 0x3180, CancelTempEnchantment = 0x3500, CancelTrade = 0x315c, - CanDuel = 0x3661, - CanRedeemTokenForBalance = 0x3703, - CastSpell = 0x32ac, + CanDuel = 0x3662, + CanRedeemTokenForBalance = 0x3705, + CastSpell = 0x32b4, ChallengeModeRequestLeaders = 0x3090, - ChangeBagSlotFlag = 0x3345, - ChangeBankBagSlotFlag = 0x3346, - ChangeMonumentAppearance = 0x3326, - ChangeRealmTicket = 0x36f6, - ChangeSubGroup = 0x364b, - CharacterCheckUpgrade = 0x36c2, - CharacterRenameRequest = 0x36bd, - CharacterUpgradeManualUnrevokeRequest = 0x36c0, - CharacterUpgradeStart = 0x36c1, - CharCustomize = 0x368b, - CharDelete = 0x369a, - CharRaceOrFactionChange = 0x3691, + ChangeBagSlotFlag = 0x334e, + ChangeBankBagSlotFlag = 0x334f, + ChangeMonumentAppearance = 0x332f, + ChangeRealmTicket = 0x36f8, + ChangeSubGroup = 0x364c, + CharacterCheckUpgrade = 0x36c4, + CharacterRenameRequest = 0x36bf, + CharacterUpgradeManualUnrevokeRequest = 0x36c2, + CharacterUpgradeStart = 0x36c3, + CharCustomize = 0x368c, + CharDelete = 0x369c, + CharRaceOrFactionChange = 0x3692, ChatAddonMessage = 0x37ee, ChatAddonMessageTargeted = 0x37ef, ChatChannelAnnouncements = 0x37e3, @@ -203,29 +205,37 @@ namespace Framework.Constants ChatReportFiltered = 0x37cc, ChatReportIgnored = 0x37cb, ChatUnregisterAllAddonPrefixes = 0x37ce, - CheckCharacterNameAvailability = 0x3644, - CheckIsAdventureMapPoiValid = 0x3251, - ChoiceResponse = 0x32b4, - ChromieTimeSelectExpansion = 0x33cf, - ClaimWeeklyReward = 0x33ab, + CheckCharacterNameAvailability = 0x3645, + CheckIsAdventureMapPoiValid = 0x3254, + ChoiceResponse = 0x32bc, + ChromieTimeSelectExpansion = 0x33d9, + ClaimWeeklyReward = 0x33b5, + ClassTalentsDeleteConfig = 0x3408, + ClassTalentsNotifyEmptyConfig = 0x3214, + ClassTalentsNotifyValidationFailed = 0x340a, + ClassTalentsRenameConfig = 0x3407, + ClassTalentsRequestNewConfig = 0x3406, + ClassTalentsSetStarterBuildActive = 0x340b, + ClassTalentsSetUsesSharedActionBars = 0x3213, ClearNewAppearance = 0x312f, ClearRaidMarker = 0x31a7, ClearTradeItem = 0x315e, - ClientPortGraveyard = 0x3539, + ClientPortGraveyard = 0x353a, CloseInteraction = 0x3499, - CloseQuestChoice = 0x32b5, - CloseRuneforgeInteraction = 0x33d7, - ClubFinderApplicationResponse = 0x371a, - ClubFinderGetApplicantsList = 0x3718, - ClubFinderPost = 0x3715, - ClubFinderRequestClubsData = 0x371c, - ClubFinderRequestClubsList = 0x3716, - ClubFinderRequestMembershipToClub = 0x3717, - ClubFinderRequestPendingClubsList = 0x371b, - ClubFinderRequestSubscribedClubPostingIds = 0x371d, - ClubFinderRespondToApplicant = 0x3719, - ClubFinderWhisperApplicantRequest = 0x3739, - ClubPresenceSubscribe = 0x36f3, + CloseQuestChoice = 0x32bd, + CloseRuneforgeInteraction = 0x33e1, + CloseTraitSystemInteraction = 0x340c, + ClubFinderApplicationResponse = 0x371c, + ClubFinderGetApplicantsList = 0x371a, + ClubFinderPost = 0x3717, + ClubFinderRequestClubsData = 0x371e, + ClubFinderRequestClubsList = 0x3718, + ClubFinderRequestMembershipToClub = 0x3719, + ClubFinderRequestPendingClubsList = 0x371d, + ClubFinderRequestSubscribedClubPostingIds = 0x371f, + ClubFinderRespondToApplicant = 0x371b, + ClubFinderWhisperApplicantRequest = 0x373b, + ClubPresenceSubscribe = 0x36f5, CollectionItemSetFavorite = 0x3633, CommentatorEnable = 0x35f0, CommentatorEnterInstance = 0x35f4, @@ -233,38 +243,47 @@ namespace Framework.Constants CommentatorGetMapInfo = 0x35f1, CommentatorGetPlayerCooldowns = 0x35f3, CommentatorGetPlayerInfo = 0x35f2, - CommentatorSpectate = 0x3737, + CommentatorSpectate = 0x3739, CommentatorStartWargame = 0x35ef, - CommerceTokenGetCount = 0x36e0, - CommerceTokenGetLog = 0x36ea, - CommerceTokenGetMarketPrice = 0x36e1, - Complaint = 0x366b, - CompleteCinematic = 0x3557, + CommerceTokenGetCount = 0x36e2, + CommerceTokenGetLog = 0x36ec, + CommerceTokenGetMarketPrice = 0x36e3, + Complaint = 0x366c, + CompleteCinematic = 0x3558, CompleteMovie = 0x34eb, ConfirmArtifactRespec = 0x31ac, - ConfirmRespecWipe = 0x3213, + ConfirmRespecWipe = 0x3216, ConnectToFailed = 0x35d4, - ConsumableTokenBuy = 0x36e5, - ConsumableTokenBuyAtMarketPrice = 0x36e6, - ConsumableTokenCanVeteranBuy = 0x36e4, - ConsumableTokenRedeem = 0x36e8, - ConsumableTokenRedeemConfirmation = 0x36e9, - ContributionContribute = 0x356b, - ContributionLastUpdateRequest = 0x356c, - ConversationCinematicReady = 0x3559, - ConversationLineStarted = 0x3558, - ConvertRaid = 0x364d, - CovenantRenownRequestCatchupState = 0x357f, - CreateCharacter = 0x3643, - CreateShipment = 0x3312, + ConsumableTokenBuy = 0x36e7, + ConsumableTokenBuyAtMarketPrice = 0x36e8, + ConsumableTokenCanVeteranBuy = 0x36e6, + ConsumableTokenRedeem = 0x36ea, + ConsumableTokenRedeemConfirmation = 0x36eb, + ContributionContribute = 0x356c, + ContributionLastUpdateRequest = 0x356d, + ConversationCinematicReady = 0x355a, + ConversationLineStarted = 0x3559, + ConvertRaid = 0x364e, + CovenantRenownRequestCatchupState = 0x3580, + CraftingOrderCancel = 0x358b, + CraftingOrderClaim = 0x3588, + CraftingOrderCreate = 0x3585, + CraftingOrderFulfill = 0x358a, + CraftingOrderListCrafterOrders = 0x3587, + CraftingOrderListMyOrders = 0x3586, + CraftingOrderReject = 0x358c, + CraftingOrderRelease = 0x3589, + CraftingOrderUpdateIgnoreList = 0x358d, + CreateCharacter = 0x3644, + CreateShipment = 0x331a, DbQueryBulk = 0x35e4, DeclineGuildInvites = 0x352d, - DeclinePetition = 0x3546, + DeclinePetition = 0x3547, DeleteEquipmentSet = 0x3519, - DelFriend = 0x36cd, - DelIgnore = 0x36d1, - DepositReagentBank = 0x334e, - DestroyItem = 0x32a2, + DelFriend = 0x36cf, + DelIgnore = 0x36d3, + DepositReagentBank = 0x3357, + DestroyItem = 0x32aa, DfBootPlayerVote = 0x3616, DfConfirmExpandSearch = 0x3608, DfGetJoinStatus = 0x3614, @@ -275,70 +294,70 @@ namespace Framework.Constants DfReadyCheckResponse = 0x3619, DfSetRoles = 0x3615, DfTeleport = 0x3617, - DiscardedTimeSyncAcks = 0x3a42, + DiscardedTimeSyncAcks = 0x3a41, DismissCritter = 0x3507, - DoCountdown = 0x3714, - DoMasterLootRoll = 0x3218, + DoCountdown = 0x3716, + DoMasterLootRoll = 0x321b, DoReadyCheck = 0x3634, DuelResponse = 0x34f0, - EjectPassenger = 0x3246, - Emote = 0x3553, + EjectPassenger = 0x3249, + Emote = 0x3554, EnableNagle = 0x376b, EnableTaxiNode = 0x34af, - EngineSurvey = 0x36df, + EngineSurvey = 0x36e1, EnterEncryptedModeAck = 0x3767, EnumCharacters = 0x35e8, - EnumCharactersDeletedByClient = 0x36d9, + EnumCharactersDeletedByClient = 0x36db, FarSight = 0x34f6, GameEventDebugDisable = 0x31b3, GameEventDebugEnable = 0x31b2, GameObjReportUse = 0x34fd, GameObjUse = 0x34fc, - GarrisonAddFollowerHealth = 0x330d, - GarrisonAssignFollowerToBuilding = 0x32f3, - GarrisonCancelConstruction = 0x32e0, - GarrisonCheckUpgradeable = 0x3341, - GarrisonCompleteMission = 0x3333, - GarrisonFullyHealAllFollowers = 0x330e, - GarrisonGenerateRecruits = 0x32f6, - GarrisonGetClassSpecCategoryInfo = 0x3305, - GarrisonGetMapData = 0x330c, - GarrisonGetMissionReward = 0x3364, - GarrisonLearnTalent = 0x3301, - GarrisonMissionBonusRoll = 0x3335, - GarrisonPurchaseBuilding = 0x32dc, - GarrisonRecruitFollower = 0x32f8, - GarrisonRemoveFollower = 0x332a, - GarrisonRemoveFollowerFromBuilding = 0x32f4, - GarrisonRenameFollower = 0x32f5, - GarrisonRequestBlueprintAndSpecializationData = 0x32db, - GarrisonRequestShipmentInfo = 0x3310, - GarrisonResearchTalent = 0x32f9, - GarrisonSetBuildingActive = 0x32dd, - GarrisonSetFollowerFavorite = 0x32f1, - GarrisonSetFollowerInactive = 0x32e9, - GarrisonSetRecruitmentPreferences = 0x32f7, - GarrisonSocketTalent = 0x33e4, - GarrisonStartMission = 0x3332, - GarrisonSwapBuildings = 0x32e1, + GarrisonAddFollowerHealth = 0x3315, + GarrisonAssignFollowerToBuilding = 0x32fb, + GarrisonCancelConstruction = 0x32e8, + GarrisonCheckUpgradeable = 0x334a, + GarrisonCompleteMission = 0x333c, + GarrisonFullyHealAllFollowers = 0x3316, + GarrisonGenerateRecruits = 0x32fe, + GarrisonGetClassSpecCategoryInfo = 0x330d, + GarrisonGetMapData = 0x3314, + GarrisonGetMissionReward = 0x336d, + GarrisonLearnTalent = 0x3309, + GarrisonMissionBonusRoll = 0x333e, + GarrisonPurchaseBuilding = 0x32e4, + GarrisonRecruitFollower = 0x3300, + GarrisonRemoveFollower = 0x3333, + GarrisonRemoveFollowerFromBuilding = 0x32fc, + GarrisonRenameFollower = 0x32fd, + GarrisonRequestBlueprintAndSpecializationData = 0x32e3, + GarrisonRequestShipmentInfo = 0x3318, + GarrisonResearchTalent = 0x3301, + GarrisonSetBuildingActive = 0x32e5, + GarrisonSetFollowerFavorite = 0x32f9, + GarrisonSetFollowerInactive = 0x32f1, + GarrisonSetRecruitmentPreferences = 0x32ff, + GarrisonSocketTalent = 0x33ee, + GarrisonStartMission = 0x333b, + GarrisonSwapBuildings = 0x32e9, GenerateRandomCharacterName = 0x35e7, - GetAccountCharacterList = 0x36b2, - GetAccountNotifications = 0x3730, - GetGarrisonInfo = 0x32d6, - GetItemPurchaseData = 0x3541, - GetLandingPageShipments = 0x3311, - GetMirrorImageData = 0x32a6, + GetAccountCharacterList = 0x36b4, + GetAccountNotifications = 0x3732, + GetGarrisonInfo = 0x32de, + GetItemPurchaseData = 0x3542, + GetLandingPageShipments = 0x3319, + GetMirrorImageData = 0x32ae, GetPvpOptionsEnabled = 0x35ee, - GetRafAccountInfo = 0x371e, - GetRemainingGameTime = 0x36e7, - GetTrophyList = 0x3323, - GetUndeleteCharacterCooldownStatus = 0x36db, - GetVasAccountCharacterList = 0x36ec, - GetVasTransferTargetRealmList = 0x36ed, - GmTicketAcknowledgeSurvey = 0x368f, - GmTicketGetCaseStatus = 0x368e, - GmTicketGetSystemStatus = 0x368d, - GossipRefreshOptions = 0x357e, + GetRafAccountInfo = 0x3720, + GetRemainingGameTime = 0x36e9, + GetTrophyList = 0x332c, + GetUndeleteCharacterCooldownStatus = 0x36dd, + GetVasAccountCharacterList = 0x36ee, + GetVasTransferTargetRealmList = 0x36ef, + GmTicketAcknowledgeSurvey = 0x3690, + GmTicketGetCaseStatus = 0x368f, + GmTicketGetSystemStatus = 0x368e, + GossipRefreshOptions = 0x357f, GossipSelectOption = 0x349a, GuildAddBattlenetFriend = 0x308e, GuildAddRank = 0x3065, @@ -377,31 +396,31 @@ namespace Framework.Constants GuildReplaceGuildMaster = 0x3089, GuildSetAchievementTracking = 0x3070, GuildSetFocusedAchievement = 0x3071, - GuildSetGuildMaster = 0x36c4, + GuildSetGuildMaster = 0x36c6, GuildSetMemberNote = 0x3073, GuildSetRankPermissions = 0x3068, GuildShiftRank = 0x3067, GuildUpdateInfoText = 0x3076, GuildUpdateMotdText = 0x3075, HearthAndResurrect = 0x3515, - HideQuestChoice = 0x32b6, + HideQuestChoice = 0x32be, HotfixRequest = 0x35e5, IgnoreTrade = 0x3159, InitiateRolePoll = 0x35da, InitiateTrade = 0x3156, - Inspect = 0x353b, + Inspect = 0x353c, InstanceLockResponse = 0x351a, - IslandQueue = 0x33a7, - ItemPurchaseRefund = 0x3542, - ItemTextQuery = 0x3342, + IslandQueue = 0x33b1, + ItemPurchaseRefund = 0x3543, + ItemTextQuery = 0x334b, JoinPetBattleQueue = 0x31df, JoinRatedBattleground = 0x3179, - KeepAlive = 0x367e, - KeyboundOverride = 0x322b, + KeepAlive = 0x367f, + KeyboundOverride = 0x322e, LatencyReport = 0x3771, - LearnPvpTalents = 0x356a, - LearnTalents = 0x3568, - LeaveGroup = 0x3648, + LearnPvpTalents = 0x356b, + LearnTalents = 0x3569, + LeaveGroup = 0x3649, LeavePetBattleQueue = 0x31e0, LfgListApplyToGroup = 0x360d, LfgListCancelApplication = 0x360e, @@ -409,101 +428,117 @@ namespace Framework.Constants LfgListGetStatus = 0x360b, LfgListInviteApplicant = 0x3610, LfgListInviteResponse = 0x3611, - LfgListJoin = 0x3386, + LfgListJoin = 0x338f, LfgListLeave = 0x360a, LfgListSearch = 0x360c, - LfgListUpdateRequest = 0x3387, + LfgListUpdateRequest = 0x3390, ListInventory = 0x34a7, - LiveRegionAccountRestore = 0x36b5, - LiveRegionCharacterCopy = 0x36b4, - LiveRegionGetAccountCharacterList = 0x36b3, - LiveRegionKeyBindingsCopy = 0x36b6, + LiveRegionAccountRestore = 0x36b7, + LiveRegionCharacterCopy = 0x36b6, + LiveRegionGetAccountCharacterList = 0x36b5, + LiveRegionKeyBindingsCopy = 0x36b8, LoadingScreenNotify = 0x35f8, - LoadSelectedTrophy = 0x3324, + LoadSelectedTrophy = 0x332d, LogoutCancel = 0x34e6, LogoutInstant = 0x34e7, LogoutRequest = 0x34e4, LogDisconnect = 0x3769, LogStreamingError = 0x376d, - LootItem = 0x3216, - LootMoney = 0x3215, - LootRelease = 0x321a, - LootRoll = 0x321b, - LootUnit = 0x3214, - LowLevelRaid1 = 0x369e, + LootItem = 0x3219, + LootMoney = 0x3218, + LootRelease = 0x321d, + LootRoll = 0x321e, + LootUnit = 0x3217, + LowLevelRaid1 = 0x36a0, LowLevelRaid2 = 0x3521, - MailCreateTextItem = 0x354d, - MailDelete = 0x322d, - MailGetList = 0x3548, - MailMarkAsRead = 0x354c, - MailReturnToSender = 0x3654, - MailTakeItem = 0x354a, - MailTakeMoney = 0x3549, - MakeContitionalAppearancePermanent = 0x322f, - MasterLootItem = 0x3217, + MailCreateTextItem = 0x354e, + MailDelete = 0x3230, + MailGetList = 0x3549, + MailMarkAsRead = 0x354d, + MailReturnToSender = 0x3655, + MailTakeItem = 0x354b, + MailTakeMoney = 0x354a, + MakeContitionalAppearancePermanent = 0x3232, + MasterLootItem = 0x321a, MergeGuildBankItemWithGuildBankItem = 0x34c7, MergeGuildBankItemWithItem = 0x34c4, MergeItemWithGuildBankItem = 0x34c2, - MinimapPing = 0x364a, + MinimapPing = 0x364b, MissileTrajectoryCollision = 0x318b, MountClearFanfare = 0x312d, MountSetFavorite = 0x3632, - MountSpecialAnim = 0x3291, - MoveApplyInertiaAck = 0x3a4f, - MoveApplyMovementForceAck = 0x3a16, - MoveChangeTransport = 0x3a30, - MoveChangeVehicleSeats = 0x3a35, - MoveCollisionDisableAck = 0x3a3a, - MoveCollisionEnableAck = 0x3a3b, - MoveDismissVehicle = 0x3a34, + MountSpecialAnim = 0x3297, + MoveAddImpulseAck = 0x3a50, + MoveApplyInertiaAck = 0x3a4e, + MoveApplyMovementForceAck = 0x3a15, + MoveChangeTransport = 0x3a2f, + MoveChangeVehicleSeats = 0x3a34, + MoveCollisionDisableAck = 0x3a39, + MoveCollisionEnableAck = 0x3a3a, + MoveDismissVehicle = 0x3a33, MoveDoubleJump = 0x39eb, - MoveEnableDoubleJumpAck = 0x3a1f, - MoveEnableSwimToFlyTransAck = 0x3a25, + MoveEnableDoubleJumpAck = 0x3a1e, + MoveEnableSwimToFlyTransAck = 0x3a24, MoveFallLand = 0x39fb, - MoveFallReset = 0x3a1a, - MoveFeatherFallAck = 0x3a1d, - MoveForceFlightBackSpeedChangeAck = 0x3a2f, - MoveForceFlightSpeedChangeAck = 0x3a2e, - MoveForcePitchRateChangeAck = 0x3a33, - MoveForceRootAck = 0x3a0f, - MoveForceRunBackSpeedChangeAck = 0x3a0d, - MoveForceRunSpeedChangeAck = 0x3a0c, - MoveForceSwimBackSpeedChangeAck = 0x3a23, - MoveForceSwimSpeedChangeAck = 0x3a0e, - MoveForceTurnRateChangeAck = 0x3a24, - MoveForceUnrootAck = 0x3a10, - MoveForceWalkSpeedChangeAck = 0x3a22, - MoveGravityDisableAck = 0x3a36, - MoveGravityEnableAck = 0x3a37, + MoveFallReset = 0x3a19, + MoveFeatherFallAck = 0x3a1c, + MoveForceFlightBackSpeedChangeAck = 0x3a2e, + MoveForceFlightSpeedChangeAck = 0x3a2d, + MoveForcePitchRateChangeAck = 0x3a32, + MoveForceRootAck = 0x3a0e, + MoveForceRunBackSpeedChangeAck = 0x3a0c, + MoveForceRunSpeedChangeAck = 0x3a0b, + MoveForceSwimBackSpeedChangeAck = 0x3a22, + MoveForceSwimSpeedChangeAck = 0x3a0d, + MoveForceTurnRateChangeAck = 0x3a23, + MoveForceUnrootAck = 0x3a0f, + MoveForceWalkSpeedChangeAck = 0x3a21, + MoveGravityDisableAck = 0x3a35, + MoveGravityEnableAck = 0x3a36, MoveGuildBankItem = 0x34c1, - MoveHeartbeat = 0x3a11, - MoveHoverAck = 0x3a14, - MoveInertiaDisableAck = 0x3a38, - MoveInertiaEnableAck = 0x3a39, - MoveInitActiveMoverComplete = 0x3a47, + MoveHeartbeat = 0x3a10, + MoveHoverAck = 0x3a13, + MoveInertiaDisableAck = 0x3a37, + MoveInertiaEnableAck = 0x3a38, + MoveInitActiveMoverComplete = 0x3a46, MoveJump = 0x39ea, - MoveKnockBackAck = 0x3a13, - MoveRemoveInertiaAck = 0x3a50, - MoveRemoveMovementForces = 0x3a18, - MoveRemoveMovementForceAck = 0x3a17, - MoveSeamlessTransferComplete = 0x3a45, - MoveSetCanFlyAck = 0x3a28, - MoveSetCanTurnWhileFallingAck = 0x3a26, - MoveSetCollisionHeightAck = 0x3a3c, - MoveSetFacing = 0x3a0a, - MoveSetFacingHeartbeat = 0x3a09, - MoveSetFly = 0x3a29, - MoveSetIgnoreMovementForcesAck = 0x3a27, - MoveSetModMovementForceMagnitudeAck = 0x3a43, - MoveSetPitch = 0x3a0b, + MoveKnockBackAck = 0x3a12, + MoveRemoveInertiaAck = 0x3a4f, + MoveRemoveMovementForces = 0x3a17, + MoveRemoveMovementForceAck = 0x3a16, + MoveSeamlessTransferComplete = 0x3a44, + MoveSetAdvFly = 0x3a52, + MoveSetAdvFlyingAddImpulseMaxSpeedAck = 0x3a58, + MoveSetAdvFlyingAirFrictionAck = 0x3a53, + MoveSetAdvFlyingBankingRateAck = 0x3a59, + MoveSetAdvFlyingDoubleJumpVelModAck = 0x3a56, + MoveSetAdvFlyingGlideStartMinHeightAck = 0x3a57, + MoveSetAdvFlyingLaunchSpeedCoefficientAck = 0x3a60, + MoveSetAdvFlyingLiftCoefficientAck = 0x3a55, + MoveSetAdvFlyingMaxVelAck = 0x3a54, + MoveSetAdvFlyingOverMaxDecelerationAck = 0x3a5e, + MoveSetAdvFlyingPitchingRateDownAck = 0x3a5a, + MoveSetAdvFlyingPitchingRateUpAck = 0x3a5b, + MoveSetAdvFlyingSurfaceFrictionAck = 0x3a5d, + MoveSetAdvFlyingTurnVelocityThresholdAck = 0x3a5c, + MoveSetCanAdvFlyAck = 0x3a51, + MoveSetCanFlyAck = 0x3a27, + MoveSetCanTurnWhileFallingAck = 0x3a25, + MoveSetCollisionHeightAck = 0x3a3b, + MoveSetFacing = 0x3a09, + MoveSetFacingHeartbeat = 0x3a5f, + MoveSetFly = 0x3a28, + MoveSetIgnoreMovementForcesAck = 0x3a26, + MoveSetModMovementForceMagnitudeAck = 0x3a42, + MoveSetPitch = 0x3a0a, MoveSetRunMode = 0x39f2, MoveSetTurnRateCheat = 0x3a06, - MoveSetVehicleRecIdAck = 0x3a15, + MoveSetVehicleRecIdAck = 0x3a14, MoveSetWalkMode = 0x39f3, - MoveSplineDone = 0x3a19, - MoveStartAscend = 0x3a2a, + MoveSplineDone = 0x3a18, + MoveStartAscend = 0x3a29, MoveStartBackward = 0x39e5, - MoveStartDescend = 0x3a31, + MoveStartDescend = 0x3a30, MoveStartForward = 0x39e4, MoveStartPitchDown = 0x39f0, MoveStartPitchUp = 0x39ef, @@ -513,51 +548,51 @@ namespace Framework.Constants MoveStartTurnLeft = 0x39ec, MoveStartTurnRight = 0x39ed, MoveStop = 0x39e6, - MoveStopAscend = 0x3a2b, + MoveStopAscend = 0x3a2a, MoveStopPitch = 0x39f1, MoveStopStrafe = 0x39e9, MoveStopSwim = 0x39fd, MoveStopTurn = 0x39ee, MoveTeleportAck = 0x39fa, - MoveTimeSkipped = 0x3a1c, - MoveUpdateFallSpeed = 0x3a1b, - MoveWaterWalkAck = 0x3a1e, + MoveTimeSkipped = 0x3a1b, + MoveUpdateFallSpeed = 0x3a1a, + MoveWaterWalkAck = 0x3a1d, MythicPlusRequestMapStats = 0x308f, NeutralPlayerSelectFaction = 0x31d5, - NextCinematicCamera = 0x3556, + NextCinematicCamera = 0x3557, ObjectUpdateFailed = 0x3181, ObjectUpdateRescued = 0x3182, - OfferPetition = 0x33ce, - OpeningCinematic = 0x3555, - OpenItem = 0x3343, - OpenMissionNpc = 0x3307, - OpenShipmentNpc = 0x330f, - OpenTradeskillNpc = 0x331a, + OfferPetition = 0x33d8, + OpeningCinematic = 0x3556, + OpenItem = 0x334c, + OpenMissionNpc = 0x330f, + OpenShipmentNpc = 0x3317, + OpenTradeskillNpc = 0x3322, OptOutOfLoot = 0x3504, OverrideScreenFlash = 0x352e, PartyInvite = 0x3602, PartyInviteResponse = 0x3604, - PartyUninvite = 0x3646, - PerformItemInteraction = 0x3237, + PartyUninvite = 0x3647, + PerformItemInteraction = 0x323a, PetitionBuy = 0x34cf, - PetitionRenameGuild = 0x36c5, + PetitionRenameGuild = 0x36c7, PetitionShowList = 0x34ce, PetitionShowSignatures = 0x34d0, PetAbandon = 0x3493, PetAction = 0x3491, PetBattleFinalNotify = 0x31e4, - PetBattleInput = 0x3640, - PetBattleQueueProposeMatchResult = 0x322c, + PetBattleInput = 0x3641, + PetBattleQueueProposeMatchResult = 0x322f, PetBattleQuitNotify = 0x31e3, - PetBattleReplaceFrontPet = 0x3641, + PetBattleReplaceFrontPet = 0x3642, PetBattleRequestPvp = 0x31dd, PetBattleRequestUpdate = 0x31de, PetBattleRequestWild = 0x31db, PetBattleScriptErrorNotify = 0x31e5, PetBattleWildLocationFail = 0x31dc, PetCancelAura = 0x3494, - PetCastSpell = 0x32ab, - PetRename = 0x3683, + PetCastSpell = 0x32b3, + PetRename = 0x3684, PetSetAction = 0x3490, PetSpellAutocast = 0x3495, PetStopAttack = 0x3492, @@ -565,189 +600,193 @@ namespace Framework.Constants PlayerLogin = 0x35ea, PushQuestToParty = 0x34a5, PvpLogData = 0x317c, - QueryBattlePetName = 0x3284, - QueryCorpseLocationFromClient = 0x365f, - QueryCorpseTransport = 0x3660, + QueryBattlePetName = 0x328a, + QueryCorpseLocationFromClient = 0x3660, + QueryCorpseTransport = 0x3661, QueryCountdownTimer = 0x31aa, - QueryCreature = 0x327e, - QueryGameObject = 0x327f, - QueryGarrisonPetName = 0x3285, - QueryGuildInfo = 0x3689, + QueryCreature = 0x3284, + QueryGameObject = 0x3285, + QueryGarrisonPetName = 0x328b, + QueryGuildInfo = 0x368a, QueryInspectAchievements = 0x350e, - QueryNextMailTime = 0x354b, - QueryNpcText = 0x3280, - QueryPageText = 0x3282, - QueryPetition = 0x3286, - QueryPetName = 0x3283, + QueryNextMailTime = 0x354c, + QueryNpcText = 0x3286, + QueryPageText = 0x3288, + QueryPetition = 0x328c, + QueryPetName = 0x3289, QueryPlayerNames = 0x3772, QueryPlayerNamesForCommunity = 0x3770, QueryPlayerNameByCommunityId = 0x376f, QueryQuestCompletionNpcs = 0x3175, - QueryQuestInfo = 0x3281, - QueryRealmName = 0x3688, - QueryScenarioPoi = 0x3655, + QueryQuestInfo = 0x3287, + QueryQuestItemUsability = 0x3176, + QueryRealmName = 0x3689, + QueryScenarioPoi = 0x3656, QueryTime = 0x34e3, - QueryTreasurePicker = 0x3367, + QueryTreasurePicker = 0x3370, QueryVoidStorage = 0x31a3, QuestConfirmAccept = 0x34a4, QuestGiverAcceptQuest = 0x349e, QuestGiverChooseReward = 0x34a0, - QuestGiverCloseQuest = 0x355c, + QuestGiverCloseQuest = 0x355d, QuestGiverCompleteQuest = 0x349f, QuestGiverHello = 0x349c, QuestGiverQueryQuest = 0x349d, QuestGiverRequestReward = 0x34a1, QuestGiverStatusMultipleQuery = 0x34a3, QuestGiverStatusQuery = 0x34a2, - QuestLogRemoveQuest = 0x3540, - QuestPoiQuery = 0x36ac, + QuestLogRemoveQuest = 0x3541, + QuestPoiQuery = 0x36ae, QuestPushResult = 0x34a6, - QuestSessionBeginResponse = 0x33bf, - QuestSessionRequestStart = 0x33be, - QuestSessionRequestStop = 0x3729, + QuestSessionBeginResponse = 0x33c9, + QuestSessionRequestStart = 0x33c8, + QuestSessionRequestStop = 0x372b, QueuedMessagesEnd = 0x376c, - QuickJoinAutoAcceptRequests = 0x3702, - QuickJoinRequestInvite = 0x3701, - QuickJoinRequestInviteWithConfirmation = 0x372e, - QuickJoinRespondToInvite = 0x3700, - QuickJoinSignalToastDisplayed = 0x36ff, + QuickJoinAutoAcceptRequests = 0x3704, + QuickJoinRequestInvite = 0x3703, + QuickJoinRequestInviteWithConfirmation = 0x3730, + QuickJoinRespondToInvite = 0x3702, + QuickJoinSignalToastDisplayed = 0x3701, RafClaimActivityReward = 0x3512, - RafClaimNextReward = 0x371f, - RafGenerateRecruitmentLink = 0x3721, - RafUpdateRecruitmentInfo = 0x3720, - RandomRoll = 0x3653, + RafClaimNextReward = 0x3721, + RafGenerateRecruitmentLink = 0x3723, + RafUpdateRecruitmentInfo = 0x3722, + RandomRoll = 0x3654, ReadyCheckResponse = 0x3635, - ReadItem = 0x3344, + ReadItem = 0x334d, ReclaimCorpse = 0x34e9, - RemoveNewItem = 0x336a, - RemoveRafRecruit = 0x3722, + RemoveNewItem = 0x3373, + RemoveRafRecruit = 0x3724, ReorderCharacters = 0x35e9, RepairItem = 0x34fa, - ReplaceTrophy = 0x3325, - RepopRequest = 0x3538, - ReportClientVariables = 0x36fc, - ReportEnabledAddons = 0x36fb, - ReportKeybindingExecutionCounts = 0x36fd, + ReplaceTrophy = 0x332e, + RepopRequest = 0x3539, + ReportClientVariables = 0x36fe, + ReportEnabledAddons = 0x36fd, + ReportFrozenWhileLoadingMap = 0x36a6, + ReportKeybindingExecutionCounts = 0x36ff, ReportPvpPlayerAfk = 0x3502, - ReportServerLag = 0x33b7, - ReportStuckInCombat = 0x33b8, - RequestAccountData = 0x3693, - RequestAreaPoiUpdate = 0x3369, + ReportServerLag = 0x33c1, + ReportStuckInCombat = 0x33c2, + RequestAccountData = 0x3694, + RequestAreaPoiUpdate = 0x3372, RequestBattlefieldStatus = 0x35dc, RequestCategoryCooldowns = 0x317e, RequestCemeteryList = 0x3177, - RequestCharacterGuildFollowInfo = 0x368a, - RequestConquestFormulaConstants = 0x32c8, - RequestCovenantCallings = 0x33a9, - RequestCrowdControlSpell = 0x353c, - RequestForcedReactions = 0x320f, - RequestGarrisonTalentWorldQuestUnlocks = 0x33e3, + RequestCharacterGuildFollowInfo = 0x368b, + RequestConquestFormulaConstants = 0x32d0, + RequestCovenantCallings = 0x33b3, + RequestCrowdControlSpell = 0x353d, + RequestForcedReactions = 0x320e, + RequestGarrisonTalentWorldQuestUnlocks = 0x33ed, RequestGuildPartyState = 0x31a9, RequestGuildRewardsList = 0x31a8, - RequestLatestSplashScreen = 0x33b9, - RequestLfgListBlacklist = 0x32b7, - RequestMythicPlusAffixes = 0x3209, - RequestMythicPlusSeasonData = 0x320a, + RequestLatestSplashScreen = 0x33c3, + RequestLfgListBlacklist = 0x32bf, + RequestMythicPlusAffixes = 0x3208, + RequestMythicPlusSeasonData = 0x3209, RequestPartyJoinUpdates = 0x35f7, - RequestPartyMemberStats = 0x3652, + RequestPartyMemberStats = 0x3653, RequestPetInfo = 0x3496, - RequestPlayedTime = 0x3289, + RequestPlayedTime = 0x328f, RequestPvpRewards = 0x3196, - RequestRaidInfo = 0x36c6, + RequestRaidInfo = 0x36c8, RequestRatedPvpInfo = 0x35e3, RequestRealmGuildMasterInfo = 0x309b, RequestResearchHistory = 0x3167, RequestScheduledPvpInfo = 0x3197, RequestStabledPets = 0x3497, - RequestVehicleExit = 0x3241, - RequestVehicleNextSeat = 0x3243, - RequestVehiclePrevSeat = 0x3242, - RequestVehicleSwitchSeat = 0x3244, - RequestWeeklyRewards = 0x33ac, - RequestWorldQuestUpdate = 0x3368, - ResetChallengeMode = 0x3207, - ResetChallengeModeCheat = 0x3208, - ResetInstances = 0x3667, - ResurrectResponse = 0x3682, - RevertMonumentAppearance = 0x3327, - RideVehicleInteract = 0x3245, + RequestVehicleExit = 0x3244, + RequestVehicleNextSeat = 0x3246, + RequestVehiclePrevSeat = 0x3245, + RequestVehicleSwitchSeat = 0x3247, + RequestWeeklyRewards = 0x33b6, + RequestWorldQuestUpdate = 0x3371, + ResetChallengeMode = 0x3206, + ResetChallengeModeCheat = 0x3207, + ResetInstances = 0x3668, + ResurrectResponse = 0x3683, + RevertMonumentAppearance = 0x3330, + RideVehicleInteract = 0x3248, SaveCufProfiles = 0x318c, SaveEquipmentSet = 0x3518, - SaveGuildEmblem = 0x32bb, - ScenePlaybackCanceled = 0x3228, - ScenePlaybackComplete = 0x3227, - SceneTriggerEvent = 0x3229, - SelfRes = 0x3543, + SaveGuildEmblem = 0x32c3, + ScenePlaybackCanceled = 0x322b, + ScenePlaybackComplete = 0x322a, + SceneTriggerEvent = 0x322c, + SelfRes = 0x3544, SellItem = 0x34a8, - SendCharacterClubInvitation = 0x36f5, - SendContactList = 0x36cb, + SendCharacterClubInvitation = 0x36f7, + SendContactList = 0x36cd, SendMail = 0x35fa, SendTextEmote = 0x348e, - ServerTimeOffsetRequest = 0x3699, - SetAchievementsHidden = 0x322e, - SetActionBarToggles = 0x3544, + ServerTimeOffsetRequest = 0x369b, + SetAchievementsHidden = 0x3231, + SetActionBarToggles = 0x3545, SetActionButton = 0x3636, - SetActiveMover = 0x3a3d, - SetAdvancedCombatLogging = 0x32c9, - SetAssistantLeader = 0x364e, - SetBackpackAutosortDisabled = 0x3347, - SetBankAutosortDisabled = 0x3348, - SetChatDisabled = 0x3735, - SetContactNotes = 0x36ce, + SetActiveMover = 0x3a3c, + SetAdvancedCombatLogging = 0x32d1, + SetAssistantLeader = 0x364f, + SetBackpackAutosortDisabled = 0x3350, + SetBankAutosortDisabled = 0x3351, + SetContactNotes = 0x36d0, SetCurrencyFlags = 0x3169, - SetDifficultyId = 0x322a, - SetDungeonDifficulty = 0x3681, + SetDifficultyId = 0x322d, + SetDungeonDifficulty = 0x3682, + SetEmpowerMinHoldStagePercent = 0x327e, SetEveryoneIsAssistant = 0x3618, SetFactionAtWar = 0x34ec, SetFactionInactive = 0x34ee, SetFactionNotAtWar = 0x34ed, SetGameEventDebugViewState = 0x31ba, - SetInsertItemsLeftToRight = 0x334a, - SetLootMethod = 0x3647, - SetLootSpecialization = 0x3551, - SetPartyAssignment = 0x3650, - SetPartyLeader = 0x3649, + SetInsertItemsLeftToRight = 0x3353, + SetLootMethod = 0x3648, + SetLootSpecialization = 0x3552, + SetPartyAssignment = 0x3651, + SetPartyLeader = 0x364a, SetPetSlot = 0x3168, - SetPlayerDeclinedNames = 0x3687, + SetPlayerDeclinedNames = 0x3688, SetPreferredCemetery = 0x3178, - SetPvp = 0x32bf, - SetRaidDifficulty = 0x36d7, + SetPvp = 0x32c7, + SetRaidDifficulty = 0x36d9, SetRole = 0x35d9, - SetSavedInstanceExtend = 0x3685, - SetSelection = 0x353a, + SetSavedInstanceExtend = 0x3686, + SetSelection = 0x353b, SetSheathed = 0x348f, - SetSortBagsRightToLeft = 0x3349, + SetSortBagsRightToLeft = 0x3352, SetTaxiBenchmarkMode = 0x3501, - SetTitle = 0x328f, + SetTitle = 0x3295, SetTradeCurrency = 0x3160, SetTradeGold = 0x315f, SetTradeItem = 0x315d, - SetUsingPartyGarrison = 0x3309, - SetWarMode = 0x32c0, + SetUsingPartyGarrison = 0x3311, + SetWarMode = 0x32c8, SetWatchedFaction = 0x34ef, - ShowTradeSkill = 0x36be, - SignPetition = 0x3545, - SilencePartyTalker = 0x3651, - SocialContractRequest = 0x373a, + ShowTradeSkill = 0x36c0, + SignPetition = 0x3546, + SilencePartyTalker = 0x3652, + SocialContractRequest = 0x373d, SocketGems = 0x34f9, - SortBags = 0x334b, - SortBankBags = 0x334c, - SortReagentBankBags = 0x334d, + SortBags = 0x3354, + SortBankBags = 0x3355, + SortReagentBankBags = 0x3356, SpellClick = 0x349b, + SpellEmpowerRelease = 0x327c, + SpellEmpowerRestart = 0x327d, SpiritHealerActivate = 0x34b5, SplitGuildBankItem = 0x34c8, SplitGuildBankItemToInventory = 0x34c5, SplitItem = 0x399e, SplitItemToGuildBank = 0x34c3, StandStateChange = 0x318a, - StartChallengeMode = 0x355d, + StartChallengeMode = 0x355e, StartSpectatorWarGame = 0x35df, StartWarGame = 0x35de, StoreGuildBankItem = 0x34be, - SubmitUserFeedback = 0x3692, - SubscriptionInterstitialResponse = 0x33d8, - SummonResponse = 0x3669, - SupportTicketSubmitComplaint = 0x3645, + SubmitUserFeedback = 0x3693, + SubscriptionInterstitialResponse = 0x33e2, + SummonResponse = 0x366a, + SupportTicketSubmitComplaint = 0x3646, SurrenderArena = 0x3174, SuspendCommsAck = 0x3764, SuspendTokenResponse = 0x376a, @@ -755,61 +794,65 @@ namespace Framework.Constants SwapInvItem = 0x399d, SwapItem = 0x399c, SwapItemWithGuildBankItem = 0x34bf, - SwapSubGroups = 0x364c, + SwapSubGroups = 0x364d, SwapVoidItem = 0x31a5, - TabardVendorActivate = 0x32bc, + TabardVendorActivate = 0x32c4, TalkToGossip = 0x3498, TaxiNodeStatusQuery = 0x34ae, TaxiQueryAvailableNodes = 0x34b0, TaxiRequestEarlyLanding = 0x34b2, - TimeAdjustmentResponse = 0x3a41, - TimeSyncResponse = 0x3a3e, - TimeSyncResponseDropped = 0x3a40, - TimeSyncResponseFailed = 0x3a3f, - ToggleDifficulty = 0x3656, - TogglePvp = 0x32be, + TimeAdjustmentResponse = 0x3a40, + TimeSyncResponse = 0x3a3d, + TimeSyncResponseDropped = 0x3a3f, + TimeSyncResponseFailed = 0x3a3e, + ToggleDifficulty = 0x3657, + TogglePvp = 0x32c6, TotemDestroyed = 0x3506, ToyClearFanfare = 0x312e, - TradeSkillSetFavorite = 0x3366, + TradeSkillSetFavorite = 0x336f, TrainerBuySpell = 0x34b4, TrainerList = 0x34b3, + TraitsCommitConfig = 0x3401, + TraitsTalentTestUnlearnSpells = 0x33ff, TransmogrifyItems = 0x3198, - TurnInPetition = 0x3547, - Tutorial = 0x36d8, + TurnInPetition = 0x3548, + Tutorial = 0x36da, TwitterCheckStatus = 0x312a, TwitterConnect = 0x3127, TwitterDisconnect = 0x312b, - UiMapQuestLinesRequest = 0x33a8, + UiMapQuestLinesRequest = 0x33b2, UnacceptTrade = 0x315b, - UndeleteCharacter = 0x36da, + UndeleteCharacter = 0x36dc, UnlearnSkill = 0x34f3, UnlearnSpecialization = 0x31a6, UnlockVoidStorage = 0x31a2, - UpdateAccountData = 0x3694, - UpdateAreaTriggerVisual = 0x32ae, - UpdateClientSettings = 0x3663, - UpdateMissileTrajectory = 0x3a44, - UpdateRaidTarget = 0x364f, - UpdateSpellVisual = 0x32ad, - UpdateVasPurchaseStates = 0x36ef, - UpgradeGarrison = 0x32d1, - UpgradeRuneforgeLegendary = 0x33d6, + UpdateAadcStatus = 0x3737, + UpdateAccountData = 0x3695, + UpdateAreaTriggerVisual = 0x32b6, + UpdateClientSettings = 0x3664, + UpdateCraftingNpcRecipes = 0x3323, + UpdateMissileTrajectory = 0x3a43, + UpdateRaidTarget = 0x3650, + UpdateSpellVisual = 0x32b5, + UpdateVasPurchaseStates = 0x36f1, + UpgradeGarrison = 0x32d9, + UpgradeRuneforgeLegendary = 0x33e0, UsedFollow = 0x3187, - UseCritterItem = 0x324b, + UseCritterItem = 0x324e, UseEquipmentSet = 0x3995, - UseItem = 0x32a7, - UseToy = 0x32aa, - VasCheckTransferOk = 0x3707, - VasGetQueueMinutes = 0x3706, - VasGetServiceStatus = 0x3705, + UseItem = 0x32af, + UseToy = 0x32b2, + VasCheckTransferOk = 0x3709, + VasGetQueueMinutes = 0x3708, + VasGetServiceStatus = 0x3707, ViolenceLevel = 0x3185, - VoiceChannelSttTokenRequest = 0x370b, - VoiceChatJoinChannel = 0x370c, - VoiceChatLogin = 0x370a, + VoiceChannelSttTokenRequest = 0x370d, + VoiceChatJoinChannel = 0x370e, + VoiceChatLogin = 0x370c, VoidStorageTransfer = 0x31a4, Warden3Data = 0x35ec, - Who = 0x3680, - WhoIs = 0x367f, + Who = 0x3681, + WhoIs = 0x3680, WorldPortResponse = 0x35f9, WrapItem = 0x3994, @@ -819,87 +862,85 @@ namespace Framework.Constants public enum ServerOpcodes : uint { - AbortNewWorld = 0x259a, - AccountCosmeticAdded = 0x2872, - AccountCriteriaUpdate = 0x2858, - AccountDataTimes = 0x26fe, - AccountMountUpdate = 0x25ac, - AccountNotificationsResponse = 0x2871, - AccountToyUpdate = 0x25ad, - AccountTransmogSetFavoritesUpdate = 0x25b0, - AccountTransmogUpdate = 0x25af, - AchievementDeleted = 0x26dd, - AchievementEarned = 0x263b, + AbortNewWorld = 0x259c, + AccountCosmeticAdded = 0x287b, + AccountCriteriaUpdate = 0x2861, + AccountDataTimes = 0x2704, + AccountMountUpdate = 0x25af, + AccountNotificationsResponse = 0x287a, + AccountToyUpdate = 0x25b0, + AccountTransmogSetFavoritesUpdate = 0x25b3, + AccountTransmogUpdate = 0x25b2, + AchievementDeleted = 0x26e2, + AchievementEarned = 0x2640, ActivateEssenceFailed = 0x3015, ActivateSoulbindFailed = 0x3017, - ActivateTaxiReply = 0x2675, - ActiveGlyphs = 0x2c54, - AddonListRequest = 0x263a, - AddBattlenetFriendResponse = 0x2635, - AddItemPassive = 0x25a8, - AddLossOfControl = 0x2669, - AddRunePower = 0x26af, - AdjustSplineDuration = 0x25cc, - AdvancedCombatLog = 0x286e, - AdventureJournalDataResponse = 0x2868, - AdventureMapOpenNpc = 0x27e5, - AeLootTargets = 0x2610, - AeLootTargetAck = 0x2611, - AiReaction = 0x26ac, - AlliedRaceDetails = 0x27eb, + ActivateTaxiReply = 0x267a, + ActiveGlyphs = 0x2c57, + AddonListRequest = 0x263f, + AddBattlenetFriendResponse = 0x263a, + AddItemPassive = 0x25ab, + AddLossOfControl = 0x266e, + AddRunePower = 0x26b4, + AdjustSplineDuration = 0x25cf, + AdvancedCombatLog = 0x2877, + AdventureJournalDataResponse = 0x2871, + AeLootTargets = 0x2615, + AeLootTargetAck = 0x2616, + AiReaction = 0x26b1, + AlliedRaceDetails = 0x27f4, AllAccountCriteria = 0x2571, AllAchievementData = 0x2570, AllGuildAchievements = 0x29b8, - ApplyMountEquipmentResult = 0x2845, + ApplyMountEquipmentResult = 0x284e, ArchaeologySurveryCast = 0x2588, AreaPoiUpdateResponse = 0x3010, - AreaSpiritHealerTime = 0x2733, + AreaSpiritHealerTime = 0x2739, AreaTriggerDenied = 0x2902, AreaTriggerForceSetPositionAndFacing = 0x28ff, - AreaTriggerNoCorpse = 0x270a, + AreaTriggerNoCorpse = 0x2710, AreaTriggerPlaySpellVisual = 0x28fe, AreaTriggerRePath = 0x28fd, AreaTriggerReShape = 0x2901, AreaTriggerUnattach = 0x2900, - ArenaClearOpponents = 0x2641, - ArenaCrowdControlSpellResult = 0x262a, - ArenaPrepOpponentSpecializations = 0x2640, - ArtifactEndgamePowersRefunded = 0x2796, - ArtifactForgeError = 0x2794, - ArtifactRespecPrompt = 0x2795, - ArtifactXpGain = 0x27de, + ArenaClearOpponents = 0x2646, + ArenaCrowdControlSpellResult = 0x262f, + ArenaPrepOpponentSpecializations = 0x2645, + ArtifactEndgamePowersRefunded = 0x279e, + ArtifactForgeError = 0x279c, + ArtifactRespecPrompt = 0x279d, + ArtifactXpGain = 0x27e7, AttackerStateUpdate = 0x294d, AttackStart = 0x2938, AttackStop = 0x2939, AttackSwingError = 0x2947, AttackSwingLandedLog = 0x2948, - AuctionableTokenAuctionSold = 0x27c7, - AuctionableTokenSellAtMarketPriceResponse = 0x27c6, - AuctionableTokenSellConfirmRequired = 0x27c5, - AuctionClosedNotification = 0x26e7, - AuctionCommandResult = 0x26e4, - AuctionDisablePostingBeforeMaintenance = 0x287F, - AuctionFavoriteList = 0x285f, - AuctionGetCommodityQuoteResult = 0x2856, - AuctionHelloResponse = 0x26e2, - AuctionListBiddedItemsResult = 0x2855, - AuctionListBucketsResult = 0x2852, - AuctionListItemsResult = 0x2853, - AuctionListOwnedItemsResult = 0x2854, - AuctionOutbidNotification = 0x26e6, - AuctionOwnerBidNotification = 0x26e8, - AuctionReplicateResponse = 0x26e3, - AuctionWonNotification = 0x26e5, + AuctionableTokenAuctionSold = 0x27d0, + AuctionableTokenSellAtMarketPriceResponse = 0x27cf, + AuctionableTokenSellConfirmRequired = 0x27ce, + AuctionClosedNotification = 0x26ed, + AuctionCommandResult = 0x26ea, + AuctionDisableNewPostings = 0x288d, + AuctionFavoriteList = 0x2868, + AuctionGetCommodityQuoteResult = 0x285f, + AuctionHelloResponse = 0x26e8, + AuctionListBiddedItemsResult = 0x285e, + AuctionListBucketsResult = 0x285b, + AuctionListItemsResult = 0x285c, + AuctionListOwnedItemsResult = 0x285d, + AuctionOutbidNotification = 0x26ec, + AuctionOwnerBidNotification = 0x26ee, + AuctionReplicateResponse = 0x26e9, + AuctionWonNotification = 0x26eb, AuraPointsDepleted = 0x2c23, AuraUpdate = 0x2c22, AuthChallenge = 0x3048, AuthFailed = 0x256c, AuthResponse = 0x256d, AvailableHotfixes = 0x290f, - AzeriteRespecNpc = 0x27e8, BagCleanupFinished = 0x2da7, - BarberShopResult = 0x26b4, - BatchPresenceSubscription = 0x2836, + BarberShopResult = 0x26b9, + BatchPresenceSubscription = 0x283f, BattlefieldList = 0x2927, BattlefieldPortDenied = 0x292d, BattlefieldStatusActive = 0x2923, @@ -915,113 +956,112 @@ namespace Framework.Constants BattlegroundPlayerLeft = 0x292c, BattlegroundPlayerPositions = 0x2928, BattlegroundPoints = 0x2949, - BattlenetChallengeAbort = 0x277d, - BattlenetChallengeStart = 0x277c, - BattlenetNotification = 0x27f6, - BattlenetResponse = 0x27f5, - BattleNetConnectionStatus = 0x27f7, - BattlePayAckFailed = 0x2777, - BattlePayBattlePetDelivered = 0x276c, - BattlePayCollectionItemDelivered = 0x276d, - BattlePayConfirmPurchase = 0x2776, - BattlePayDeliveryEnded = 0x276a, - BattlePayDeliveryStarted = 0x2769, - BattlePayDistributionAssignVasResponse = 0x2877, - BattlePayDistributionUnrevoked = 0x2767, - BattlePayDistributionUpdate = 0x2768, - BattlePayGetDistributionListResponse = 0x2766, - BattlePayGetProductListResponse = 0x2764, - BattlePayGetPurchaseListResponse = 0x2765, - BattlePayMountDelivered = 0x276b, - BattlePayPurchaseUpdate = 0x2775, - BattlePayStartCheckout = 0x2812, - BattlePayStartDistributionAssignToTargetResponse = 0x2773, - BattlePayStartPurchaseResponse = 0x2772, - BattlePayValidatePurchaseResponse = 0x2806, - BattlePetsHealed = 0x25ec, - BattlePetCageDateError = 0x2670, - BattlePetDeleted = 0x25e9, - BattlePetError = 0x2630, - BattlePetJournal = 0x25e8, - BattlePetJournalLockAcquired = 0x25e6, - BattlePetJournalLockDenied = 0x25e7, - BattlePetLicenseChanged = 0x25ed, - BattlePetRestored = 0x25eb, - BattlePetRevoked = 0x25ea, - BattlePetTrapLevel = 0x25e4, - BattlePetUpdates = 0x25e3, - BinderConfirm = 0x26f1, + BattlenetChallengeAbort = 0x2783, + BattlenetChallengeStart = 0x2782, + BattlenetNotification = 0x2800, + BattlenetResponse = 0x27ff, + BattleNetConnectionStatus = 0x2801, + BattlePayAckFailed = 0x277d, + BattlePayBattlePetDelivered = 0x2772, + BattlePayCollectionItemDelivered = 0x2773, + BattlePayConfirmPurchase = 0x277c, + BattlePayDeliveryEnded = 0x2770, + BattlePayDeliveryStarted = 0x276f, + BattlePayDistributionAssignVasResponse = 0x2880, + BattlePayDistributionUnrevoked = 0x276d, + BattlePayDistributionUpdate = 0x276e, + BattlePayGetDistributionListResponse = 0x276c, + BattlePayGetProductListResponse = 0x276a, + BattlePayGetPurchaseListResponse = 0x276b, + BattlePayMountDelivered = 0x2771, + BattlePayPurchaseUpdate = 0x277b, + BattlePayStartCheckout = 0x281c, + BattlePayStartDistributionAssignToTargetResponse = 0x2779, + BattlePayStartPurchaseResponse = 0x2778, + BattlePayValidatePurchaseResponse = 0x2810, + BattlePetsHealed = 0x25f1, + BattlePetCageDateError = 0x2675, + BattlePetDeleted = 0x25ee, + BattlePetError = 0x2635, + BattlePetJournal = 0x25ed, + BattlePetJournalLockAcquired = 0x25eb, + BattlePetJournalLockDenied = 0x25ec, + BattlePetLicenseChanged = 0x25f2, + BattlePetRestored = 0x25f0, + BattlePetRevoked = 0x25ef, + BattlePetTrapLevel = 0x25e9, + BattlePetUpdates = 0x25e8, BindPointUpdate = 0x257d, - BlackMarketBidOnItemResult = 0x2620, - BlackMarketOpenResult = 0x261e, - BlackMarketOutbid = 0x2621, - BlackMarketRequestItemsResult = 0x261f, - BlackMarketWon = 0x2622, - BonusRollEmpty = 0x263d, + BlackMarketBidOnItemResult = 0x2625, + BlackMarketOutbid = 0x2626, + BlackMarketRequestItemsResult = 0x2624, + BlackMarketWon = 0x2627, + BonusRollEmpty = 0x2642, BossKill = 0x294c, BreakTarget = 0x2937, BroadcastAchievement = 0x2bbc, - BroadcastSummonCast = 0x2838, - BroadcastSummonResponse = 0x2839, - BuyFailed = 0x26bd, - BuySucceeded = 0x26bc, + BroadcastSummonCast = 0x2841, + BroadcastSummonResponse = 0x2842, + BuyFailed = 0x26c2, + BuySucceeded = 0x26c1, CacheInfo = 0x291d, CacheVersion = 0x291c, - CalendarClearPendingAction = 0x2695, - CalendarCommandResult = 0x2696, - CalendarCommunityInvite = 0x2685, - CalendarEventRemovedAlert = 0x268d, - CalendarEventUpdatedAlert = 0x268e, - CalendarInviteAdded = 0x2686, - CalendarInviteAlert = 0x268a, - CalendarInviteNotes = 0x268f, - CalendarInviteNotesAlert = 0x2690, - CalendarInviteRemoved = 0x2687, - CalendarInviteRemovedAlert = 0x268c, - CalendarInviteStatus = 0x2688, - CalendarInviteStatusAlert = 0x268b, - CalendarModeratorStatus = 0x2689, - CalendarRaidLockoutAdded = 0x2691, - CalendarRaidLockoutRemoved = 0x2692, - CalendarRaidLockoutUpdated = 0x2693, - CalendarSendCalendar = 0x2683, - CalendarSendEvent = 0x2684, - CalendarSendNumPending = 0x2694, - CameraEffect = 0x2719, - CancelAutoRepeat = 0x26d3, + 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, CancelCombat = 0x2946, - CancelOrphanSpellVisual = 0x2c46, - CancelScene = 0x262f, - CancelSpellVisual = 0x2c44, - CancelSpellVisualKit = 0x2c48, + CancelOrphanSpellVisual = 0x2c49, + CancelPreloadWorld = 0x259a, + CancelScene = 0x2634, + CancelSpellVisual = 0x2c47, + CancelSpellVisualKit = 0x2c4b, CanDuelResult = 0x2942, - CanRedeemTokenForBalanceResponse = 0x2805, + CanRedeemTokenForBalanceResponse = 0x280f, CapturePointRemoved = 0x292a, - CastFailed = 0x2c57, + CastFailed = 0x2c5a, CategoryCooldown = 0x2c16, - ChainMissileBounce = 0x25c4, - ChallengeModeComplete = 0x2604, - ChallengeModeRequestLeadersResult = 0x2608, - ChallengeModeReset = 0x2603, - ChallengeModeStart = 0x2601, - ChallengeModeUpdateDeathCount = 0x2602, + ChainMissileBounce = 0x25c7, + ChallengeModeComplete = 0x2609, + ChallengeModeRequestLeadersResult = 0x260d, + ChallengeModeReset = 0x2608, + ChallengeModeStart = 0x2606, + ChallengeModeUpdateDeathCount = 0x2607, ChangePlayerDifficultyResult = 0x3004, - ChangeRealmTicketResponse = 0x27f8, + ChangeRealmTicketResponse = 0x2802, ChannelList = 0x2bc3, ChannelNotify = 0x2bc0, ChannelNotifyJoined = 0x2bc1, ChannelNotifyLeft = 0x2bc2, - CharacterCheckUpgradeResult = 0x27b0, - CharacterLoginFailed = 0x26f9, - CharacterObjectTestResponse = 0x277b, - CharacterRenameResult = 0x2756, - CharacterUpgradeAborted = 0x27af, - CharacterUpgradeComplete = 0x27ae, - CharacterUpgradeManualUnrevokeResult = 0x27b1, - CharacterUpgradeStarted = 0x27ad, - CharCustomizeFailure = 0x26d7, - CharCustomizeSuccess = 0x26d8, - CharFactionChangeResult = 0x279a, + CharacterCheckUpgradeResult = 0x27b9, + CharacterLoginFailed = 0x26ff, + CharacterObjectTestResponse = 0x2781, + CharacterRenameResult = 0x275c, + CharacterUpgradeAborted = 0x27b8, + CharacterUpgradeComplete = 0x27b7, + CharacterUpgradeManualUnrevokeResult = 0x27ba, + CharacterUpgradeStarted = 0x27b6, + CharCustomizeFailure = 0x26dc, + CharCustomizeSuccess = 0x26dd, + CharFactionChangeResult = 0x27a3, Chat = 0x2bad, ChatAutoResponded = 0x2bb8, ChatDown = 0x2bbd, @@ -1038,88 +1078,95 @@ namespace Framework.Constants CheckAbandonNpe = 0x3018, CheckCharacterNameAvailabilityResult = 0x2584, CheckWargameEntry = 0x2592, - ChromieTimeOpenNpc = 0x27ed, - ChromieTimeSelectExpansionSuccess = 0x2862, - ClaimRafRewardResponse = 0x2849, + ChromieTimeSelectExpansionSuccess = 0x286b, + ClaimRafRewardResponse = 0x2852, ClearAllSpellCharges = 0x2c27, - ClearBossEmotes = 0x25b7, - ClearCooldown = 0x26b1, + ClearBossEmotes = 0x25ba, + ClearCooldown = 0x26b6, ClearCooldowns = 0x2c26, ClearResurrect = 0x257f, ClearSpellCharges = 0x2c28, ClearTarget = 0x2943, ClearTreasurePickerCache = 0x2aa1, - CloseArtifactForge = 0x2793, - CloseHeartForge = 0x2818, - CloseItemForge = 0x2791, - ClubFinderErrorMessage = 0x2841, - ClubFinderGetClubPostingIdsResponse = 0x2844, - ClubFinderLookupClubPostingsList = 0x2842, - ClubFinderResponseCharacterApplicationList = 0x283f, - ClubFinderResponsePostRecruitmentMessage = 0x2843, - ClubFinderUpdateApplications = 0x2840, - ClubFinderWhisperApplicantResponse = 0x287a, - CoinRemoved = 0x260f, + CloseArtifactForge = 0x279b, + ClubFinderErrorMessage = 0x284a, + ClubFinderGetClubPostingIdsResponse = 0x284d, + ClubFinderLookupClubPostingsList = 0x284b, + ClubFinderResponseCharacterApplicationList = 0x2848, + ClubFinderResponsePostRecruitmentMessage = 0x284c, + ClubFinderUpdateApplications = 0x2849, + ClubFinderWhisperApplicantResponse = 0x2887, + CoinRemoved = 0x2614, CombatEventFailed = 0x293a, - CommentatorMapInfo = 0x26fb, - CommentatorPlayerInfo = 0x26fc, - CommentatorStateChanged = 0x26fa, - CommerceTokenGetCountResponse = 0x27c2, - CommerceTokenGetLogResponse = 0x27ce, - CommerceTokenGetMarketPriceResponse = 0x27c4, - CommerceTokenUpdate = 0x27c3, - ComplaintResult = 0x26a3, - CompleteShipmentResponse = 0x278c, - ConfirmPartyInvite = 0x2804, + CommentatorMapInfo = 0x2701, + CommentatorPlayerInfo = 0x2702, + CommentatorStateChanged = 0x2700, + CommerceTokenGetCountResponse = 0x27cb, + CommerceTokenGetLogResponse = 0x27d7, + CommerceTokenGetMarketPriceResponse = 0x27cd, + CommerceTokenUpdate = 0x27cc, + ComplaintResult = 0x26a8, + CompleteShipmentResponse = 0x2794, + ConfirmPartyInvite = 0x280e, ConnectTo = 0x304d, - ConquestFormulaConstants = 0x2778, - ConsoleWrite = 0x262d, - ConsumableTokenBuyAtMarketPriceResponse = 0x27ca, - ConsumableTokenBuyChoiceRequired = 0x27c9, - ConsumableTokenCanVeteranBuyResponse = 0x27c8, - ConsumableTokenRedeemConfirmRequired = 0x27cc, - ConsumableTokenRedeemResponse = 0x27cd, - ContactList = 0x2779, - ContributionLastUpdateResponse = 0x280b, - ControlUpdate = 0x263f, - ConvertItemsToCurrencyValue = 0x286b, - CooldownCheat = 0x272c, - CooldownEvent = 0x26b0, - CorpseLocation = 0x2647, - CorpseReclaimDelay = 0x273d, - CorpseTransportQuery = 0x2706, + ConquestFormulaConstants = 0x277e, + ConsoleWrite = 0x2632, + ConsumableTokenBuyAtMarketPriceResponse = 0x27d3, + ConsumableTokenBuyChoiceRequired = 0x27d2, + ConsumableTokenCanVeteranBuyResponse = 0x27d1, + ConsumableTokenRedeemConfirmRequired = 0x27d5, + ConsumableTokenRedeemResponse = 0x27d6, + ContactList = 0x277f, + ContributionLastUpdateResponse = 0x2815, + ControlUpdate = 0x2644, + ConvertItemsToCurrencyValue = 0x2874, + CooldownCheat = 0x2732, + CooldownEvent = 0x26b5, + CorpseLocation = 0x264c, + CorpseReclaimDelay = 0x2743, + CorpseTransportQuery = 0x270c, CovenantCallingsAvailabilityResponse = 0x2aa3, - CovenantPreviewOpenNpc = 0x27ee, - CovenantRenownOpenNpc = 0x286a, - CovenantRenownSendCatchupState = 0x286c, - CreateChar = 0x26f5, - CreateShipmentResponse = 0x278b, - CriteriaDeleted = 0x26dc, - CriteriaUpdate = 0x26d6, - CrossedInebriationThreshold = 0x26b8, - CustomLoadScreen = 0x25c7, + CovenantPreviewOpenNpc = 0x27f7, + CovenantRenownSendCatchupState = 0x2875, + CraftingHouseHelloResponse = 0x289e, + CraftingOrderCancelResult = 0x289a, + CraftingOrderClaimResult = 0x2896, + CraftingOrderCraftResult = 0x2898, + CraftingOrderCreateResult = 0x2894, + CraftingOrderFulfillResult = 0x2899, + CraftingOrderListOrdersResponse = 0x2895, + CraftingOrderRejectResult = 0x289c, + CraftingOrderReleaseResult = 0x2897, + CraftingOrderUpdateState = 0x289f, + CraftEnchantResult = 0x289d, + CreateChar = 0x26fb, + CreateShipmentResponse = 0x2793, + CriteriaDeleted = 0x26e1, + CriteriaUpdate = 0x26db, + CrossedInebriationThreshold = 0x26bd, + CustomLoadScreen = 0x25ca, DailyQuestsReset = 0x2a80, - DamageCalcLog = 0x27b7, + DamageCalcLog = 0x27c0, DbReply = 0x290e, - DeathReleaseLoc = 0x26c9, - DebugMenuManagerFullUpdate = 0x264d, + DeathReleaseLoc = 0x26ce, + DebugMenuManagerFullUpdate = 0x2652, DefenseMessage = 0x2bb6, - DeleteChar = 0x26f6, + DeleteChar = 0x26fc, DeleteExpiredMissionsResult = 0x2980, - DestroyArenaUnit = 0x2735, - DestructibleBuildingDamage = 0x26ed, + DestroyArenaUnit = 0x273b, + DestructibleBuildingDamage = 0x26f3, DifferentInstanceFromParty = 0x258c, - DisenchantCredit = 0x25a5, + DisenchantCredit = 0x25a8, DismountResult = 0x257c, DispelFailed = 0x2c30, - DisplayGameError = 0x259f, + DisplayGameError = 0x25a1, DisplayPlayerChoice = 0x2ffc, - DisplayPromotion = 0x2644, + DisplayPromotion = 0x2649, DisplayQuestPopup = 0x2a9e, - DisplaySoulbindUpdateMessage = 0x2870, - DisplayToast = 0x261c, - DisplayWorldText = 0x27df, - DontAutoPushSpellsToActionBar = 0x25da, + DisplaySoulbindUpdateMessage = 0x2879, + DisplayToast = 0x2621, + DisplayWorldText = 0x27e8, + DontAutoPushSpellsToActionBar = 0x25df, DropNewConnection = 0x304c, DuelArranged = 0x293c, DuelComplete = 0x2940, @@ -1128,66 +1175,68 @@ namespace Framework.Constants DuelOutOfBounds = 0x293d, DuelRequested = 0x293b, DuelWinner = 0x2941, - DurabilityDamageDeath = 0x2739, - Emote = 0x27b8, - EnableBarberShop = 0x26b3, - EnchantmentLog = 0x2707, - EncounterEnd = 0x2771, - EncounterStart = 0x2770, - EndLightningStorm = 0x26a0, + DurabilityDamageDeath = 0x273f, + Emote = 0x27c1, + EnableBarberShop = 0x26b8, + EnchantmentLog = 0x270d, + EncounterEnd = 0x2777, + EncounterStart = 0x2776, + EndLightningStorm = 0x26a5, + EnsureWorldLoaded = 0x2881, EnterEncryptedMode = 0x3049, EnumCharactersResult = 0x2583, - EnumVasPurchaseStatesResponse = 0x27e4, + EnumVasPurchaseStatesResponse = 0x27ed, EnvironmentalDamageLog = 0x2c21, - EquipmentSetId = 0x26a9, + EquipmentSetId = 0x26ae, ExpectedSpamRecords = 0x2bb1, - ExplorationExperience = 0x2752, - ExternalTransactionIdGenerated = 0x2869, - FactionBonusInfo = 0x2718, + ExplorationExperience = 0x2758, + ExternalTransactionIdGenerated = 0x2872, + FactionBonusInfo = 0x271e, FailedPlayerCondition = 0x2ffa, - FailedQuestTurnIn = 0x2801, - FeatureSystemStatus = 0x25bb, - FeatureSystemStatusGlueScreen = 0x25bc, - FeignDeathResisted = 0x2738, - FishEscaped = 0x26c6, - FishNotHooked = 0x26c5, + FailedQuestTurnIn = 0x280b, + FeatureSystemStatus = 0x25be, + FeatureSystemStatusGlueScreen = 0x25bf, + FeignDeathResisted = 0x273e, + FishEscaped = 0x26cb, + FishNotHooked = 0x26ca, FlightSplineSync = 0x2e2b, - ForcedDeathUpdate = 0x26ca, - ForceAnim = 0x2744, - ForceAnimations = 0x2745, - ForceObjectRelink = 0x2643, - FriendStatus = 0x277a, - GainMawPower = 0x27d3, - GameObjectActivateAnimKit = 0x25bf, - GameObjectBase = 0x2819, - GameObjectCustomAnim = 0x25c0, - GameObjectDespawn = 0x25c1, - GameObjectPlaySpellVisual = 0x2c4b, - GameObjectPlaySpellVisualKit = 0x2c4a, - GameObjectResetState = 0x2712, - GameObjectSetStateLocal = 0x27f4, - GameObjectUiLink = 0x270e, - GameSpeedSet = 0x2679, - GameTimeSet = 0x2700, - GameTimeUpdate = 0x26ff, + ForcedDeathUpdate = 0x26cf, + ForceAnim = 0x274a, + ForceAnimations = 0x274b, + ForceObjectRelink = 0x2648, + FriendStatus = 0x2780, + GainMawPower = 0x27dc, + GameObjectActivateAnimKit = 0x25c2, + GameObjectBase = 0x2822, + GameObjectCloseInteraction = 0x2885, + GameObjectCustomAnim = 0x25c3, + GameObjectDespawn = 0x25c4, + GameObjectInteraction = 0x2884, + GameObjectPlaySpellVisual = 0x2c4e, + GameObjectPlaySpellVisualKit = 0x2c4d, + GameObjectResetState = 0x2718, + GameObjectSetStateLocal = 0x27fe, + GameSpeedSet = 0x267e, + GameTimeSet = 0x2706, + GameTimeUpdate = 0x2705, GarrisonActivateMissionBonusAbility = 0x2982, - GarrisonAddEvent = 0x29a5, + GarrisonAddEvent = 0x29a6, GarrisonAddFollowerResult = 0x2974, GarrisonAddMissionResult = 0x2978, - GarrisonAddSpecGroups = 0x29a8, - GarrisonApplyTalentSocketDataChanges = 0x29ac, + GarrisonAddSpecGroups = 0x29a9, + GarrisonApplyTalentSocketDataChanges = 0x29ad, GarrisonAssignFollowerToBuildingResult = 0x298a, - GarrisonAutoTroopMinLevelUpdateResult = 0x29ae, + GarrisonAutoTroopMinLevelUpdateResult = 0x29af, GarrisonBuildingActivated = 0x2969, GarrisonBuildingRemoved = 0x2962, GarrisonBuildingSetActiveSpecializationResult = 0x2964, GarrisonChangeMissionStartTimeResult = 0x297b, - GarrisonClearCollection = 0x29a4, - GarrisonClearEventList = 0x29a7, - GarrisonClearSpecGroups = 0x29a9, - GarrisonCollectionRemoveEntry = 0x29a3, - GarrisonCollectionUpdateEntry = 0x29a2, - GarrisonCompleteBuildingConstructionResult = 0x299a, + GarrisonClearCollection = 0x29a5, + GarrisonClearEventList = 0x29a8, + GarrisonClearSpecGroups = 0x29aa, + GarrisonCollectionRemoveEntry = 0x29a4, + GarrisonCollectionUpdateEntry = 0x29a3, + GarrisonCompleteBuildingConstructionResult = 0x299b, GarrisonCompleteMissionResult = 0x297a, GarrisonCreateResult = 0x296a, GarrisonDeleteMissionResult = 0x2981, @@ -1201,26 +1250,23 @@ namespace Framework.Constants GarrisonGenerateFollowersResult = 0x2991, GarrisonGetClassSpecCategoryInfoResult = 0x2973, GarrisonGetRecallPortalLastUsedTimeResult = 0x297c, - GarrisonIsUpgradeableResponse = 0x299c, + GarrisonIsUpgradeableResponse = 0x299d, GarrisonLearnBlueprintResult = 0x2965, GarrisonLearnSpecializationResult = 0x2963, - GarrisonListCompletedMissionsCheatResult = 0x299d, + GarrisonListCompletedMissionsCheatResult = 0x299e, GarrisonListFollowersCheatResult = 0x2977, - GarrisonMapDataResponse = 0x299f, + GarrisonMapDataResponse = 0x29a0, GarrisonMissionBonusRollResult = 0x297e, - GarrisonMissionRequestRewardInfoResponse = 0x29a0, + GarrisonMissionRequestRewardInfoResponse = 0x29a1, GarrisonMissionStartConditionUpdate = 0x2983, - GarrisonOpenArchitect = 0x2994, GarrisonOpenCrafter = 0x2995, - GarrisonOpenMissionNpc = 0x2996, GarrisonOpenRecruitmentNpc = 0x298e, - GarrisonOpenTalentNpc = 0x298f, GarrisonPlaceBuildingResult = 0x2961, GarrisonPlotPlaced = 0x295f, GarrisonPlotRemoved = 0x2960, GarrisonRecruitFollowerResult = 0x2992, GarrisonRemoteInfo = 0x2968, - GarrisonRemoveEvent = 0x29a6, + GarrisonRemoveEvent = 0x29a7, GarrisonRemoveFollowerAbilityResult = 0x298d, GarrisonRemoveFollowerFromBuildingResult = 0x298b, GarrisonRemoveFollowerResult = 0x2975, @@ -1230,47 +1276,49 @@ namespace Framework.Constants GarrisonResetTalentTree = 0x2971, GarrisonResetTalentTreeSocketData = 0x2972, GarrisonStartMissionResult = 0x2979, - GarrisonSwapBuildingsResponse = 0x2999, - GarrisonSwitchTalentTreeBranch = 0x29aa, + GarrisonSwapBuildingsResponse = 0x299a, + GarrisonSwitchTalentTreeBranch = 0x29ab, GarrisonTalentCompleted = 0x296d, GarrisonTalentRemoved = 0x296e, GarrisonTalentRemoveSocketData = 0x2970, GarrisonTalentUpdateSocketData = 0x296f, - GarrisonTalentWorldQuestUnlocksResponse = 0x29ab, + GarrisonTalentWorldQuestUnlocksResponse = 0x29ac, GarrisonUnlearnBlueprintResult = 0x2966, GarrisonUpdateFollower = 0x2976, - GarrisonUpdateGarrisonMonumentSelections = 0x299b, - GarrisonUpdateMissionCheatResult = 0x29ad, + GarrisonUpdateGarrisonMonumentSelections = 0x299c, + GarrisonUpdateMissionCheatResult = 0x29ae, GarrisonUpgradeResult = 0x296b, GarrisonUseRecallPortalResult = 0x297d, GenerateRandomCharacterNameResult = 0x2585, - GenerateSsoTokenResponse = 0x280c, - GetAccountCharacterListResult = 0x2754, + GenerateSsoTokenResponse = 0x2816, + GetAccountCharacterListResult = 0x275a, GetGarrisonInfoResult = 0x295e, - GetLandingPageShipmentsResponse = 0x278e, - GetRemainingGameTimeResponse = 0x27cb, - GetSelectedTrophyIdResponse = 0x27b5, - GetShipmentsOfTypeResponse = 0x278d, - GetShipmentInfoResponse = 0x2789, - GetTrophyListResponse = 0x27b4, - GetVasAccountCharacterListResult = 0x27e0, - GetVasTransferTargetRealmListResult = 0x27e1, + GetLandingPageShipmentsResponse = 0x2796, + GetRemainingGameTimeResponse = 0x27d4, + GetSelectedTrophyIdResponse = 0x27be, + GetShipmentsOfTypeResponse = 0x2795, + GetShipmentInfoResponse = 0x2791, + GetTrophyListResponse = 0x27bd, + GetVasAccountCharacterListResult = 0x27e9, + GetVasTransferTargetRealmListResult = 0x27ea, GmPlayerInfo = 0x3005, GmRequestPlayerInfo = 0x2ffb, - GmTicketCaseStatus = 0x269b, - GmTicketSystemStatus = 0x269a, - GodMode = 0x26f0, + GmTicketCaseStatus = 0x26a0, + GmTicketSystemStatus = 0x269f, + GodMode = 0x26f6, GossipComplete = 0x2a97, GossipMessage = 0x2a98, - GossipPoi = 0x2786, + GossipOptionNpcInteraction = 0x2aa7, + GossipPoi = 0x278e, GossipQuestUpdate = 0x2a99, GossipRefreshOptions = 0x2aa6, GroupActionThrottled = 0x2590, - GroupAutoKick = 0x2784, - GroupDecline = 0x2781, - GroupDestroyed = 0x2783, - GroupNewLeader = 0x2625, - GroupUninvite = 0x2782, + GroupAutoKick = 0x278b, + GroupDecline = 0x2787, + GroupDestroyed = 0x278a, + GroupNewLeader = 0x262a, + GroupRequestDecline = 0x2788, + GroupUninvite = 0x2789, GuildAchievementDeleted = 0x29c5, GuildAchievementEarned = 0x29c4, GuildAchievementMembers = 0x29c7, @@ -1324,60 +1372,59 @@ namespace Framework.Constants GuildRoster = 0x29bb, GuildRosterUpdate = 0x29bc, GuildSendRankChange = 0x29b9, - HealthUpdate = 0x26c7, - HighestThreatUpdate = 0x26cf, + HealthUpdate = 0x26cc, + HighestThreatUpdate = 0x26d4, HotfixConnect = 0x2911, HotfixMessage = 0x2910, - InitializeFactions = 0x2717, + InitializeFactions = 0x271d, InitialSetup = 0x2580, - InitWorldStates = 0x273a, - InspectResult = 0x2629, - InstanceEncounterChangePriority = 0x27a0, - InstanceEncounterDisengageUnit = 0x279f, - InstanceEncounterEnd = 0x27a8, - InstanceEncounterEngageUnit = 0x279e, - InstanceEncounterGainCombatResurrectionCharge = 0x27aa, - InstanceEncounterInCombatResurrection = 0x27a9, - InstanceEncounterObjectiveComplete = 0x27a3, - InstanceEncounterObjectiveStart = 0x27a2, - InstanceEncounterObjectiveUpdate = 0x27a7, - InstanceEncounterPhaseShiftChanged = 0x27ab, - InstanceEncounterStart = 0x27a4, - InstanceEncounterTimerStart = 0x27a1, - InstanceEncounterUpdateAllowReleaseInProgress = 0x27a6, - InstanceEncounterUpdateSuppressRelease = 0x27a5, - InstanceGroupSizeChanged = 0x26ee, - InstanceInfo = 0x262c, - InstanceReset = 0x267e, - InstanceResetFailed = 0x267f, - InstanceSaveCreated = 0x276f, - InterruptPowerRegen = 0x2c59, + InitWorldStates = 0x2740, + 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, + InterruptPowerRegen = 0x2c5c, InvalidatePageText = 0x2918, InvalidatePlayer = 0x2fff, - InvalidPromotionCode = 0x2746, + InvalidPromotionCode = 0x274c, InventoryChangeFailure = 0x2da5, - InventoryFixupComplete = 0x2803, - InventoryFullOverflow = 0x2814, - IslandsMissionNpc = 0x27ea, - IslandAzeriteGain = 0x274f, - IslandComplete = 0x2750, + InventoryFixupComplete = 0x280d, + InventoryFullOverflow = 0x281e, + IslandAzeriteGain = 0x2755, + IslandComplete = 0x2756, IsQuestCompleteResponse = 0x2a84, - ItemChanged = 0x26df, - ItemCooldown = 0x27b6, - ItemEnchantTimeUpdate = 0x2748, - ItemExpirePurchaseRefund = 0x259e, - ItemInteractionComplete = 0x2861, - ItemPurchaseRefundResult = 0x259c, - ItemPushResult = 0x261b, - ItemTimeUpdate = 0x2747, - KickReason = 0x2681, - LatencyReportPing = 0x2873, - LearnedSpells = 0x2c4d, - LearnPvpTalentFailed = 0x25ce, - LearnTalentFailed = 0x25cd, - LegacyLootRules = 0x281a, - LevelLinkingResult = 0x2847, - LevelUpInfo = 0x26de, + ItemChanged = 0x26e5, + ItemCooldown = 0x27bf, + ItemEnchantTimeUpdate = 0x274e, + ItemExpirePurchaseRefund = 0x25a0, + ItemInteractionComplete = 0x286a, + ItemPurchaseRefundResult = 0x259e, + ItemPushResult = 0x2620, + ItemTimeUpdate = 0x274d, + KickReason = 0x2686, + LatencyReportPing = 0x287c, + LearnedSpells = 0x2c50, + LearnPvpTalentFailed = 0x25d3, + LearnTalentFailed = 0x25d2, + LegacyLootRules = 0x2823, + LevelLinkingResult = 0x2850, + LevelUpInfo = 0x26e3, LfgBootPlayer = 0x2a35, LfgDisabled = 0x2a33, LfgExpandSearchPrompt = 0x2a3b, @@ -1405,45 +1452,47 @@ namespace Framework.Constants LfgSlotInvalid = 0x2a30, LfgTeleportDenied = 0x2a32, LfgUpdateStatus = 0x2a24, - LiveRegionAccountRestoreResult = 0x2761, - LiveRegionCharacterCopyResult = 0x2760, - LiveRegionGetAccountCharacterListResult = 0x2755, - LiveRegionKeyBindingsCopyResult = 0x2762, - LoadCufProfiles = 0x25b8, - LoadEquipmentSet = 0x2702, - LoginSetTimeSpeed = 0x2701, - LoginVerifyWorld = 0x2599, - LogoutCancelAck = 0x267d, - LogoutComplete = 0x267c, - LogoutResponse = 0x267b, - LogXpGain = 0x26da, - LootAllPassed = 0x2619, - LootList = 0x2734, - LootMoneyNotify = 0x2614, - LootRelease = 0x2613, - LootReleaseAll = 0x2612, - LootRemoved = 0x260e, - LootResponse = 0x260d, - LootRoll = 0x2616, - LootRollsComplete = 0x2618, - LootRollWon = 0x261a, - LossOfControlAuraUpdate = 0x2668, - MailCommandResult = 0x2633, - MailListResult = 0x2749, - MailQueryNextTimeResult = 0x274a, + LiveRegionAccountRestoreResult = 0x2767, + LiveRegionCharacterCopyResult = 0x2766, + LiveRegionGetAccountCharacterListResult = 0x275b, + LiveRegionKeyBindingsCopyResult = 0x2768, + LoadCufProfiles = 0x25bb, + LoadEquipmentSet = 0x2708, + LobbyMatchmakerPartyInfo = 0x2889, + 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, MapObjectivesInit = 0x294b, - MapObjEvents = 0x25c2, - MasterLootCandidateList = 0x2617, - MeetingStoneFailed = 0x287c, + MapObjEvents = 0x25c5, + MasterLootCandidateList = 0x261c, + MeetingStoneFailed = 0x288a, MessageBox = 0x2576, - MinimapPing = 0x26c4, + MinimapPing = 0x26c9, MirrorImageComponentedData = 0x2c14, MirrorImageCreatureData = 0x2c13, - MissileCancel = 0x25c3, - ModifyCooldown = 0x2757, + MissileCancel = 0x25c6, + ModifyCooldown = 0x275d, Motd = 0x2baf, MountResult = 0x257b, - MovementEnforcementAlert = 0x2837, + MovementEnforcementAlert = 0x2840, + MoveAddImpulse = 0x2e32, MoveApplyInertia = 0x2e2e, MoveApplyMovementForce = 0x2e15, MoveDisableCollision = 0x2e11, @@ -1461,6 +1510,20 @@ namespace Framework.Constants MoveRemoveMovementForce = 0x2e16, MoveRoot = 0x2df9, MoveSetActiveMover = 0x2dd5, + MoveSetAdvFlyingAddImpulseMaxSpeed = 0x2e3b, + MoveSetAdvFlyingAirFriction = 0x2e36, + MoveSetAdvFlyingBankingRate = 0x2e3c, + MoveSetAdvFlyingDoubleJumpVelMod = 0x2e39, + MoveSetAdvFlyingGlideStartMinHeight = 0x2e3a, + MoveSetAdvFlyingLaunchSpeedCoefficient = 0x2e42, + MoveSetAdvFlyingLiftCoefficient = 0x2e38, + MoveSetAdvFlyingMaxVel = 0x2e37, + MoveSetAdvFlyingOverMaxDeceleration = 0x2e41, + MoveSetAdvFlyingPitchingRateDown = 0x2e3d, + MoveSetAdvFlyingPitchingRateUp = 0x2e3e, + MoveSetAdvFlyingSurfaceFriction = 0x2e40, + MoveSetAdvFlyingTurnVelocityThreshold = 0x2e3f, + MoveSetCanAdvFly = 0x2e34, MoveSetCanFly = 0x2e05, MoveSetCanTurnWhileFalling = 0x2e07, MoveSetCollisionHeight = 0x2e13, @@ -1512,11 +1575,13 @@ namespace Framework.Constants MoveSplineUnsetHover = 0x2e22, MoveTeleport = 0x2e04, MoveUnroot = 0x2dfa, + MoveUnsetCanAdvFly = 0x2e35, MoveUnsetCanFly = 0x2e06, MoveUnsetCanTurnWhileFalling = 0x2e08, MoveUnsetHovering = 0x2e02, MoveUnsetIgnoreMovementForces = 0x2e0a, MoveUpdate = 0x2de0, + MoveUpdateAddImpulse = 0x2e33, MoveUpdateApplyInertia = 0x2e30, MoveUpdateApplyMovementForce = 0x2de4, MoveUpdateCollisionHeight = 0x2ddf, @@ -1534,82 +1599,79 @@ namespace Framework.Constants MoveUpdateTeleport = 0x2de1, MoveUpdateTurnRate = 0x2ddd, MoveUpdateWalkSpeed = 0x2dd8, - MultiFloorLeaveFloor = 0x27d0, - MultiFloorNewFloor = 0x27cf, - MythicPlusAllMapStats = 0x2605, - MythicPlusCurrentAffixes = 0x2607, - MythicPlusNewWeekRecord = 0x260a, - MythicPlusSeasonData = 0x2606, - NeutralPlayerFactionSelectResult = 0x25d5, - NewTaxiPath = 0x2676, + MultiFloorLeaveFloor = 0x27d9, + MultiFloorNewFloor = 0x27d8, + MythicPlusAllMapStats = 0x260a, + MythicPlusCurrentAffixes = 0x260c, + MythicPlusNewWeekRecord = 0x260f, + MythicPlusSeasonData = 0x260b, + NeutralPlayerFactionSelectResult = 0x25da, + NewTaxiPath = 0x267b, NewWorld = 0x2598, - NotifyDestLocSpellCast = 0x2c43, - NotifyMissileTrajectoryCollision = 0x26a2, - NotifyMoney = 0x259b, - NotifyReceivedMail = 0x2634, - OfferPetitionError = 0x26ad, - OnCancelExpectedRideVehicleAura = 0x26db, + NotifyDestLocSpellCast = 0x2c46, + NotifyMissileTrajectoryCollision = 0x26a7, + NotifyMoney = 0x259d, + NotifyReceivedMail = 0x2639, + NpcInteractionOpenResult = 0x2883, + OfferPetitionError = 0x26b2, + OnCancelExpectedRideVehicleAura = 0x26e0, OnMonsterMove = 0x2dd4, - OpenAnimaDiversionUi = 0x270f, - OpenArtifactForge = 0x2792, + OpenArtifactForge = 0x279a, OpenContainer = 0x2da6, - OpenHeartForge = 0x2817, - OpenItemForge = 0x2790, OpenLfgDungeonFinder = 0x2a31, - OpenShipmentNpcFromGossip = 0x2788, - OpenShipmentNpcResult = 0x278a, - OverrideLight = 0x26b2, - PageText = 0x270d, - PartyCommandResult = 0x2785, - PartyInvite = 0x25b9, - PartyKillLog = 0x274d, - PartyMemberFullState = 0x274c, - PartyMemberPartialState = 0x274b, - PartyNotifyLfgLeaderChange = 0x2867, - PartyUpdate = 0x25ee, - PastTimeEvents = 0x25be, - PauseMirrorTimer = 0x2704, - PendingRaidLock = 0x26ec, - PetitionAlreadySigned = 0x25a1, + OpenShipmentNpcResult = 0x2792, + OverrideLight = 0x26b7, + PageText = 0x2713, + PartyCommandResult = 0x278c, + PartyInvite = 0x25bc, + PartyKillLog = 0x2753, + PartyMemberFullState = 0x2752, + PartyMemberPartialState = 0x2751, + PartyNotifyLfgLeaderChange = 0x2870, + PartyUpdate = 0x25f3, + PastTimeEvents = 0x25c1, + PauseMirrorTimer = 0x270a, + PendingRaidLock = 0x26f2, + PetitionAlreadySigned = 0x25a3, PetitionRenameGuildResponse = 0x29fa, - PetitionShowList = 0x26b5, - PetitionShowSignatures = 0x26b6, - PetitionSignResults = 0x273f, - PetActionFeedback = 0x273c, - PetActionSound = 0x2698, + PetitionShowList = 0x26ba, + PetitionShowSignatures = 0x26bb, + PetitionSignResults = 0x2745, + PetActionFeedback = 0x2742, + PetActionSound = 0x269d, PetAdded = 0x2595, - PetBattleChatRestricted = 0x25fc, - PetBattleDebugQueueDumpResponse = 0x266d, - PetBattleFinalizeLocation = 0x25f5, - PetBattleFinalRound = 0x25fa, - PetBattleFinished = 0x25fb, - PetBattleFirstRound = 0x25f7, - PetBattleInitialUpdate = 0x25f6, - PetBattleMaxGameLengthWarning = 0x25fd, - PetBattlePvpChallenge = 0x25f4, - PetBattleQueueProposeMatch = 0x2631, - PetBattleQueueStatus = 0x2632, - PetBattleReplacementsMade = 0x25f9, - PetBattleRequestFailed = 0x25f3, - PetBattleRoundResult = 0x25f8, - PetBattleSlotUpdates = 0x25e5, - PetCastFailed = 0x2c58, + 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 = 0x25ea, + PetCastFailed = 0x2c5b, PetClearSpells = 0x2c24, - PetDismissSound = 0x2699, - PetGodMode = 0x2673, - PetGuids = 0x26f8, - PetLearnedSpells = 0x2c4f, + PetDismissSound = 0x269e, + PetGodMode = 0x2678, + PetGuids = 0x26fe, + PetLearnedSpells = 0x2c52, PetMode = 0x258b, - PetNameInvalid = 0x26ba, + PetNameInvalid = 0x26bf, PetNewlyTamed = 0x2589, PetSlotUpdated = 0x258a, PetSpellsMessage = 0x2c25, PetStableList = 0x2596, PetStableResult = 0x2597, - PetTameFailure = 0x26aa, - PetUnlearnedSpells = 0x2c50, + PetTameFailure = 0x26af, + PetUnlearnedSpells = 0x2c53, PhaseShiftChange = 0x2578, - PlayedTime = 0x26cb, + PlayedTime = 0x26d0, PlayerAzeriteItemEquippedStatusChanged = 0x3014, PlayerAzeriteItemGains = 0x3013, PlayerBonusRollFailed = 0x3016, @@ -1620,40 +1682,42 @@ namespace Framework.Constants PlayerIsAdventureMapPoiValid = 0x3009, PlayerOpenSubscriptionInterstitial = 0x300e, PlayerSaveGuildEmblem = 0x29f9, + PlayerShowGenericWidgetDisplay = 0x301e, PlayerShowUiEventToast = 0x3019, PlayerSkinned = 0x3006, - PlayerTabardVendorActivate = 0x3007, PlayerTutorialHighlightSpell = 0x300d, PlayerTutorialUnhighlightSpell = 0x300c, - PlayMusic = 0x275c, - PlayObjectSound = 0x275d, - PlayOneShotAnimKit = 0x2724, - PlayOrphanSpellVisual = 0x2c47, - PlayScene = 0x262e, - PlaySound = 0x275b, - PlaySpeakerbotSound = 0x275e, - PlaySpellVisual = 0x2c45, - PlaySpellVisualKit = 0x2c49, - PlayTimeWarning = 0x26f2, + PlayMusic = 0x2762, + PlayObjectSound = 0x2763, + PlayOneShotAnimKit = 0x272a, + PlayOrphanSpellVisual = 0x2c4a, + PlayScene = 0x2633, + PlaySound = 0x2761, + PlaySpeakerbotSound = 0x2764, + PlaySpellVisual = 0x2c48, + PlaySpellVisualKit = 0x2c4c, + PlayTimeWarning = 0x26f8, Pong = 0x304e, - PowerUpdate = 0x26c8, + PowerUpdate = 0x26cd, PreloadChildMap = 0x2579, - PrepopulateNameCache = 0x283a, - PreRessurect = 0x275a, - PrintNotification = 0x25c6, - ProcResist = 0x274e, - PushSpellToActionBar = 0x2c51, + PreloadWorld = 0x2599, + PrepopulateNameCache = 0x2843, + PreRessurect = 0x2760, + PrintNotification = 0x25c9, + ProcResist = 0x2754, + ProfessionGossip = 0x27f9, + PushSpellToActionBar = 0x2c54, PvpCredit = 0x2945, PvpMatchComplete = 0x294f, PvpMatchInitialize = 0x2950, PvpMatchStart = 0x294e, PvpMatchStatistics = 0x2932, PvpOptionsEnabled = 0x2934, - PvpTierRecord = 0x2874, + PvpTierRecord = 0x287d, QueryBattlePetNameResponse = 0x291a, QueryCreatureResponse = 0x2914, QueryGameObjectResponse = 0x2915, - QueryGarrisonPetNameResponse = 0x299e, + QueryGarrisonPetNameResponse = 0x299f, QueryGuildFollowInfoResponse = 0x29e7, QueryGuildInfoResponse = 0x29e5, QueryItemTextResponse = 0x291e, @@ -1665,7 +1729,7 @@ namespace Framework.Constants QueryPlayerNameByCommunityIdResponse = 0x3002, QueryQuestInfoResponse = 0x2a96, QueryRealmGuildMasterInfoResponse = 0x29e6, - QueryTimeResponse = 0x26d9, + QueryTimeResponse = 0x26de, QuestCompletionNpcResponse = 0x2a81, QuestConfirmAccept = 0x2a8f, QuestForceRemoved = 0x2a9c, @@ -1678,255 +1742,261 @@ namespace Framework.Constants QuestGiverRequestItems = 0x2a93, QuestGiverStatus = 0x2a9b, QuestGiverStatusMultiple = 0x2a91, + QuestItemUsabilityResponse = 0x2a82, QuestLogFull = 0x2a87, QuestNonLogUpdateComplete = 0x2a88, QuestPoiQueryResponse = 0x2a9d, QuestPoiUpdateResponse = 0x2a9f, QuestPushResult = 0x2a90, - QuestSessionInfoResponse = 0x285d, - QuestSessionReadyCheck = 0x284b, - QuestSessionReadyCheckResponse = 0x284c, - QuestSessionResult = 0x284a, + QuestSessionInfoResponse = 0x2866, + QuestSessionReadyCheck = 0x2854, + QuestSessionReadyCheckResponse = 0x2855, + QuestSessionResult = 0x2853, QuestUpdateAddCredit = 0x2a8c, QuestUpdateAddCreditSimple = 0x2a8d, QuestUpdateAddPvpCredit = 0x2a8e, QuestUpdateComplete = 0x2a89, QuestUpdateFailed = 0x2a8a, QuestUpdateFailedTimer = 0x2a8b, - QueueSummaryUpdate = 0x2802, - RafAccountInfo = 0x2848, - RafActivityStateChanged = 0x2859, - RaidDifficultySet = 0x279b, - RaidGroupOnly = 0x279d, + QueueSummaryUpdate = 0x280c, + RafAccountInfo = 0x2851, + RafActivityStateChanged = 0x2862, + RaidDifficultySet = 0x27a4, + RaidGroupOnly = 0x27a6, RaidInstanceMessage = 0x2bb4, - RaidMarkersChanged = 0x25a2, - RandomRoll = 0x2628, + RaidMarkersChanged = 0x25a4, + RandomRoll = 0x262d, RatedPvpInfo = 0x2931, - ReadyCheckCompleted = 0x25f2, - ReadyCheckResponse = 0x25f1, - ReadyCheckStarted = 0x25f0, - ReadItemResultFailed = 0x2797, - ReadItemResultOk = 0x278f, - RealmLookupInfo = 0x27bb, + ReadyCheckCompleted = 0x25f7, + ReadyCheckResponse = 0x25f6, + ReadyCheckStarted = 0x25f5, + ReadItemResultFailed = 0x27a0, + ReadItemResultOk = 0x2797, + RealmLookupInfo = 0x27c4, RealmQueryResponse = 0x2913, - ReattachResurrect = 0x273e, - RecruitAFriendFailure = 0x26b7, - RefreshComponent = 0x2649, + ReattachResurrect = 0x2744, + RecraftItemResult = 0x289b, + RecruitAFriendFailure = 0x26bc, + RefreshComponent = 0x264e, RefreshSpellHistory = 0x2c2c, - RemoveItemPassive = 0x25a9, - RemoveSpellFromActionBar = 0x2c52, - ReplaceTrophyResponse = 0x27b3, + RemoveItemPassive = 0x25ac, + RemoveSpellFromActionBar = 0x2c55, + ReplaceTrophyResponse = 0x27bc, ReportPvpPlayerAfkResult = 0x3001, RequestCemeteryListResponse = 0x2591, RequestPvpRewardsResponse = 0x2935, RequestScheduledPvpInfoResponse = 0x2936, ResearchComplete = 0x2587, ResetCompressionContext = 0x304f, - ResetFailedNotify = 0x26ae, + ResetFailedNotify = 0x26b3, ResetQuestPoi = 0x2aa0, ResetRangedCombatTimer = 0x2944, ResetWeeklyCurrency = 0x2575, - RespecWipeConfirm = 0x260b, + RespecWipeConfirm = 0x2610, RespondInspectAchievements = 0x2572, - RestartGlobalCooldown = 0x2c60, - RestrictedAccountWarning = 0x25b5, - ResumeCast = 0x2c3b, - ResumeCastBar = 0x2c3e, + RestartGlobalCooldown = 0x2c64, + RestrictedAccountWarning = 0x25b8, + ResumeCast = 0x2c3e, + ResumeCastBar = 0x2c41, ResumeComms = 0x304b, - ResumeToken = 0x25a7, + ResumeToken = 0x25aa, ResurrectRequest = 0x257e, - ResyncRunes = 0x2c5f, - ReturnApplicantList = 0x283e, - ReturnRecruitingClubs = 0x283d, + ResyncRunes = 0x2c62, + ReturningPlayerPrompt = 0x279f, + ReturnApplicantList = 0x2847, + ReturnRecruitingClubs = 0x2846, RoleChangedInform = 0x258d, RoleChosen = 0x2a39, RolePollInform = 0x258e, - RuneforgeLegendaryCraftingOpenNpc = 0x27ef, - RuneRegenDebug = 0x25b2, - ScenarioCompleted = 0x27dd, - ScenarioPois = 0x262b, - ScenarioProgressUpdate = 0x2624, - ScenarioShowCriteria = 0x27f2, - ScenarioState = 0x2623, - ScenarioUiUpdate = 0x27f1, - ScenarioVacate = 0x2798, - SceneObjectEvent = 0x25db, - SceneObjectPetBattleFinalRound = 0x25e0, - SceneObjectPetBattleFinished = 0x25e1, - SceneObjectPetBattleFirstRound = 0x25dd, - SceneObjectPetBattleInitialUpdate = 0x25dc, - SceneObjectPetBattleReplacementsMade = 0x25df, - SceneObjectPetBattleRoundResult = 0x25de, - ScriptCast = 0x2c56, - SeasonInfo = 0x25bd, - SellResponse = 0x26bb, - SendItemPassives = 0x25aa, + RuneforgeLegendaryCraftingOpenNpc = 0x27f8, + RuneRegenDebug = 0x25b5, + ScenarioCompleted = 0x27e6, + ScenarioPois = 0x2630, + ScenarioProgressUpdate = 0x2629, + ScenarioShowCriteria = 0x27fc, + ScenarioState = 0x2628, + ScenarioUiUpdate = 0x27fb, + ScenarioVacate = 0x27a1, + SceneObjectEvent = 0x25e0, + SceneObjectPetBattleFinalRound = 0x25e5, + SceneObjectPetBattleFinished = 0x25e6, + SceneObjectPetBattleFirstRound = 0x25e2, + SceneObjectPetBattleInitialUpdate = 0x25e1, + SceneObjectPetBattleReplacementsMade = 0x25e4, + SceneObjectPetBattleRoundResult = 0x25e3, + ScriptCast = 0x2c59, + SeasonInfo = 0x25c0, + SellResponse = 0x26c0, + SendItemPassives = 0x25ad, SendKnownSpells = 0x2c2a, - SendRaidTargetUpdateAll = 0x2626, - SendRaidTargetUpdateSingle = 0x2627, + SendRaidTargetUpdateAll = 0x262b, + SendRaidTargetUpdateSingle = 0x262c, SendSpellCharges = 0x2c2d, SendSpellHistory = 0x2c2b, SendUnlearnSpells = 0x2c2e, - ServerFirstAchievements = 0x2646, - ServerTime = 0x267a, - ServerTimeOffset = 0x2708, + ServerFirstAchievements = 0x264b, + ServerTime = 0x267f, + ServerTimeOffset = 0x270e, SetupCurrency = 0x2573, SetupResearchHistory = 0x2586, - SetAiAnimKit = 0x2723, - SetAllTaskProgress = 0x277f, - SetAnimTier = 0x2727, - SetChrUpgradeTier = 0x25d8, + SetAiAnimKit = 0x2729, + SetAllTaskProgress = 0x2785, + SetAnimTier = 0x272d, + SetChrUpgradeTier = 0x25dd, SetCurrency = 0x2574, SetDfFastLaunchResult = 0x2a2e, - SetDungeonDifficulty = 0x269c, - SetFactionAtWar = 0x26f4, - SetFactionNotVisible = 0x271e, - SetFactionStanding = 0x271f, - SetFactionVisible = 0x271d, - SetFlatSpellModifier = 0x2c36, - SetForcedReactions = 0x2711, - SetItemPurchaseData = 0x259d, - SetLootMethodFailed = 0x27c1, - SetMaxWeeklyQuantity = 0x25a0, - SetMeleeAnimKit = 0x2726, - SetMovementAnimKit = 0x2725, - SetPctSpellModifier = 0x2c37, - SetPetSpecialization = 0x261d, + SetDungeonDifficulty = 0x26a1, + SetFactionAtWar = 0x26fa, + SetFactionNotVisible = 0x2724, + SetFactionStanding = 0x2725, + SetFactionVisible = 0x2723, + SetFlatSpellModifier = 0x2c39, + SetForcedReactions = 0x2717, + SetItemPurchaseData = 0x259f, + SetLootMethodFailed = 0x27ca, + SetMaxWeeklyQuantity = 0x25a2, + SetMeleeAnimKit = 0x272c, + SetMovementAnimKit = 0x272b, + SetPctSpellModifier = 0x2c3a, + SetPetSpecialization = 0x2622, SetPlayerDeclinedNamesResult = 0x3003, - SetPlayHoverAnim = 0x25b6, - SetProficiency = 0x2728, - SetQuestReplayCooldownOverride = 0x2851, - SetShipmentReadyResponse = 0x2997, + SetPlayHoverAnim = 0x25b9, + SetProficiency = 0x272e, + SetQuestReplayCooldownOverride = 0x285a, + SetShipmentReadyResponse = 0x2998, SetSpellCharges = 0x2c29, - SetTaskComplete = 0x2780, - SetTimeZoneInformation = 0x266f, - SetVehicleRecId = 0x26eb, - ShadowlandsCapacitanceUpdate = 0x2878, - ShipmentFactionUpdateResult = 0x2998, - ShowBank = 0x2677, - ShowMailbox = 0x2799, - ShowNeutralPlayerFactionSelectUi = 0x25d4, + SetTaskComplete = 0x2786, + SetTimeZoneInformation = 0x2674, + SetVehicleRecId = 0x26f1, + ShadowlandsCapacitanceUpdate = 0x2882, + ShipmentFactionUpdateResult = 0x2999, + ShowNeutralPlayerFactionSelectUi = 0x25d9, ShowQuestCompletionText = 0x2a95, - ShowTaxiNodes = 0x26c3, - ShowTradeSkillResponse = 0x2763, - SocialContractRequestResponse = 0x287d, - SocketGemsFailure = 0x271b, - SocketGemsSuccess = 0x271a, - SpecialMountAnim = 0x2697, - SpecInvoluntarilyChanged = 0x270c, + ShowTaxiNodes = 0x26c8, + ShowTradeSkillResponse = 0x2769, + SocialContractRequestResponse = 0x288b, + SocketGemsFailure = 0x2721, + SocketGemsSuccess = 0x2720, + SpecialMountAnim = 0x269c, + SpecInvoluntarilyChanged = 0x2712, SpellAbsorbLog = 0x2c1f, SpellCategoryCooldown = 0x2c17, SpellChannelStart = 0x2c34, SpellChannelUpdate = 0x2c35, SpellCooldown = 0x2c15, SpellDamageShield = 0x2c31, - SpellDelayed = 0x2c3f, + SpellDelayed = 0x2c42, SpellDispellLog = 0x2c1a, + SpellEmpowerSetStage = 0x2c38, + SpellEmpowerStart = 0x2c36, + SpellEmpowerUpdate = 0x2c37, SpellEnergizeLog = 0x2c1c, - SpellExecuteLog = 0x2c40, - SpellFailedOther = 0x2c55, - SpellFailure = 0x2c53, - SpellFailureMessage = 0x2c5a, - SpellGo = 0x2c39, + SpellExecuteLog = 0x2c43, + SpellFailedOther = 0x2c58, + SpellFailure = 0x2c56, + SpellFailureMessage = 0x2c5d, + SpellGo = 0x2c3c, SpellHealAbsorbLog = 0x2c1e, SpellHealLog = 0x2c1d, SpellInstakillLog = 0x2c33, SpellInterruptLog = 0x2c20, - SpellMissLog = 0x2c41, + SpellMissLog = 0x2c44, SpellNonMeleeDamageLog = 0x2c32, SpellOrDamageImmune = 0x2c2f, SpellPeriodicAuraLog = 0x2c1b, - SpellPrepare = 0x2c38, - SpellStart = 0x2c3a, - SpellVisualLoadScreen = 0x25c8, - SpiritHealerConfirm = 0x2709, - SplashScreenShowLatest = 0x2863, - StandStateUpdate = 0x2710, - StartElapsedTimer = 0x25fe, - StartElapsedTimers = 0x2600, - StartLightningStorm = 0x269f, - StartLootRoll = 0x2615, - StartMirrorTimer = 0x2703, - StartTimer = 0x25a4, - StopElapsedTimer = 0x25ff, - StopMirrorTimer = 0x2705, - StopSpeakerbotSound = 0x275f, - StreamingMovies = 0x25a3, - SummonCancel = 0x26a8, + SpellPrepare = 0x2c3b, + SpellStart = 0x2c3d, + SpellVisualLoadScreen = 0x25cb, + SplashScreenShowLatest = 0x286c, + StandStateUpdate = 0x2716, + StarterBuildActivateFailed = 0x25d1, + 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 = 0x2715, - SupercededSpells = 0x2c4c, + SummonRequest = 0x271b, + SupercededSpells = 0x2c4f, SuspendComms = 0x304a, - SuspendToken = 0x25a6, - SyncWowEntitlements = 0x285b, - TalentsInvoluntarilyReset = 0x270b, - TaxiNodeStatus = 0x2674, - TextEmote = 0x2672, - ThreatClear = 0x26d2, - ThreatRemove = 0x26d1, - ThreatUpdate = 0x26d0, + SuspendToken = 0x25a9, + SyncWowEntitlements = 0x2864, + TalentsInvoluntarilyReset = 0x2711, + TaxiNodeStatus = 0x2679, + TextEmote = 0x2677, + ThreatClear = 0x26d7, + ThreatRemove = 0x26d6, + ThreatUpdate = 0x26d5, TimeAdjustment = 0x2dd3, TimeSyncRequest = 0x2dd2, - TitleEarned = 0x26cd, - TitleLost = 0x26ce, - TotemCreated = 0x26be, - TotemDurationChanged = 0x26bf, - TotemMoved = 0x26c0, + TitleEarned = 0x26d2, + TitleLost = 0x26d3, + TotemCreated = 0x26c3, + TotemDurationChanged = 0x26c4, + TotemMoved = 0x26c5, TradeStatus = 0x2582, TradeUpdated = 0x2581, - TrainerBuyFailed = 0x26d5, - TrainerList = 0x26d4, - TransferAborted = 0x26f7, - TransferPending = 0x25c9, - TransmogrifyNpc = 0x27e7, + TrainerBuyFailed = 0x26da, + TrainerList = 0x26d9, + TraitConfigCommitFailed = 0x25d0, + TransferAborted = 0x26fd, + TransferPending = 0x25cc, TreasurePickerResponse = 0x291f, - TriggerCinematic = 0x27b9, - TriggerMovie = 0x26c1, - TurnInPetitionResult = 0x2741, - TutorialFlags = 0x27ac, + TriggerCinematic = 0x27c2, + TriggerMovie = 0x26c6, + TurnInPetitionResult = 0x2747, + TutorialFlags = 0x27b5, TwitterStatus = 0x3043, - UiHealingRangeModified = 0x2737, - UiItemInteractionNpc = 0x27e9, + UiHealingRangeModified = 0x273d, UiMapQuestLinesResponse = 0x2aa2, - UndeleteCharacterResponse = 0x27bc, - UndeleteCooldownStatusResponse = 0x27bd, - UnlearnedSpells = 0x2c4e, + UndeleteCharacterResponse = 0x27c5, + UndeleteCooldownStatusResponse = 0x27c6, + UnlearnedSpells = 0x2c51, UnloadChildMap = 0x257a, - UpdateAadcStatusResponse = 0x2875, - UpdateAccountData = 0x26fd, - UpdateActionButtons = 0x25d9, - UpdateBnetSessionKey = 0x2813, + UpdateAadcStatusResponse = 0x287e, + UpdateAccountData = 0x2703, + UpdateActionButtons = 0x25de, + UpdateBnetSessionKey = 0x281d, UpdateCapturePoint = 0x2929, - UpdateCelestialBody = 0x280f, - UpdateCharacterFlags = 0x27b2, - UpdateChargeCategoryCooldown = 0x2759, - UpdateCooldown = 0x2758, + UpdateCelestialBody = 0x2819, + UpdateCharacterFlags = 0x27bb, + UpdateChargeCategoryCooldown = 0x275f, + UpdateCooldown = 0x275e, + UpdateCraftingNpcRecipes = 0x2996, UpdateDailyMissionCounter = 0x297f, - UpdateExpansionLevel = 0x263e, - UpdateGameTimeState = 0x2816, - UpdateInstanceOwnership = 0x26a1, - UpdateLastInstance = 0x2680, - UpdateObject = 0x27ba, - UpdatePrimarySpec = 0x25d1, - UpdateRecentPlayerGuids = 0x25ef, - UpdateTalentData = 0x25d0, - UpdateTaskProgress = 0x277e, + UpdateExpansionLevel = 0x2643, + UpdateGameTimeState = 0x2820, + UpdateInstanceOwnership = 0x26a6, + UpdateLastInstance = 0x2685, + UpdateObject = 0x27c3, + UpdatePrimarySpec = 0x25d6, + UpdateRecentPlayerGuids = 0x25f4, + UpdateTalentData = 0x25d5, + UpdateTaskProgress = 0x2784, UpdateWeeklySpellUsage = 0x2c19, - UpdateWorldState = 0x273b, + UpdateWorldState = 0x2741, UserlistAdd = 0x2bb9, UserlistRemove = 0x2bba, UserlistUpdate = 0x2bbb, - UseEquipmentSetResult = 0x2742, - VasCheckTransferOkResponse = 0x280a, - VasGetQueueMinutesResponse = 0x2808, - VasGetServiceStatusResponse = 0x2807, - VasPurchaseComplete = 0x27e3, - VasPurchaseStateUpdate = 0x27e2, - VendorInventory = 0x25b4, + UseEquipmentSetResult = 0x2748, + VasCheckTransferOkResponse = 0x2814, + VasGetQueueMinutesResponse = 0x2812, + VasGetServiceStatusResponse = 0x2811, + VasPurchaseComplete = 0x27ec, + VasPurchaseStateUpdate = 0x27eb, + VendorInventory = 0x25b7, VignetteUpdate = 0x3008, - VoiceChannelInfoResponse = 0x280e, - VoiceChannelSttTokenResponse = 0x286f, - VoiceLoginResponse = 0x280d, + VoiceChannelInfoResponse = 0x2818, + VoiceChannelSttTokenResponse = 0x2878, + VoiceLoginResponse = 0x2817, VoidItemSwapResponse = 0x2da4, VoidStorageContents = 0x2da1, VoidStorageFailed = 0x2da0, @@ -1935,24 +2005,24 @@ namespace Framework.Constants WaitQueueFinish = 0x256f, WaitQueueUpdate = 0x256e, Warden3Data = 0x2577, - Warden3Disabled = 0x2811, - Warden3Enabled = 0x2810, - WarfrontComplete = 0x2751, + Warden3Disabled = 0x281b, + Warden3Enabled = 0x281a, + WarfrontComplete = 0x2757, WargameRequestSuccessfullySentToOpponent = 0x2933, - Weather = 0x269e, - WeeklyRewardsProgressResult = 0x2866, - WeeklyRewardsResult = 0x2864, - WeeklyRewardClaimResult = 0x2865, + Weather = 0x26a3, + WeeklyRewardsProgressResult = 0x286f, + WeeklyRewardsResult = 0x286d, + WeeklyRewardClaimResult = 0x286e, WeeklySpellUsage = 0x2c18, Who = 0x2bae, - WhoIs = 0x269d, - WillBeKickedForAddedSubscriptionTime = 0x2815, - WorldMapOpenNpc = 0x27e6, + WhoIs = 0x26a2, + WillBeKickedForAddedSubscriptionTime = 0x281f, WorldQuestUpdateResponse = 0x300f, - WorldServerInfo = 0x25ab, - WowEntitlementNotification = 0x285c, - XpGainAborted = 0x25c5, - XpGainEnabled = 0x279c, + WorldServerInfo = 0x25ae, + WowEntitlementNotification = 0x2865, + XpAwardedFromCurrency = 0x28a0, + XpGainAborted = 0x25c8, + XpGainEnabled = 0x27a5, ZoneUnderAttack = 0x2bb5, // Opcodes That Are Not Generated Automatically diff --git a/Source/Framework/Constants/PlayerConst.cs b/Source/Framework/Constants/PlayerConst.cs index 61f17f86a..2b52e1ff7 100644 --- a/Source/Framework/Constants/PlayerConst.cs +++ b/Source/Framework/Constants/PlayerConst.cs @@ -21,7 +21,7 @@ namespace Framework.Constants { public struct PlayerConst { - public const Expansion CurrentExpansion = Expansion.ShadowLands; + public const Expansion CurrentExpansion = Expansion.Dragonflight; public const int MaxTalentTiers = 7; public const int MaxTalentColumns = 3; @@ -35,7 +35,7 @@ namespace Framework.Constants public const int ReqPrimaryTreeTalents = 31; public const int ExploredZonesSize = 192; public const ulong MaxMoneyAmount = 99999999999UL; - public const int MaxActionButtons = 132; + public const int MaxActionButtons = 180; public const int MaxActionButtonActionValue = 0x00FFFFFF + 1; public const int MaxDailyQuests = 25; @@ -55,8 +55,6 @@ namespace Framework.Constants public const int MaxRunes = 7; public const int MaxRechargingRunes = 3; - public const int CustomDisplaySize = 3; - public const int ArtifactsAllWeaponsGeneralWeaponEquippedPassive = 197886; public const int MaxArtifactTier = 1; @@ -152,7 +150,9 @@ namespace Framework.Constants Com = 0x08, // Commentator Dev = 0x10, BossSound = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper - Mobile = 0x40 + Mobile = 0x40, + Guide = 0x1000, + Newcomer = 0x2000 } public enum DrunkenState @@ -558,7 +558,7 @@ namespace Framework.Constants // first slot for item stored (in any way in player items data) Start = 0, // last+1 slot for item stored (in any way in player items data) - End = 199, + End = 218, Count = (End - Start) } @@ -753,7 +753,9 @@ namespace Framework.Constants FailedAffectingCombat = 5, FailedCantRemoveTalent = 6, FailedCantDoThatChallengeModeActive = 7, - FailedRestArea = 8 + FailedRestArea = 8, + UnspentTalentPoints = 9, + InPvpMatch = 10 } public enum TutorialsFlag diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index 89ef77c66..985fd237b 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -308,11 +308,11 @@ namespace Framework.Constants | 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.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.KulTiran) | GetMaskForRace(Race.DarkIronDwarf) | GetMaskForRace(Race.MechaGnome) | GetMaskForRace(Race.DracthyrAlliance)); public static ulong RaceMaskHorde = RaceMaskAllPlayable & ~RaceMaskAlliance; @@ -430,9 +430,53 @@ 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) { - return raceId < Race.Max && raceBits[(int)raceId] >= 0 && raceBits[(int)raceId] < 64 ? (1 << raceBits[(int)raceId]) : 0; + int raceBit = GetRaceBit(raceId); + return raceBit >= 0 && raceBit < sizeof(long) * 8 ? (1L << raceBit) : 0; } public static bool IsActivePetSlot(PetSaveMode slot) @@ -678,11 +722,13 @@ namespace Framework.Constants Monk = 10, Druid = 11, DemonHunter = 12, - Max = 13, + Evoker = 13, + Adventurer = 14, + Max = 15, ClassMaskAllPlayable = ((1 << (Warrior - 1)) | (1 << (Paladin - 1)) | (1 << (Hunter - 1)) | (1 << (Rogue - 1)) | (1 << (Priest - 1)) | (1 << (Deathknight - 1)) | (1 << (Shaman - 1)) | - (1 << (Mage - 1)) | (1 << (Warlock - 1)) | (1 << (Monk - 1)) | (1 << (Druid - 1)) | (1 << (DemonHunter - 1))), + (1 << (Mage - 1)) | (1 << (Warlock - 1)) | (1 << (Monk - 1)) | (1 << (Druid - 1)) | (1 << (DemonHunter - 1)) | (1 << (Evoker - 1))), ClassMaskAllCreatures = ((1 << (Warrior - 1)) | (1 << (Paladin - 1)) | (1 << (Rogue - 1)) | (1 << (Mage - 1))), @@ -729,7 +775,16 @@ namespace Framework.Constants Vulpera = 35, MagharOrc = 36, MechaGnome = 37, - Max + DracthyrAlliance = 52, + DracthyrHorde = 70, + //CompanionDrake = 71, + //CompanionProtoDragon = 72, + //CompanionSerpent = 73, + //CompanionWyvern = 74, + //DracthyrVisageAlliance = 75, + //DracthyrVisageHorde= 76, + //CompanionPterrodax = 77 + Max = 78 } public enum Expansion @@ -744,6 +799,7 @@ namespace Framework.Constants Legion = 6, BattleForAzeroth = 7, ShadowLands = 8, + Dragonflight = 9, Max, MaxAccountExpansions @@ -769,7 +825,9 @@ namespace Framework.Constants ArcaneCharges = 16, Fury = 17, Pain = 18, - Max = 19, + Essence = 19, + Max = 20, + All = 127, // default for class? Health = -2, // (-2 as signed value) MaxPerClass = 7 @@ -1543,7 +1601,9 @@ namespace Framework.Constants CharacterCreatingDisabled, CharacterCreatingDisabledClassmask, CharacterCreatingDisabledRacemask, + CharacterCreatingEvokersPerRealm, CharacterCreatingMinLevelForDemonHunter, + CharacterCreatingMinLevelForEvoker, CharactersPerAccount, CharactersPerRealm, ChardeleteDeathKnightMinLevel, @@ -1907,1074 +1967,1098 @@ namespace Framework.Constants AmmoOnly = 19, NoSlotAvailable = 20, WrongBagType = 21, - ItemMaxCount = 22, - NotEquippable = 23, - CantStack = 24, - CantSwap = 25, - SlotEmpty = 26, - ItemNotFound = 27, - TooFewToSplit = 28, - SplitFailed = 29, - NotABag = 30, - NotOwner = 31, - OnlyOneQuiver = 32, - NoBankSlot = 33, - NoBankHere = 34, - ItemLocked = 35, - Equipped2handed = 36, - VendorNotInterested = 37, - VendorRefuseScrappableAzerite = 38, - VendorHatesYou = 39, - VendorSoldOut = 40, - VendorTooFar = 41, - VendorDoesntBuy = 42, - NotEnoughMoney = 43, - ReceiveItemS = 44, - DropBoundItem = 45, - TradeBoundItem = 46, - TradeQuestItem = 47, - TradeTempEnchantBound = 48, - TradeGroundItem = 49, - TradeBag = 50, - TradeFactionSpecific = 51, - SpellFailedS = 52, - ItemCooldown = 53, - PotionCooldown = 54, - FoodCooldown = 55, - SpellCooldown = 56, - AbilityCooldown = 57, - SpellAlreadyKnownS = 58, - PetSpellAlreadyKnownS = 59, - ProficiencyGainedS = 60, - SkillGainedS = 61, - SkillUpSi = 62, - LearnSpellS = 63, - LearnAbilityS = 64, - LearnPassiveS = 65, - LearnRecipeS = 66, - LearnCompanionS = 67, - LearnMountS = 68, - LearnToyS = 69, - LearnHeirloomS = 70, - LearnTransmogS = 71, - CompletedTransmogSetS = 72, - AppearanceAlreadyLearned = 73, - RevokeTransmogS = 74, - InvitePlayerS = 75, - InviteSelf = 76, - InvitedToGroupSs = 77, - InvitedAlreadyInGroupSs = 78, - AlreadyInGroupS = 79, - CrossRealmRaidInvite = 80, - PlayerBusyS = 81, - NewLeaderS = 82, - NewLeaderYou = 83, - NewGuideS = 84, - NewGuideYou = 85, - LeftGroupS = 86, - LeftGroupYou = 87, - GroupDisbanded = 88, - DeclineGroupS = 89, - JoinedGroupS = 90, - UninviteYou = 91, - BadPlayerNameS = 92, - NotInGroup = 93, - TargetNotInGroupS = 94, - TargetNotInInstanceS = 95, - NotInInstanceGroup = 96, - GroupFull = 97, - NotLeader = 98, - PlayerDiedS = 99, - GuildCreateS = 100, - GuildInviteS = 101, - InvitedToGuildSss = 102, - AlreadyInGuildS = 103, - AlreadyInvitedToGuildS = 104, - InvitedToGuild = 105, - AlreadyInGuild = 106, - GuildAccept = 107, - GuildDeclineS = 108, - GuildDeclineAutoS = 109, - GuildPermissions = 110, - GuildJoinS = 111, - GuildFounderS = 112, - GuildPromoteSss = 113, - GuildDemoteSs = 114, - GuildDemoteSss = 115, - GuildInviteSelf = 116, - GuildQuitS = 117, - GuildLeaveS = 118, - GuildRemoveSs = 119, - GuildRemoveSelf = 120, - GuildDisbandS = 121, - GuildDisbandSelf = 122, - GuildLeaderS = 123, - GuildLeaderSelf = 124, - GuildPlayerNotFoundS = 125, - GuildPlayerNotInGuildS = 126, - GuildPlayerNotInGuild = 127, - GuildCantPromoteS = 128, - GuildCantDemoteS = 129, - GuildNotInAGuild = 130, - GuildInternal = 131, - GuildLeaderIsS = 132, - GuildLeaderChangedSs = 133, - GuildDisbanded = 134, - GuildNotAllied = 135, - GuildLeaderLeave = 136, - GuildRanksLocked = 137, - GuildRankInUse = 138, - GuildRankTooHighS = 139, - GuildRankTooLowS = 140, - GuildNameExistsS = 141, - GuildWithdrawLimit = 142, - GuildNotEnoughMoney = 143, - GuildTooMuchMoney = 144, - GuildBankConjuredItem = 145, - GuildBankEquippedItem = 146, - GuildBankBoundItem = 147, - GuildBankQuestItem = 148, - GuildBankWrappedItem = 149, - GuildBankFull = 150, - GuildBankWrongTab = 151, - NoGuildCharter = 152, - OutOfRange = 153, - PlayerDead = 154, - ClientLockedOut = 155, - ClientOnTransport = 156, - KilledByS = 157, - LootLocked = 158, - LootTooFar = 159, - LootDidntKill = 160, - LootBadFacing = 161, - LootNotstanding = 162, - LootStunned = 163, - LootNoUi = 164, - LootWhileInvulnerable = 165, - NoLoot = 166, - QuestAcceptedS = 167, - QuestCompleteS = 168, - QuestFailedS = 169, - QuestFailedBagFullS = 170, - QuestFailedMaxCountS = 171, - QuestFailedLowLevel = 172, - QuestFailedMissingItems = 173, - QuestFailedWrongRace = 174, - QuestFailedNotEnoughMoney = 175, - QuestFailedExpansion = 176, - QuestOnlyOneTimed = 177, - QuestNeedPrereqs = 178, - QuestNeedPrereqsCustom = 179, - QuestAlreadyOn = 180, - QuestAlreadyDone = 181, - QuestAlreadyDoneDaily = 182, - QuestHasInProgress = 183, - QuestRewardExpI = 184, - QuestRewardMoneyS = 185, - QuestMustChoose = 186, - QuestLogFull = 187, - CombatDamageSsi = 188, - InspectS = 189, - CantUseItem = 190, - CantUseItemInArena = 191, - CantUseItemInRatedBattleground = 192, - MustEquipItem = 193, - PassiveAbility = 194, - Skill2HNotFound = 195, - NoAttackTarget = 196, - InvalidAttackTarget = 197, - AttackPvpTargetWhileUnflagged = 198, - AttackStunned = 199, - AttackPacified = 200, - AttackMounted = 201, - AttackFleeing = 202, - AttackConfused = 203, - AttackCharmed = 204, - AttackDead = 205, - AttackPreventedByMechanicS = 206, - AttackChannel = 207, - Taxisamenode = 208, - Taxinosuchpath = 209, - Taxiunspecifiedservererror = 210, - Taxinotenoughmoney = 211, - Taxitoofaraway = 212, - Taxinovendornearby = 213, - Taxinotvisited = 214, - Taxiplayerbusy = 215, - Taxiplayeralreadymounted = 216, - Taxiplayershapeshifted = 217, - Taxiplayermoving = 218, - Taxinopaths = 219, - Taxinoteligible = 220, - Taxinotstanding = 221, - NoReplyTarget = 222, - GenericNoTarget = 223, - InitiateTradeS = 224, - TradeRequestS = 225, - TradeBlockedS = 226, - TradeTargetDead = 227, - TradeTooFar = 228, - TradeCancelled = 229, - TradeComplete = 230, - TradeBagFull = 231, - TradeTargetBagFull = 232, - TradeMaxCountExceeded = 233, - TradeTargetMaxCountExceeded = 234, - InventoryTradeTooManyUniqueItem = 235, - AlreadyTrading = 236, - MountInvalidmountee = 237, - MountToofaraway = 238, - MountAlreadymounted = 239, - MountNotmountable = 240, - MountNotyourpet = 241, - MountOther = 242, - MountLooting = 243, - MountRacecantmount = 244, - MountShapeshifted = 245, - MountNoFavorites = 246, - MountNoMounts = 247, - DismountNopet = 248, - DismountNotmounted = 249, - DismountNotyourpet = 250, - SpellFailedTotems = 251, - SpellFailedReagents = 252, - SpellFailedReagentsGeneric = 253, - SpellFailedOptionalReagents = 254, - CantTradeGold = 255, - SpellFailedEquippedItem = 256, - SpellFailedEquippedItemClassS = 257, - SpellFailedShapeshiftFormS = 258, - SpellFailedAnotherInProgress = 259, - Badattackfacing = 260, - Badattackpos = 261, - ChestInUse = 262, - UseCantOpen = 263, - UseLocked = 264, - DoorLocked = 265, - ButtonLocked = 266, - UseLockedWithItemS = 267, - UseLockedWithSpellS = 268, - UseLockedWithSpellKnownSi = 269, - UseTooFar = 270, - UseBadAngle = 271, - UseObjectMoving = 272, - UseSpellFocus = 273, - UseDestroyed = 274, - SetLootFreeforall = 275, - SetLootRoundrobin = 276, - SetLootMaster = 277, - SetLootGroup = 278, - SetLootThresholdS = 279, - NewLootMasterS = 280, - SpecifyMasterLooter = 281, - LootSpecChangedS = 282, - TameFailed = 283, - ChatWhileDead = 284, - ChatPlayerNotFoundS = 285, - Newtaxipath = 286, - NoPet = 287, - Notyourpet = 288, - PetNotRenameable = 289, - QuestObjectiveCompleteS = 290, - QuestUnknownComplete = 291, - QuestAddKillSii = 292, - QuestAddFoundSii = 293, - QuestAddItemSii = 294, - QuestAddPlayerKillSii = 295, - Cannotcreatedirectory = 296, - Cannotcreatefile = 297, - PlayerWrongFaction = 298, - PlayerIsNeutral = 299, - BankslotFailedTooMany = 300, - BankslotInsufficientFunds = 301, - BankslotNotbanker = 302, - FriendDbError = 303, - FriendListFull = 304, - FriendAddedS = 305, - BattletagFriendAddedS = 306, - FriendOnlineSs = 307, - FriendOfflineS = 308, - FriendNotFound = 309, - FriendWrongFaction = 310, - FriendRemovedS = 311, - BattletagFriendRemovedS = 312, - FriendError = 313, - FriendAlreadyS = 314, - FriendSelf = 315, - FriendDeleted = 316, - IgnoreFull = 317, - IgnoreSelf = 318, - IgnoreNotFound = 319, - IgnoreAlreadyS = 320, - IgnoreAddedS = 321, - IgnoreRemovedS = 322, - IgnoreAmbiguous = 323, - IgnoreDeleted = 324, - OnlyOneBolt = 325, - OnlyOneAmmo = 326, - SpellFailedEquippedSpecificItem = 327, - WrongBagTypeSubclass = 328, - CantWrapStackable = 329, - CantWrapEquipped = 330, - CantWrapWrapped = 331, - CantWrapBound = 332, - CantWrapUnique = 333, - CantWrapBags = 334, - OutOfMana = 335, - OutOfRage = 336, - OutOfFocus = 337, - OutOfEnergy = 338, - OutOfChi = 339, - OutOfHealth = 340, - OutOfRunes = 341, - OutOfRunicPower = 342, - OutOfSoulShards = 343, - OutOfLunarPower = 344, - OutOfHolyPower = 345, - OutOfMaelstrom = 346, - OutOfComboPoints = 347, - OutOfInsanity = 348, - OutOfArcaneCharges = 349, - OutOfFury = 350, - OutOfPain = 351, - OutOfPowerDisplay = 352, - LootGone = 353, - MountForceddismount = 354, - AutofollowTooFar = 355, - UnitNotFound = 356, - InvalidFollowTarget = 357, - InvalidFollowPvpCombat = 358, - InvalidFollowTargetPvpCombat = 359, - InvalidInspectTarget = 360, - GuildemblemSuccess = 361, - GuildemblemInvalidTabardColors = 362, - GuildemblemNoguild = 363, - GuildemblemNotguildmaster = 364, - GuildemblemNotenoughmoney = 365, - GuildemblemInvalidvendor = 366, - EmblemerrorNotabardgeoset = 367, - SpellOutOfRange = 368, - CommandNeedsTarget = 369, - NoammoS = 370, - Toobusytofollow = 371, - DuelRequested = 372, - DuelCancelled = 373, - Deathbindalreadybound = 374, - DeathbindSuccessS = 375, - Noemotewhilerunning = 376, - ZoneExplored = 377, - ZoneExploredXp = 378, - InvalidItemTarget = 379, - InvalidQuestTarget = 380, - IgnoringYouS = 381, - FishNotHooked = 382, - FishEscaped = 383, - SpellFailedNotunsheathed = 384, - PetitionOfferedS = 385, - PetitionSigned = 386, - PetitionSignedS = 387, - PetitionDeclinedS = 388, - PetitionAlreadySigned = 389, - PetitionRestrictedAccountTrial = 390, - PetitionAlreadySignedOther = 391, - PetitionInGuild = 392, - PetitionCreator = 393, - PetitionNotEnoughSignatures = 394, - PetitionNotSameServer = 395, - PetitionFull = 396, - PetitionAlreadySignedByS = 397, - GuildNameInvalid = 398, - SpellUnlearnedS = 399, - PetSpellRooted = 400, - PetSpellAffectingCombat = 401, - PetSpellOutOfRange = 402, - PetSpellNotBehind = 403, - PetSpellTargetsDead = 404, - PetSpellDead = 405, - PetSpellNopath = 406, - ItemCantBeDestroyed = 407, - TicketAlreadyExists = 408, - TicketCreateError = 409, - TicketUpdateError = 410, - TicketDbError = 411, - TicketNoText = 412, - TicketTextTooLong = 413, - ObjectIsBusy = 414, - ExhaustionWellrested = 415, - ExhaustionRested = 416, - ExhaustionNormal = 417, - ExhaustionTired = 418, - ExhaustionExhausted = 419, - NoItemsWhileShapeshifted = 420, - CantInteractShapeshifted = 421, - RealmNotFound = 422, - MailQuestItem = 423, - MailBoundItem = 424, - MailConjuredItem = 425, - MailBag = 426, - MailToSelf = 427, - MailTargetNotFound = 428, - MailDatabaseError = 429, - MailDeleteItemError = 430, - MailWrappedCod = 431, - MailCantSendRealm = 432, - MailTempReturnOutage = 433, - MailRecepientCantReceiveMail = 434, - MailSent = 435, - MailTargetIsTrial = 436, - NotHappyEnough = 437, - UseCantImmune = 438, - CantBeDisenchanted = 439, - CantUseDisarmed = 440, - AuctionDatabaseError = 441, - AuctionHigherBid = 442, - AuctionAlreadyBid = 443, - AuctionOutbidS = 444, - AuctionWonS = 445, - AuctionRemovedS = 446, - AuctionBidPlaced = 447, - LogoutFailed = 448, - QuestPushSuccessS = 449, - QuestPushInvalidS = 450, - QuestPushInvalidToRecipientS = 451, - QuestPushAcceptedS = 452, - QuestPushDeclinedS = 453, - QuestPushBusyS = 454, - QuestPushDeadS = 455, - QuestPushDeadToRecipientS = 456, - QuestPushLogFullS = 457, - QuestPushLogFullToRecipientS = 458, - QuestPushOnquestS = 459, - QuestPushOnquestToRecipientS = 460, - QuestPushAlreadyDoneS = 461, - QuestPushAlreadyDoneToRecipientS = 462, - QuestPushNotDailyS = 463, - QuestPushTimerExpiredS = 464, - QuestPushNotInPartyS = 465, - QuestPushDifferentServerDailyS = 466, - QuestPushDifferentServerDailyToRecipientS = 467, - QuestPushNotAllowedS = 468, - QuestPushPrerequisiteS = 469, - QuestPushPrerequisiteToRecipientS = 470, - QuestPushLowLevelS = 471, - QuestPushLowLevelToRecipientS = 472, - QuestPushHighLevelS = 473, - QuestPushHighLevelToRecipientS = 474, - QuestPushClassS = 475, - QuestPushClassToRecipientS = 476, - QuestPushRaceS = 477, - QuestPushRaceToRecipientS = 478, - QuestPushLowFactionS = 479, - QuestPushLowFactionToRecipientS = 480, - QuestPushExpansionS = 481, - QuestPushExpansionToRecipientS = 482, - QuestPushNotGarrisonOwnerS = 483, - QuestPushNotGarrisonOwnerToRecipientS = 484, - QuestPushWrongCovenantS = 485, - QuestPushWrongCovenantToRecipientS = 486, - QuestPushNewPlayerExperienceS = 487, - QuestPushNewPlayerExperienceToRecipientS = 488, - QuestPushWrongFactionS = 489, - QuestPushWrongFactionToRecipientS = 490, - QuestPushCrossFactionRestrictedS = 491, - RaidGroupLowlevel = 492, - RaidGroupOnly = 493, - RaidGroupFull = 494, - RaidGroupRequirementsUnmatch = 495, - CorpseIsNotInInstance = 496, - PvpKillHonorable = 497, - PvpKillDishonorable = 498, - SpellFailedAlreadyAtFullHealth = 499, - SpellFailedAlreadyAtFullMana = 500, - SpellFailedAlreadyAtFullPowerS = 501, - AutolootMoneyS = 502, - GenericStunned = 503, - GenericThrottle = 504, - ClubFinderSearchingTooFast = 505, - TargetStunned = 506, - MustRepairDurability = 507, - RaidYouJoined = 508, - RaidYouLeft = 509, - InstanceGroupJoinedWithParty = 510, - InstanceGroupJoinedWithRaid = 511, - RaidMemberAddedS = 512, - RaidMemberRemovedS = 513, - InstanceGroupAddedS = 514, - InstanceGroupRemovedS = 515, - ClickOnItemToFeed = 516, - TooManyChatChannels = 517, - LootRollPending = 518, - LootPlayerNotFound = 519, - NotInRaid = 520, - LoggingOut = 521, - TargetLoggingOut = 522, - NotWhileMounted = 523, - NotWhileShapeshifted = 524, - NotInCombat = 525, - NotWhileDisarmed = 526, - PetBroken = 527, - TalentWipeError = 528, - SpecWipeError = 529, - GlyphWipeError = 530, - PetSpecWipeError = 531, - FeignDeathResisted = 532, - MeetingStoneInQueueS = 533, - MeetingStoneLeftQueueS = 534, - MeetingStoneOtherMemberLeft = 535, - MeetingStonePartyKickedFromQueue = 536, - MeetingStoneMemberStillInQueue = 537, - MeetingStoneSuccess = 538, - MeetingStoneInProgress = 539, - MeetingStoneMemberAddedS = 540, - MeetingStoneGroupFull = 541, - MeetingStoneNotLeader = 542, - MeetingStoneInvalidLevel = 543, - MeetingStoneTargetNotInParty = 544, - MeetingStoneTargetInvalidLevel = 545, - MeetingStoneMustBeLeader = 546, - MeetingStoneNoRaidGroup = 547, - MeetingStoneNeedParty = 548, - MeetingStoneNotFound = 549, - MeetingStoneTargetInVehicle = 550, - GuildemblemSame = 551, - EquipTradeItem = 552, - PvpToggleOn = 553, - PvpToggleOff = 554, - GroupJoinBattlegroundDeserters = 555, - GroupJoinBattlegroundDead = 556, - GroupJoinBattlegroundS = 557, - GroupJoinBattlegroundFail = 558, - GroupJoinBattlegroundTooMany = 559, - SoloJoinBattlegroundS = 560, - JoinSingleScenarioS = 561, - BattlegroundTooManyQueues = 562, - BattlegroundCannotQueueForRated = 563, - BattledgroundQueuedForRated = 564, - BattlegroundTeamLeftQueue = 565, - BattlegroundNotInBattleground = 566, - AlreadyInArenaTeamS = 567, - InvalidPromotionCode = 568, - BgPlayerJoinedSs = 569, - BgPlayerLeftS = 570, - RestrictedAccount = 571, - RestrictedAccountTrial = 572, - PlayTimeExceeded = 573, - ApproachingPartialPlayTime = 574, - ApproachingPartialPlayTime2 = 575, - ApproachingNoPlayTime = 576, - ApproachingNoPlayTime2 = 577, - UnhealthyTime = 578, - ChatRestrictedTrial = 579, - ChatThrottled = 580, - MailReachedCap = 581, - InvalidRaidTarget = 582, - RaidLeaderReadyCheckStartS = 583, - ReadyCheckInProgress = 584, - ReadyCheckThrottled = 585, - DungeonDifficultyFailed = 586, - DungeonDifficultyChangedS = 587, - TradeWrongRealm = 588, - TradeNotOnTaplist = 589, - ChatPlayerAmbiguousS = 590, - LootCantLootThatNow = 591, - LootMasterInvFull = 592, - LootMasterUniqueItem = 593, - LootMasterOther = 594, - FilteringYouS = 595, - UsePreventedByMechanicS = 596, - ItemUniqueEquippable = 597, - LfgLeaderIsLfmS = 598, - LfgPending = 599, - CantSpeakLangage = 600, - VendorMissingTurnins = 601, - BattlegroundNotInTeam = 602, - NotInBattleground = 603, - NotEnoughHonorPoints = 604, - NotEnoughArenaPoints = 605, - SocketingRequiresMetaGem = 606, - SocketingMetaGemOnlyInMetaslot = 607, - SocketingRequiresHydraulicGem = 608, - SocketingHydraulicGemOnlyInHydraulicslot = 609, - SocketingRequiresCogwheelGem = 610, - SocketingCogwheelGemOnlyInCogwheelslot = 611, - SocketingItemTooLowLevel = 612, - ItemMaxCountSocketed = 613, - SystemDisabled = 614, - QuestFailedTooManyDailyQuestsI = 615, - ItemMaxCountEquippedSocketed = 616, - ItemUniqueEquippableSocketed = 617, - UserSquelched = 618, - AccountSilenced = 619, - PartyMemberSilenced = 620, - PartyMemberSilencedLfgDelist = 621, - TooMuchGold = 622, - NotBarberSitting = 623, - QuestFailedCais = 624, - InviteRestrictedTrial = 625, - VoiceIgnoreFull = 626, - VoiceIgnoreSelf = 627, - VoiceIgnoreNotFound = 628, - VoiceIgnoreAlreadyS = 629, - VoiceIgnoreAddedS = 630, - VoiceIgnoreRemovedS = 631, - VoiceIgnoreAmbiguous = 632, - VoiceIgnoreDeleted = 633, - UnknownMacroOptionS = 634, - NotDuringArenaMatch = 635, - NotInRatedBattleground = 636, - PlayerSilenced = 637, - PlayerUnsilenced = 638, - ComsatDisconnect = 639, - ComsatReconnectAttempt = 640, - ComsatConnectFail = 641, - MailInvalidAttachmentSlot = 642, - MailTooManyAttachments = 643, - MailInvalidAttachment = 644, - MailAttachmentExpired = 645, - VoiceChatParentalDisableMic = 646, - ProfaneChatName = 647, - PlayerSilencedEcho = 648, - PlayerUnsilencedEcho = 649, - LootCantLootThat = 650, - ArenaExpiredCais = 651, - GroupActionThrottled = 652, - AlreadyPickpocketed = 653, - NameInvalid = 654, - NameNoName = 655, - NameTooShort = 656, - NameTooLong = 657, - NameMixedLanguages = 658, - NameProfane = 659, - NameReserved = 660, - NameThreeConsecutive = 661, - NameInvalidSpace = 662, - NameConsecutiveSpaces = 663, - NameRussianConsecutiveSilentCharacters = 664, - NameRussianSilentCharacterAtBeginningOrEnd = 665, - NameDeclensionDoesntMatchBaseName = 666, - RecruitAFriendNotLinked = 667, - RecruitAFriendNotNow = 668, - RecruitAFriendSummonLevelMax = 669, - RecruitAFriendSummonCooldown = 670, - RecruitAFriendSummonOffline = 671, - RecruitAFriendInsufExpanLvl = 672, - RecruitAFriendMapIncomingTransferNotAllowed = 673, - NotSameAccount = 674, - BadOnUseEnchant = 675, - TradeSelf = 676, - TooManySockets = 677, - ItemMaxLimitCategoryCountExceededIs = 678, - TradeTargetMaxLimitCategoryCountExceededIs = 679, - ItemMaxLimitCategorySocketedExceededIs = 680, - ItemMaxLimitCategoryEquippedExceededIs = 681, - ShapeshiftFormCannotEquip = 682, - ItemInventoryFullSatchel = 683, - ScalingStatItemLevelExceeded = 684, - ScalingStatItemLevelTooLow = 685, - PurchaseLevelTooLow = 686, - GroupSwapFailed = 687, - InviteInCombat = 688, - InvalidGlyphSlot = 689, - GenericNoValidTargets = 690, - CalendarEventAlertS = 691, - PetLearnSpellS = 692, - PetLearnAbilityS = 693, - PetSpellUnlearnedS = 694, - InviteUnknownRealm = 695, - InviteNoPartyServer = 696, - InvitePartyBusy = 697, - PartyTargetAmbiguous = 698, - PartyLfgInviteRaidLocked = 699, - PartyLfgBootLimit = 700, - PartyLfgBootCooldownS = 701, - PartyLfgBootNotEligibleS = 702, - PartyLfgBootInpatientTimerS = 703, - PartyLfgBootInProgress = 704, - PartyLfgBootTooFewPlayers = 705, - PartyLfgBootVoteSucceeded = 706, - PartyLfgBootVoteFailed = 707, - PartyLfgBootInCombat = 708, - PartyLfgBootDungeonComplete = 709, - PartyLfgBootLootRolls = 710, - PartyLfgBootVoteRegistered = 711, - PartyPrivateGroupOnly = 712, - PartyLfgTeleportInCombat = 713, - RaidDisallowedByLevel = 714, - RaidDisallowedByCrossRealm = 715, - PartyRoleNotAvailable = 716, - JoinLfgObjectFailed = 717, - LfgRemovedLevelup = 718, - LfgRemovedXpToggle = 719, - LfgRemovedFactionChange = 720, - BattlegroundInfoThrottled = 721, - BattlegroundAlreadyIn = 722, - ArenaTeamChangeFailedQueued = 723, - ArenaTeamPermissions = 724, - NotWhileFalling = 725, - NotWhileMoving = 726, - NotWhileFatigued = 727, - MaxSockets = 728, - MultiCastActionTotemS = 729, - BattlegroundJoinLevelup = 730, - RemoveFromPvpQueueXpGain = 731, - BattlegroundJoinXpGain = 732, - BattlegroundJoinMercenary = 733, - BattlegroundJoinTooManyHealers = 734, - BattlegroundJoinRatedTooManyHealers = 735, - BattlegroundJoinTooManyTanks = 736, - BattlegroundJoinTooManyDamage = 737, - RaidDifficultyFailed = 738, - RaidDifficultyChangedS = 739, - LegacyRaidDifficultyChangedS = 740, - RaidLockoutChangedS = 741, - RaidConvertedToParty = 742, - PartyConvertedToRaid = 743, - PlayerDifficultyChangedS = 744, - GmresponseDbError = 745, - BattlegroundJoinRangeIndex = 746, - ArenaJoinRangeIndex = 747, - RemoveFromPvpQueueFactionChange = 748, - BattlegroundJoinFailed = 749, - BattlegroundJoinNoValidSpecForRole = 750, - BattlegroundJoinRespec = 751, - BattlegroundInvitationDeclined = 752, - BattlegroundJoinTimedOut = 753, - BattlegroundDupeQueue = 754, - BattlegroundJoinMustCompleteQuest = 755, - InBattlegroundRespec = 756, - MailLimitedDurationItem = 757, - YellRestrictedTrial = 758, - ChatRaidRestrictedTrial = 759, - LfgRoleCheckFailed = 760, - LfgRoleCheckFailedTimeout = 761, - LfgRoleCheckFailedNotViable = 762, - LfgReadyCheckFailed = 763, - LfgReadyCheckFailedTimeout = 764, - LfgGroupFull = 765, - LfgNoLfgObject = 766, - LfgNoSlotsPlayer = 767, - LfgNoSlotsParty = 768, - LfgNoSpec = 769, - LfgMismatchedSlots = 770, - LfgMismatchedSlotsLocalXrealm = 771, - LfgPartyPlayersFromDifferentRealms = 772, - LfgMembersNotPresent = 773, - LfgGetInfoTimeout = 774, - LfgInvalidSlot = 775, - LfgDeserterPlayer = 776, - LfgDeserterParty = 777, - LfgDead = 778, - LfgRandomCooldownPlayer = 779, - LfgRandomCooldownParty = 780, - LfgTooManyMembers = 781, - LfgTooFewMembers = 782, - LfgProposalFailed = 783, - LfgProposalDeclinedSelf = 784, - LfgProposalDeclinedParty = 785, - LfgNoSlotsSelected = 786, - LfgNoRolesSelected = 787, - LfgRoleCheckInitiated = 788, - LfgReadyCheckInitiated = 789, - LfgPlayerDeclinedRoleCheck = 790, - LfgPlayerDeclinedReadyCheck = 791, - LfgJoinedQueue = 792, - LfgJoinedFlexQueue = 793, - LfgJoinedRfQueue = 794, - LfgJoinedScenarioQueue = 795, - LfgJoinedWorldPvpQueue = 796, - LfgJoinedBattlefieldQueue = 797, - LfgJoinedList = 798, - LfgLeftQueue = 799, - LfgLeftList = 800, - LfgRoleCheckAborted = 801, - LfgReadyCheckAborted = 802, - LfgCantUseBattleground = 803, - LfgCantUseDungeons = 804, - LfgReasonTooManyLfg = 805, - LfgFarmLimit = 806, - LfgNoCrossFactionParties = 807, - InvalidTeleportLocation = 808, - TooFarToInteract = 809, - BattlegroundPlayersFromDifferentRealms = 810, - DifficultyChangeCooldownS = 811, - DifficultyChangeCombatCooldownS = 812, - DifficultyChangeWorldstate = 813, - DifficultyChangeEncounter = 814, - DifficultyChangeCombat = 815, - DifficultyChangePlayerBusy = 816, - DifficultyChangeAlreadyStarted = 817, - DifficultyChangeOtherHeroicS = 818, - DifficultyChangeHeroicInstanceAlreadyRunning = 819, - ArenaTeamPartySize = 820, - SoloShuffleWargameGroupSize = 821, - SoloShuffleWargameGroupComp = 822, - PvpPlayerAbandoned = 823, - QuestForceRemovedS = 824, - AttackNoActions = 825, - InRandomBg = 826, - InNonRandomBg = 827, - BnFriendSelf = 828, - BnFriendAlready = 829, - BnFriendBlocked = 830, - BnFriendListFull = 831, - BnFriendRequestSent = 832, - BnBroadcastThrottle = 833, - BgDeveloperOnly = 834, - CurrencySpellSlotMismatch = 835, - CurrencyNotTradable = 836, - RequiresExpansionS = 837, - QuestFailedSpell = 838, - TalentFailedNotEnoughTalentsInPrimaryTree = 839, - TalentFailedNoPrimaryTreeSelected = 840, - TalentFailedCantRemoveTalent = 841, - TalentFailedUnknown = 842, - WargameRequestFailure = 843, - RankRequiresAuthenticator = 844, - GuildBankVoucherFailed = 845, - WargameRequestSent = 846, - RequiresAchievementI = 847, - RefundResultExceedMaxCurrency = 848, - CantBuyQuantity = 849, - ItemIsBattlePayLocked = 850, - PartyAlreadyInBattlegroundQueue = 851, - PartyConfirmingBattlegroundQueue = 852, - BattlefieldTeamPartySize = 853, - InsuffTrackedCurrencyIs = 854, - NotOnTournamentRealm = 855, - GuildTrialAccountTrial = 856, - GuildTrialAccountVeteran = 857, - GuildUndeletableDueToLevel = 858, - CantDoThatInAGroup = 859, - GuildLeaderReplaced = 860, - TransmogrifyCantEquip = 861, - TransmogrifyInvalidItemType = 862, - TransmogrifyNotSoulbound = 863, - TransmogrifyInvalidSource = 864, - TransmogrifyInvalidDestination = 865, - TransmogrifyMismatch = 866, - TransmogrifyLegendary = 867, - TransmogrifySameItem = 868, - TransmogrifySameAppearance = 869, - TransmogrifyNotEquipped = 870, - VoidDepositFull = 871, - VoidWithdrawFull = 872, - VoidStorageWrapped = 873, - VoidStorageStackable = 874, - VoidStorageUnbound = 875, - VoidStorageRepair = 876, - VoidStorageCharges = 877, - VoidStorageQuest = 878, - VoidStorageConjured = 879, - VoidStorageMail = 880, - VoidStorageBag = 881, - VoidTransferStorageFull = 882, - VoidTransferInvFull = 883, - VoidTransferInternalError = 884, - VoidTransferItemInvalid = 885, - DifficultyDisabledInLfg = 886, - VoidStorageUnique = 887, - VoidStorageLoot = 888, - VoidStorageHoliday = 889, - VoidStorageDuration = 890, - VoidStorageLoadFailed = 891, - VoidStorageInvalidItem = 892, - ParentalControlsChatMuted = 893, - SorStartExperienceIncomplete = 894, - SorInvalidEmail = 895, - SorInvalidComment = 896, - ChallengeModeResetCooldownS = 897, - ChallengeModeResetKeystone = 898, - PetJournalAlreadyInLoadout = 899, - ReportSubmittedSuccessfully = 900, - ReportSubmissionFailed = 901, - SuggestionSubmittedSuccessfully = 902, - BugSubmittedSuccessfully = 903, - ChallengeModeEnabled = 904, - ChallengeModeDisabled = 905, - PetbattleCreateFailed = 906, - PetbattleNotHere = 907, - PetbattleNotHereOnTransport = 908, - PetbattleNotHereUnevenGround = 909, - PetbattleNotHereObstructed = 910, - PetbattleNotWhileInCombat = 911, - PetbattleNotWhileDead = 912, - PetbattleNotWhileFlying = 913, - PetbattleTargetInvalid = 914, - PetbattleTargetOutOfRange = 915, - PetbattleTargetNotCapturable = 916, - PetbattleNotATrainer = 917, - PetbattleDeclined = 918, - PetbattleInBattle = 919, - PetbattleInvalidLoadout = 920, - PetbattleAllPetsDead = 921, - PetbattleNoPetsInSlots = 922, - PetbattleNoAccountLock = 923, - PetbattleWildPetTapped = 924, - PetbattleRestrictedAccount = 925, - PetbattleOpponentNotAvailable = 926, - PetbattleNotWhileInMatchedBattle = 927, - CantHaveMorePetsOfThatType = 928, - CantHaveMorePets = 929, - PvpMapNotFound = 930, - PvpMapNotSet = 931, - PetbattleQueueQueued = 932, - PetbattleQueueAlreadyQueued = 933, - PetbattleQueueJoinFailed = 934, - PetbattleQueueJournalLock = 935, - PetbattleQueueRemoved = 936, - PetbattleQueueProposalDeclined = 937, - PetbattleQueueProposalTimeout = 938, - PetbattleQueueOpponentDeclined = 939, - PetbattleQueueRequeuedInternal = 940, - PetbattleQueueRequeuedRemoved = 941, - PetbattleQueueSlotLocked = 942, - PetbattleQueueSlotEmpty = 943, - PetbattleQueueSlotNoTracker = 944, - PetbattleQueueSlotNoSpecies = 945, - PetbattleQueueSlotCantBattle = 946, - PetbattleQueueSlotRevoked = 947, - PetbattleQueueSlotDead = 948, - PetbattleQueueSlotNoPet = 949, - PetbattleQueueNotWhileNeutral = 950, - PetbattleGameTimeLimitWarning = 951, - PetbattleGameRoundsLimitWarning = 952, - HasRestriction = 953, - ItemUpgradeItemTooLowLevel = 954, - ItemUpgradeNoPath = 955, - ItemUpgradeNoMoreUpgrades = 956, - BonusRollEmpty = 957, - ChallengeModeFull = 958, - ChallengeModeInProgress = 959, - ChallengeModeIncorrectKeystone = 960, - BattletagFriendNotFound = 961, - BattletagFriendNotValid = 962, - BattletagFriendNotAllowed = 963, - BattletagFriendThrottled = 964, - BattletagFriendSuccess = 965, - PetTooHighLevelToUncage = 966, - PetbattleInternal = 967, - CantCagePetYet = 968, - NoLootInChallengeMode = 969, - QuestPetBattleVictoriesPvpIi = 970, - RoleCheckAlreadyInProgress = 971, - RecruitAFriendAccountLimit = 972, - RecruitAFriendFailed = 973, - SetLootPersonal = 974, - SetLootMethodFailedCombat = 975, - ReagentBankFull = 976, - ReagentBankLocked = 977, - GarrisonBuildingExists = 978, - GarrisonInvalidPlot = 979, - GarrisonInvalidBuildingid = 980, - GarrisonInvalidPlotBuilding = 981, - GarrisonRequiresBlueprint = 982, - GarrisonNotEnoughCurrency = 983, - GarrisonNotEnoughGold = 984, - GarrisonCompleteMissionWrongFollowerType = 985, - AlreadyUsingLfgList = 986, - RestrictedAccountLfgListTrial = 987, - ToyUseLimitReached = 988, - ToyAlreadyKnown = 989, - TransmogSetAlreadyKnown = 990, - NotEnoughCurrency = 991, - SpecIsDisabled = 992, - FeatureRestrictedTrial = 993, - CantBeObliterated = 994, - CantBeScrapped = 995, - ArtifactRelicDoesNotMatchArtifact = 996, - MustEquipArtifact = 997, - CantDoThatRightNow = 998, - AffectingCombat = 999, - EquipmentManagerCombatSwapS = 1000, - EquipmentManagerBagsFull = 1001, - EquipmentManagerMissingItemS = 1002, - MovieRecordingWarningPerf = 1003, - MovieRecordingWarningDiskFull = 1004, - MovieRecordingWarningNoMovie = 1005, - MovieRecordingWarningRequirements = 1006, - MovieRecordingWarningCompressing = 1007, - NoChallengeModeReward = 1008, - ClaimedChallengeModeReward = 1009, - ChallengeModePeriodResetSs = 1010, - CantDoThatChallengeModeActive = 1011, - TalentFailedRestArea = 1012, - CannotAbandonLastPet = 1013, - TestCvarSetSss = 1014, - QuestTurnInFailReason = 1015, - ClaimedChallengeModeRewardOld = 1016, - TalentGrantedByAura = 1017, - ChallengeModeAlreadyComplete = 1018, - GlyphTargetNotAvailable = 1019, - PvpWarmodeToggleOn = 1020, - PvpWarmodeToggleOff = 1021, - SpellFailedLevelRequirement = 1022, - BattlegroundJoinRequiresLevel = 1023, - BattlegroundJoinDisqualified = 1024, - BattlegroundJoinDisqualifiedNoName = 1025, - VoiceChatGenericUnableToConnect = 1026, - VoiceChatServiceLost = 1027, - VoiceChatChannelNameTooShort = 1028, - VoiceChatChannelNameTooLong = 1029, - VoiceChatChannelAlreadyExists = 1030, - VoiceChatTargetNotFound = 1031, - VoiceChatTooManyRequests = 1032, - VoiceChatPlayerSilenced = 1033, - VoiceChatParentalDisableAll = 1034, - VoiceChatDisabled = 1035, - NoPvpReward = 1036, - ClaimedPvpReward = 1037, - AzeriteEssenceSelectionFailedEssenceNotUnlocked = 1038, - AzeriteEssenceSelectionFailedCantRemoveEssence = 1039, - AzeriteEssenceSelectionFailedConditionFailed = 1040, - AzeriteEssenceSelectionFailedRestArea = 1041, - AzeriteEssenceSelectionFailedSlotLocked = 1042, - AzeriteEssenceSelectionFailedNotAtForge = 1043, - AzeriteEssenceSelectionFailedHeartLevelTooLow = 1044, - AzeriteEssenceSelectionFailedNotEquipped = 1045, - SocketingRequiresPunchcardredGem = 1046, - SocketingPunchcardredGemOnlyInPunchcardredslot = 1047, - SocketingRequiresPunchcardyellowGem = 1048, - SocketingPunchcardyellowGemOnlyInPunchcardyellowslot = 1049, - SocketingRequiresPunchcardblueGem = 1050, - SocketingPunchcardblueGemOnlyInPunchcardblueslot = 1051, - SocketingRequiresDominationShard = 1052, - SocketingDominationShardOnlyInDominationslot = 1053, - SocketingRequiresCypherGem = 1054, - SocketingCypherGemOnlyInCypherslot = 1055, - LevelLinkingResultLinked = 1056, - LevelLinkingResultUnlinked = 1057, - ClubFinderErrorPostClub = 1058, - ClubFinderErrorApplyClub = 1059, - ClubFinderErrorRespondApplicant = 1060, - ClubFinderErrorCancelApplication = 1061, - ClubFinderErrorTypeAcceptApplication = 1062, - ClubFinderErrorTypeNoInvitePermissions = 1063, - ClubFinderErrorTypeNoPostingPermissions = 1064, - ClubFinderErrorTypeApplicantList = 1065, - ClubFinderErrorTypeApplicantListNoPerm = 1066, - ClubFinderErrorTypeFinderNotAvailable = 1067, - ClubFinderErrorTypeGetPostingIds = 1068, - ClubFinderErrorTypeJoinApplication = 1069, - ClubFinderErrorTypeRealmNotEligible = 1070, - ClubFinderErrorTypeFlaggedRename = 1071, - ClubFinderErrorTypeFlaggedDescriptionChange = 1072, - ItemInteractionNotEnoughGold = 1073, - ItemInteractionNotEnoughCurrency = 1074, - PlayerChoiceErrorPendingChoice = 1075, - SoulbindInvalidConduit = 1076, - SoulbindInvalidConduitItem = 1077, - SoulbindInvalidTalent = 1078, - SoulbindDuplicateConduit = 1079, - ActivateSoulbindS = 1080, - ActivateSoulbindFailedRestArea = 1081, - CantUseProfanity = 1082, - NotInPetBattle = 1083, - NotInNpe = 1084, - NoSpec = 1085, - NoDominationshardOverwrite = 1086, - UseWeeklyRewardsDisabled = 1087, - CrossFactionGroupJoined = 1088, - CantTargetUnfriendlyInOverworld = 1089 + ReagentbagWrongSlot = 22, + SlotOnlyReagentbag = 23, + ReagentbagItemType = 24, + ItemMaxCount = 25, + NotEquippable = 26, + CantStack = 27, + CantSwap = 28, + SlotEmpty = 29, + ItemNotFound = 30, + TooFewToSplit = 31, + SplitFailed = 32, + NotABag = 33, + NotOwner = 34, + OnlyOneQuiver = 35, + NoBankSlot = 36, + NoBankHere = 37, + ItemLocked = 38, + Handed2Equipped = 39, + VendorNotInterested = 40, + VendorRefuseScrappableAzerite = 41, + VendorHatesYou = 42, + VendorSoldOut = 43, + VendorTooFar = 44, + VendorDoesntBuy = 45, + NotEnoughMoney = 46, + ReceiveItemS = 47, + DropBoundItem = 48, + TradeBoundItem = 49, + TradeQuestItem = 50, + TradeTempEnchantBound = 51, + TradeGroundItem = 52, + TradeBag = 53, + TradeFactionSpecific = 54, + SpellFailedS = 55, + ItemCooldown = 56, + PotionCooldown = 57, + FoodCooldown = 58, + SpellCooldown = 59, + AbilityCooldown = 60, + SpellAlreadyKnownS = 61, + PetSpellAlreadyKnownS = 62, + ProficiencyGainedS = 63, + SkillGainedS = 64, + SkillUpSi = 65, + LearnSpellS = 66, + LearnAbilityS = 67, + LearnPassiveS = 68, + LearnRecipeS = 69, + ProfessionsRecipeDiscoveryS = 70, + LearnCompanionS = 71, + LearnMountS = 72, + LearnToyS = 73, + LearnHeirloomS = 74, + LearnTransmogS = 75, + CompletedTransmogSetS = 76, + AppearanceAlreadyLearned = 77, + RevokeTransmogS = 78, + InvitePlayerS = 79, + SuggestInvitePlayerS = 80, + InformSuggestInviteS = 81, + InformSuggestInviteSs = 82, + RequestJoinPlayerS = 83, + InviteSelf = 84, + InvitedToGroupSs = 85, + InvitedAlreadyInGroupSs = 86, + AlreadyInGroupS = 87, + RequestedInviteToGroupSs = 88, + CrossRealmRaidInvite = 89, + PlayerBusyS = 90, + NewLeaderS = 91, + NewLeaderYou = 92, + NewGuideS = 93, + NewGuideYou = 94, + LeftGroupS = 95, + LeftGroupYou = 96, + GroupDisbanded = 97, + DeclineGroupS = 98, + DeclineGroupRequestS = 99, + JoinedGroupS = 100, + UninviteYou = 101, + BadPlayerNameS = 102, + NotInGroup = 103, + TargetNotInGroupS = 104, + TargetNotInInstanceS = 105, + NotInInstanceGroup = 106, + GroupFull = 107, + NotLeader = 108, + PlayerDiedS = 109, + GuildCreateS = 110, + GuildInviteS = 111, + InvitedToGuildSss = 112, + AlreadyInGuildS = 113, + AlreadyInvitedToGuildS = 114, + InvitedToGuild = 115, + AlreadyInGuild = 116, + GuildAccept = 117, + GuildDeclineS = 118, + GuildDeclineAutoS = 119, + GuildPermissions = 120, + GuildJoinS = 121, + GuildFounderS = 122, + GuildPromoteSss = 123, + GuildDemoteSs = 124, + GuildDemoteSss = 125, + GuildInviteSelf = 126, + GuildQuitS = 127, + GuildLeaveS = 128, + GuildRemoveSs = 129, + GuildRemoveSelf = 130, + GuildDisbandS = 131, + GuildDisbandSelf = 132, + GuildLeaderS = 133, + GuildLeaderSelf = 134, + GuildPlayerNotFoundS = 135, + GuildPlayerNotInGuildS = 136, + GuildPlayerNotInGuild = 137, + GuildCantPromoteS = 138, + GuildCantDemoteS = 139, + GuildNotInAGuild = 140, + GuildInternal = 141, + GuildLeaderIsS = 142, + GuildLeaderChangedSs = 143, + GuildDisbanded = 144, + GuildNotAllied = 145, + GuildLeaderLeave = 146, + GuildRanksLocked = 147, + GuildRankInUse = 148, + GuildRankTooHighS = 149, + GuildRankTooLowS = 150, + GuildNameExistsS = 151, + GuildWithdrawLimit = 152, + GuildNotEnoughMoney = 153, + GuildTooMuchMoney = 154, + GuildBankConjuredItem = 155, + GuildBankEquippedItem = 156, + GuildBankBoundItem = 157, + GuildBankQuestItem = 158, + GuildBankWrappedItem = 159, + GuildBankFull = 160, + GuildBankWrongTab = 161, + NoGuildCharter = 162, + OutOfRange = 163, + PlayerDead = 164, + ClientLockedOut = 165, + ClientOnTransport = 166, + KilledByS = 167, + LootLocked = 168, + LootTooFar = 169, + LootDidntKill = 170, + LootBadFacing = 171, + LootNotstanding = 172, + LootStunned = 173, + LootNoUi = 174, + LootWhileInvulnerable = 175, + NoLoot = 176, + QuestAcceptedS = 177, + QuestCompleteS = 178, + QuestFailedS = 179, + QuestFailedBagFullS = 180, + QuestFailedMaxCountS = 181, + QuestFailedLowLevel = 182, + QuestFailedMissingItems = 183, + QuestFailedWrongRace = 184, + QuestFailedNotEnoughMoney = 185, + QuestFailedExpansion = 186, + QuestOnlyOneTimed = 187, + QuestNeedPrereqs = 188, + QuestNeedPrereqsCustom = 189, + QuestAlreadyOn = 190, + QuestAlreadyDone = 191, + QuestAlreadyDoneDaily = 192, + QuestHasInProgress = 193, + QuestRewardExpI = 194, + QuestRewardMoneyS = 195, + QuestMustChoose = 196, + QuestLogFull = 197, + CombatDamageSsi = 198, + InspectS = 199, + CantUseItem = 200, + CantUseItemInArena = 201, + CantUseItemInRatedBattleground = 202, + MustEquipItem = 203, + PassiveAbility = 204, + H2skillnotfound = 205, + NoAttackTarget = 206, + InvalidAttackTarget = 207, + AttackPvpTargetWhileUnflagged = 208, + AttackStunned = 209, + AttackPacified = 210, + AttackMounted = 211, + AttackFleeing = 212, + AttackConfused = 213, + AttackCharmed = 214, + AttackDead = 215, + AttackPreventedByMechanicS = 216, + AttackChannel = 217, + Taxisamenode = 218, + Taxinosuchpath = 219, + Taxiunspecifiedservererror = 220, + Taxinotenoughmoney = 221, + Taxitoofaraway = 222, + Taxinovendornearby = 223, + Taxinotvisited = 224, + Taxiplayerbusy = 225, + Taxiplayeralreadymounted = 226, + Taxiplayershapeshifted = 227, + Taxiplayermoving = 228, + Taxinopaths = 229, + Taxinoteligible = 230, + Taxinotstanding = 231, + Taxiincombat = 232, + NoReplyTarget = 233, + GenericNoTarget = 234, + InitiateTradeS = 235, + TradeRequestS = 236, + TradeBlockedS = 237, + TradeTargetDead = 238, + TradeTooFar = 239, + TradeCancelled = 240, + TradeComplete = 241, + TradeBagFull = 242, + TradeTargetBagFull = 243, + TradeMaxCountExceeded = 244, + TradeTargetMaxCountExceeded = 245, + InventoryTradeTooManyUniqueItem = 246, + AlreadyTrading = 247, + MountInvalidmountee = 248, + MountToofaraway = 249, + MountAlreadymounted = 250, + MountNotmountable = 251, + MountNotyourpet = 252, + MountOther = 253, + MountLooting = 254, + MountRacecantmount = 255, + MountShapeshifted = 256, + MountNoFavorites = 257, + MountNoMounts = 258, + DismountNopet = 259, + DismountNotmounted = 260, + DismountNotyourpet = 261, + SpellFailedTotems = 262, + SpellFailedReagents = 263, + SpellFailedReagentsGeneric = 264, + SpellFailedOptionalReagents = 265, + CantTradeGold = 266, + SpellFailedEquippedItem = 267, + SpellFailedEquippedItemClassS = 268, + SpellFailedShapeshiftFormS = 269, + SpellFailedAnotherInProgress = 270, + Badattackfacing = 271, + Badattackpos = 272, + ChestInUse = 273, + UseCantOpen = 274, + UseLocked = 275, + DoorLocked = 276, + ButtonLocked = 277, + UseLockedWithItemS = 278, + UseLockedWithSpellS = 279, + UseLockedWithSpellKnownSi = 280, + UseTooFar = 281, + UseBadAngle = 282, + UseObjectMoving = 283, + UseSpellFocus = 284, + UseDestroyed = 285, + SetLootFreeforall = 286, + SetLootRoundrobin = 287, + SetLootMaster = 288, + SetLootGroup = 289, + SetLootThresholdS = 290, + NewLootMasterS = 291, + SpecifyMasterLooter = 292, + LootSpecChangedS = 293, + TameFailed = 294, + ChatWhileDead = 295, + ChatPlayerNotFoundS = 296, + Newtaxipath = 297, + NoPet = 298, + Notyourpet = 299, + PetNotRenameable = 300, + QuestObjectiveCompleteS = 301, + QuestUnknownComplete = 302, + QuestAddKillSii = 303, + QuestAddFoundSii = 304, + QuestAddItemSii = 305, + QuestAddPlayerKillSii = 306, + Cannotcreatedirectory = 307, + Cannotcreatefile = 308, + PlayerWrongFaction = 309, + PlayerIsNeutral = 310, + BankslotFailedTooMany = 311, + BankslotInsufficientFunds = 312, + BankslotNotbanker = 313, + FriendDbError = 314, + FriendListFull = 315, + FriendAddedS = 316, + BattletagFriendAddedS = 317, + FriendOnlineSs = 318, + FriendOfflineS = 319, + FriendNotFound = 320, + FriendWrongFaction = 321, + FriendRemovedS = 322, + BattletagFriendRemovedS = 323, + FriendError = 324, + FriendAlreadyS = 325, + FriendSelf = 326, + FriendDeleted = 327, + IgnoreFull = 328, + IgnoreSelf = 329, + IgnoreNotFound = 330, + IgnoreAlreadyS = 331, + IgnoreAddedS = 332, + IgnoreRemovedS = 333, + IgnoreAmbiguous = 334, + IgnoreDeleted = 335, + OnlyOneBolt = 336, + OnlyOneAmmo = 337, + SpellFailedEquippedSpecificItem = 338, + WrongBagTypeSubclass = 339, + CantWrapStackable = 340, + CantWrapEquipped = 341, + CantWrapWrapped = 342, + CantWrapBound = 343, + CantWrapUnique = 344, + CantWrapBags = 345, + OutOfMana = 346, + OutOfRage = 347, + OutOfFocus = 348, + OutOfEnergy = 349, + OutOfChi = 350, + OutOfHealth = 351, + OutOfRunes = 352, + OutOfRunicPower = 353, + OutOfSoulShards = 354, + OutOfLunarPower = 355, + OutOfHolyPower = 356, + OutOfMaelstrom = 357, + OutOfComboPoints = 358, + OutOfInsanity = 359, + OutOfEssence = 360, + OutOfArcaneCharges = 361, + OutOfFury = 362, + OutOfPain = 363, + OutOfPowerDisplay = 364, + LootGone = 365, + MountForceddismount = 366, + AutofollowTooFar = 367, + UnitNotFound = 368, + InvalidFollowTarget = 369, + InvalidFollowPvpCombat = 370, + InvalidFollowTargetPvpCombat = 371, + InvalidInspectTarget = 372, + GuildemblemSuccess = 373, + GuildemblemInvalidTabardColors = 374, + GuildemblemNoguild = 375, + GuildemblemNotguildmaster = 376, + GuildemblemNotenoughmoney = 377, + GuildemblemInvalidvendor = 378, + EmblemerrorNotabardgeoset = 379, + SpellOutOfRange = 380, + CommandNeedsTarget = 381, + NoammoS = 382, + Toobusytofollow = 383, + DuelRequested = 384, + DuelCancelled = 385, + Deathbindalreadybound = 386, + DeathbindSuccessS = 387, + Noemotewhilerunning = 388, + ZoneExplored = 389, + ZoneExploredXp = 390, + InvalidItemTarget = 391, + InvalidQuestTarget = 392, + IgnoringYouS = 393, + FishNotHooked = 394, + FishEscaped = 395, + SpellFailedNotunsheathed = 396, + PetitionOfferedS = 397, + PetitionSigned = 398, + PetitionSignedS = 399, + PetitionDeclinedS = 400, + PetitionAlreadySigned = 401, + PetitionRestrictedAccountTrial = 402, + PetitionAlreadySignedOther = 403, + PetitionInGuild = 404, + PetitionCreator = 405, + PetitionNotEnoughSignatures = 406, + PetitionNotSameServer = 407, + PetitionFull = 408, + PetitionAlreadySignedByS = 409, + GuildNameInvalid = 410, + SpellUnlearnedS = 411, + PetSpellRooted = 412, + PetSpellAffectingCombat = 413, + PetSpellOutOfRange = 414, + PetSpellNotBehind = 415, + PetSpellTargetsDead = 416, + PetSpellDead = 417, + PetSpellNopath = 418, + ItemCantBeDestroyed = 419, + TicketAlreadyExists = 420, + TicketCreateError = 421, + TicketUpdateError = 422, + TicketDbError = 423, + TicketNoText = 424, + TicketTextTooLong = 425, + ObjectIsBusy = 426, + ExhaustionWellrested = 427, + ExhaustionRested = 428, + ExhaustionNormal = 429, + ExhaustionTired = 430, + ExhaustionExhausted = 431, + NoItemsWhileShapeshifted = 432, + CantInteractShapeshifted = 433, + RealmNotFound = 434, + MailQuestItem = 435, + MailBoundItem = 436, + MailConjuredItem = 437, + MailBag = 438, + MailToSelf = 439, + MailTargetNotFound = 440, + MailDatabaseError = 441, + MailDeleteItemError = 442, + MailWrappedCod = 443, + MailCantSendRealm = 444, + MailTempReturnOutage = 445, + MailRecepientCantReceiveMail = 446, + MailSent = 447, + MailTargetIsTrial = 448, + NotHappyEnough = 449, + UseCantImmune = 450, + CantBeDisenchanted = 451, + CantUseDisarmed = 452, + AuctionDatabaseError = 453, + AuctionHigherBid = 454, + AuctionAlreadyBid = 455, + AuctionOutbidS = 456, + AuctionWonS = 457, + AuctionRemovedS = 458, + AuctionBidPlaced = 459, + LogoutFailed = 460, + QuestPushSuccessS = 461, + QuestPushInvalidS = 462, + QuestPushInvalidToRecipientS = 463, + QuestPushAcceptedS = 464, + QuestPushDeclinedS = 465, + QuestPushBusyS = 466, + QuestPushDeadS = 467, + QuestPushDeadToRecipientS = 468, + QuestPushLogFullS = 469, + QuestPushLogFullToRecipientS = 470, + QuestPushOnquestS = 471, + QuestPushOnquestToRecipientS = 472, + QuestPushAlreadyDoneS = 473, + QuestPushAlreadyDoneToRecipientS = 474, + QuestPushNotDailyS = 475, + QuestPushTimerExpiredS = 476, + QuestPushNotInPartyS = 477, + QuestPushDifferentServerDailyS = 478, + QuestPushDifferentServerDailyToRecipientS = 479, + QuestPushNotAllowedS = 480, + QuestPushPrerequisiteS = 481, + QuestPushPrerequisiteToRecipientS = 482, + QuestPushLowLevelS = 483, + QuestPushLowLevelToRecipientS = 484, + QuestPushHighLevelS = 485, + QuestPushHighLevelToRecipientS = 486, + QuestPushClassS = 487, + QuestPushClassToRecipientS = 488, + QuestPushRaceS = 489, + QuestPushRaceToRecipientS = 490, + QuestPushLowFactionS = 491, + QuestPushLowFactionToRecipientS = 492, + QuestPushExpansionS = 493, + QuestPushExpansionToRecipientS = 494, + QuestPushNotGarrisonOwnerS = 495, + QuestPushNotGarrisonOwnerToRecipientS = 496, + QuestPushWrongCovenantS = 497, + QuestPushWrongCovenantToRecipientS = 498, + QuestPushNewPlayerExperienceS = 499, + QuestPushNewPlayerExperienceToRecipientS = 500, + QuestPushWrongFactionS = 501, + QuestPushWrongFactionToRecipientS = 502, + QuestPushCrossFactionRestrictedS = 503, + RaidGroupLowlevel = 504, + RaidGroupOnly = 505, + RaidGroupFull = 506, + RaidGroupRequirementsUnmatch = 507, + CorpseIsNotInInstance = 508, + PvpKillHonorable = 509, + PvpKillDishonorable = 510, + SpellFailedAlreadyAtFullHealth = 511, + SpellFailedAlreadyAtFullMana = 512, + SpellFailedAlreadyAtFullPowerS = 513, + AutolootMoneyS = 514, + GenericStunned = 515, + GenericThrottle = 516, + ClubFinderSearchingTooFast = 517, + TargetStunned = 518, + MustRepairDurability = 519, + RaidYouJoined = 520, + RaidYouLeft = 521, + InstanceGroupJoinedWithParty = 522, + InstanceGroupJoinedWithRaid = 523, + RaidMemberAddedS = 524, + RaidMemberRemovedS = 525, + InstanceGroupAddedS = 526, + InstanceGroupRemovedS = 527, + ClickOnItemToFeed = 528, + TooManyChatChannels = 529, + LootRollPending = 530, + LootPlayerNotFound = 531, + NotInRaid = 532, + LoggingOut = 533, + TargetLoggingOut = 534, + NotWhileMounted = 535, + NotWhileShapeshifted = 536, + NotInCombat = 537, + NotWhileDisarmed = 538, + PetBroken = 539, + TalentWipeError = 540, + SpecWipeError = 541, + GlyphWipeError = 542, + PetSpecWipeError = 543, + FeignDeathResisted = 544, + MeetingStoneInQueueS = 545, + MeetingStoneLeftQueueS = 546, + MeetingStoneOtherMemberLeft = 547, + MeetingStonePartyKickedFromQueue = 548, + MeetingStoneMemberStillInQueue = 549, + MeetingStoneSuccess = 550, + MeetingStoneInProgress = 551, + MeetingStoneMemberAddedS = 552, + MeetingStoneGroupFull = 553, + MeetingStoneNotLeader = 554, + MeetingStoneInvalidLevel = 555, + MeetingStoneTargetNotInParty = 556, + MeetingStoneTargetInvalidLevel = 557, + MeetingStoneMustBeLeader = 558, + MeetingStoneNoRaidGroup = 559, + MeetingStoneNeedParty = 560, + MeetingStoneNotFound = 561, + MeetingStoneTargetInVehicle = 562, + GuildemblemSame = 563, + EquipTradeItem = 564, + PvpToggleOn = 565, + PvpToggleOff = 566, + GroupJoinBattlegroundDeserters = 567, + GroupJoinBattlegroundDead = 568, + GroupJoinBattlegroundS = 569, + GroupJoinBattlegroundFail = 570, + GroupJoinBattlegroundTooMany = 571, + SoloJoinBattlegroundS = 572, + JoinSingleScenarioS = 573, + BattlegroundTooManyQueues = 574, + BattlegroundCannotQueueForRated = 575, + BattledgroundQueuedForRated = 576, + BattlegroundTeamLeftQueue = 577, + BattlegroundNotInBattleground = 578, + AlreadyInArenaTeamS = 579, + InvalidPromotionCode = 580, + BgPlayerJoinedSs = 581, + BgPlayerLeftS = 582, + RestrictedAccount = 583, + RestrictedAccountTrial = 584, + PlayTimeExceeded = 585, + ApproachingPartialPlayTime = 586, + ApproachingPartialPlayTime2 = 587, + ApproachingNoPlayTime = 588, + ApproachingNoPlayTime2 = 589, + UnhealthyTime = 590, + ChatRestrictedTrial = 591, + ChatThrottled = 592, + MailReachedCap = 593, + InvalidRaidTarget = 594, + RaidLeaderReadyCheckStartS = 595, + ReadyCheckInProgress = 596, + ReadyCheckThrottled = 597, + DungeonDifficultyFailed = 598, + DungeonDifficultyChangedS = 599, + TradeWrongRealm = 600, + TradeNotOnTaplist = 601, + ChatPlayerAmbiguousS = 602, + LootCantLootThatNow = 603, + LootMasterInvFull = 604, + LootMasterUniqueItem = 605, + LootMasterOther = 606, + FilteringYouS = 607, + UsePreventedByMechanicS = 608, + ItemUniqueEquippable = 609, + LfgLeaderIsLfmS = 610, + LfgPending = 611, + CantSpeakLangage = 612, + VendorMissingTurnins = 613, + BattlegroundNotInTeam = 614, + NotInBattleground = 615, + NotEnoughHonorPoints = 616, + NotEnoughArenaPoints = 617, + SocketingRequiresMetaGem = 618, + SocketingMetaGemOnlyInMetaslot = 619, + SocketingRequiresHydraulicGem = 620, + SocketingHydraulicGemOnlyInHydraulicslot = 621, + SocketingRequiresCogwheelGem = 622, + SocketingCogwheelGemOnlyInCogwheelslot = 623, + SocketingItemTooLowLevel = 624, + ItemMaxCountSocketed = 625, + SystemDisabled = 626, + QuestFailedTooManyDailyQuestsI = 627, + ItemMaxCountEquippedSocketed = 628, + ItemUniqueEquippableSocketed = 629, + UserSquelched = 630, + AccountSilenced = 631, + PartyMemberSilenced = 632, + PartyMemberSilencedLfgDelist = 633, + TooMuchGold = 634, + NotBarberSitting = 635, + QuestFailedCais = 636, + InviteRestrictedTrial = 637, + VoiceIgnoreFull = 638, + VoiceIgnoreSelf = 639, + VoiceIgnoreNotFound = 640, + VoiceIgnoreAlreadyS = 641, + VoiceIgnoreAddedS = 642, + VoiceIgnoreRemovedS = 643, + VoiceIgnoreAmbiguous = 644, + VoiceIgnoreDeleted = 645, + UnknownMacroOptionS = 646, + NotDuringArenaMatch = 647, + NotInRatedBattleground = 648, + PlayerSilenced = 649, + PlayerUnsilenced = 650, + ComsatDisconnect = 651, + ComsatReconnectAttempt = 652, + ComsatConnectFail = 653, + MailInvalidAttachmentSlot = 654, + MailTooManyAttachments = 655, + MailInvalidAttachment = 656, + MailAttachmentExpired = 657, + VoiceChatParentalDisableMic = 658, + ProfaneChatName = 659, + PlayerSilencedEcho = 660, + PlayerUnsilencedEcho = 661, + LootCantLootThat = 662, + ArenaExpiredCais = 663, + GroupActionThrottled = 664, + AlreadyPickpocketed = 665, + NameInvalid = 666, + NameNoName = 667, + NameTooShort = 668, + NameTooLong = 669, + NameMixedLanguages = 670, + NameProfane = 671, + NameReserved = 672, + NameThreeConsecutive = 673, + NameInvalidSpace = 674, + NameConsecutiveSpaces = 675, + NameRussianConsecutiveSilentCharacters = 676, + NameRussianSilentCharacterAtBeginningOrEnd = 677, + NameDeclensionDoesntMatchBaseName = 678, + RecruitAFriendNotLinked = 679, + RecruitAFriendNotNow = 680, + RecruitAFriendSummonLevelMax = 681, + RecruitAFriendSummonCooldown = 682, + RecruitAFriendSummonOffline = 683, + RecruitAFriendInsufExpanLvl = 684, + RecruitAFriendMapIncomingTransferNotAllowed = 685, + NotSameAccount = 686, + BadOnUseEnchant = 687, + TradeSelf = 688, + TooManySockets = 689, + ItemMaxLimitCategoryCountExceededIs = 690, + TradeTargetMaxLimitCategoryCountExceededIs = 691, + ItemMaxLimitCategorySocketedExceededIs = 692, + ItemMaxLimitCategoryEquippedExceededIs = 693, + ShapeshiftFormCannotEquip = 694, + ItemInventoryFullSatchel = 695, + ScalingStatItemLevelExceeded = 696, + ScalingStatItemLevelTooLow = 697, + PurchaseLevelTooLow = 698, + GroupSwapFailed = 699, + InviteInCombat = 700, + InvalidGlyphSlot = 701, + GenericNoValidTargets = 702, + CalendarEventAlertS = 703, + PetLearnSpellS = 704, + PetLearnAbilityS = 705, + PetSpellUnlearnedS = 706, + InviteUnknownRealm = 707, + InviteNoPartyServer = 708, + InvitePartyBusy = 709, + InvitePartyBusyPendingRequest = 710, + InvitePartyBusyPendingSuggest = 711, + PartyTargetAmbiguous = 712, + PartyLfgInviteRaidLocked = 713, + PartyLfgBootLimit = 714, + PartyLfgBootCooldownS = 715, + PartyLfgBootNotEligibleS = 716, + PartyLfgBootInpatientTimerS = 717, + PartyLfgBootInProgress = 718, + PartyLfgBootTooFewPlayers = 719, + PartyLfgBootVoteSucceeded = 720, + PartyLfgBootVoteFailed = 721, + PartyLfgBootInCombat = 722, + PartyLfgBootDungeonComplete = 723, + PartyLfgBootLootRolls = 724, + PartyLfgBootVoteRegistered = 725, + PartyPrivateGroupOnly = 726, + PartyLfgTeleportInCombat = 727, + RaidDisallowedByLevel = 728, + RaidDisallowedByCrossRealm = 729, + PartyRoleNotAvailable = 730, + JoinLfgObjectFailed = 731, + LfgRemovedLevelup = 732, + LfgRemovedXpToggle = 733, + LfgRemovedFactionChange = 734, + BattlegroundInfoThrottled = 735, + BattlegroundAlreadyIn = 736, + ArenaTeamChangeFailedQueued = 737, + ArenaTeamPermissions = 738, + NotWhileFalling = 739, + NotWhileMoving = 740, + NotWhileFatigued = 741, + MaxSockets = 742, + MultiCastActionTotemS = 743, + BattlegroundJoinLevelup = 744, + RemoveFromPvpQueueXpGain = 745, + BattlegroundJoinXpGain = 746, + BattlegroundJoinMercenary = 747, + BattlegroundJoinTooManyHealers = 748, + BattlegroundJoinRatedTooManyHealers = 749, + BattlegroundJoinTooManyTanks = 750, + BattlegroundJoinTooManyDamage = 751, + RaidDifficultyFailed = 752, + RaidDifficultyChangedS = 753, + LegacyRaidDifficultyChangedS = 754, + RaidLockoutChangedS = 755, + RaidConvertedToParty = 756, + PartyConvertedToRaid = 757, + PlayerDifficultyChangedS = 758, + GmresponseDbError = 759, + BattlegroundJoinRangeIndex = 760, + ArenaJoinRangeIndex = 761, + RemoveFromPvpQueueFactionChange = 762, + BattlegroundJoinFailed = 763, + BattlegroundJoinNoValidSpecForRole = 764, + BattlegroundJoinRespec = 765, + BattlegroundInvitationDeclined = 766, + BattlegroundJoinTimedOut = 767, + BattlegroundDupeQueue = 768, + BattlegroundJoinMustCompleteQuest = 769, + InBattlegroundRespec = 770, + MailLimitedDurationItem = 771, + YellRestrictedTrial = 772, + ChatRaidRestrictedTrial = 773, + LfgRoleCheckFailed = 774, + LfgRoleCheckFailedTimeout = 775, + LfgRoleCheckFailedNotViable = 776, + LfgReadyCheckFailed = 777, + LfgReadyCheckFailedTimeout = 778, + LfgGroupFull = 779, + LfgNoLfgObject = 780, + LfgNoSlotsPlayer = 781, + LfgNoSlotsParty = 782, + LfgNoSpec = 783, + LfgMismatchedSlots = 784, + LfgMismatchedSlotsLocalXrealm = 785, + LfgPartyPlayersFromDifferentRealms = 786, + LfgMembersNotPresent = 787, + LfgGetInfoTimeout = 788, + LfgInvalidSlot = 789, + LfgDeserterPlayer = 790, + LfgDeserterParty = 791, + LfgDead = 792, + LfgRandomCooldownPlayer = 793, + LfgRandomCooldownParty = 794, + LfgTooManyMembers = 795, + LfgTooFewMembers = 796, + LfgProposalFailed = 797, + LfgProposalDeclinedSelf = 798, + LfgProposalDeclinedParty = 799, + LfgNoSlotsSelected = 800, + LfgNoRolesSelected = 801, + LfgRoleCheckInitiated = 802, + LfgReadyCheckInitiated = 803, + LfgPlayerDeclinedRoleCheck = 804, + LfgPlayerDeclinedReadyCheck = 805, + LfgJoinedQueue = 806, + LfgJoinedFlexQueue = 807, + LfgJoinedRfQueue = 808, + LfgJoinedScenarioQueue = 809, + LfgJoinedWorldPvpQueue = 810, + LfgJoinedBattlefieldQueue = 811, + LfgJoinedList = 812, + LfgLeftQueue = 813, + LfgLeftList = 814, + LfgRoleCheckAborted = 815, + LfgReadyCheckAborted = 816, + LfgCantUseBattleground = 817, + LfgCantUseDungeons = 818, + LfgReasonTooManyLfg = 819, + LfgFarmLimit = 820, + LfgNoCrossFactionParties = 821, + InvalidTeleportLocation = 822, + TooFarToInteract = 823, + BattlegroundPlayersFromDifferentRealms = 824, + DifficultyChangeCooldownS = 825, + DifficultyChangeCombatCooldownS = 826, + DifficultyChangeWorldstate = 827, + DifficultyChangeEncounter = 828, + DifficultyChangeCombat = 829, + DifficultyChangePlayerBusy = 830, + DifficultyChangeAlreadyStarted = 831, + DifficultyChangeOtherHeroicS = 832, + DifficultyChangeHeroicInstanceAlreadyRunning = 833, + ArenaTeamPartySize = 834, + SoloShuffleWargameGroupSize = 835, + SoloShuffleWargameGroupComp = 836, + SoloShuffleMinItemLevel = 837, + PvpPlayerAbandoned = 838, + QuestForceRemovedS = 839, + AttackNoActions = 840, + InRandomBg = 841, + InNonRandomBg = 842, + BnFriendSelf = 843, + BnFriendAlready = 844, + BnFriendBlocked = 845, + BnFriendListFull = 846, + BnFriendRequestSent = 847, + BnBroadcastThrottle = 848, + BgDeveloperOnly = 849, + CurrencySpellSlotMismatch = 850, + CurrencyNotTradable = 851, + RequiresExpansionS = 852, + QuestFailedSpell = 853, + TalentFailedUnspentTalentPoints = 854, + TalentFailedNotEnoughTalentsInPrimaryTree = 855, + TalentFailedNoPrimaryTreeSelected = 856, + TalentFailedCantRemoveTalent = 857, + TalentFailedUnknown = 858, + TalentFailedInCombat = 859, + TalentFailedInPvpMatch = 860, + TalentFailedInMythicPlus = 861, + WargameRequestFailure = 862, + RankRequiresAuthenticator = 863, + GuildBankVoucherFailed = 864, + WargameRequestSent = 865, + RequiresAchievementI = 866, + RefundResultExceedMaxCurrency = 867, + CantBuyQuantity = 868, + ItemIsBattlePayLocked = 869, + PartyAlreadyInBattlegroundQueue = 870, + PartyConfirmingBattlegroundQueue = 871, + BattlefieldTeamPartySize = 872, + InsuffTrackedCurrencyIs = 873, + NotOnTournamentRealm = 874, + GuildTrialAccountTrial = 875, + GuildTrialAccountVeteran = 876, + GuildUndeletableDueToLevel = 877, + CantDoThatInAGroup = 878, + GuildLeaderReplaced = 879, + TransmogrifyCantEquip = 880, + TransmogrifyInvalidItemType = 881, + TransmogrifyNotSoulbound = 882, + TransmogrifyInvalidSource = 883, + TransmogrifyInvalidDestination = 884, + TransmogrifyMismatch = 885, + TransmogrifyLegendary = 886, + TransmogrifySameItem = 887, + TransmogrifySameAppearance = 888, + TransmogrifyNotEquipped = 889, + VoidDepositFull = 890, + VoidWithdrawFull = 891, + VoidStorageWrapped = 892, + VoidStorageStackable = 893, + VoidStorageUnbound = 894, + VoidStorageRepair = 895, + VoidStorageCharges = 896, + VoidStorageQuest = 897, + VoidStorageConjured = 898, + VoidStorageMail = 899, + VoidStorageBag = 900, + VoidTransferStorageFull = 901, + VoidTransferInvFull = 902, + VoidTransferInternalError = 903, + VoidTransferItemInvalid = 904, + DifficultyDisabledInLfg = 905, + VoidStorageUnique = 906, + VoidStorageLoot = 907, + VoidStorageHoliday = 908, + VoidStorageDuration = 909, + VoidStorageLoadFailed = 910, + VoidStorageInvalidItem = 911, + ParentalControlsChatMuted = 912, + SorStartExperienceIncomplete = 913, + SorInvalidEmail = 914, + SorInvalidComment = 915, + ChallengeModeResetCooldownS = 916, + ChallengeModeResetKeystone = 917, + PetJournalAlreadyInLoadout = 918, + ReportSubmittedSuccessfully = 919, + ReportSubmissionFailed = 920, + SuggestionSubmittedSuccessfully = 921, + BugSubmittedSuccessfully = 922, + ChallengeModeEnabled = 923, + ChallengeModeDisabled = 924, + PetbattleCreateFailed = 925, + PetbattleNotHere = 926, + PetbattleNotHereOnTransport = 927, + PetbattleNotHereUnevenGround = 928, + PetbattleNotHereObstructed = 929, + PetbattleNotWhileInCombat = 930, + PetbattleNotWhileDead = 931, + PetbattleNotWhileFlying = 932, + PetbattleTargetInvalid = 933, + PetbattleTargetOutOfRange = 934, + PetbattleTargetNotCapturable = 935, + PetbattleNotATrainer = 936, + PetbattleDeclined = 937, + PetbattleInBattle = 938, + PetbattleInvalidLoadout = 939, + PetbattleAllPetsDead = 940, + PetbattleNoPetsInSlots = 941, + PetbattleNoAccountLock = 942, + PetbattleWildPetTapped = 943, + PetbattleRestrictedAccount = 944, + PetbattleOpponentNotAvailable = 945, + PetbattleNotWhileInMatchedBattle = 946, + CantHaveMorePetsOfThatType = 947, + CantHaveMorePets = 948, + PvpMapNotFound = 949, + PvpMapNotSet = 950, + PetbattleQueueQueued = 951, + PetbattleQueueAlreadyQueued = 952, + PetbattleQueueJoinFailed = 953, + PetbattleQueueJournalLock = 954, + PetbattleQueueRemoved = 955, + PetbattleQueueProposalDeclined = 956, + PetbattleQueueProposalTimeout = 957, + PetbattleQueueOpponentDeclined = 958, + PetbattleQueueRequeuedInternal = 959, + PetbattleQueueRequeuedRemoved = 960, + PetbattleQueueSlotLocked = 961, + PetbattleQueueSlotEmpty = 962, + PetbattleQueueSlotNoTracker = 963, + PetbattleQueueSlotNoSpecies = 964, + PetbattleQueueSlotCantBattle = 965, + PetbattleQueueSlotRevoked = 966, + PetbattleQueueSlotDead = 967, + PetbattleQueueSlotNoPet = 968, + PetbattleQueueNotWhileNeutral = 969, + PetbattleGameTimeLimitWarning = 970, + PetbattleGameRoundsLimitWarning = 971, + HasRestriction = 972, + ItemUpgradeItemTooLowLevel = 973, + ItemUpgradeNoPath = 974, + ItemUpgradeNoMoreUpgrades = 975, + BonusRollEmpty = 976, + ChallengeModeFull = 977, + ChallengeModeInProgress = 978, + ChallengeModeIncorrectKeystone = 979, + BattletagFriendNotFound = 980, + BattletagFriendNotValid = 981, + BattletagFriendNotAllowed = 982, + BattletagFriendThrottled = 983, + BattletagFriendSuccess = 984, + PetTooHighLevelToUncage = 985, + PetbattleInternal = 986, + CantCagePetYet = 987, + NoLootInChallengeMode = 988, + QuestPetBattleVictoriesPvpIi = 989, + RoleCheckAlreadyInProgress = 990, + RecruitAFriendAccountLimit = 991, + RecruitAFriendFailed = 992, + SetLootPersonal = 993, + SetLootMethodFailedCombat = 994, + ReagentBankFull = 995, + ReagentBankLocked = 996, + GarrisonBuildingExists = 997, + GarrisonInvalidPlot = 998, + GarrisonInvalidBuildingid = 999, + GarrisonInvalidPlotBuilding = 1000, + GarrisonRequiresBlueprint = 1001, + GarrisonNotEnoughCurrency = 1002, + GarrisonNotEnoughGold = 1003, + GarrisonCompleteMissionWrongFollowerType = 1004, + AlreadyUsingLfgList = 1005, + RestrictedAccountLfgListTrial = 1006, + ToyUseLimitReached = 1007, + ToyAlreadyKnown = 1008, + TransmogSetAlreadyKnown = 1009, + NotEnoughCurrency = 1010, + SpecIsDisabled = 1011, + FeatureRestrictedTrial = 1012, + CantBeObliterated = 1013, + CantBeScrapped = 1014, + CantBeRecrafted = 1015, + ArtifactRelicDoesNotMatchArtifact = 1016, + MustEquipArtifact = 1017, + CantDoThatRightNow = 1018, + AffectingCombat = 1019, + EquipmentManagerCombatSwapS = 1020, + EquipmentManagerBagsFull = 1021, + EquipmentManagerMissingItemS = 1022, + MovieRecordingWarningPerf = 1023, + MovieRecordingWarningDiskFull = 1024, + MovieRecordingWarningNoMovie = 1025, + MovieRecordingWarningRequirements = 1026, + MovieRecordingWarningCompressing = 1027, + NoChallengeModeReward = 1028, + ClaimedChallengeModeReward = 1029, + ChallengeModePeriodResetSs = 1030, + CantDoThatChallengeModeActive = 1031, + TalentFailedRestArea = 1032, + CannotAbandonLastPet = 1033, + TestCvarSetSss = 1034, + QuestTurnInFailReason = 1035, + ClaimedChallengeModeRewardOld = 1036, + TalentGrantedByAura = 1037, + ChallengeModeAlreadyComplete = 1038, + GlyphTargetNotAvailable = 1039, + PvpWarmodeToggleOn = 1040, + PvpWarmodeToggleOff = 1041, + SpellFailedLevelRequirement = 1042, + SpellFailedCantFlyHere = 1043, + BattlegroundJoinRequiresLevel = 1044, + BattlegroundJoinDisqualified = 1045, + BattlegroundJoinDisqualifiedNoName = 1046, + VoiceChatGenericUnableToConnect = 1047, + VoiceChatServiceLost = 1048, + VoiceChatChannelNameTooShort = 1049, + VoiceChatChannelNameTooLong = 1050, + VoiceChatChannelAlreadyExists = 1051, + VoiceChatTargetNotFound = 1052, + VoiceChatTooManyRequests = 1053, + VoiceChatPlayerSilenced = 1054, + VoiceChatParentalDisableAll = 1055, + VoiceChatDisabled = 1056, + NoPvpReward = 1057, + ClaimedPvpReward = 1058, + AzeriteEssenceSelectionFailedEssenceNotUnlocked = 1059, + AzeriteEssenceSelectionFailedCantRemoveEssence = 1060, + AzeriteEssenceSelectionFailedConditionFailed = 1061, + AzeriteEssenceSelectionFailedRestArea = 1062, + AzeriteEssenceSelectionFailedSlotLocked = 1063, + AzeriteEssenceSelectionFailedNotAtForge = 1064, + AzeriteEssenceSelectionFailedHeartLevelTooLow = 1065, + AzeriteEssenceSelectionFailedNotEquipped = 1066, + SocketingRequiresPunchcardredGem = 1067, + SocketingPunchcardredGemOnlyInPunchcardredslot = 1068, + SocketingRequiresPunchcardyellowGem = 1069, + SocketingPunchcardyellowGemOnlyInPunchcardyellowslot = 1070, + SocketingRequiresPunchcardblueGem = 1071, + SocketingPunchcardblueGemOnlyInPunchcardblueslot = 1072, + SocketingRequiresDominationShard = 1073, + SocketingDominationShardOnlyInDominationslot = 1074, + SocketingRequiresCypherGem = 1075, + SocketingCypherGemOnlyInCypherslot = 1076, + SocketingRequiresTinkerGem = 1077, + SocketingTinkerGemOnlyInTinkerslot = 1078, + LevelLinkingResultLinked = 1079, + LevelLinkingResultUnlinked = 1080, + ClubFinderErrorPostClub = 1081, + ClubFinderErrorApplyClub = 1082, + ClubFinderErrorRespondApplicant = 1083, + ClubFinderErrorCancelApplication = 1084, + ClubFinderErrorTypeAcceptApplication = 1085, + ClubFinderErrorTypeNoInvitePermissions = 1086, + ClubFinderErrorTypeNoPostingPermissions = 1087, + ClubFinderErrorTypeApplicantList = 1088, + ClubFinderErrorTypeApplicantListNoPerm = 1089, + ClubFinderErrorTypeFinderNotAvailable = 1090, + ClubFinderErrorTypeGetPostingIds = 1091, + ClubFinderErrorTypeJoinApplication = 1092, + ClubFinderErrorTypeRealmNotEligible = 1093, + ClubFinderErrorTypeFlaggedRename = 1094, + ClubFinderErrorTypeFlaggedDescriptionChange = 1095, + ItemInteractionNotEnoughGold = 1096, + ItemInteractionNotEnoughCurrency = 1097, + PlayerChoiceErrorPendingChoice = 1098, + SoulbindInvalidConduit = 1099, + SoulbindInvalidConduitItem = 1100, + SoulbindInvalidTalent = 1101, + SoulbindDuplicateConduit = 1102, + ActivateSoulbindS = 1103, + ActivateSoulbindFailedRestArea = 1104, + CantUseProfanity = 1105, + NotInPetBattle = 1106, + NotInNpe = 1107, + NoSpec = 1108, + NoDominationshardOverwrite = 1109, + UseWeeklyRewardsDisabled = 1110, + CrossFactionGroupJoined = 1111, + CantTargetUnfriendlyInOverworld = 1112, + EquipablespellsSlotsFull = 1113 } public enum SceneFlags diff --git a/Source/Framework/Constants/Spells/SpellAuraConst.cs b/Source/Framework/Constants/Spells/SpellAuraConst.cs index f852167f3..2b4f8b00c 100644 --- a/Source/Framework/Constants/Spells/SpellAuraConst.cs +++ b/Source/Framework/Constants/Spells/SpellAuraConst.cs @@ -528,10 +528,34 @@ namespace Framework.Constants ModHealingTakenFromCaster = 504, ModPlayerChoiceRerolls = 505, // NYI DisableInertia = 506, // NYI - Unk507 = 507, + ModDamageTakenFromCasterByLabel = 507, Unk508 = 508, Unk509 = 509, - ModifiedRaidInstance = 510, // Related to "Fated" raid affixes + ModifiedRaidInstance = 510, // NYI; Related to "Fated" raid affixes + ApplyProfessionEffect = 511, // Nyi; Miscvalue[0] = Professioneffectid + Unk512 = 512, + Unk513 = 513, + Unk514 = 514, + Unk515 = 515, + Unk516 = 516, + Unk517 = 517, + Unk518 = 518, + ModCooldownRecoveryRateAll = 519, // Nyi; Applies To All Spells, Not Filtered By Familyflags Or Label + Unk520 = 520, + Unk521 = 521, + Unk522 = 522, + Unk523 = 523, + Unk524 = 524, + DisplayProfessionEquipment = 525, // Nyi; Miscvalue[0] = Profession (Enum, Not Id) + Unk526 = 526, + Unk527 = 527, + AllowBlockingSpells = 528, // Nyi + ModSpellBlockChance = 529, // Nyi + Unk530 = 530, + Unk531 = 531, + Unk532 = 532, + DisableNavigation = 533, // Disables Map Pins + Unk534 = 534, Total } diff --git a/Source/Framework/Constants/Spells/SpellConst.cs b/Source/Framework/Constants/Spells/SpellConst.cs index 22c112707..c45028aba 100644 --- a/Source/Framework/Constants/Spells/SpellConst.cs +++ b/Source/Framework/Constants/Spells/SpellConst.cs @@ -473,8 +473,8 @@ namespace Framework.Constants BadTargets = 13, PvpTargetWhileUnflagged = 14, CantBeCharmed = 15, - CantBeDisenchanted = 16, - CantBeDisenchantedSkill = 17, + CantBeSalvaged = 16, + CantBeSalvagedSkill = 17, CantBeEnchanted = 18, CantBeMilled = 19, CantBeProspected = 20, @@ -767,13 +767,16 @@ namespace Framework.Constants IneligibleWeaponAppearance = 307, PlayerCondition = 308, NotWhileChromieTimed = 309, - OptionalReagents = 310, + CraftingReagents = 310, SpectatorOrCommentator = 311, SoulbindConduitLearnFailedInvalidCovenant = 312, ShadowlandsRidingRequirement = 313, NotInMageTower = 314, GarrisonFollowerAtMinLevel = 315, - Unknown = 316, + CantBeRecrafted = 316, + PassiveReplaced = 317, + CantFlyHere = 318, + Unknown = 319, // 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 @@ -1357,7 +1360,45 @@ namespace Framework.Constants YouHaveOtherWaysToSummonPocopoc = 635, // You Have Other Ways To Summon Pocopoc While In Zereth Mortis. RequiresMoreSyllabicRecall = 636, // Requires More Syllabic Recall. ThisBattlePetCannotRideOnMagicSaucer = 637, // This Battle Pet Is Unable To Ride On The Magic Saucer. + YouCanOnlyDoThisWhileMidair = 638, // You Can Only Do This While Midair. + YouCannotDoThatWhileAirborne = 639, // You Cannot Do That While Airborne. PocopocIsUnavailableOnQuestline = 640, // Pocopoc Is Unavailable To Summon During The Questline A Means To An End. + RequiresSulfuronSlammer = 711, // Requires Sulfuron Slammer + NotReadyYet = 788, // Not Ready Yet. + QualityOfTieredMedallionSettingIsTooLow = 789, // The Quality Of Your Tiered Medallion Setting Is Too Low To Add Another Socket To This Item. + YouHaveNotLearnedBarrelRoll = 790, // You Have Not Learned Barrel Roll. + TargetMustBeAnEliteElemental = 791, // Target Must Be An Elite Elemental. + SkillCheckAlreadyFailed = 792, // Skill Check Already Failed. + YourTargetWasRecentlyFed = 793, // Your Target Was Recently Fed. + CannotLureElusiveCreatureTowardsTown = 794, // You Cannot Lure An Elusive Creature Towards A Town. + NoWorthwhileCreaturesInAreaToLureOut = 795, // There Are No Worthwhile Creatures In This Area To Lure Out. + CannotLureWildBeast = 796, // This Is A Daycare For Whelps. Why Would You Try To Lure A Wild Beast Here...? + YouHaveNoArcaneEssencesInYourInventory = 797, // You Have No Arcane Essences In Your Inventory. + ThatPlayerIsCurrentlyNotInterestedInEngagingWithYourShenanigans = 798, // That Player Is Currently Not Interested In Engaging With Your Shenanigans. + CantBeCastOnNonPlayerCharacters = 799, // Can'T Be Cast On Non Player Characters. + ASignalFlareWasRecentlyFiredAtThisLocation = 800, // A Signal Flare Was Recently Fired At This Location. + ThisTinkerIsTooComplicatedForYou = 801, // This Tinker Is Too Complicated For You. + TheDuckRefusesToPlayWhileAnotherMaestroIsNearby = 802, // The Duck Refuses To Play While Another Maestro Is Nearby. + YouHaveStudiedTheseNotesExtensivelyandThereIsNothingNewToLearnFromThem = 803, // You Have Studied These Notes Extensively And There Is Nothing New To Learn From Them. + YouDontHaveEnoughGold = 804, // You Don'T Have Enough Gold. + YouDoNotKnowHowToTameOttuk = 805, // You Do Not Know How To Tame Ottuk. + ClanAylaagIsCurrentlyTravellingandCannotBeTeleportedTo = 806, // Clan Aylaag Is Currently Travelling And Cannot Be Teleported To. + NotEnoughInsanity = 807, // Not Enough Insanity + YouMustWaitToAccessThisAgain = 808, // You Must Wait To Access This Again. + YouDoNotKnowHowToTameDragonkin = 809, // You Do Not Know How To Tame Dragonkin. + RequiresAnEmptySoulCage = 810, // Requires An Empty Soul Cage. + YouAlreadyHaveACagedSoulOfThatType = 811, // You Already Have A Caged Soul Of That Type. + YouCantDoThatHere = 812, // You Can'T Do That Here. + YouDoNotHaveAnyElementalGemsSocketed = 813, // You Do Not Have Any Elemental Gems Socketed. + YouMustBeInTheDragonIsles = 814, // You Must Be In The Dragon Isles. + YouCannotDoThatWhileUnderwater = 815, // You Cannot Do That While Underwater. + YouMustBeRidingAStolenTameMagmammoth = 816, // You Must Be Riding A Stolen Tame Magmammoth. + YouMustBeFlyingAboveWaterInsideAnActiveTuskarrFishingHole = 817, // You Must Be Flying Above Water Inside An Active Tuskarr Fishing Hole. + YouAreAlreadyBraveEnoughToContinueWithYourExperimentation = 818, // You Are Already Brave Enough To Continue With Your Experimentation. + YouDontKnowHowToRepairThisItem = 819, // You Don'T Know How To Repair This Item. + ThereIsNoMoreRoomOnThatHandhold = 820, // There Is No More Room On That Handhold. + YouMustUnblockThisSpotByCompletingADailyQuest = 821, // You Must Unblock This Spot By Completing A Daily Quest. + YouMustBeCloserToAnIceHoleToDoThat = 822, // You Must Be Closer To An Ice Hole To Do That. } public enum SpellMissInfo @@ -1468,7 +1509,8 @@ namespace Framework.Constants Unk78 = 78, Unk91 = 91, Unk100 = 100, - DemonHunter = 107 + DemonHunter = 107, + Evoker = 224 } [Flags] @@ -2434,8 +2476,23 @@ namespace Framework.Constants ModifyKeystone2 = 285, GrantBattlepetExperience = 286, SetGarrisonFollowerLevel = 287, - Unk288 = 288, - Unk289 = 289, + CraftItem = 288, // Miscvalue[0] = Craftingdataid + ModifyAuraStacks = 289, // Miscvalue[0] = 0 Means Add, = 1 Means Set + ModifyCooldown = 290, + ModifyCooldowns = 291, // Miscvalue[0] = Spellfamily, Miscvalue[1] = Maybe Bit Index For Family Flags? Off By 1 For The Only Spell Using This Effect + ModifyCooldownsByCategory = 292, // Miscvalue[0] = Category + ModifyCharges = 293, // Miscvalue[0] = Charge Category + CraftLoot = 294, // Miscvalue[0] = Craftingdataid + SalvageItem = 295, // Miscvalue[0] = Itemsalvageid + CraftSalvageItem = 296, // Miscvalue[0] = Itemsalvageid, Miscvalue[1] = Craftingdataid + RecraftItem = 297, + CancelAllPrivateConversations = 298, + Unk299 = 299, // Something With Items, As Of 10.0.2 All Spells Are Named "Downgrading" + Unk300 = 300, + CraftEnchant = 301, // Miscvalue[0] = Craftingdataid, Miscvalue[1] = ? + Gathering = 302, + CreateTraitTreeConfig = 303, // Miscvalue[0] = Traittreeid + ChangeActiveCombatTraitConfig = 304, TotalSpellEffects } diff --git a/Source/Framework/Constants/UnitConst.cs b/Source/Framework/Constants/UnitConst.cs index 9aed05b69..8a44b35e2 100644 --- a/Source/Framework/Constants/UnitConst.cs +++ b/Source/Framework/Constants/UnitConst.cs @@ -164,6 +164,7 @@ namespace Framework.Constants ArcaneCharges, Fury, Pain, + Essence, Armor, // ARMOR..RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum. ResistanceHoly, ResistanceFire, @@ -183,7 +184,7 @@ namespace Framework.Constants ResistanceStart = Armor, ResistanceEnd = ResistanceArcane + 1, PowerStart = Mana, - PowerEnd = Pain + 1 + PowerEnd = Essence + 1 } public enum UnitModifierFlatType { diff --git a/Source/Framework/Database/Databases/HotfixDatabase.cs b/Source/Framework/Database/Databases/HotfixDatabase.cs index e285791bc..5a2bd1dec 100644 --- a/Source/Framework/Database/Databases/HotfixDatabase.cs +++ b/Source/Framework/Database/Databases/HotfixDatabase.cs @@ -165,7 +165,7 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_BARBER_SHOP_STYLE_LOCALE, "SELECT ID, DisplayName_lang, Description_lang FROM barber_shop_style_locale WHERE locale = ?"); // BattlePetBreedQuality.db2 - PrepareStatement(HotfixStatements.SEL_BATTLE_PET_BREED_QUALITY, "SELECT ID, StateMultiplier, QualityEnum FROM battle_pet_breed_quality"); + PrepareStatement(HotfixStatements.SEL_BATTLE_PET_BREED_QUALITY, "SELECT ID, MaxQualityRoll, StateMultiplier, QualityEnum FROM battle_pet_breed_quality"); // BattlePetBreedState.db2 PrepareStatement(HotfixStatements.SEL_BATTLE_PET_BREED_STATE, "SELECT ID, BattlePetStateID, Value, BattlePetBreedID FROM battle_pet_breed_state"); @@ -202,7 +202,7 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_CHAR_TITLES_LOCALE, "SELECT ID, Name_lang, Name1_lang FROM char_titles_locale WHERE locale = ?"); // CharacterLoadout.db2 - PrepareStatement(HotfixStatements.SEL_CHARACTER_LOADOUT, "SELECT ID, RaceMask, ChrClassID, Purpose, Unused910 FROM character_loadout"); + PrepareStatement(HotfixStatements.SEL_CHARACTER_LOADOUT, "SELECT ID, RaceMask, ChrClassID, Purpose, ItemContext FROM character_loadout"); // CharacterLoadoutItem.db2 PrepareStatement(HotfixStatements.SEL_CHARACTER_LOADOUT_ITEM, "SELECT ID, CharacterLoadoutID, ItemID FROM character_loadout_item"); @@ -229,8 +229,8 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_CHR_CLASSES_X_POWER_TYPES, "SELECT ID, PowerType, ClassID FROM chr_classes_x_power_types"); // ChrCustomizationChoice.db2 - PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_CHOICE, "SELECT Name, ID, ChrCustomizationOptionID, ChrCustomizationReqID, SortOrder, UiOrderIndex, " + - "Flags, AddedInPatch, SwatchColor1, SwatchColor2 FROM chr_customization_choice"); + PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_CHOICE, "SELECT Name, ID, ChrCustomizationOptionID, ChrCustomizationReqID, " + + "ChrCustomizationVisReqID, SortOrder, UiOrderIndex, Flags, AddedInPatch, SwatchColor1, SwatchColor2 FROM chr_customization_choice"); PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_CHOICE_LOCALE, "SELECT ID, Name_lang FROM chr_customization_choice_locale WHERE locale = ?"); // ChrCustomizationDisplayInfo.db2 @@ -240,7 +240,7 @@ namespace Framework.Database // ChrCustomizationElement.db2 PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_ELEMENT, "SELECT ID, ChrCustomizationChoiceID, RelatedChrCustomizationChoiceID, " + "ChrCustomizationGeosetID, ChrCustomizationSkinnedModelID, ChrCustomizationMaterialID, ChrCustomizationBoneSetID, " + - "ChrCustomizationCondModelID, ChrCustomizationDisplayInfoID, ChrCustItemGeoModifyID FROM chr_customization_element"); + "ChrCustomizationCondModelID, ChrCustomizationDisplayInfoID, ChrCustItemGeoModifyID, ChrCustomizationVoiceID FROM chr_customization_element"); // ChrCustomizationOption.db2 PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_OPTION, "SELECT Name, ID, SecondaryID, Flags, ChrModelID, SortIndex, ChrCustomizationCategoryID, " + @@ -248,7 +248,8 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_OPTION_LOCALE, "SELECT ID, Name_lang FROM chr_customization_option_locale WHERE locale = ?"); // ChrCustomizationReq.db2 - PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ, "SELECT ID, Flags, ClassMask, AchievementID, OverrideArchive, ItemModifiedAppearanceID FROM chr_customization_req"); + PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ, "SELECT ID, ReqSource, Flags, ClassMask, AchievementID, QuestID, OverrideArchive, ItemModifiedAppearanceID FROM chr_customization_req"); + PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ_LOCALE, "SELECT ID, ReqSource_lang FROM chr_customization_req_locale WHERE locale = ?"); // ChrCustomizationReqChoice.db2 PrepareStatement(HotfixStatements.SEL_CHR_CUSTOMIZATION_REQ_CHOICE, "SELECT ID, ChrCustomizationChoiceID, ChrCustomizationReqID FROM chr_customization_req_choice"); @@ -260,7 +261,7 @@ namespace Framework.Database "BarberShopCameraHeightOffsetScale, BarberShopCameraRotationOffset FROM chr_model"); // ChrRaceXChrModel.db2 - PrepareStatement(HotfixStatements.SEL_CHR_RACE_X_CHR_MODEL, "SELECT ID, ChrRacesID, ChrModelID FROM chr_race_x_chr_model"); + PrepareStatement(HotfixStatements.SEL_CHR_RACE_X_CHR_MODEL, "SELECT ID, ChrRacesID, ChrModelID, Sex, AllowedTransmogSlots FROM chr_race_x_chr_model"); // ChrRaces.db2 PrepareStatement(HotfixStatements.SEL_CHR_RACES, "SELECT ID, ClientPrefix, ClientFileString, Name, NameFemale, NameLowercase, NameFemaleLowercase, " + @@ -272,7 +273,7 @@ namespace Framework.Database "MaleModelFallbackRaceID, FemaleModelFallbackRaceID, MaleTextureFallbackRaceID, FemaleTextureFallbackRaceID, PlayableRaceBit, " + "HelmetAnimScalingRaceID, TransmogrifyDisabledSlotMask, UnalteredVisualCustomizationRaceID, AlteredFormCustomizeOffsetFallback1, " + "AlteredFormCustomizeOffsetFallback2, AlteredFormCustomizeOffsetFallback3, AlteredFormCustomizeRotationFallback, Unknown910_11, " + - "Unknown910_12, Unknown910_13, Unknown910_21, Unknown910_22, Unknown910_23, BaseLanguage, CreatureType, MaleModelFallbackSex, " + + "Unknown910_12, Unknown910_13, Unknown910_21, Unknown910_22, Unknown910_23, Unknown1000, BaseLanguage, CreatureType, MaleModelFallbackSex, " + "FemaleModelFallbackSex, MaleTextureFallbackSex, FemaleTextureFallbackSex FROM chr_races"); PrepareStatement(HotfixStatements.SEL_CHR_RACES_LOCALE, "SELECT ID, Name_lang, NameFemale_lang, NameLowercase_lang, NameFemaleLowercase_lang, LoreName_lang, " + "LoreNameFemale_lang, LoreNameLower_lang, LoreNameLowerFemale_lang, LoreDescription_lang, ShortName_lang, ShortNameFemale_lang, " + @@ -285,7 +286,7 @@ namespace Framework.Database " WHERE locale = ?"); // CinematicCamera.db2 - PrepareStatement(HotfixStatements.SEL_CINEMATIC_CAMERA, "SELECT ID, OriginX, OriginY, OriginZ, SoundID, OriginFacing, FileDataID, Unknown915 FROM cinematic_camera"); + PrepareStatement(HotfixStatements.SEL_CINEMATIC_CAMERA, "SELECT ID, OriginX, OriginY, OriginZ, SoundID, OriginFacing, FileDataID, ConversationID FROM cinematic_camera"); // CinematicSequences.db2 PrepareStatement(HotfixStatements.SEL_CINEMATIC_SEQUENCES, "SELECT ID, SoundID, Camera1, Camera2, Camera3, Camera4, Camera5, Camera6, Camera7, Camera8 FROM cinematic_sequences"); @@ -310,7 +311,7 @@ namespace Framework.Database "ExtendedDisplayInfoID, NPCSoundID, ParticleColorID, PortraitCreatureDisplayInfoID, PortraitTextureFileDataID, ObjectEffectPackageID, " + "AnimReplacementSetID, Flags, StateSpellVisualKitID, PlayerOverrideScale, PetInstanceScale, UnarmedWeaponType, MountPoofSpellVisualKitID, " + "DissolveEffectID, Gender, DissolveOutEffectID, CreatureModelMinLod, TextureVariationFileDataID1, TextureVariationFileDataID2, " + - "TextureVariationFileDataID3 FROM creature_display_info"); + "TextureVariationFileDataID3, TextureVariationFileDataID4 FROM creature_display_info"); // CreatureDisplayInfoExtra.db2 PrepareStatement(HotfixStatements.SEL_CREATURE_DISPLAY_INFO_EXTRA, "SELECT ID, DisplayRaceID, DisplaySexID, DisplayClassID, Flags, BakeMaterialResourcesID, " + @@ -348,14 +349,15 @@ namespace Framework.Database // CurrencyTypes.db2 PrepareStatement(HotfixStatements.SEL_CURRENCY_TYPES, "SELECT ID, Name, Description, CategoryID, InventoryIconFileID, SpellWeight, SpellCategory, MaxQty, " + - "MaxEarnablePerWeek, Quality, FactionID, ItemGroupSoundsID, XpQuestDifficulty, AwardConditionID, MaxQtyWorldStateID, Flags1, Flags2 FROM currency_types"); + "MaxEarnablePerWeek, Quality, FactionID, ItemGroupSoundsID, XpQuestDifficulty, AwardConditionID, MaxQtyWorldStateID, " + + "RechargingAmountPerCycle, RechargingCycleDurationMS, Flags1, Flags2 FROM currency_types"); PrepareStatement(HotfixStatements.SEL_CURRENCY_TYPES_LOCALE, "SELECT ID, Name_lang, Description_lang FROM currency_types_locale WHERE locale = ?"); // Curve.db2 PrepareStatement(HotfixStatements.SEL_CURVE, "SELECT ID, Type, Flags FROM curve"); // CurvePoint.db2 - PrepareStatement(HotfixStatements.SEL_CURVE_POINT, "SELECT ID, PosX, PosY, PreSLSquishPosX, PreSLSquishPosY, CurveID, OrderIndex FROM curve_point"); + PrepareStatement(HotfixStatements.SEL_CURVE_POINT, "SELECT PosX, PosY, PreSLSquishPosX, PreSLSquishPosY, ID, CurveID, OrderIndex FROM curve_point"); // DestructibleModelData.db2 PrepareStatement(HotfixStatements.SEL_DESTRUCTIBLE_MODEL_DATA, "SELECT ID, State0ImpactEffectDoodadSet, State0AmbientDoodadSet, State1Wmo, " + @@ -369,8 +371,8 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_DIFFICULTY_LOCALE, "SELECT ID, Name_lang FROM difficulty_locale WHERE locale = ?"); // DungeonEncounter.db2 - PrepareStatement(HotfixStatements.SEL_DUNGEON_ENCOUNTER, "SELECT Name, ID, MapID, DifficultyID, OrderIndex, CompleteWorldStateID, Bit, CreatureDisplayID, " + - "Flags, SpellIconFileID, Faction FROM dungeon_encounter"); + PrepareStatement(HotfixStatements.SEL_DUNGEON_ENCOUNTER, "SELECT Name, ID, MapID, DifficultyID, OrderIndex, CompleteWorldStateID, Bit, Flags, " + + "SpellIconFileID, Faction FROM dungeon_encounter"); PrepareStatement(HotfixStatements.SEL_DUNGEON_ENCOUNTER_LOCALE, "SELECT ID, Name_lang FROM dungeon_encounter_locale WHERE locale = ?"); // DurabilityCosts.db2 @@ -404,15 +406,15 @@ namespace Framework.Database // Faction.db2 PrepareStatement(HotfixStatements.SEL_FACTION, "SELECT ID, ReputationRaceMask1, ReputationRaceMask2, ReputationRaceMask3, ReputationRaceMask4, Name, " + - "Description, ReputationIndex, ParentFactionID, Expansion, FriendshipRepID, Flags, ParagonFactionID, ReputationClassMask1, " + - "ReputationClassMask2, ReputationClassMask3, ReputationClassMask4, ReputationFlags1, ReputationFlags2, ReputationFlags3, ReputationFlags4, " + - "ReputationBase1, ReputationBase2, ReputationBase3, ReputationBase4, ReputationMax1, ReputationMax2, ReputationMax3, ReputationMax4, " + - "ParentFactionMod1, ParentFactionMod2, ParentFactionCap1, ParentFactionCap2 FROM faction"); + "Description, ReputationIndex, ParentFactionID, Expansion, FriendshipRepID, Flags, ParagonFactionID, RenownFactionID, RenownCurrencyID, " + + "ReputationClassMask1, ReputationClassMask2, ReputationClassMask3, ReputationClassMask4, ReputationFlags1, ReputationFlags2, " + + "ReputationFlags3, ReputationFlags4, ReputationBase1, ReputationBase2, ReputationBase3, ReputationBase4, ReputationMax1, ReputationMax2, " + + "ReputationMax3, ReputationMax4, ParentFactionMod1, ParentFactionMod2, ParentFactionCap1, ParentFactionCap2 FROM faction"); PrepareStatement(HotfixStatements.SEL_FACTION_LOCALE, "SELECT ID, Name_lang, Description_lang FROM faction_locale WHERE locale = ?"); // FactionTemplate.db2 PrepareStatement(HotfixStatements.SEL_FACTION_TEMPLATE, "SELECT ID, Faction, Flags, FactionGroup, FriendGroup, EnemyGroup, Enemies1, Enemies2, Enemies3, " + - "Enemies4, Friend1, Friend2, Friend3, Friend4 FROM faction_template"); + "Enemies4, Enemies5, Enemies6, Enemies7, Enemies8, Friend1, Friend2, Friend3, Friend4, Friend5, Friend6, Friend7, Friend8 FROM faction_template"); // FriendshipRepReaction.db2 PrepareStatement(HotfixStatements.SEL_FRIENDSHIP_REP_REACTION, "SELECT ID, Reaction, FriendshipRepID, ReactionThreshold, OverrideColor FROM friendship_rep_reaction"); @@ -517,6 +519,11 @@ namespace Framework.Database // GlyphRequiredSpec.db2 PrepareStatement(HotfixStatements.SEL_GLYPH_REQUIRED_SPEC, "SELECT ID, ChrSpecializationID, GlyphPropertiesID FROM glyph_required_spec"); + // GossipNpcOption.db2 + PrepareStatement(HotfixStatements.SEL_GOSSIP_NPC_OPTION, "SELECT ID, GossipNpcOption, LFGDungeonsID, TrainerID, GarrFollowerTypeID, CharShipmentID, " + + "GarrTalentTreeID, UiMapID, UiItemInteractionID, Unknown_1000_8, Unknown_1000_9, CovenantID, GossipOptionID, TraitTreeID, ProfessionID, " + + "Unknown_1002_14 FROM gossip_npc_option"); + // GuildColorBackground.db2 PrepareStatement(HotfixStatements.SEL_GUILD_COLOR_BACKGROUND, "SELECT ID, Red, Blue, Green FROM guild_color_background"); @@ -556,7 +563,7 @@ namespace Framework.Database // Item.db2 PrepareStatement(HotfixStatements.SEL_ITEM, "SELECT ID, ClassID, SubclassID, Material, InventoryType, SheatheType, SoundOverrideSubclassID, IconFileDataID, " + - "ItemGroupSoundsID, ContentTuningID, ModifiedCraftingReagentItemID FROM item"); + "ItemGroupSoundsID, ContentTuningID, ModifiedCraftingReagentItemID, CraftingQualityID FROM item"); // ItemAppearance.db2 PrepareStatement(HotfixStatements.SEL_ITEM_APPEARANCE, "SELECT ID, DisplayType, ItemDisplayInfoID, DefaultIconFileDataID, UiOrder, PlayerConditionID FROM item_appearance"); @@ -684,15 +691,15 @@ namespace Framework.Database "StatPercentageOfSocket2, StatPercentageOfSocket3, StatPercentageOfSocket4, StatPercentageOfSocket5, StatPercentageOfSocket6, " + "StatPercentageOfSocket7, StatPercentageOfSocket8, StatPercentageOfSocket9, StatPercentageOfSocket10, StatPercentEditor1, StatPercentEditor2, " + "StatPercentEditor3, StatPercentEditor4, StatPercentEditor5, StatPercentEditor6, StatPercentEditor7, StatPercentEditor8, StatPercentEditor9, " + - "StatPercentEditor10, Stackable, MaxCount, RequiredAbility, SellPrice, BuyPrice, VendorStackCount, PriceVariance, PriceRandomValue, Flags1, " + - "Flags2, Flags3, Flags4, FactionRelated, ModifiedCraftingReagentItemID, ContentTuningID, PlayerLevelToItemLevelCurveID, " + - "ItemNameDescriptionID, RequiredTransmogHoliday, RequiredHoliday, GemProperties, SocketMatchEnchantmentId, TotemCategoryID, InstanceBound, " + - "ZoneBound1, ZoneBound2, ItemSet, LockID, PageID, ItemDelay, MinFactionID, RequiredSkillRank, RequiredSkill, ItemLevel, AllowableClass, " + - "ArtifactID, SpellWeight, SpellWeightCategory, SocketType1, SocketType2, SocketType3, SheatheType, Material, PageMaterialID, Bonding, " + - "DamageDamageType, StatModifierBonusStat1, StatModifierBonusStat2, StatModifierBonusStat3, StatModifierBonusStat4, StatModifierBonusStat5, " + - "StatModifierBonusStat6, StatModifierBonusStat7, StatModifierBonusStat8, StatModifierBonusStat9, StatModifierBonusStat10, ContainerSlots, " + - "MinReputation, RequiredPVPMedal, RequiredPVPRank, RequiredLevel, InventoryType, OverallQualityID FROM item_sparse"); - PrepareStatement(HotfixStatements.SEL_ITEM_SPARSE_LOCALE, "SELECT ID, Description_lang, Display3_lang, Display2_lang, Display1_lang, Display_lang" + + "StatPercentEditor10, Stackable, MaxCount, MinReputation, RequiredAbility, SellPrice, BuyPrice, VendorStackCount, PriceVariance, " + + "PriceRandomValue, Flags1, Flags2, Flags3, Flags4, FactionRelated, ModifiedCraftingReagentItemID, ContentTuningID, " + + "PlayerLevelToItemLevelCurveID, ItemNameDescriptionID, RequiredTransmogHoliday, RequiredHoliday, GemProperties, SocketMatchEnchantmentId, " + + "TotemCategoryID, InstanceBound, ZoneBound1, ZoneBound2, ItemSet, LockID, PageID, ItemDelay, MinFactionID, RequiredSkillRank, RequiredSkill, " + + "ItemLevel, AllowableClass, ArtifactID, SpellWeight, SpellWeightCategory, SocketType1, SocketType2, SocketType3, SheatheType, Material, " + + "PageMaterialID, Bonding, DamageDamageType, StatModifierBonusStat1, StatModifierBonusStat2, StatModifierBonusStat3, StatModifierBonusStat4, " + + "StatModifierBonusStat5, StatModifierBonusStat6, StatModifierBonusStat7, StatModifierBonusStat8, StatModifierBonusStat9, " + + "StatModifierBonusStat10, ContainerSlots, RequiredPVPMedal, RequiredPVPRank, RequiredLevel, InventoryType, OverallQualityID FROM item_sparse"); + PrepareStatement(HotfixStatements.SEL_ITEM_SPARSE_LOCALE, "SELECT ID, Description_lang, Display3_lang, Display2_lang, Display1_lang, Display_lang" + " FROM item_sparse_locale WHERE locale = ?"); // ItemSpec.db2 @@ -720,7 +727,7 @@ namespace Framework.Database // JournalInstance.db2 PrepareStatement(HotfixStatements.SEL_JOURNAL_INSTANCE, "SELECT ID, Name, Description, MapID, BackgroundFileDataID, ButtonFileDataID, " + - "ButtonSmallFileDataID, LoreFileDataID, OrderIndex, Flags, AreaID FROM journal_instance"); + "ButtonSmallFileDataID, LoreFileDataID, Flags, AreaID FROM journal_instance"); PrepareStatement(HotfixStatements.SEL_JOURNAL_INSTANCE_LOCALE, "SELECT ID, Name_lang, Description_lang FROM journal_instance_locale WHERE locale = ?"); // JournalTier.db2 @@ -774,7 +781,7 @@ namespace Framework.Database // Map.db2 PrepareStatement(HotfixStatements.SEL_MAP, "SELECT ID, Directory, MapName, MapDescription0, MapDescription1, PvpShortDescription, PvpLongDescription, " + "CorpseX, CorpseY, MapType, InstanceType, ExpansionID, AreaTableID, LoadingScreenID, TimeOfDayOverride, ParentMapID, CosmeticParentMapID, " + - "TimeOffset, MinimapIconScale, CorpseMapID, MaxPlayers, WindSettingsID, ZmpFileDataID, WdtFileDataID, Flags1, Flags2, Flags3 FROM map"); + "TimeOffset, MinimapIconScale, CorpseMapID, MaxPlayers, WindSettingsID, ZmpFileDataID, WdtFileDataID, NavigationMaxDistance, Flags1, Flags2, Flags3 FROM map"); PrepareStatement(HotfixStatements.SEL_MAP_LOCALE, "SELECT ID, MapName_lang, MapDescription0_lang, MapDescription1_lang, PvpShortDescription_lang, " + "PvpLongDescription_lang FROM map_locale WHERE locale = ?"); @@ -805,7 +812,7 @@ namespace Framework.Database // MountCapability.db2 PrepareStatement(HotfixStatements.SEL_MOUNT_CAPABILITY, "SELECT ID, Flags, ReqRidingSkill, ReqAreaID, ReqSpellAuraID, ReqSpellKnownID, ModSpellAuraID, " + - "ReqMapID, PlayerConditionID FROM mount_capability"); + "ReqMapID, PlayerConditionID, FlightCapabilityID FROM mount_capability"); // MountTypeXCapability.db2 PrepareStatement(HotfixStatements.SEL_MOUNT_TYPE_X_CAPABILITY, "SELECT ID, MountTypeID, MountCapabilityID, OrderIndex FROM mount_type_x_capability"); @@ -852,16 +859,18 @@ namespace Framework.Database "MinExpansionLevel, MaxExpansionLevel, MinAvgItemLevel, MaxAvgItemLevel, MinAvgEquippedItemLevel, MaxAvgEquippedItemLevel, PhaseUseFlags, " + "PhaseID, PhaseGroupID, Flags, ChrSpecializationIndex, ChrSpecializationRole, ModifierTreeID, PowerType, PowerTypeComp, PowerTypeValue, " + "WeaponSubclassMask, MaxGuildLevel, MinGuildLevel, MaxExpansionTier, MinExpansionTier, MinPVPRank, MaxPVPRank, ContentTuningID, CovenantID, " + - "SkillID1, SkillID2, SkillID3, SkillID4, MinSkill1, MinSkill2, MinSkill3, MinSkill4, MaxSkill1, MaxSkill2, MaxSkill3, MaxSkill4, " + - "MinFactionID1, MinFactionID2, MinFactionID3, MinReputation1, MinReputation2, MinReputation3, PrevQuestID1, PrevQuestID2, PrevQuestID3, " + - "PrevQuestID4, CurrQuestID1, CurrQuestID2, CurrQuestID3, CurrQuestID4, CurrentCompletedQuestID1, CurrentCompletedQuestID2, " + + "TraitNodeEntryLogic, SkillID1, SkillID2, SkillID3, SkillID4, MinSkill1, MinSkill2, MinSkill3, MinSkill4, MaxSkill1, MaxSkill2, MaxSkill3, " + + "MaxSkill4, MinFactionID1, MinFactionID2, MinFactionID3, MinReputation1, MinReputation2, MinReputation3, PrevQuestID1, PrevQuestID2, " + + "PrevQuestID3, PrevQuestID4, CurrQuestID1, CurrQuestID2, CurrQuestID3, CurrQuestID4, CurrentCompletedQuestID1, CurrentCompletedQuestID2, " + "CurrentCompletedQuestID3, CurrentCompletedQuestID4, SpellID1, SpellID2, SpellID3, SpellID4, ItemID1, ItemID2, ItemID3, ItemID4, ItemCount1, " + "ItemCount2, ItemCount3, ItemCount4, Explored1, Explored2, Time1, Time2, AuraSpellID1, AuraSpellID2, AuraSpellID3, AuraSpellID4, AuraStacks1, " + "AuraStacks2, AuraStacks3, AuraStacks4, Achievement1, Achievement2, Achievement3, Achievement4, AreaID1, AreaID2, AreaID3, AreaID4, " + "LfgStatus1, LfgStatus2, LfgStatus3, LfgStatus4, LfgCompare1, LfgCompare2, LfgCompare3, LfgCompare4, LfgValue1, LfgValue2, LfgValue3, " + "LfgValue4, CurrencyID1, CurrencyID2, CurrencyID3, CurrencyID4, CurrencyCount1, CurrencyCount2, CurrencyCount3, CurrencyCount4, " + "QuestKillMonster1, QuestKillMonster2, QuestKillMonster3, QuestKillMonster4, QuestKillMonster5, QuestKillMonster6, MovementFlags1, " + - "MovementFlags2 FROM player_condition"); + "MovementFlags2, TraitNodeEntryID1, TraitNodeEntryID2, TraitNodeEntryID3, TraitNodeEntryID4, TraitNodeEntryMinRank1, TraitNodeEntryMinRank2, " + + "TraitNodeEntryMinRank3, TraitNodeEntryMinRank4, TraitNodeEntryMaxRank1, TraitNodeEntryMaxRank2, TraitNodeEntryMaxRank3, " + + "TraitNodeEntryMaxRank4 FROM player_condition"); PrepareStatement(HotfixStatements.SEL_PLAYER_CONDITION_LOCALE, "SELECT ID, FailureDescription_lang FROM player_condition_locale WHERE locale = ?"); // PowerDisplay.db2 @@ -884,7 +893,7 @@ namespace Framework.Database // PvpTalent.db2 PrepareStatement(HotfixStatements.SEL_PVP_TALENT, "SELECT Description, ID, SpecID, SpellID, OverridesSpellID, Flags, ActionBarSpellID, PvpTalentCategoryID, " + - "LevelRequired FROM pvp_talent"); + "LevelRequired, PlayerConditionID FROM pvp_talent"); PrepareStatement(HotfixStatements.SEL_PVP_TALENT_LOCALE, "SELECT ID, Description_lang FROM pvp_talent_locale WHERE locale = ?"); // PvpTalentCategory.db2 @@ -921,7 +930,7 @@ namespace Framework.Database PrepareStatement(HotfixStatements.SEL_QUEST_SORT_LOCALE, "SELECT ID, SortName_lang FROM quest_sort_locale WHERE locale = ?"); // QuestV2.db2 - PrepareStatement(HotfixStatements.SEL_QUEST_V2, "SELECT ID, UniqueBitFlag FROM quest_v2"); + PrepareStatement(HotfixStatements.SEL_QUEST_V2, "SELECT ID, UniqueBitFlag, UiQuestDetailsTheme FROM quest_v2"); // QuestXp.db2 PrepareStatement(HotfixStatements.SEL_QUEST_XP, "SELECT ID, Difficulty1, Difficulty2, Difficulty3, Difficulty4, Difficulty5, Difficulty6, Difficulty7, " + @@ -965,14 +974,17 @@ namespace Framework.Database // SkillLine.db2 PrepareStatement(HotfixStatements.SEL_SKILL_LINE, "SELECT DisplayName, AlternateVerb, Description, HordeDisplayName, OverrideSourceInfoDisplayName, ID, " + - "CategoryID, SpellIconFileID, CanLink, ParentSkillLineID, ParentTierIndex, Flags, SpellBookSpellID FROM skill_line"); + "CategoryID, SpellIconFileID, CanLink, ParentSkillLineID, ParentTierIndex, Flags, SpellBookSpellID, ExpansionNameSharedStringID, " + + "HordeExpansionNameSharedStringID FROM skill_line"); PrepareStatement(HotfixStatements.SEL_SKILL_LINE_LOCALE, "SELECT ID, DisplayName_lang, AlternateVerb_lang, Description_lang, HordeDisplayName_lang" + " FROM skill_line_locale WHERE locale = ?"); // SkillLineAbility.db2 - PrepareStatement(HotfixStatements.SEL_SKILL_LINE_ABILITY, "SELECT RaceMask, ID, SkillLine, Spell, MinSkillLineRank, ClassMask, SupercedesSpell, " + - "AcquireMethod, TrivialSkillLineRankHigh, TrivialSkillLineRankLow, Flags, NumSkillUps, UniqueBit, TradeSkillCategoryID, SkillupSkillLineID" + - " FROM skill_line_ability"); + PrepareStatement(HotfixStatements.SEL_SKILL_LINE_ABILITY, "SELECT RaceMask, AbilityVerb, AbilityAllVerb, ID, SkillLine, Spell, MinSkillLineRank, ClassMask, " + + "SupercedesSpell, AcquireMethod, TrivialSkillLineRankHigh, TrivialSkillLineRankLow, Flags, NumSkillUps, UniqueBit, TradeSkillCategoryID, " + + "SkillupSkillLineID FROM skill_line_ability"); + PrepareStatement(HotfixStatements.SEL_SKILL_LINE_ABILITY_LOCALE, "SELECT ID, AbilityVerb_lang, AbilityAllVerb_lang FROM skill_line_ability_locale" + + " WHERE locale = ?"); // SkillRaceClassInfo.db2 PrepareStatement(HotfixStatements.SEL_SKILL_RACE_CLASS_INFO, "SELECT ID, RaceMask, SkillID, ClassMask, Flags, Availability, MinLevel, SkillTierID" + @@ -983,8 +995,8 @@ namespace Framework.Database // SoundKit.db2 PrepareStatement(HotfixStatements.SEL_SOUND_KIT, "SELECT ID, SoundType, VolumeFloat, Flags, MinDistance, DistanceCutoff, EAXDef, SoundKitAdvancedID, " + - "VolumeVariationPlus, VolumeVariationMinus, PitchVariationPlus, PitchVariationMinus, DialogType, PitchAdjust, BusOverwriteID, MaxInstances" + - " FROM sound_kit"); + "VolumeVariationPlus, VolumeVariationMinus, PitchVariationPlus, PitchVariationMinus, DialogType, PitchAdjust, BusOverwriteID, MaxInstances, " + + "SoundMixGroupID FROM sound_kit"); // SpecializationSpells.db2 PrepareStatement(HotfixStatements.SEL_SPECIALIZATION_SPELLS, "SELECT Description, ID, SpecID, SpellID, OverridesSpellID, DisplayOrder" + @@ -1000,8 +1012,8 @@ namespace Framework.Database // SpellAuraRestrictions.db2 PrepareStatement(HotfixStatements.SEL_SPELL_AURA_RESTRICTIONS, "SELECT ID, DifficultyID, CasterAuraState, TargetAuraState, ExcludeCasterAuraState, " + - "ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, SpellID" + - " FROM spell_aura_restrictions"); + "ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, CasterAuraType, TargetAuraType, " + + "ExcludeCasterAuraType, ExcludeTargetAuraType, SpellID FROM spell_aura_restrictions"); // SpellCastTimes.db2 PrepareStatement(HotfixStatements.SEL_SPELL_CAST_TIMES, "SELECT ID, Base, Minimum FROM spell_cast_times"); @@ -1023,8 +1035,8 @@ namespace Framework.Database "SpellClassMask3, SpellClassMask4 FROM spell_class_options"); // SpellCooldowns.db2 - PrepareStatement(HotfixStatements.SEL_SPELL_COOLDOWNS, "SELECT ID, DifficultyID, CategoryRecoveryTime, RecoveryTime, StartRecoveryTime, SpellID" + - " FROM spell_cooldowns"); + PrepareStatement(HotfixStatements.SEL_SPELL_COOLDOWNS, "SELECT ID, DifficultyID, CategoryRecoveryTime, RecoveryTime, StartRecoveryTime, AuraSpellID, " + + "SpellID FROM spell_cooldowns"); // SpellDuration.db2 PrepareStatement(HotfixStatements.SEL_SPELL_DURATION, "SELECT ID, Duration, MaxDuration FROM spell_duration"); @@ -1050,10 +1062,10 @@ namespace Framework.Database "ChannelInterruptFlags1, ChannelInterruptFlags2, SpellID FROM spell_interrupts"); // SpellItemEnchantment.db2 - PrepareStatement(HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT, "SELECT ID, Name, HordeName, EffectArg1, EffectArg2, EffectArg3, EffectScalingPoints1, " + - "EffectScalingPoints2, EffectScalingPoints3, IconFileDataID, MinItemLevel, MaxItemLevel, TransmogUseConditionID, TransmogCost, " + - "EffectPointsMin1, EffectPointsMin2, EffectPointsMin3, ItemVisual, Flags, RequiredSkillID, RequiredSkillRank, ItemLevel, Charges, Effect1, " + - "Effect2, Effect3, ScalingClass, ScalingClassRestricted, ConditionID, MinLevel, MaxLevel FROM spell_item_enchantment"); + PrepareStatement(HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT, "SELECT ID, Name, HordeName, Duration, EffectArg1, EffectArg2, EffectArg3, " + + "EffectScalingPoints1, EffectScalingPoints2, EffectScalingPoints3, IconFileDataID, MinItemLevel, MaxItemLevel, TransmogUseConditionID, " + + "TransmogCost, EffectPointsMin1, EffectPointsMin2, EffectPointsMin3, ItemVisual, Flags, RequiredSkillID, RequiredSkillRank, ItemLevel, " + + "Charges, Effect1, Effect2, Effect3, ScalingClass, ScalingClassRestricted, ConditionID, MinLevel, MaxLevel FROM spell_item_enchantment"); PrepareStatement(HotfixStatements.SEL_SPELL_ITEM_ENCHANTMENT_LOCALE, "SELECT ID, Name_lang, HordeName_lang FROM spell_item_enchantment_locale WHERE locale = ?"); // SpellItemEnchantmentCondition.db2 @@ -1083,7 +1095,7 @@ namespace Framework.Database // SpellPower.db2 PrepareStatement(HotfixStatements.SEL_SPELL_POWER, "SELECT ID, OrderIndex, ManaCost, ManaCostPerLevel, ManaPerSecond, PowerDisplayID, AltPowerBarID, " + - "PowerCostPct, PowerCostMaxPct, PowerPctPerSecond, PowerType, RequiredAuraSpellID, OptionalCost, SpellID FROM spell_power"); + "PowerCostPct, PowerCostMaxPct, OptionalCostPct, PowerPctPerSecond, PowerType, RequiredAuraSpellID, OptionalCost, SpellID FROM spell_power"); // SpellPowerDifficulty.db2 PrepareStatement(HotfixStatements.SEL_SPELL_POWER_DIFFICULTY, "SELECT ID, DifficultyID, OrderIndex FROM spell_power_difficulty"); @@ -1104,7 +1116,10 @@ namespace Framework.Database // SpellReagents.db2 PrepareStatement(HotfixStatements.SEL_SPELL_REAGENTS, "SELECT ID, SpellID, Reagent1, Reagent2, Reagent3, Reagent4, Reagent5, Reagent6, Reagent7, Reagent8, " + - "ReagentCount1, ReagentCount2, ReagentCount3, ReagentCount4, ReagentCount5, ReagentCount6, ReagentCount7, ReagentCount8 FROM spell_reagents"); + "ReagentCount1, ReagentCount2, ReagentCount3, ReagentCount4, ReagentCount5, ReagentCount6, ReagentCount7, ReagentCount8, " + + "ReagentRecraftCount1, ReagentRecraftCount2, ReagentRecraftCount3, ReagentRecraftCount4, ReagentRecraftCount5, ReagentRecraftCount6, " + + "ReagentRecraftCount7, ReagentRecraftCount8, ReagentSource1, ReagentSource2, ReagentSource3, ReagentSource4, ReagentSource5, ReagentSource6, " + + "ReagentSource7, ReagentSource8 FROM spell_reagents"); // SpellReagentsCurrency.db2 PrepareStatement(HotfixStatements.SEL_SPELL_REAGENTS_CURRENCY, "SELECT ID, SpellID, CurrencyTypesID, CurrencyCount FROM spell_reagents_currency"); @@ -1150,7 +1165,7 @@ namespace Framework.Database " FROM spell_visual_kit"); // SpellXSpellVisual.db2 - PrepareStatement(HotfixStatements.SEL_SPELL_X_SPELL_VISUAL, "SELECT ID, DifficultyID, SpellVisualID, Probability, Priority, SpellIconFileID, " + + PrepareStatement(HotfixStatements.SEL_SPELL_X_SPELL_VISUAL, "SELECT ID, DifficultyID, SpellVisualID, Probability, Flags, Priority, SpellIconFileID, " + "ActiveIconFileID, ViewerUnitConditionID, ViewerPlayerConditionID, CasterUnitConditionID, CasterPlayerConditionID, SpellID" + " FROM spell_x_spell_visual"); @@ -1221,7 +1236,7 @@ namespace Framework.Database "Region2Z, ID, UiMapID, OrderIndex, MapID, AreaID, WmoDoodadPlacementID, WmoGroupID FROM ui_map_assignment"); // UiMapLink.db2 - PrepareStatement(HotfixStatements.SEL_UI_MAP_LINK, "SELECT UiMinX, UiMinY, UiMaxX, UiMaxY, ID, ParentUiMapID, OrderIndex, ChildUiMapID, " + + PrepareStatement(HotfixStatements.SEL_UI_MAP_LINK, "SELECT UiMinX, UiMinY, UiMaxX, UiMaxY, ID, ParentUiMapID, OrderIndex, ChildUiMapID, PlayerConditionID, " + "OverrideHighlightFileDataID, OverrideHighlightAtlasID, Flags FROM ui_map_link"); // UiMapXMapArt.db2 @@ -1417,6 +1432,7 @@ namespace Framework.Database SEL_CHR_CUSTOMIZATION_OPTION_LOCALE, SEL_CHR_CUSTOMIZATION_REQ, + SEL_CHR_CUSTOMIZATION_REQ_LOCALE, SEL_CHR_CUSTOMIZATION_REQ_CHOICE, @@ -1551,6 +1567,8 @@ namespace Framework.Database SEL_GLYPH_REQUIRED_SPEC, + SEL_GOSSIP_NPC_OPTION, + SEL_GUILD_COLOR_BACKGROUND, SEL_GUILD_COLOR_BORDER, @@ -1800,6 +1818,7 @@ namespace Framework.Database SEL_SKILL_LINE_LOCALE, SEL_SKILL_LINE_ABILITY, + SEL_SKILL_LINE_ABILITY_LOCALE, SEL_SKILL_RACE_CLASS_INFO, diff --git a/Source/Game/Achievements/CriteriaHandler.cs b/Source/Game/Achievements/CriteriaHandler.cs index 0f2417498..613c14c27 100644 --- a/Source/Game/Achievements/CriteriaHandler.cs +++ b/Source/Game/Achievements/CriteriaHandler.cs @@ -2758,7 +2758,7 @@ namespace Game.Achievements bool bagScanReachedEnd = referencePlayer.ForEachItem(ItemSearchLocation.Everywhere, item => { - bool hasBonus = item.m_itemData.BonusListIDs._value.Any(bonusListID => bonusListIDs.Contains(bonusListID)); + bool hasBonus = item.GetBonusListIDs().Any(bonusListID => bonusListIDs.Contains(bonusListID)); return !hasBonus; }); @@ -2880,7 +2880,7 @@ namespace Game.Achievements if (pvpTier == null) return false; - if (pvpTier.BracketID >= referencePlayer.m_activePlayerData.PvpInfo.GetSize()) + if (pvpTier.BracketID >= referencePlayer.m_activePlayerData.PvpInfo.Size()) return false; var pvpInfo = referencePlayer.m_activePlayerData.PvpInfo[pvpTier.BracketID]; @@ -2918,7 +2918,7 @@ namespace Game.Achievements } case ModifierTreeType.PlayerPvpTierInBracketEqualOrGreaterThan: // 239 { - if (secondaryAsset >= referencePlayer.m_activePlayerData.PvpInfo.GetSize()) + if (secondaryAsset >= referencePlayer.m_activePlayerData.PvpInfo.Size()) return false; var pvpInfo = referencePlayer.m_activePlayerData.PvpInfo[secondaryAsset]; @@ -3475,7 +3475,7 @@ namespace Game.Achievements if (pvpTier == null) return false; - if (pvpTier.BracketID >= referencePlayer.m_activePlayerData.PvpInfo.GetSize()) + if (pvpTier.BracketID >= referencePlayer.m_activePlayerData.PvpInfo.Size()) return false; var pvpInfo = referencePlayer.m_activePlayerData.PvpInfo[pvpTier.BracketID]; @@ -3486,7 +3486,7 @@ namespace Game.Achievements } case ModifierTreeType.PlayerBestWeeklyWinPvpTierInBracketEqualOrGreaterThan: // 325 { - if (secondaryAsset >= referencePlayer.m_activePlayerData.PvpInfo.GetSize()) + if (secondaryAsset >= referencePlayer.m_activePlayerData.PvpInfo.Size()) return false; var pvpInfo = referencePlayer.m_activePlayerData.PvpInfo[secondaryAsset]; @@ -3518,6 +3518,109 @@ namespace Game.Achievements break; } + case ModifierTreeType.PlayerAuraWithLabelStackCountEqualOrGreaterThan: // 335 + { + uint count = 0; + referencePlayer.HasAura(aura => + { + if (aura.GetSpellInfo().HasLabel((uint)secondaryAsset)) + count += aura.GetStackAmount(); + return false; + }); + if (count < reqValue) + return false; + break; + } + case ModifierTreeType.PlayerAuraWithLabelStackCountEqual: // 336 + { + uint count = 0; + referencePlayer.HasAura(aura => + { + if (aura.GetSpellInfo().HasLabel((uint)secondaryAsset)) + count += aura.GetStackAmount(); + return false; + }); + if (count != reqValue) + return false; + break; + } + case ModifierTreeType.PlayerAuraWithLabelStackCountEqualOrLessThan: // 337 + { + uint count = 0; + referencePlayer.HasAura(aura => + { + if (aura.GetSpellInfo().HasLabel((uint)secondaryAsset)) + count += aura.GetStackAmount(); + return false; + }); + if (count > reqValue) + return false; + break; + } + case ModifierTreeType.PlayerIsInCrossFactionGroup: // 338 + { + var group = referencePlayer.GetGroup(); + if (!group.GetGroupFlags().HasFlag(GroupFlags.CrossFaction)) + return false; + break; + } + case ModifierTreeType.PlayerHasTraitNodeEntryInActiveConfig: // 340 + { + bool hasTraitNodeEntry() + { + foreach (var traitConfig in referencePlayer.m_activePlayerData.TraitConfigs) + { + if ((TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat) + { + if (referencePlayer.m_activePlayerData.ActiveCombatTraitConfigID != traitConfig.ID + || !((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags).HasFlag(TraitCombatConfigFlags.ActiveForSpec)) + continue; + } + + foreach (var traitEntry in traitConfig.Entries) + if (traitEntry.TraitNodeEntryID == reqValue) + return true; + } + return false; + } + if (!hasTraitNodeEntry()) + return false; + break; + } + case ModifierTreeType.PlayerHasTraitNodeEntryInActiveConfigRankGreaterOrEqualThan: // 341 + { + var traitNodeEntryRank = new Func(() => + { + foreach (var traitConfig in referencePlayer.m_activePlayerData.TraitConfigs) + { + if ((TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat) + { + if (referencePlayer.m_activePlayerData.ActiveCombatTraitConfigID != traitConfig.ID + || !((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags).HasFlag(TraitCombatConfigFlags.ActiveForSpec)) + continue; + } + + foreach (var traitEntry in traitConfig.Entries) + if (traitEntry.TraitNodeEntryID == secondaryAsset) + return (short)traitEntry.Rank; + } + return null; + })(); + if (!traitNodeEntryRank.HasValue || traitNodeEntryRank < reqValue) + return false; + break; + } + case ModifierTreeType.PlayerDaysSinceLogout: // 344 + if (GameTime.GetGameTime() - referencePlayer.m_playerData.LogoutTime < reqValue * Time.Day) + return false; + break; + case ModifierTreeType.PlayerCanUseItem: // 351 + { + ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(reqValue); + if (itemTemplate == null || referencePlayer.CanUseItem(itemTemplate) != InventoryResult.Ok) + return false; + break; + } default: return false; } diff --git a/Source/Game/AuctionHouse/AuctionManager.cs b/Source/Game/AuctionHouse/AuctionManager.cs index 952a19664..ceebe4ba5 100644 --- a/Source/Game/AuctionHouse/AuctionManager.cs +++ b/Source/Game/AuctionHouse/AuctionManager.cs @@ -113,7 +113,7 @@ namespace Game public string BuildItemAuctionMailSubject(AuctionMailType type, AuctionPosting auction) { return BuildAuctionMailSubject(auction.Items[0].GetEntry(), type, auction.Id, auction.GetTotalItemCount(), - auction.Items[0].GetModifier(ItemModifier.BattlePetSpeciesId), auction.Items[0].GetContext(), auction.Items[0].m_itemData.BonusListIDs); + auction.Items[0].GetModifier(ItemModifier.BattlePetSpeciesId), auction.Items[0].GetContext(), auction.Items[0].GetBonusListIDs()); } public string BuildCommodityAuctionMailSubject(AuctionMailType type, uint itemId, uint itemCount) @@ -1998,7 +1998,7 @@ namespace Game public class SubclassFilter { public FilterType SubclassMask; - public uint[] InvTypes = new uint[ItemConst.MaxItemSubclassTotal]; + public ulong[] InvTypes = new ulong[ItemConst.MaxItemSubclassTotal]; } public enum FilterType : uint diff --git a/Source/Game/BattleGrounds/BattleGroundManager.cs b/Source/Game/BattleGrounds/BattleGroundManager.cs index 51e1816bb..9742b40c1 100644 --- a/Source/Game/BattleGrounds/BattleGroundManager.cs +++ b/Source/Game/BattleGrounds/BattleGroundManager.cs @@ -860,12 +860,12 @@ namespace Game.BattleGrounds public ushort GetMinPlayersPerTeam() { - return BattlemasterEntry.MinPlayers; + return (ushort)BattlemasterEntry.MinPlayers; } public ushort GetMaxPlayersPerTeam() { - return BattlemasterEntry.MaxPlayers; + return (ushort)BattlemasterEntry.MaxPlayers; } public byte GetMinLevel() diff --git a/Source/Game/Conditions/ConditionManager.cs b/Source/Game/Conditions/ConditionManager.cs index f6ef3bf44..439e446de 100644 --- a/Source/Game/Conditions/ConditionManager.cs +++ b/Source/Game/Conditions/ConditionManager.cs @@ -656,7 +656,7 @@ namespace Game var pMenuItemBounds = Global.ObjectMgr.GetGossipMenuItemsMapBounds(cond.SourceGroup); foreach (var gossipMenuItem in pMenuItemBounds) { - if (gossipMenuItem.MenuId == cond.SourceGroup && gossipMenuItem.OptionId == cond.SourceEntry) + if (gossipMenuItem.MenuID == cond.SourceGroup && gossipMenuItem.OrderIndex == cond.SourceEntry) { gossipMenuItem.Conditions.Add(cond); return true; @@ -2442,6 +2442,45 @@ namespace Game if (condition.CovenantID != 0 && player.m_playerData.CovenantID != condition.CovenantID) return false; + if (condition.TraitNodeEntryID.Any(traitNodeEntryId => traitNodeEntryId != 0)) + { + var getTraitNodeEntryRank = ushort? (int traitNodeEntryId) => + { + foreach (var traitConfig in player.m_activePlayerData.TraitConfigs) + { + if ((TraitConfigType)(int)traitConfig.Type == TraitConfigType.Combat) + { + if (player.m_activePlayerData.ActiveCombatTraitConfigID != traitConfig.ID + || !((TraitCombatConfigFlags)(int)traitConfig.CombatConfigFlags).HasFlag(TraitCombatConfigFlags.ActiveForSpec)) + continue; + } + + foreach (var traitEntry in traitConfig.Entries) + if (traitEntry.TraitNodeEntryID == traitNodeEntryId) + return (ushort)traitEntry.Rank; + } + return null; + }; + + results = new bool[condition.TraitNodeEntryID.Length]; + Array.Fill(results, true); + for (var i = 0; i < condition.TraitNodeEntryID.Count(); ++i) + { + if (condition.TraitNodeEntryID[i] == 0) + continue; + + var rank = getTraitNodeEntryRank(condition.TraitNodeEntryID[i]); + if (!rank.HasValue) + results[i] = false; + else if (condition.TraitNodeEntryMinRank[i] != 0 && rank < condition.TraitNodeEntryMinRank[i]) + results[i] = false; + else if (condition.TraitNodeEntryMaxRank[i] != 0 && rank > condition.TraitNodeEntryMaxRank[i]) + results[i] = false; + } + + if (!PlayerConditionLogic(condition.TraitNodeEntryLogic, results)) + return false; + } return true; } diff --git a/Source/Game/DataStorage/CliDB.cs b/Source/Game/DataStorage/CliDB.cs index 661a6f71e..8db748a0a 100644 --- a/Source/Game/DataStorage/CliDB.cs +++ b/Source/Game/DataStorage/CliDB.cs @@ -164,6 +164,7 @@ namespace Game.DataStorage GlyphBindableSpellStorage = ReadDB2("GlyphBindableSpell.db2", HotfixStatements.SEL_GLYPH_BINDABLE_SPELL); GlyphPropertiesStorage = ReadDB2("GlyphProperties.db2", HotfixStatements.SEL_GLYPH_PROPERTIES); GlyphRequiredSpecStorage = ReadDB2("GlyphRequiredSpec.db2", HotfixStatements.SEL_GLYPH_REQUIRED_SPEC); + GossipNPCOptionStorage = ReadDB2("GossipNPCOption.db2", HotfixStatements.SEL_GOSSIP_NPC_OPTION); GuildColorBackgroundStorage = ReadDB2("GuildColorBackground.db2", HotfixStatements.SEL_GUILD_COLOR_BACKGROUND); GuildColorBorderStorage = ReadDB2("GuildColorBorder.db2", HotfixStatements.SEL_GUILD_COLOR_BORDER); GuildColorEmblemStorage = ReadDB2("GuildColorEmblem.db2", HotfixStatements.SEL_GUILD_COLOR_EMBLEM); @@ -401,13 +402,13 @@ namespace Game.DataStorage } // Check loaded DB2 files proper version - if (!AreaTableStorage.ContainsKey(14083) || // last area added in 9.2.7 (45114) - !CharTitlesStorage.ContainsKey(727) || // last char title added in 9.2.7 (45114) - !GemPropertiesStorage.ContainsKey(3922) || // last gem property added in 9.2.7 (45114) - !ItemStorage.ContainsKey(199202) || // last item added in 9.2.7 (45114) - !ItemExtendedCostStorage.ContainsKey(7316) || // last item extended cost added in 9.2.7 (45114) - !MapStorage.ContainsKey(2559) || // last map added in 9.2.7 (45114) - !SpellNameStorage.ContainsKey(387936)) // last spell added in 9.2.7 (45114) + if (!CliDB.AreaTableStorage.ContainsKey(14618) || // last area added in 10.0.2 (46741) + !CliDB.CharTitlesStorage.ContainsKey(749) || // last char title added in 10.0.2 (46741) + !CliDB.GemPropertiesStorage.ContainsKey(4028) || // last gem property added in 10.0.2 (46741) + !CliDB.ItemStorage.ContainsKey(202712) || // last item added in 10.0.2 (46741) + !CliDB.ItemExtendedCostStorage.ContainsKey(7862) || // last item extended cost added in 10.0.2 (46741) + !CliDB.MapStorage.ContainsKey(2582) || // last map added in 10.0.2 (46741) + !CliDB.SpellNameStorage.ContainsKey(399311)) // last spell added in 10.0.2 (46741) { Log.outError(LogFilter.Misc, "You have _outdated_ DB2 files. Please extract correct versions from current using client."); Global.WorldMgr.ShutdownServ(10, ShutdownMask.Force, ShutdownExitCode.Error); @@ -562,6 +563,7 @@ namespace Game.DataStorage public static DB6Storage GlyphBindableSpellStorage; public static DB6Storage GlyphPropertiesStorage; public static DB6Storage GlyphRequiredSpecStorage; + public static DB6Storage GossipNPCOptionStorage; public static DB6Storage GuildColorBackgroundStorage; public static DB6Storage GuildColorBorderStorage; public static DB6Storage GuildColorEmblemStorage; @@ -799,6 +801,10 @@ namespace Game.DataStorage return row.Druid; case Class.DemonHunter: return row.DemonHunter; + case Class.Evoker: + return row.Evoker; + case Class.Adventurer: + return row.Adventurer; default: break; } @@ -834,6 +840,10 @@ namespace Game.DataStorage return row.Druid; case (int)Class.DemonHunter: return row.DemonHunter; + case (int)Class.Evoker: + return row.Evoker; + case (int)Class.Adventurer: + return row.Adventurer; case -1: case -7: return row.Item; @@ -851,6 +861,8 @@ namespace Game.DataStorage return row.DamageReplaceStat; case -9: return row.DamageSecondary; + case -10: + return row.ManaConsumable; default: break; } diff --git a/Source/Game/DataStorage/DB2Manager.cs b/Source/Game/DataStorage/DB2Manager.cs index 1b2d6b3de..dc051ae24 100644 --- a/Source/Game/DataStorage/DB2Manager.cs +++ b/Source/Game/DataStorage/DB2Manager.cs @@ -118,7 +118,9 @@ namespace Game.DataStorage if (battlemaster.MaxPlayers < battlemaster.MinPlayers) { Log.outError(LogFilter.ServerLoading, $"Battlemaster ({battlemaster.Id}) contains bad values for MinPlayers ({battlemaster.MinPlayers}) and MaxPlayers ({battlemaster.MaxPlayers}). Swapping values."); - MathFunctions.Swap(ref battlemaster.MaxPlayers, ref battlemaster.MinPlayers); + sbyte minPlayers = battlemaster.MinPlayers; + battlemaster.MinPlayers = (sbyte)battlemaster.MaxPlayers; + battlemaster.MaxPlayers = minPlayers; } } @@ -196,16 +198,16 @@ namespace Game.DataStorage ChrModelRecord model = ChrModelStorage.LookupByKey(raceModel.ChrModelID); if (model != null) { - _chrModelsByRaceAndGender[Tuple.Create((byte)raceModel.ChrRacesID, (byte)model.Sex)] = model; + _chrModelsByRaceAndGender[Tuple.Create((byte)raceModel.ChrRacesID, (byte)raceModel.Sex)] = model; var customizationOptionsForModel = customizationOptionsByModel.LookupByKey(model.Id); if (customizationOptionsForModel != null) { - _chrCustomizationOptionsByRaceAndGender.AddRange(Tuple.Create((byte)raceModel.ChrRacesID, (byte)model.Sex), customizationOptionsForModel); + _chrCustomizationOptionsByRaceAndGender.AddRange(Tuple.Create((byte)raceModel.ChrRacesID, (byte)raceModel.Sex), customizationOptionsForModel); uint parentRace = parentRaces.LookupByKey(raceModel.ChrRacesID); if (parentRace != 0) - _chrCustomizationOptionsByRaceAndGender.AddRange(Tuple.Create((byte)parentRace, (byte)model.Sex), customizationOptionsForModel); + _chrCustomizationOptionsByRaceAndGender.AddRange(Tuple.Create((byte)parentRace, (byte)raceModel.Sex), customizationOptionsForModel); } // link shapeshift displays to race/gender/form @@ -220,7 +222,7 @@ namespace Game.DataStorage data.Displays.Add(displayInfoByCustomizationChoice.LookupByKey(data.Choices[i].Id)); } - _chrCustomizationChoicesForShapeshifts[Tuple.Create((byte)raceModel.ChrRacesID, (byte)model.Sex, shapeshiftOptionsForModel.Item2)] = data; + _chrCustomizationChoicesForShapeshifts[Tuple.Create((byte)raceModel.ChrRacesID, (byte)raceModel.Sex, shapeshiftOptionsForModel.Item2)] = data; } } } @@ -2396,7 +2398,7 @@ namespace Game.DataStorage Dictionary _itemLevelDeltaToBonusListContainer = new(); MultiMap _itemBonusTrees = new(); Dictionary _itemChildEquipment = new(); - ItemClassRecord[] _itemClassByOldEnum = new ItemClassRecord[19]; + ItemClassRecord[] _itemClassByOldEnum = new ItemClassRecord[20]; List _itemsWithCurrencyCost = new(); MultiMap _itemCategoryConditions = new(); MultiMap _itemLevelQualitySelectorQualities = new(); diff --git a/Source/Game/DataStorage/Structs/B_Records.cs b/Source/Game/DataStorage/Structs/B_Records.cs index 8366e3452..2afa11792 100644 --- a/Source/Game/DataStorage/Structs/B_Records.cs +++ b/Source/Game/DataStorage/Structs/B_Records.cs @@ -47,6 +47,7 @@ namespace Game.DataStorage public sealed class BattlePetBreedQualityRecord { public uint Id; + public int MaxQualityRoll; public float StateMultiplier; public sbyte QualityEnum; } @@ -68,7 +69,7 @@ namespace Game.DataStorage public uint SummonSpellID; public int IconFileDataID; public sbyte PetTypeEnum; - public ushort Flags; + public int Flags; public sbyte SourceTypeEnum; public int CardUIModelSceneID; public int LoadoutUIModelSceneID; @@ -96,8 +97,8 @@ namespace Game.DataStorage public byte MinLevel; public byte MaxLevel; public sbyte RatedPlayers; - public byte MinPlayers; - public byte MaxPlayers; + public sbyte MinPlayers; + public int MaxPlayers; public sbyte GroupsAllowed; public sbyte MaxGroupSize; public ushort HolidayWorldState; diff --git a/Source/Game/DataStorage/Structs/C_Records.cs b/Source/Game/DataStorage/Structs/C_Records.cs index db3e95fa3..20632cd9b 100644 --- a/Source/Game/DataStorage/Structs/C_Records.cs +++ b/Source/Game/DataStorage/Structs/C_Records.cs @@ -44,8 +44,8 @@ namespace Game.DataStorage public uint Id; public long RaceMask; public sbyte ChrClassID; - public sbyte Purpose; - public sbyte Unused910; + public int Purpose; + public sbyte ItemContext; public bool IsForNewCharacter() { return Purpose == 9; } } @@ -131,6 +131,7 @@ namespace Game.DataStorage public uint Id; public uint ChrCustomizationOptionID; public uint ChrCustomizationReqID; + public int ChrCustomizationVisReqID; public ushort SortOrder; public ushort UiOrderIndex; public int Flags; @@ -159,6 +160,7 @@ namespace Game.DataStorage public int ChrCustomizationCondModelID; public int ChrCustomizationDisplayInfoID; public int ChrCustItemGeoModifyID; + public int ChrCustomizationVoiceID; } public sealed class ChrCustomizationOptionRecord @@ -181,9 +183,11 @@ namespace Game.DataStorage public sealed class ChrCustomizationReqRecord { public uint Id; + public string ReqSource; public int Flags; public int ClassMask; public int AchievementID; + public int QuestID; public int OverrideArchive; // -1: allow any, otherwise must match OverrideArchive cvar public uint ItemModifiedAppearanceID; @@ -223,6 +227,8 @@ namespace Game.DataStorage public uint Id; public int ChrRacesID; public int ChrModelID; + public int Sex; + public int AllowedTransmogSlots; } public sealed class ChrRacesRecord @@ -273,6 +279,7 @@ namespace Game.DataStorage public float AlteredFormCustomizeRotationFallback; public float[] Unknown910_1 = new float[3]; public float[] Unknown910_2 = new float[3]; + public int Unknown1000; public sbyte BaseLanguage; public sbyte CreatureType; public sbyte MaleModelFallbackSex; @@ -312,7 +319,7 @@ namespace Game.DataStorage public uint SoundID; // Sound ID (voiceover for cinematic) public float OriginFacing; // Orientation in map used for basis for M2 co public uint FileDataID; // Model - public int Unknown915; + public uint ConversationID; } public sealed class CinematicSequencesRecord @@ -409,7 +416,7 @@ namespace Game.DataStorage public sbyte Gender; public int DissolveOutEffectID; public sbyte CreatureModelMinLod; - public int[] TextureVariationFileDataID = new int[3]; + public int[] TextureVariationFileDataID = new int[4]; } public sealed class CreatureDisplayInfoExtraRecord @@ -542,6 +549,8 @@ namespace Game.DataStorage public int XpQuestDifficulty; public int AwardConditionID; public int MaxQtyWorldStateID; + public uint RechargingAmountPerCycle; + public uint RechargingCycleDurationMS; public int[] Flags = new int[2]; } @@ -554,9 +563,9 @@ namespace Game.DataStorage public sealed class CurvePointRecord { - public uint Id; public Vector2 Pos; public Vector2 PreSLSquishPos; + public uint Id; public ushort CurveID; public byte OrderIndex; } diff --git a/Source/Game/DataStorage/Structs/D_Records.cs b/Source/Game/DataStorage/Structs/D_Records.cs index 22a922d7e..fdc502870 100644 --- a/Source/Game/DataStorage/Structs/D_Records.cs +++ b/Source/Game/DataStorage/Structs/D_Records.cs @@ -73,7 +73,6 @@ namespace Game.DataStorage public int OrderIndex; public int CompleteWorldStateID; public sbyte Bit; - public int CreatureDisplayID; public int Flags; public int SpellIconFileID; public int Faction; diff --git a/Source/Game/DataStorage/Structs/F_Records.cs b/Source/Game/DataStorage/Structs/F_Records.cs index 9e257c8ac..46836193a 100644 --- a/Source/Game/DataStorage/Structs/F_Records.cs +++ b/Source/Game/DataStorage/Structs/F_Records.cs @@ -29,8 +29,10 @@ namespace Game.DataStorage public ushort ParentFactionID; public byte Expansion; public uint FriendshipRepID; - public byte Flags; + public int Flags; public ushort ParagonFactionID; + public int RenownFactionID; + public int RenownCurrencyID; public short[] ReputationClassMask = new short[4]; public ushort[] ReputationFlags = new ushort[4]; public int[] ReputationBase = new int[4]; @@ -47,14 +49,16 @@ namespace Game.DataStorage public sealed class FactionTemplateRecord { + static int MAX_FACTION_RELATIONS = 8; + public uint Id; public ushort Faction; public ushort Flags; public byte FactionGroup; public byte FriendGroup; public byte EnemyGroup; - public ushort[] Enemies = new ushort[4]; - public ushort[] Friend = new ushort[4]; + public ushort[] Enemies = new ushort[MAX_FACTION_RELATIONS]; + public ushort[] Friend = new ushort[MAX_FACTION_RELATIONS]; // helpers public bool IsFriendlyTo(FactionTemplateRecord entry) @@ -64,10 +68,10 @@ namespace Game.DataStorage if (entry.Faction != 0) { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) if (Enemies[i] == entry.Faction) return false; - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) if (Friend[i] == entry.Faction) return true; } @@ -80,10 +84,10 @@ namespace Game.DataStorage if (entry.Faction != 0) { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) if (Enemies[i] == entry.Faction) return true; - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) if (Friend[i] == entry.Faction) return false; } @@ -92,7 +96,7 @@ namespace Game.DataStorage public bool IsHostileToPlayers() { return (EnemyGroup & (byte)FactionMasks.Player) != 0; } public bool IsNeutralToAll() { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < MAX_FACTION_RELATIONS; ++i) if (Enemies[i] != 0) return false; return EnemyGroup == 0 && FriendGroup == 0; diff --git a/Source/Game/DataStorage/Structs/G_Records.cs b/Source/Game/DataStorage/Structs/G_Records.cs index 039a0705a..f8eeb0582 100644 --- a/Source/Game/DataStorage/Structs/G_Records.cs +++ b/Source/Game/DataStorage/Structs/G_Records.cs @@ -270,7 +270,7 @@ namespace Game.DataStorage public ushort UiTextureKitID; public int GarrTalentTreeType; public int PlayerConditionID; - public sbyte FeatureTypeIndex; + public byte FeatureTypeIndex; public sbyte FeatureSubtypeIndex; public int CurrencyID; } @@ -312,6 +312,26 @@ namespace Game.DataStorage public uint GlyphPropertiesID; } + public sealed class GossipNPCOptionRecord + { + public uint Id; + public int GossipNpcOption; + public int LFGDungeonsID; + public int TrainerID; + public int GarrFollowerTypeID; + public int CharShipmentID; + public int GarrTalentTreeID; + public int UiMapID; + public int UiItemInteractionID; + public int Unknown_1000_8; + public int Unknown_1000_9; + public int CovenantID; + public int GossipOptionID; + public int TraitTreeID; + public int ProfessionID; + public int Unknown_1002_14; + } + public sealed class GuildColorBackgroundRecord { public uint Id; diff --git a/Source/Game/DataStorage/Structs/GameTablesRecords.cs b/Source/Game/DataStorage/Structs/GameTablesRecords.cs index 8e15ace4d..7eb3ece23 100644 --- a/Source/Game/DataStorage/Structs/GameTablesRecords.cs +++ b/Source/Game/DataStorage/Structs/GameTablesRecords.cs @@ -47,6 +47,8 @@ namespace Game.DataStorage public float DeathKnight; public float Monk; public float DemonHunter; + public float Evoker; + public float Adventurer; } public sealed class GtBattlePetXPRecord @@ -128,6 +130,8 @@ namespace Game.DataStorage public float DeathKnight; public float Monk; public float DemonHunter; + public float Evoker; + public float Adventurer; public float Item; public float Consumable; public float Gem1; @@ -136,6 +140,7 @@ namespace Game.DataStorage public float Health; public float DamageReplaceStat; public float DamageSecondary; + public float ManaConsumable; } public sealed class GtXpRecord diff --git a/Source/Game/DataStorage/Structs/I_Records.cs b/Source/Game/DataStorage/Structs/I_Records.cs index 69ed03f3d..20bdc591b 100644 --- a/Source/Game/DataStorage/Structs/I_Records.cs +++ b/Source/Game/DataStorage/Structs/I_Records.cs @@ -59,6 +59,7 @@ namespace Game.DataStorage public byte ItemGroupSoundsID; public int ContentTuningID; public int ModifiedCraftingReagentItemID; + public int CraftingQualityID; } public sealed class ItemAppearanceRecord @@ -215,7 +216,7 @@ namespace Game.DataStorage public byte ArenaBracket; // arena slot restrictions (min slot value) public byte Flags; public byte MinFactionID; - public byte MinReputation; + public int MinReputation; public byte RequiredAchievement; // required personal arena rating public uint[] ItemID = new uint[ItemConst.MaxItemExtCostItems]; // required item id public ushort[] ItemCount = new ushort[ItemConst.MaxItemExtCostItems]; // required count of 1st item @@ -305,7 +306,7 @@ namespace Game.DataStorage public byte OverallQualityID; public int ExpansionID; public ushort MinFactionID; - public byte MinReputation; + public int MinReputation; public int AllowableClass; public sbyte RequiredLevel; public ushort RequiredSkill; @@ -356,6 +357,7 @@ namespace Game.DataStorage public int[] StatPercentEditor = new int[ItemConst.MaxStats]; public uint Stackable; public uint MaxCount; + public uint MinReputation; public uint RequiredAbility; public uint SellPrice; public uint BuyPrice; @@ -395,7 +397,6 @@ namespace Game.DataStorage public byte DamageType; public sbyte[] StatModifierBonusStat = new sbyte[ItemConst.MaxStats]; public byte ContainerSlots; - public byte MinReputation; public byte RequiredPVPMedal; public byte RequiredPVPRank; public sbyte RequiredLevel; diff --git a/Source/Game/DataStorage/Structs/J_Records.cs b/Source/Game/DataStorage/Structs/J_Records.cs index bf7ca9671..45759ac9c 100644 --- a/Source/Game/DataStorage/Structs/J_Records.cs +++ b/Source/Game/DataStorage/Structs/J_Records.cs @@ -65,7 +65,6 @@ namespace Game.DataStorage public int ButtonFileDataID; public int ButtonSmallFileDataID; public int LoreFileDataID; - public byte OrderIndex; public int Flags; public ushort AreaID; } diff --git a/Source/Game/DataStorage/Structs/M_Records.cs b/Source/Game/DataStorage/Structs/M_Records.cs index c1d1f0f17..cec2b1d75 100644 --- a/Source/Game/DataStorage/Structs/M_Records.cs +++ b/Source/Game/DataStorage/Structs/M_Records.cs @@ -51,6 +51,7 @@ namespace Game.DataStorage public short WindSettingsID; public int ZmpFileDataID; public int WdtFileDataID; + public int NavigationMaxDistance; public uint[] Flags = new uint[3]; // Helpers @@ -98,6 +99,7 @@ namespace Game.DataStorage case 1642: case 1643: case 2222: + case 2444: return true; default: return false; @@ -107,7 +109,7 @@ namespace Game.DataStorage public bool IsDynamicDifficultyMap() { return GetFlags().HasFlag(MapFlags.DynamicDifficulty); } public bool IsFlexLocking() { return GetFlags().HasFlag(MapFlags.FlexibleRaidLocking); } public bool IsGarrison() { return GetFlags().HasFlag(MapFlags.Garrison); } - public bool IsSplitByFaction() { return Id == 609 || Id == 2175; } + public bool IsSplitByFaction() { return Id == 609 || Id == 2175 || Id == 2570; } public MapFlags GetFlags() { return (MapFlags)Flags[0]; } public MapFlags2 GetFlags2() { return (MapFlags2)Flags[1]; } @@ -213,6 +215,7 @@ namespace Game.DataStorage public uint ModSpellAuraID; public short ReqMapID; public int PlayerConditionID; + public int FlightCapabilityID; } public sealed class MountTypeXCapabilityRecord diff --git a/Source/Game/DataStorage/Structs/P_Records.cs b/Source/Game/DataStorage/Structs/P_Records.cs index 9b85a6ddf..657fa9038 100644 --- a/Source/Game/DataStorage/Structs/P_Records.cs +++ b/Source/Game/DataStorage/Structs/P_Records.cs @@ -99,6 +99,7 @@ namespace Game.DataStorage public byte MaxPVPRank; public uint ContentTuningID; public int CovenantID; + public uint TraitNodeEntryLogic; public ushort[] SkillID = new ushort[4]; public ushort[] MinSkill = new ushort[4]; public ushort[] MaxSkill = new ushort[4]; @@ -123,6 +124,9 @@ namespace Game.DataStorage public uint[] CurrencyCount = new uint[4]; public uint[] QuestKillMonster = new uint[6]; public int[] MovementFlags = new int[2]; + public int[]TraitNodeEntryID = new int[4]; + public ushort[]TraitNodeEntryMinRank = new ushort[4]; + public ushort[]TraitNodeEntryMaxRank = new ushort[4]; } public sealed class PowerDisplayRecord @@ -141,12 +145,12 @@ namespace Game.DataStorage public string CostGlobalStringTag; public uint Id; public PowerType PowerTypeEnum; - public sbyte MinPower; - public short MaxBasePower; - public sbyte CenterPower; - public sbyte DefaultPower; - public sbyte DisplayModifier; - public short RegenInterruptTimeMS; + public int MinPower; + public int MaxBasePower; + public int CenterPower; + public int DefaultPower; + public int DisplayModifier; + public int RegenInterruptTimeMS; public float RegenPeace; public float RegenCombat; public short Flags; @@ -197,6 +201,7 @@ namespace Game.DataStorage public int ActionBarSpellID; public int PvpTalentCategoryID; public int LevelRequired; + public int PlayerConditionID; } public sealed class PvpTalentCategoryRecord diff --git a/Source/Game/DataStorage/Structs/Q_Records.cs b/Source/Game/DataStorage/Structs/Q_Records.cs index 8392433e5..37ae6baed 100644 --- a/Source/Game/DataStorage/Structs/Q_Records.cs +++ b/Source/Game/DataStorage/Structs/Q_Records.cs @@ -31,7 +31,7 @@ namespace Game.DataStorage public LocalizedString InfoName; public sbyte Type; public int Modifiers; - public ushort Profession; + public int Profession; } public sealed class QuestLineXQuestRecord @@ -69,6 +69,7 @@ namespace Game.DataStorage { public uint Id; public ushort UniqueBitFlag; + public int UiQuestDetailsTheme; } public sealed class QuestXPRecord diff --git a/Source/Game/DataStorage/Structs/S_Records.cs b/Source/Game/DataStorage/Structs/S_Records.cs index d92a784b8..d9435b5a7 100644 --- a/Source/Game/DataStorage/Structs/S_Records.cs +++ b/Source/Game/DataStorage/Structs/S_Records.cs @@ -97,6 +97,8 @@ namespace Game.DataStorage public int ParentTierIndex; public ushort Flags; public int SpellBookSpellID; + public int ExpansionNameSharedStringID; + public int HordeExpansionNameSharedStringID; public SkillLineFlags GetFlags() => (SkillLineFlags)Flags; } @@ -104,6 +106,8 @@ namespace Game.DataStorage public sealed class SkillLineAbilityRecord { public long RaceMask; + public string AbilityVerb; + public string AbilityAllVerb; public uint Id; public ushort SkillLine; public uint Spell; @@ -146,7 +150,7 @@ namespace Game.DataStorage public uint Id; public uint SoundType; public float VolumeFloat; - public ushort Flags; + public int Flags; public float MinDistance; public float DistanceCutoff; public byte EAXDef; @@ -159,6 +163,7 @@ namespace Game.DataStorage public float PitchAdjust; public ushort BusOverwriteID; public byte MaxInstances; + public uint SoundMixGroupID; } public sealed class SpecializationSpellsRecord @@ -194,15 +199,19 @@ namespace Game.DataStorage public sealed class SpellAuraRestrictionsRecord { public uint Id; - public byte DifficultyID; - public byte CasterAuraState; - public byte TargetAuraState; - public byte ExcludeCasterAuraState; - public byte ExcludeTargetAuraState; + public uint DifficultyID; + public int CasterAuraState; + public int TargetAuraState; + public int ExcludeCasterAuraState; + public int ExcludeTargetAuraState; public uint CasterAuraSpell; public uint TargetAuraSpell; public uint ExcludeCasterAuraSpell; public uint ExcludeTargetAuraSpell; + public int CasterAuraType; + public int TargetAuraType; + public int ExcludeCasterAuraType; + public int ExcludeTargetAuraType; public uint SpellID; } @@ -219,7 +228,7 @@ namespace Game.DataStorage public uint SpellID; public byte FacingCasterFlags; public ushort MinFactionID; - public sbyte MinReputation; + public int MinReputation; public ushort RequiredAreasID; public byte RequiredAuraVision; public ushort RequiresSpellFocus; @@ -266,6 +275,7 @@ namespace Game.DataStorage public uint CategoryRecoveryTime; public uint RecoveryTime; public uint StartRecoveryTime; + public uint AuraSpellID; public uint SpellID; } @@ -340,6 +350,7 @@ namespace Game.DataStorage public uint Id; public string Name; public string HordeName; + public int Duration; public uint[] EffectArg = new uint[ItemConst.MaxItemEnchantmentEffects]; public float[] EffectScalingPoints = new float[ItemConst.MaxItemEnchantmentEffects]; public uint IconFileDataID; @@ -439,6 +450,7 @@ namespace Game.DataStorage public int AltPowerBarID; public float PowerCostPct; public float PowerCostMaxPct; + public float OptionalCostPct; public float PowerPctPerSecond; public PowerType PowerType; public uint RequiredAuraSpellID; @@ -495,6 +507,8 @@ namespace Game.DataStorage public uint SpellID; public int[] Reagent = new int[SpellConst.MaxReagents]; public ushort[] ReagentCount = new ushort[SpellConst.MaxReagents]; + public short[] ReagentRecraftCount = new short[SpellConst.MaxReagents]; + public byte[] ReagentSource = new byte[SpellConst.MaxReagents]; } public sealed class SpellReagentsCurrencyRecord @@ -638,6 +652,7 @@ namespace Game.DataStorage public byte DifficultyID; public uint SpellVisualID; public float Probability; + public int Flags; public int Priority; public int SpellIconFileID; public int ActiveIconFileID; diff --git a/Source/Game/DataStorage/Structs/U_Records.cs b/Source/Game/DataStorage/Structs/U_Records.cs index 1e7d985a0..d0073a6fc 100644 --- a/Source/Game/DataStorage/Structs/U_Records.cs +++ b/Source/Game/DataStorage/Structs/U_Records.cs @@ -61,6 +61,7 @@ namespace Game.DataStorage public int ParentUiMapID; public int OrderIndex; public int ChildUiMapID; + public int PlayerConditionID; public int OverrideHighlightFileDataID; public int OverrideHighlightAtlasID; public int Flags; diff --git a/Source/Game/Entities/Corpse.cs b/Source/Game/Entities/Corpse.cs index 24f48a4dc..55bf48be0 100644 --- a/Source/Game/Entities/Corpse.cs +++ b/Source/Game/Entities/Corpse.cs @@ -106,7 +106,7 @@ namespace Game.Entities DeleteFromDB(trans); StringBuilder items = new(); - for (var i = 0; i < EquipmentSlot.End; ++i) + for (var i = 0; i < m_corpseData.Items.GetSize(); ++i) items.Append($"{m_corpseData.Items[i]} "); byte index = 0; @@ -187,8 +187,9 @@ namespace Game.Entities SetObjectScale(1.0f); SetDisplayId(field.Read(5)); StringArray items = new(field.Read(6), ' '); - for (uint index = 0; index < EquipmentSlot.End; ++index) - SetItem(index, uint.Parse(items[(int)index])); + if (items.Length == m_corpseData.Items.GetSize()) + for (uint index = 0; index < m_corpseData.Items.GetSize(); ++index) + SetItem(index, uint.Parse(items[(int)index])); SetRace(field.Read(7)); SetClass(field.Read(8)); diff --git a/Source/Game/Entities/Creature/Gossip.cs b/Source/Game/Entities/Creature/Gossip.cs index 6146de931..055d6b54d 100644 --- a/Source/Game/Entities/Creature/Gossip.cs +++ b/Source/Game/Entities/Creature/Gossip.cs @@ -30,47 +30,58 @@ namespace Game.Misc { public class GossipMenu { - public uint AddMenuItem(int menuItemId, GossipOptionNpc optionNpc, string message, uint sender, uint action, string boxMessage, uint boxMoney, bool coded = false) + public uint AddMenuItem(int gossipOptionId, int orderIndex, GossipOptionNpc optionNpc, string optionText, uint language, + GossipOptionFlags flags, int? gossipNpcOptionId, bool boxCoded, uint boxMoney, string boxText, int? spellId, + int? overrideIconId, uint sender, uint action) { Cypher.Assert(_menuItems.Count <= SharedConst.MaxGossipMenuItems); // Find a free new id - script case - if (menuItemId == -1) + if (orderIndex == -1) { - menuItemId = 0; + orderIndex = 0; if (_menuId != 0) { - // set baseline menuItemId as higher than whatever exists in db + // set baseline orderIndex as higher than whatever exists in db var bounds = Global.ObjectMgr.GetGossipMenuItemsMapBounds(_menuId); - var itr = bounds.MaxBy(a => a.OptionId); + var itr = bounds.MaxBy(a => a.OrderIndex); if (itr != null) - menuItemId = (int)(itr.OptionId + 1); + orderIndex = (int)(itr.OrderIndex + 1); } if (!_menuItems.Empty()) { - foreach (var item in _menuItems) + foreach (var pair in _menuItems) { - if (item.Key > menuItemId) + if (pair.Value.OrderIndex > orderIndex) break; - menuItemId = (int)item.Key + 1; + orderIndex = (int)pair.Value.OrderIndex + 1; } } } - GossipMenuItem menuItem = new(); + if (gossipOptionId == 0) + gossipOptionId = -((int)_menuId * 100 + orderIndex); + GossipMenuItem menuItem = new(); + menuItem.GossipOptionID = gossipOptionId; + menuItem.OrderIndex = (uint)orderIndex; menuItem.OptionNpc = optionNpc; - menuItem.Message = message; - menuItem.IsCoded = coded; + menuItem.OptionText = optionText; + menuItem.Language = language; + menuItem.Flags = flags; + menuItem.GossipNpcOptionID = gossipNpcOptionId; + menuItem.BoxCoded = boxCoded; + menuItem.BoxMoney = boxMoney; + menuItem.BoxText = boxText; + menuItem.SpellID = spellId; + menuItem.OverrideIconID = overrideIconId; menuItem.Sender = sender; menuItem.Action = action; - menuItem.BoxMessage = boxMessage; - menuItem.BoxMoney = boxMoney; - _menuItems[(uint)menuItemId] = menuItem; - return (uint)menuItemId; + _menuItems.Add((uint)orderIndex, menuItem); + return (uint)orderIndex; } /// @@ -89,79 +100,104 @@ namespace Game.Misc return; /// Find the one with the given menu item id. - var gossipMenuItems = bounds.Find(menuItem => menuItem.OptionId == menuItemId); + var gossipMenuItems = bounds.Find(menuItem => menuItem.OrderIndex == menuItemId); if (gossipMenuItems == null) return; + AddMenuItem(gossipMenuItems, sender, action); + } + + public void AddMenuItem(GossipMenuItems menuItem, uint sender, uint action) + { // Store texts for localization. string strOptionText, strBoxText; - BroadcastTextRecord optionBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(gossipMenuItems.OptionBroadcastTextId); - BroadcastTextRecord boxBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(gossipMenuItems.BoxBroadcastTextId); + BroadcastTextRecord optionBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(menuItem.OptionBroadcastTextId); + BroadcastTextRecord boxBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(menuItem.BoxBroadcastTextId); // OptionText if (optionBroadcastText != null) strOptionText = Global.DB2Mgr.GetBroadcastTextValue(optionBroadcastText, GetLocale()); else - strOptionText = gossipMenuItems.OptionText; + { + strOptionText = menuItem.OptionText; + + /// Find localizations from database. + if (GetLocale() != Locale.enUS) + { + GossipMenuItemsLocale gossipMenuLocale = Global.ObjectMgr.GetGossipMenuItemsLocale(menuItem.MenuID, menuItem.OrderIndex); + if (gossipMenuLocale != null) + ObjectManager.GetLocaleString(gossipMenuLocale.OptionText, GetLocale(), ref strOptionText); + } + } // BoxText if (boxBroadcastText != null) strBoxText = Global.DB2Mgr.GetBroadcastTextValue(boxBroadcastText, GetLocale()); else - strBoxText = gossipMenuItems.BoxText; - - // Check need of localization. - if (boxBroadcastText == null) { + strBoxText = menuItem.BoxText; + // Find localizations from database. - GossipMenuItemsLocale gossipMenuLocale = Global.ObjectMgr.GetGossipMenuItemsLocale(menuId, menuItemId); - if (gossipMenuLocale != null) - ObjectManager.GetLocaleString(gossipMenuLocale.BoxText, GetLocale(), ref strBoxText); + if (GetLocale() != Locale.enUS) + { + GossipMenuItemsLocale gossipMenuLocale = Global.ObjectMgr.GetGossipMenuItemsLocale(menuItem.MenuID, menuItem.OrderIndex); + if (gossipMenuLocale != null) + ObjectManager.GetLocaleString(gossipMenuLocale.BoxText, GetLocale(), ref strBoxText); + } } - // Add menu item with existing method. Menu item id -1 is also used in ADD_GOSSIP_ITEM macro. - AddMenuItem((int)gossipMenuItems.OptionId, gossipMenuItems.OptionNpc, strOptionText, sender, action, strBoxText, gossipMenuItems.BoxMoney, gossipMenuItems.BoxCoded); - AddGossipMenuItemData(gossipMenuItems.OptionId, gossipMenuItems.ActionMenuId, gossipMenuItems.ActionPoiId); + AddMenuItem(menuItem.GossipOptionID, (int)menuItem.OrderIndex, menuItem.OptionNpc, strOptionText, menuItem.Language, menuItem.Flags, + menuItem.GossipNpcOptionID, menuItem.BoxCoded, menuItem.BoxMoney, strBoxText, menuItem.SpellID, (int)menuItem.OverrideIconID, sender, action); + AddGossipMenuItemData(menuItem.OrderIndex, menuItem.ActionMenuID, menuItem.ActionPoiID); } public void AddGossipMenuItemData(uint menuItemId, uint gossipActionMenuId, uint gossipActionPoi) { - GossipMenuItemData itemData = new(); - - itemData.GossipActionMenuId = gossipActionMenuId; - itemData.GossipActionPoi = gossipActionPoi; - - _menuItemData[menuItemId] = itemData; + GossipMenuItem menuItem = _menuItems[menuItemId]; + menuItem.ActionMenuID = gossipActionMenuId; + menuItem.ActionPoiID = gossipActionPoi; } - public uint GetMenuItemSender(uint menuItemId) + public GossipMenuItem GetItem(int gossipOptionId) { - if (_menuItems.ContainsKey(menuItemId)) - return _menuItems.LookupByKey(menuItemId).Sender; - else - return 0; + return _menuItems.Values.FirstOrDefault(item => item.GossipOptionID == gossipOptionId); } - public uint GetMenuItemAction(uint menuItemId) + GossipMenuItem GetItemByIndex(uint orderIndex) { - if (_menuItems.ContainsKey(menuItemId)) - return _menuItems.LookupByKey(menuItemId).Action; - else - return 0; + return _menuItems.LookupByKey(orderIndex); } - public bool IsMenuItemCoded(uint menuItemId) + public uint GetMenuItemSender(uint orderIndex) { - if (_menuItems.ContainsKey(menuItemId)) - return _menuItems.LookupByKey(menuItemId).IsCoded; - else - return false; + GossipMenuItem item = GetItemByIndex(orderIndex); + if (item != null) + return item.Sender; + + return 0; + } + + public uint GetMenuItemAction(uint orderIndex) + { + GossipMenuItem item = GetItemByIndex(orderIndex); + if (item != null) + return item.Action; + + return 0; + } + + public bool IsMenuItemCoded(uint orderIndex) + { + GossipMenuItem item = GetItemByIndex(orderIndex); + if (item != null) + return item.BoxCoded; + + return false; } public void ClearMenu() { _menuItems.Clear(); - _menuItemData.Clear(); } public void SetMenuId(uint menu_id) { _menuId = menu_id; } @@ -179,23 +215,12 @@ namespace Game.Misc return _menuItems.Empty(); } - public GossipMenuItem GetItem(uint id) - { - return _menuItems.LookupByKey(id); - } - - public GossipMenuItemData GetItemData(uint indexId) - { - return _menuItemData.LookupByKey(indexId); - } - - public Dictionary GetMenuItems() + public SortedDictionary GetMenuItems() { return _menuItems; } - Dictionary _menuItems = new(); - Dictionary _menuItemData = new(); + SortedDictionary _menuItems = new(); uint _menuId; Locale _locale; } @@ -245,18 +270,21 @@ namespace Game.Misc if (text != null) packet.TextID = (int)text.Data.SelectRandomElementByWeight(data => data.Probability).BroadcastTextID; - foreach (var pair in _gossipMenu.GetMenuItems()) + foreach (var (index, item) in _gossipMenu.GetMenuItems()) { ClientGossipOptions opt = new(); - GossipMenuItem item = pair.Value; - opt.ClientOption = (int)pair.Key; + opt.GossipOptionID = item.GossipOptionID; opt.OptionNPC = item.OptionNpc; - opt.OptionFlags = (byte)(item.IsCoded ? 1 : 0); // makes pop up box password + opt.OptionFlags = (byte)(item.BoxCoded ? 1 : 0); // makes pop up box password opt.OptionCost = (int)item.BoxMoney; // money required to open menu, 2.0.3 opt.OptionLanguage = item.Language; - opt.Text = item.Message; // text for gossip item - opt.Confirm = item.BoxMessage; // accept text (related to money) pop up box, 2.0.3 + opt.Flags = item.Flags; + opt.OrderIndex = (int)item.OrderIndex; + opt.Text = item.OptionText; // text for gossip item + opt.Confirm = item.BoxText; // accept text (related to money) pop up box, 2.0.3 opt.Status = GossipOptionStatus.Available; + opt.SpellID = item.SpellID; + opt.OverrideIconID = item.OverrideIconID; packet.GossipOptions.Add(opt); } @@ -404,6 +432,14 @@ namespace Game.Misc packet.PortraitTurnInName = quest.PortraitTurnInName; Locale locale = _session.GetSessionDbLocaleIndex(); + + packet.ConditionalDescriptionText = quest.ConditionalQuestDescription.Select(text => + { + string content = text.Text[(int)Locale.enUS]; + ObjectManager.GetLocaleString(text.Text, locale, ref content); + return new ConditionalQuestText(text.PlayerConditionId, text.QuestgiverCreatureId, content); + }).ToList(); + if (locale != Locale.enUS) { QuestTemplateLocale localeData = Global.ObjectMgr.GetQuestLocale(quest.Id); @@ -432,6 +468,7 @@ namespace Game.Misc packet.DisplayPopup = displayPopup; packet.QuestFlags[0] = (uint)(quest.Flags & (WorldConfig.GetBoolValue(WorldCfg.QuestIgnoreAutoAccept) ? ~QuestFlags.AutoAccept : ~QuestFlags.None)); packet.QuestFlags[1] = (uint)quest.FlagsEx; + packet.QuestFlags[2] = (uint)quest.FlagsEx2; packet.SuggestedPartyMembers = quest.SuggestedPlayers; // RewardSpell can teach multiple spells in trigger spell effects. But not all effects must be SPELL_EFFECT_LEARN_SPELL. See example spell 33950 @@ -488,6 +525,14 @@ namespace Game.Misc packet.PortraitTurnInName = quest.PortraitTurnInName; Locale locale = _session.GetSessionDbLocaleIndex(); + + packet.ConditionalRewardText = quest.ConditionalOfferRewardText.Select(text => + { + string content = text.Text[(int)Locale.enUS]; + ObjectManager.GetLocaleString(text.Text, locale, ref content); + return new ConditionalQuestText(text.PlayerConditionId, text.QuestgiverCreatureId, content); + }).ToList(); + if (locale != Locale.enUS) { QuestTemplateLocale localeData = Global.ObjectMgr.GetQuestLocale(quest.Id); @@ -513,7 +558,10 @@ namespace Game.Misc // Is there a better way? what about game objects? Creature creature = ObjectAccessor.GetCreature(_session.GetPlayer(), npcGUID); if (creature) + { + packet.QuestGiverCreatureID = creature.GetEntry(); offer.QuestGiverCreatureID = creature.GetCreatureTemplate().Entry; + } offer.QuestID = quest.Id; offer.AutoLaunched = autoLaunched; @@ -524,6 +572,7 @@ namespace Game.Misc offer.QuestFlags[0] = (uint)quest.Flags; offer.QuestFlags[1] = (uint)quest.FlagsEx; + offer.QuestFlags[2] = (uint)quest.FlagsEx2; packet.PortraitTurnIn = quest.QuestTurnInPortrait; packet.PortraitGiver = quest.QuestGiverPortrait; @@ -553,6 +602,13 @@ namespace Game.Misc packet.CompletionText = quest.RequestItemsText; Locale locale = _session.GetSessionDbLocaleIndex(); + packet.ConditionalCompletionText = quest.ConditionalRequestItemsText.Select(text => + { + string content = text.Text[(int)Locale.enUS]; + ObjectManager.GetLocaleString(text.Text, locale, ref content); + return new ConditionalQuestText(text.PlayerConditionId, text.QuestgiverCreatureId, content); + }).ToList(); + if (locale != Locale.enUS) { QuestTemplateLocale localeData = Global.ObjectMgr.GetQuestLocale(quest.Id); @@ -586,6 +642,7 @@ namespace Game.Misc packet.QuestFlags[0] = (uint)quest.Flags; packet.QuestFlags[1] = (uint)quest.FlagsEx; + packet.QuestFlags[2] = (uint)quest.FlagsEx2; packet.SuggestPartyMembers = quest.SuggestedPlayers; // incomplete: FD @@ -687,20 +744,26 @@ namespace Game.Misc public class GossipMenuItem { + public int GossipOptionID; + public uint OrderIndex; public GossipOptionNpc OptionNpc; - public bool IsCoded; - public string Message; + public string OptionText; + public uint Language; + public GossipOptionFlags Flags; + public int? GossipNpcOptionID; + public bool BoxCoded; + public uint BoxMoney; + public string BoxText; + public int? SpellID; + public int? OverrideIconID; + + // action data + public uint ActionMenuID; + public uint ActionPoiID; + + // additional scripting identifiers public uint Sender; public uint Action; - public string BoxMessage; - public uint BoxMoney; - public uint Language; - } - - public class GossipMenuItemData - { - public uint GossipActionMenuId; // MenuId of the gossip triggered by this action - public uint GossipActionPoi; } public struct NpcTextData @@ -721,18 +784,23 @@ namespace Game.Misc public class GossipMenuItems { - public uint MenuId; - public uint OptionId; + public uint MenuID; + public int GossipOptionID; + public uint OrderIndex; public GossipOptionNpc OptionNpc; public string OptionText; public uint OptionBroadcastTextId; public uint Language; - public uint ActionMenuId; - public uint ActionPoiId; + public GossipOptionFlags Flags; + public uint ActionMenuID; + public uint ActionPoiID; + public int? GossipNpcOptionID; public bool BoxCoded; public uint BoxMoney; public string BoxText; public uint BoxBroadcastTextId; + public int? SpellID; + public int? OverrideIconID; public List Conditions = new(); } @@ -741,11 +809,6 @@ namespace Game.Misc public int FriendshipFactionID; } - public class GossipMenuItemAddon - { - public int? GarrTalentTreeID; - } - public class PointOfInterest { public uint Id; diff --git a/Source/Game/Entities/GameObject/GameObject.cs b/Source/Game/Entities/GameObject/GameObject.cs index 3820d5b78..3014eea85 100644 --- a/Source/Game/Entities/GameObject/GameObject.cs +++ b/Source/Game/Entities/GameObject/GameObject.cs @@ -2422,8 +2422,9 @@ namespace Game.Entities if (!item) return; - OpenHeartForge openHeartForge = new(); - openHeartForge.ForgeGUID = GetGUID(); + GameObjectInteraction openHeartForge = new(); + openHeartForge.ObjectGUID = GetGUID(); + openHeartForge.InteractionType = PlayerInteractionType.AzeriteForge; player.SendPacket(openHeartForge); break; } @@ -2438,9 +2439,25 @@ namespace Game.Entities if (!player) return; - GameObjectUILink gameObjectUILink = new(); + GameObjectInteraction gameObjectUILink = new(); gameObjectUILink.ObjectGUID = GetGUID(); - gameObjectUILink.UILink = (int)GetGoInfo().UILink.UILinkType; + switch (GetGoInfo().UILink.UILinkType) + { + case 0: + gameObjectUILink.InteractionType = PlayerInteractionType.AdventureJournal; + break; + case 1: + gameObjectUILink.InteractionType = PlayerInteractionType.ObliterumForge; + break; + case 2: + gameObjectUILink.InteractionType = PlayerInteractionType.ScrappingMachine; + break; + case 3: + gameObjectUILink.InteractionType = PlayerInteractionType.ItemInteraction; + break; + default: + break; + } player.SendPacket(gameObjectUILink); return; } diff --git a/Source/Game/Entities/GameObject/GameObjectData.cs b/Source/Game/Entities/GameObject/GameObjectData.cs index 31e1c4013..a60af5f33 100644 --- a/Source/Game/Entities/GameObject/GameObjectData.cs +++ b/Source/Game/Entities/GameObject/GameObjectData.cs @@ -231,6 +231,9 @@ namespace Game.Entities [FieldOffset(68)] public clientmodel ClientModel; + [FieldOffset(68)] + public craftingTable CraftingTable; + [FieldOffset(68)] public raw Raw; @@ -768,6 +771,7 @@ namespace Game.Entities public uint InfiniteAOI; // 10 Infinite AOI, enum { false, true, }; Default: false public uint NotLOSBlocking; // 11 Not LOS Blocking, enum { false, true, }; Default: false public uint InteractRadiusOverride; // 12 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + public uint Collisionupdatedelayafteropen; // 13 Collision update delay(ms) after open, int, Min value: 0, Max value: 2147483647, Default value: 0 } public struct button @@ -909,6 +913,13 @@ namespace Game.Entities public uint floatOnWater; // 7 floatOnWater, enum { false, true, }; Default: false public uint conditionID1; // 8 conditionID1, References: PlayerCondition, NoValue = 0 public uint InteractRadiusOverride; // 9 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + public uint gossipID; // 10 gossipID, References: Gossip, NoValue = 0 + public uint spellFocusType2; // 11 spellFocusType 2, References: SpellFocusObject, NoValue = 0 + public uint spellFocusType3; // 12 spellFocusType 3, References: SpellFocusObject, NoValue = 0 + public uint spellFocusType4; // 13 spellFocusType 4, References: SpellFocusObject, NoValue = 0 + public uint Profession; // 14 Profession, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing + public uint Profession2; // 15 Profession 2, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing + public uint Profession3; // 16 Profession 3, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing } public struct text @@ -1179,7 +1190,7 @@ namespace Game.Entities public struct dungeonDifficulty { - public uint InstanceType; // 0 Instance Type, enum { Not Instanced, Party Dungeon, Raid Dungeon, PVP Battlefield, Arena Battlefield, Scenario, }; Default: Party Dungeon + public uint InstanceType; // 0 Instance Type, enum { Not Instanced, Party Dungeon, Raid Dungeon, PVP Battlefield, Arena Battlefield, Scenario, WoWLabs }; Default: Party Dungeon public uint DifficultyNormal; // 1 Difficulty Normal, References: animationdata, NoValue = 0 public uint DifficultyHeroic; // 2 Difficulty Heroic, References: animationdata, NoValue = 0 public uint DifficultyEpic; // 3 Difficulty Epic, References: animationdata, NoValue = 0 @@ -1199,6 +1210,7 @@ namespace Game.Entities public int HeightOffset; // 1 Height Offset (inches), int, Min value: -100, Max value: 100, Default value: 0 public uint SitAnimKit; // 2 Sit Anim Kit, References: AnimKit, NoValue = 0 public uint InteractRadiusOverride; // 3 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + public uint CustomizationScope; // 4 Customization Scope, int, Min value: 0, Max value: 2147483647, Default value: 0 } public struct destructiblebuilding @@ -1490,6 +1502,7 @@ namespace Game.Entities public uint WhenAvailable; // 0 When Available, References: GameObjectDisplayInfo, NoValue = 0 public uint open; // 1 open, References: Lock_, NoValue = 0 public uint InteractRadiusOverride; // 2 Interact Radius Override (in hundredths), int, Min value: 0, Max value: 2147483647, Default value: 0 + public uint ExpansionLevel; // 3 Expansion Level, int, Min value: 0, Max value: 2147483647, Default value: 0 } public struct clientmodel @@ -1499,6 +1512,11 @@ namespace Game.Entities public uint InfiniteAOI; // 2 Infinite AOI, enum { false, true, }; Default: false public uint TrueInfiniteAOI; // 3 True Infinite AOI (programmer only!), enum { false, true, }; Default: false } + + public struct craftingTable + { + public uint Profession; // 0 Profession, enum { First Aid, Blacksmithing, Leatherworking, Alchemy, Herbalism, Cooking, Mining, Tailoring, Engineering, Enchanting, Fishing, Skinning, Jewelcrafting, Inscription, Archaeology, }; Default: Blacksmithing + } #endregion } diff --git a/Source/Game/Entities/Item/AzeriteEmpoweredItem.cs b/Source/Game/Entities/Item/AzeriteEmpoweredItem.cs index fa14b9b10..2308dca8b 100644 --- a/Source/Game/Entities/Item/AzeriteEmpoweredItem.cs +++ b/Source/Game/Entities/Item/AzeriteEmpoweredItem.cs @@ -147,7 +147,7 @@ namespace Game.Entities SetUpdateFieldValue(ref m_values.ModifyValue(m_azeriteEmpoweredItemData).ModifyValue(m_azeriteEmpoweredItemData.Selections, i), 0); _bonusData = new BonusData(GetTemplate()); - foreach (uint bonusListID in (List)m_itemData.BonusListIDs) + foreach (uint bonusListID in GetBonusListIDs()) _bonusData.AddBonusList(bonusListID); } diff --git a/Source/Game/Entities/Item/Item.cs b/Source/Game/Entities/Item/Item.cs index 37edb6c9b..edfd484a0 100644 --- a/Source/Game/Entities/Item/Item.cs +++ b/Source/Game/Entities/Item/Item.cs @@ -187,7 +187,7 @@ namespace Game.Entities ss.Clear(); - foreach (int bonusListID in (List)m_itemData.BonusListIDs) + foreach (int bonusListID in GetBonusListIDs()) ss.Append($"{bonusListID} "); stmt.AddValue(++index, ss.ToString()); @@ -802,9 +802,13 @@ namespace Game.Entities return m_container != null ? m_container.GetSlot() : InventorySlots.Bag0; } - public bool IsEquipped() { return !IsInBag() && m_slot < EquipmentSlot.End; } + public bool IsEquipped() + { + return !IsInBag() && ((m_slot >= EquipmentSlot.Start && m_slot < EquipmentSlot.End) + || (m_slot >= ProfessionSlots.Start && m_slot < ProfessionSlots.End)); + } - public bool CanBeTraded(bool mail = false, bool trade = false) + public bool CanBeTraded(bool mail = false, bool trade = false) { if (m_lootGenerated) return false; @@ -1603,7 +1607,13 @@ namespace Game.Entities -1, // INVTYPE_THROWN EquipmentSlot.MainHand, // INVTYPE_RANGEDRIGHT -1, // INVTYPE_QUIVER - -1 // INVTYPE_RELIC + -1, // INVTYPE_RELIC + -1, // INVTYPE_PROFESSION_TOOL + -1, // INVTYPE_PROFESSION_GEAR + -1, // INVTYPE_EQUIPABLE_SPELL_OFFENSIVE + -1, // INVTYPE_EQUIPABLE_SPELL_UTILITY + -1, // INVTYPE_EQUIPABLE_SPELL_DEFENSIVE + -1 // INVTYPE_EQUIPABLE_SPELL_MOBILITY }; public static bool CanTransmogrifyItemWithItem(Item item, ItemModifiedAppearanceRecord itemModifiedAppearance) @@ -2075,17 +2085,22 @@ namespace Game.Entities return 0; } + public List GetBonusListIDs() { return m_itemData.ItemBonusKey.GetValue().BonusListIDs; } + public void AddBonuses(uint bonusListID) { - var bonusListIDs = (List)m_itemData.BonusListIDs; + var bonusListIDs = GetBonusListIDs(); if (bonusListIDs.Contains(bonusListID)) return; var bonuses = Global.DB2Mgr.GetItemBonusList(bonusListID); if (bonuses != null) { - bonusListIDs.Add(bonusListID); - SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.BonusListIDs), bonusListIDs); + ItemBonusKey itemBonusKey = new(); + itemBonusKey.ItemID = GetEntry(); + itemBonusKey.BonusListIDs = GetBonusListIDs(); + itemBonusKey.BonusListIDs.Add(bonusListID); + SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemBonusKey), itemBonusKey); foreach (ItemBonusRecord bonus in bonuses) _bonusData.AddBonus(bonus.BonusType, bonus.Value); @@ -2098,9 +2113,12 @@ namespace Game.Entities if (bonusListIDs == null) bonusListIDs = new List(); - SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.BonusListIDs), bonusListIDs); + ItemBonusKey itemBonusKey = new(); + itemBonusKey.ItemID = GetEntry(); + itemBonusKey.BonusListIDs = bonusListIDs; + SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemBonusKey), itemBonusKey); - foreach (uint bonusListID in (List)m_itemData.BonusListIDs) + foreach (uint bonusListID in GetBonusListIDs()) _bonusData.AddBonusList(bonusListID); SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemAppearanceModID), (byte)_bonusData.AppearanceModID); @@ -2108,7 +2126,9 @@ namespace Game.Entities public void ClearBonuses() { - SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.BonusListIDs), new List()); + ItemBonusKey itemBonusKey = new(); + itemBonusKey.ItemID = GetEntry(); + SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemBonusKey), itemBonusKey); _bonusData = new BonusData(GetTemplate()); SetUpdateFieldValue(m_values.ModifyValue(m_itemData).ModifyValue(m_itemData.ItemAppearanceModID), (byte)_bonusData.AppearanceModID); } @@ -2721,6 +2741,8 @@ namespace Game.Entities if (!pProto.GetBagFamily().HasAnyFlag(BagFamilyMask.CookingSupp)) return false; return true; + case ItemSubClassContainer.ReagentContainer: + return pProto.IsCraftingReagent(); default: return false; } diff --git a/Source/Game/Entities/Object/Update/UpdateField.cs b/Source/Game/Entities/Object/Update/UpdateField.cs index bb9044b92..7f7eacef3 100644 --- a/Source/Game/Entities/Object/Update/UpdateField.cs +++ b/Source/Game/Entities/Object/Update/UpdateField.cs @@ -67,6 +67,29 @@ namespace Game.Entities T GetValue(); } + public class UpdateFieldString : IUpdateField + { + public string _value; + public int BlockBit; + public int Bit; + + public UpdateFieldString(int blockBit, int bit) + { + BlockBit = blockBit; + Bit = bit; + _value = ""; + } + + public static implicit operator string(UpdateFieldString updateField) + { + return updateField._value; + } + + public void SetValue(string value) { _value = value; } + + public string GetValue() { return _value; } + } + public class UpdateField : IUpdateField where T : new() { public T _value; @@ -380,6 +403,8 @@ namespace Game.Entities ((IHasChangesMask)updateField._value).ClearChangesMask(); } + public void ClearChangesMask(UpdateFieldString updateField) { } + public void ClearChangesMask(OptionalUpdateField updateField) where U : new() { if (typeof(IHasChangesMask).IsAssignableFrom(typeof(U)) && updateField.HasValue()) diff --git a/Source/Game/Entities/Object/Update/UpdateFields.cs b/Source/Game/Entities/Object/Update/UpdateFields.cs index da49ca7d5..c04f94da9 100644 --- a/Source/Game/Entities/Object/Update/UpdateFields.cs +++ b/Source/Game/Entities/Object/Update/UpdateFields.cs @@ -400,25 +400,25 @@ namespace Game.Entities public class ItemData : BaseUpdateData { - public UpdateField> BonusListIDs = new(0, 1); - public DynamicUpdateField ArtifactPowers = new(0, 2); - public DynamicUpdateField Gems = new(0, 3); - public UpdateField Owner = new(0, 4); - public UpdateField ContainedIn = new(0, 5); - public UpdateField Creator = new(0, 6); - public UpdateField GiftCreator = new(0, 7); - public UpdateField StackCount = new(0, 8); - public UpdateField Expiration = new(0, 9); - public UpdateField DynamicFlags = new(0, 10); - public UpdateField Durability = new(0, 11); - public UpdateField MaxDurability = new(0, 12); - public UpdateField CreatePlayedTime = new(0, 13); - public UpdateField Context = new(0, 14); - public UpdateField CreateTime = new(0, 15); - public UpdateField ArtifactXP = new(0, 16); - public UpdateField ItemAppearanceModID = new(0, 17); - public UpdateField Modifiers = new(0, 18); - public UpdateField DynamicFlags2 = new(0, 19); + public DynamicUpdateField ArtifactPowers = new(0, 1); + public DynamicUpdateField Gems = new(0, 2); + public UpdateField Owner = new(0, 3); + public UpdateField ContainedIn = new(0, 4); + public UpdateField Creator = new(0, 5); + public UpdateField GiftCreator = new(0, 6); + public UpdateField StackCount = new(0, 7); + public UpdateField Expiration = new(0, 8); + public UpdateField DynamicFlags = new(0, 9); + public UpdateField Durability = new(0, 10); + public UpdateField MaxDurability = new(0, 11); + public UpdateField CreatePlayedTime = new(0, 12); + public UpdateField Context = new(0, 13); + public UpdateField CreateTime = new(0, 14); + public UpdateField ArtifactXP = new(0, 15); + public UpdateField ItemAppearanceModID = new(0, 16); + public UpdateField Modifiers = new(0, 17); + public UpdateField DynamicFlags2 = new(0, 18); + public UpdateField ItemBonusKey = new(0, 19); public UpdateField DEBUGItemLevel = new(0, 20); public UpdateFieldArray SpellCharges = new(5, 21, 22); public UpdateFieldArray Enchantment = new(13, 27, 28); @@ -427,11 +427,6 @@ namespace Game.Entities public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { - List bonusList = BonusListIDs; - data.WriteInt32(bonusList.Count); - for (int i = 0; i < bonusList.Count; ++i) - data.WriteUInt32(bonusList[i]); - data.WritePackedGuid(Owner); data.WritePackedGuid(ContainedIn); data.WritePackedGuid(Creator); @@ -457,7 +452,7 @@ namespace Game.Entities } data.WriteUInt32(CreatePlayedTime); data.WriteInt32(Context); - data.WriteInt64(CreateTime); + data.WriteUInt64(CreateTime); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt64(ArtifactXP); @@ -468,6 +463,10 @@ namespace Game.Entities if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) { data.WriteUInt32(DynamicFlags2); + } + ItemBonusKey.GetValue().Write(data); + if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) + { data.WriteUInt16(DEBUGItemLevel); } for (int i = 0; i < ArtifactPowers.Size(); ++i) @@ -478,12 +477,12 @@ namespace Game.Entities { Gems[i].WriteCreate(data, owner, receiver); } - ((ItemModList)Modifiers).WriteCreate(data, owner, receiver); + Modifiers.GetValue().WriteCreate(data, owner, receiver); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Item owner, Player receiver) { - UpdateMask allowedMaskForTarget = new(41, new uint[] { 0xF804E4FFu, 0x000001FFu }); + UpdateMask allowedMaskForTarget = new(41, new uint[] { 0xF80A727Fu, 0x000001FFu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -491,12 +490,12 @@ namespace Game.Entities public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) - allowedMaskForTarget.OR(new UpdateMask(41, new uint[] { 0x07FB1B00u, 0x00000000u })); + allowedMaskForTarget.OR(new UpdateMask(41, new uint[] { 0x07F58D80u, 0x00000000u })); } public void FilterDisallowedFieldsMaskForFlag(UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags) { - UpdateMask allowedMaskForTarget = new(41, new[] { 0xF804E4FFu, 0x000001FFu }); + UpdateMask allowedMaskForTarget = new(41, new[] { 0xF80A727Fu, 0x000001FFu }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask.AND(allowedMaskForTarget); } @@ -511,24 +510,13 @@ namespace Game.Entities if (changesMask[0]) { if (changesMask[1]) - { - List bonusList = BonusListIDs; - data.WriteBits(bonusList.Count, 32); - for (int i = 0; i < bonusList.Count; ++i) - data.WriteUInt32(bonusList[i]); - } - } - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[2]) { if (!ignoreNestedChangesMask) ArtifactPowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ArtifactPowers.Size(), data); } - if (changesMask[3]) + if (changesMask[2]) { if (!ignoreNestedChangesMask) Gems.WriteUpdateMask(data); @@ -539,7 +527,7 @@ namespace Game.Entities data.FlushBits(); if (changesMask[0]) { - if (changesMask[2]) + if (changesMask[1]) { for (int i = 0; i < ArtifactPowers.Size(); ++i) { @@ -549,7 +537,7 @@ namespace Game.Entities } } } - if (changesMask[3]) + if (changesMask[2]) { for (int i = 0; i < Gems.Size(); ++i) { @@ -559,73 +547,77 @@ namespace Game.Entities } } } - if (changesMask[4]) + if (changesMask[3]) { data.WritePackedGuid(Owner); } - if (changesMask[5]) + if (changesMask[4]) { data.WritePackedGuid(ContainedIn); } - if (changesMask[6]) + if (changesMask[5]) { data.WritePackedGuid(Creator); } - if (changesMask[7]) + if (changesMask[6]) { data.WritePackedGuid(GiftCreator); } - if (changesMask[8]) + if (changesMask[7]) { data.WriteUInt32(StackCount); } - if (changesMask[9]) + if (changesMask[8]) { data.WriteUInt32(Expiration); } - if (changesMask[10]) + if (changesMask[9]) { data.WriteUInt32(DynamicFlags); } - if (changesMask[11]) + if (changesMask[10]) { data.WriteUInt32(Durability); } - if (changesMask[12]) + if (changesMask[11]) { data.WriteUInt32(MaxDurability); } - if (changesMask[13]) + if (changesMask[12]) { data.WriteUInt32(CreatePlayedTime); } - if (changesMask[14]) + if (changesMask[13]) { data.WriteInt32(Context); } - if (changesMask[15]) + if (changesMask[14]) { - data.WriteInt64(CreateTime); + data.WriteUInt64(CreateTime); } - if (changesMask[16]) + if (changesMask[15]) { data.WriteUInt64(ArtifactXP); } - if (changesMask[17]) + if (changesMask[16]) { data.WriteUInt8(ItemAppearanceModID); } - if (changesMask[19]) + if (changesMask[18]) { data.WriteUInt32(DynamicFlags2); } + if (changesMask[19]) + { + ItemBonusKey.GetValue().Write(data); + } if (changesMask[20]) { data.WriteUInt16(DEBUGItemLevel); } - if (changesMask[18]) + if (changesMask[17]) { - ((ItemModList)Modifiers).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + Modifiers.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } if (changesMask[21]) @@ -652,7 +644,6 @@ namespace Game.Entities public override void ClearChangesMask() { - ClearChangesMask(BonusListIDs); ClearChangesMask(ArtifactPowers); ClearChangesMask(Gems); ClearChangesMask(Owner); @@ -671,6 +662,7 @@ namespace Game.Entities ClearChangesMask(ItemAppearanceModID); ClearChangesMask(Modifiers); ClearChangesMask(DynamicFlags2); + ClearChangesMask(ItemBonusKey); ClearChangesMask(DEBUGItemLevel); ClearChangesMask(SpellCharges); ClearChangesMask(Enchantment); @@ -1170,115 +1162,117 @@ namespace Game.Entities public UpdateField BattlePetCompanionGUID = new(0, 20); public UpdateField BattlePetDBID = new(0, 21); public UpdateField ChannelData = new(0, 22); - public UpdateField SummonedByHomeRealm = new(0, 23); - public UpdateField Race = new(0, 24); - public UpdateField ClassId = new(0, 25); - public UpdateField PlayerClassId = new(0, 26); - public UpdateField Sex = new(0, 27); - public UpdateField DisplayPower = new(0, 28); - public UpdateField OverrideDisplayPowerID = new(0, 29); - public UpdateField Health = new(0, 30); - public UpdateField MaxHealth = new(0, 31); - public UpdateField Level = new(32, 33); - public UpdateField EffectiveLevel = new(32, 34); - public UpdateField ContentTuningID = new(32, 35); - public UpdateField ScalingLevelMin = new(32, 36); - public UpdateField ScalingLevelMax = new(32, 37); - public UpdateField ScalingLevelDelta = new(32, 38); - public UpdateField ScalingFactionGroup = new(32, 39); - public UpdateField ScalingHealthItemLevelCurveID = new(32, 40); - public UpdateField ScalingDamageItemLevelCurveID = new(32, 41); - public UpdateField FactionTemplate = new(32, 42); - public UpdateField Flags = new(32, 43); - public UpdateField Flags2 = new(32, 44); - public UpdateField Flags3 = new(32, 45); - public UpdateField AuraState = new(32, 46); - public UpdateField RangedAttackRoundBaseTime = new(32, 47); - public UpdateField BoundingRadius = new(32, 48); - public UpdateField CombatReach = new(32, 49); - public UpdateField DisplayScale = new(32, 50); - public UpdateField CreatureFamily = new(32, 51); - public UpdateField CreatureType = new(32, 52); - public UpdateField NativeDisplayID = new(32, 53); - public UpdateField NativeXDisplayScale = new(32, 54); - public UpdateField MountDisplayID = new(32, 55); - public UpdateField CosmeticMountDisplayID = new(32, 56); - public UpdateField MinDamage = new(32, 57); - public UpdateField MaxDamage = new(32, 58); - public UpdateField MinOffHandDamage = new(32, 59); - public UpdateField MaxOffHandDamage = new(32, 60); - public UpdateField StandState = new(32, 61); - public UpdateField PetTalentPoints = new(32, 62); - public UpdateField VisFlags = new(32, 63); - public UpdateField AnimTier = new(64, 65); - public UpdateField PetNumber = new(64, 66); - public UpdateField PetNameTimestamp = new(64, 67); - public UpdateField PetExperience = new(64, 68); - public UpdateField PetNextLevelExperience = new(64, 69); - public UpdateField ModCastingSpeed = new(64, 70); - public UpdateField ModCastingSpeedNeg = new(64, 71); - public UpdateField ModSpellHaste = new(64, 72); - public UpdateField ModHaste = new(64, 73); - public UpdateField ModRangedHaste = new(64, 74); - public UpdateField ModHasteRegen = new(64, 75); - public UpdateField ModTimeRate = new(64, 76); - public UpdateField CreatedBySpell = new(64, 77); - public UpdateField EmoteState = new(64, 78); - public UpdateField BaseMana = new(64, 79); - public UpdateField BaseHealth = new(64, 80); - public UpdateField SheatheState = new(64, 81); - public UpdateField PvpFlags = new(64, 82); - public UpdateField PetFlags = new(64, 83); - public UpdateField ShapeshiftForm = new(64, 84); - public UpdateField AttackPower = new(64, 85); - public UpdateField AttackPowerModPos = new(64, 86); - public UpdateField AttackPowerModNeg = new(64, 87); - public UpdateField AttackPowerMultiplier = new(64, 88); - public UpdateField RangedAttackPower = new(64, 89); - public UpdateField RangedAttackPowerModPos = new(64, 90); - public UpdateField RangedAttackPowerModNeg = new(64, 91); - public UpdateField RangedAttackPowerMultiplier = new(64, 92); - public UpdateField MainHandWeaponAttackPower = new(64, 93); - public UpdateField OffHandWeaponAttackPower = new(64, 94); - public UpdateField RangedWeaponAttackPower = new(64, 95); - public UpdateField SetAttackSpeedAura = new(96, 97); - public UpdateField Lifesteal = new(96, 98); - public UpdateField MinRangedDamage = new(96, 99); - public UpdateField MaxRangedDamage = new(96, 100); - public UpdateField ManaCostMultiplier = new(96, 101); - public UpdateField MaxHealthModifier = new(96, 102); - public UpdateField HoverHeight = new(96, 103); - public UpdateField MinItemLevelCutoff = new(96, 104); - public UpdateField MinItemLevel = new(96, 105); - public UpdateField MaxItemLevel = new(96, 106); - public UpdateField AzeriteItemLevel = new(96, 107); - public UpdateField WildBattlePetLevel = new(96, 108); - public UpdateField BattlePetCompanionExperience = new(96, 109); - public UpdateField BattlePetCompanionNameTimestamp = new(96, 110); - public UpdateField InteractSpellID = new(96, 111); - public UpdateField ScaleDuration = new(96, 112); - public UpdateField LooksLikeMountID = new(96, 113); - public UpdateField LooksLikeCreatureID = new(96, 114); - public UpdateField LookAtControllerID = new(96, 115); - public UpdateField TaxiNodesID = new(96, 116); - public UpdateField GuildGUID = new(96, 117); - public UpdateField SilencedSchoolMask = new(96, 118); - public UpdateField NameplateAttachToGUID = new(96, 119); // When set, nameplate of this unit will instead appear on that object - public UpdateFieldArray NpcFlags = new(2, 120, 121); - public UpdateFieldArray Power = new(7, 123, 124); - public UpdateFieldArray MaxPower = new(7, 123, 131); - public UpdateFieldArray PowerRegenFlatModifier = new(7, 123, 138); - public UpdateFieldArray PowerRegenInterruptedFlatModifier = new(7, 123, 145); - public UpdateFieldArray VirtualItems = new(3, 152, 153); - public UpdateFieldArray AttackRoundBaseTime = new(2, 156, 157); - public UpdateFieldArray Stats = new(4, 159, 160); - public UpdateFieldArray StatPosBuff = new(4, 159, 164); - public UpdateFieldArray StatNegBuff = new(4, 159, 168); - public UpdateFieldArray Resistances = new(7, 172, 173); - public UpdateFieldArray BonusResistanceMods = new(7, 172, 180); - public UpdateFieldArray ManaCostModifier = new(7, 172, 187); + public UpdateField SpellEmpowerStage = new(0, 23); + public UpdateField SummonedByHomeRealm = new(0, 24); + public UpdateField Race = new(0, 25); + public UpdateField ClassId = new(0, 26); + public UpdateField PlayerClassId = new(0, 27); + public UpdateField Sex = new(0, 28); + public UpdateField DisplayPower = new(0, 29); + public UpdateField OverrideDisplayPowerID = new(0, 30); + public UpdateField Health = new(0, 31); + public UpdateField MaxHealth = new(32, 33); + public UpdateField Level = new(32, 34); + public UpdateField EffectiveLevel = new(32, 35); + public UpdateField ContentTuningID = new(32, 36); + public UpdateField ScalingLevelMin = new(32, 37); + public UpdateField ScalingLevelMax = new(32, 38); + public UpdateField ScalingLevelDelta = new(32, 39); + public UpdateField ScalingFactionGroup = new(32, 40); + public UpdateField ScalingHealthItemLevelCurveID = new(32, 41); + public UpdateField ScalingDamageItemLevelCurveID = new(32, 42); + public UpdateField FactionTemplate = new(32, 43); + public UpdateField Flags = new(32, 44); + public UpdateField Flags2 = new(32, 45); + public UpdateField Flags3 = new(32, 46); + public UpdateField AuraState = new(32, 47); + public UpdateField RangedAttackRoundBaseTime = new(32, 48); + public UpdateField BoundingRadius = new(32, 49); + public UpdateField CombatReach = new(32, 50); + public UpdateField DisplayScale = new(32, 51); + public UpdateField CreatureFamily = new(32, 52); + public UpdateField CreatureType = new(32, 53); + public UpdateField NativeDisplayID = new(32, 54); + public UpdateField NativeXDisplayScale = new(32, 55); + public UpdateField MountDisplayID = new(32, 56); + public UpdateField CosmeticMountDisplayID = new(32, 57); + public UpdateField MinDamage = new(32, 58); + public UpdateField MaxDamage = new(32, 59); + public UpdateField MinOffHandDamage = new(32, 60); + public UpdateField MaxOffHandDamage = new(32, 61); + public UpdateField StandState = new(32, 62); + public UpdateField PetTalentPoints = new(32, 63); + public UpdateField VisFlags = new(64, 65); + public UpdateField AnimTier = new(64, 66); + public UpdateField PetNumber = new(64, 67); + public UpdateField PetNameTimestamp = new(64, 68); + public UpdateField PetExperience = new(64, 69); + public UpdateField PetNextLevelExperience = new(64, 70); + public UpdateField ModCastingSpeed = new(64, 71); + public UpdateField ModCastingSpeedNeg = new(64, 72); + public UpdateField ModSpellHaste = new(64, 73); + public UpdateField ModHaste = new(64, 74); + public UpdateField ModRangedHaste = new(64, 75); + public UpdateField ModHasteRegen = new(64, 76); + public UpdateField ModTimeRate = new(64, 77); + public UpdateField CreatedBySpell = new(64, 78); + public UpdateField EmoteState = new(64, 79); + public UpdateField BaseMana = new(64, 80); + public UpdateField BaseHealth = new(64, 81); + public UpdateField SheatheState = new(64, 82); + public UpdateField PvpFlags = new(64, 83); + public UpdateField PetFlags = new(64, 84); + public UpdateField ShapeshiftForm = new(64, 85); + public UpdateField AttackPower = new(64, 86); + 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 TaxiNodesID = new(96, 117); + public UpdateField GuildGUID = new(96, 118); + public UpdateField FlightCapabilityID = new(96, 119); + public UpdateField SilencedSchoolMask = new(96, 120); + public UpdateField NameplateAttachToGUID = new(96, 121); // When set, nameplate of this unit will instead appear on that object + public UpdateFieldArray NpcFlags = new(2, 122, 123); + public UpdateFieldArray Power = new(7, 125, 126); + public UpdateFieldArray MaxPower = new(7, 125, 133); + public UpdateFieldArray PowerRegenFlatModifier = new(7, 125, 140); + public UpdateFieldArray PowerRegenInterruptedFlatModifier = new(7, 125, 147); + public UpdateFieldArray VirtualItems = new(3, 154, 155); + public UpdateFieldArray AttackRoundBaseTime = new(2, 158, 159); + public UpdateFieldArray Stats = new(4, 161, 162); + public UpdateFieldArray StatPosBuff = new(4, 161, 166); + public UpdateFieldArray StatNegBuff = new(4, 161, 170); + public UpdateFieldArray Resistances = new(7, 174, 175); + public UpdateFieldArray BonusResistanceMods = new(7, 174, 182); + public UpdateFieldArray ManaCostModifier = new(7, 174, 189); - public UnitData() : base(0, TypeId.Unit, 194) { } + public UnitData() : base(0, TypeId.Unit, 196) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { @@ -1289,11 +1283,11 @@ namespace Game.Entities data.WriteUInt32(StateSpellVisualID); data.WriteUInt32(StateAnimID); data.WriteUInt32(StateAnimKitID); - data.WriteInt32(((List)StateWorldEffectIDs).Count); + data.WriteInt32(StateWorldEffectIDs.GetValue().Count); data.WriteUInt32(StateWorldEffectsQuestObjectiveID); data.WriteInt32(SpellOverrideNameID); - for (int i = 0; i < ((List)StateWorldEffectIDs).Count; ++i) - data.WriteUInt32(((List)StateWorldEffectIDs)[i]); + for (int i = 0; i < StateWorldEffectIDs.GetValue().Count; ++i) + data.WriteUInt32(StateWorldEffectIDs.GetValue()[i]); data.WritePackedGuid(Charm); data.WritePackedGuid(Summon); @@ -1308,7 +1302,8 @@ namespace Game.Entities data.WritePackedGuid(Target); data.WritePackedGuid(BattlePetCompanionGUID); data.WriteUInt64(BattlePetDBID); - ((UnitChannel)ChannelData).WriteCreate(data, owner, receiver); + ChannelData.GetValue().WriteCreate(data, owner, receiver); + data.WriteInt8(SpellEmpowerStage); data.WriteUInt32(SummonedByHomeRealm); data.WriteUInt8(Race); data.WriteUInt8(ClassId); @@ -1457,6 +1452,7 @@ namespace Game.Entities data.WriteInt32(PassiveSpells.Size()); data.WriteInt32(WorldEffects.Size()); data.WriteInt32(ChannelObjects.Size()); + data.WriteInt32(FlightCapabilityID); data.WriteUInt32(SilencedSchoolMask); data.WritePackedGuid(NameplateAttachToGUID); @@ -1472,7 +1468,7 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Unit owner, Player receiver) { - UpdateMask allowedMaskForTarget = new(195, new uint[] { 0xFFFFDFFFu, 0xE1FF7FFFu, 0x001EFFFFu, 0xFFFFFF81u, 0x7F0003FFu, 0x00000000u, 0x00000000u }); + UpdateMask allowedMaskForTarget = new(195, new uint[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0xFC000FFFu, 0x00000001u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -1480,16 +1476,16 @@ namespace Game.Entities public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Owner)) - allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00002000u, 0x1E008000u, 0xFFE10000u, 0x0800007Eu, 0x80FFFC00u, 0xFFFFFFFFu, 0x00000003u })); + allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00002000u, 0x3C010000u, 0xFFC20000u, 0x200000FEu, 0x03FFF000u, 0xFFFFFFFEu, 0x0000000Fu })); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.UnitAll)) - allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x08000000u, 0x00FFFC00u, 0x00000000u, 0x00000000u })); + allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00000000u, 0x00000000u, 0x00000000u, 0x20000000u, 0x03FFF000u, 0x00000000u, 0x00000000u })); if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.Empath)) - allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00000000u, 0x1E000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x000FF000u, 0x00000000u })); + allowedMaskForTarget.OR(new UpdateMask(195, new uint[] { 0x00000000u, 0x3C000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x003FC000u, 0x00000000u })); } public void FilterDisallowedFieldsMaskForFlag(UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags) { - UpdateMask allowedMaskForTarget = new(195, new[] { 0xFFFFDFFFu, 0xE1FF7FFFu, 0x001EFFFFu, 0xFFFFFF81u, 0x7F0003FFu, 0x00000000u, 0x00000000u }); + UpdateMask allowedMaskForTarget = new(195, new[] { 0xFFFFDFFFu, 0xC3FEFFFFu, 0x003DFFFFu, 0xFFFFFF01u, 0xFC000FFFu, 0x00000001u, 0x00000000u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask.AND(allowedMaskForTarget); } @@ -1505,10 +1501,10 @@ namespace Game.Entities { if (changesMask[1]) { - data.WriteBits(((List)StateWorldEffectIDs).Count, 32); - for (int i = 0; i < ((List)StateWorldEffectIDs).Count; ++i) + data.WriteBits(StateWorldEffectIDs.GetValue().Count, 32); + for (int i = 0; i < StateWorldEffectIDs.GetValue().Count; ++i) { - data.WriteUInt32(((List)StateWorldEffectIDs)[i]); + data.WriteUInt32(StateWorldEffectIDs.GetValue()[i]); } } } @@ -1628,7 +1624,7 @@ namespace Game.Entities } if (changesMask[19]) { - data.WritePackedGuid(Target); + data .WritePackedGuid( Target); } if (changesMask[20]) { @@ -1640,477 +1636,485 @@ namespace Game.Entities } if (changesMask[22]) { - ((UnitChannel)ChannelData).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + ChannelData.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[23]) { - data.WriteUInt32(SummonedByHomeRealm); + data.WriteInt8(SpellEmpowerStage); } if (changesMask[24]) { - data.WriteUInt8(Race); + data.WriteUInt32(SummonedByHomeRealm); } if (changesMask[25]) { - data.WriteUInt8(ClassId); + data.WriteUInt8(Race); } if (changesMask[26]) { - data.WriteUInt8(PlayerClassId); + data.WriteUInt8(ClassId); } if (changesMask[27]) { - data.WriteUInt8(Sex); + data.WriteUInt8(PlayerClassId); } if (changesMask[28]) { - data.WriteUInt8(DisplayPower); + data.WriteUInt8(Sex); } if (changesMask[29]) { - data.WriteUInt32(OverrideDisplayPowerID); + data.WriteUInt8(DisplayPower); } if (changesMask[30]) { - data.WriteUInt64(Health); + data.WriteUInt32(OverrideDisplayPowerID); } if (changesMask[31]) { - data.WriteUInt64(MaxHealth); + data.WriteUInt64(Health); } } if (changesMask[32]) { if (changesMask[33]) { - data.WriteUInt32(Level); + data.WriteUInt64(MaxHealth); } if (changesMask[34]) { - data.WriteInt32(EffectiveLevel); + data.WriteUInt32(Level); } if (changesMask[35]) { - data.WriteUInt32(ContentTuningID); + data.WriteInt32(EffectiveLevel); } if (changesMask[36]) { - data.WriteInt32(ScalingLevelMin); + data.WriteUInt32(ContentTuningID); } if (changesMask[37]) { - data.WriteInt32(ScalingLevelMax); + data.WriteInt32(ScalingLevelMin); } if (changesMask[38]) { - data.WriteInt32(ScalingLevelDelta); + data.WriteInt32(ScalingLevelMax); } if (changesMask[39]) { - data.WriteInt32(ScalingFactionGroup); + data.WriteInt32(ScalingLevelDelta); } if (changesMask[40]) { - data.WriteInt32(ScalingHealthItemLevelCurveID); + data.WriteInt32(ScalingFactionGroup); } if (changesMask[41]) { - data.WriteInt32(ScalingDamageItemLevelCurveID); + data.WriteInt32(ScalingHealthItemLevelCurveID); } if (changesMask[42]) { - data.WriteUInt32(GetViewerDependentFactionTemplate(this, owner, receiver)); + data.WriteInt32(ScalingDamageItemLevelCurveID); } if (changesMask[43]) { - data.WriteUInt32(GetViewerDependentFlags(this, owner, receiver)); + data.WriteUInt32(GetViewerDependentFactionTemplate(this, owner, receiver)); } if (changesMask[44]) { - data.WriteUInt32(Flags2); + data.WriteUInt32(GetViewerDependentFlags(this, owner, receiver)); } if (changesMask[45]) { - data.WriteUInt32(GetViewerDependentFlags3(this, owner, receiver)); + data.WriteUInt32(Flags2); } if (changesMask[46]) { - data.WriteUInt32(GetViewerDependentAuraState(this, owner, receiver)); + data.WriteUInt32(GetViewerDependentFlags3(this, owner, receiver)); } if (changesMask[47]) { - data.WriteUInt32(RangedAttackRoundBaseTime); + data.WriteUInt32(GetViewerDependentAuraState(this, owner, receiver)); } if (changesMask[48]) { - data.WriteFloat(BoundingRadius); + data.WriteUInt32(RangedAttackRoundBaseTime); } if (changesMask[49]) { - data.WriteFloat(CombatReach); + data.WriteFloat(BoundingRadius); } if (changesMask[50]) { - data.WriteFloat(DisplayScale); + data.WriteFloat(CombatReach); } if (changesMask[51]) { - data.WriteInt32(CreatureFamily); + data.WriteFloat(DisplayScale); } if (changesMask[52]) { - data.WriteInt32(CreatureType); + data.WriteInt32(CreatureFamily); } if (changesMask[53]) { - data.WriteUInt32(NativeDisplayID); + data.WriteInt32(CreatureType); } if (changesMask[54]) { - data.WriteFloat(NativeXDisplayScale); + data.WriteUInt32(NativeDisplayID); } if (changesMask[55]) { - data.WriteUInt32(MountDisplayID); + data.WriteFloat(NativeXDisplayScale); } if (changesMask[56]) { - data.WriteUInt32(CosmeticMountDisplayID); + data.WriteUInt32(MountDisplayID); } if (changesMask[57]) { - data.WriteFloat(MinDamage); + data.WriteUInt32(CosmeticMountDisplayID); } if (changesMask[58]) { - data.WriteFloat(MaxDamage); + data.WriteFloat(MinDamage); } if (changesMask[59]) { - data.WriteFloat(MinOffHandDamage); + data.WriteFloat(MaxDamage); } if (changesMask[60]) { - data.WriteFloat(MaxOffHandDamage); + data.WriteFloat(MinOffHandDamage); } if (changesMask[61]) { - data.WriteUInt8(StandState); + data.WriteFloat(MaxOffHandDamage); } if (changesMask[62]) { - data.WriteUInt8(PetTalentPoints); + data.WriteUInt8(StandState); } if (changesMask[63]) { - data.WriteUInt8(VisFlags); + data.WriteUInt8(PetTalentPoints); } } if (changesMask[64]) { if (changesMask[65]) { - data.WriteUInt8(AnimTier); + data.WriteUInt8(VisFlags); } if (changesMask[66]) { - data.WriteUInt32(PetNumber); + data.WriteUInt8(AnimTier); } if (changesMask[67]) { - data.WriteUInt32(PetNameTimestamp); + data.WriteUInt32(PetNumber); } if (changesMask[68]) { - data.WriteUInt32(PetExperience); + data.WriteUInt32(PetNameTimestamp); } if (changesMask[69]) { - data.WriteUInt32(PetNextLevelExperience); + data.WriteUInt32(PetExperience); } if (changesMask[70]) { - data.WriteFloat(ModCastingSpeed); + data.WriteUInt32(PetNextLevelExperience); } if (changesMask[71]) { - data.WriteFloat(ModCastingSpeedNeg); + data.WriteFloat(ModCastingSpeed); } if (changesMask[72]) { - data.WriteFloat(ModSpellHaste); + data.WriteFloat(ModCastingSpeedNeg); } if (changesMask[73]) { - data.WriteFloat(ModHaste); + data.WriteFloat(ModSpellHaste); } if (changesMask[74]) { - data.WriteFloat(ModRangedHaste); + data.WriteFloat(ModHaste); } if (changesMask[75]) { - data.WriteFloat(ModHasteRegen); + data.WriteFloat(ModRangedHaste); } if (changesMask[76]) { - data.WriteFloat(ModTimeRate); + data.WriteFloat(ModHasteRegen); } if (changesMask[77]) { - data.WriteUInt32(CreatedBySpell); + data.WriteFloat(ModTimeRate); } if (changesMask[78]) { - data.WriteInt32(EmoteState); + data.WriteUInt32(CreatedBySpell); } if (changesMask[79]) { - data.WriteUInt32(BaseMana); + data.WriteInt32(EmoteState); } if (changesMask[80]) { - data.WriteUInt32(BaseHealth); + data.WriteUInt32(BaseMana); } if (changesMask[81]) { - data.WriteUInt8(SheatheState); + data.WriteUInt32(BaseHealth); } if (changesMask[82]) { - data.WriteUInt8((byte)GetViewerDependentPvpFlags(this, owner, receiver)); + data.WriteUInt8(SheatheState); } if (changesMask[83]) { - data.WriteUInt8(PetFlags); + data.WriteUInt8(GetViewerDependentPvpFlags(this, owner, receiver)); } if (changesMask[84]) { - data.WriteUInt8(ShapeshiftForm); + data.WriteUInt8(PetFlags); } if (changesMask[85]) { - data.WriteInt32(AttackPower); + data.WriteUInt8(ShapeshiftForm); } if (changesMask[86]) { - data.WriteInt32(AttackPowerModPos); + data.WriteInt32(AttackPower); } if (changesMask[87]) { - data.WriteInt32(AttackPowerModNeg); + data.WriteInt32(AttackPowerModPos); } if (changesMask[88]) { - data.WriteFloat(AttackPowerMultiplier); + data.WriteInt32(AttackPowerModNeg); } if (changesMask[89]) { - data.WriteInt32(RangedAttackPower); + data.WriteFloat(AttackPowerMultiplier); } if (changesMask[90]) { - data.WriteInt32(RangedAttackPowerModPos); + data.WriteInt32(RangedAttackPower); } if (changesMask[91]) { - data.WriteInt32(RangedAttackPowerModNeg); + data.WriteInt32(RangedAttackPowerModPos); } if (changesMask[92]) { - data.WriteFloat(RangedAttackPowerMultiplier); + data.WriteInt32(RangedAttackPowerModNeg); } if (changesMask[93]) { - data.WriteInt32(MainHandWeaponAttackPower); + data.WriteFloat(RangedAttackPowerMultiplier); } if (changesMask[94]) { - data.WriteInt32(OffHandWeaponAttackPower); + data.WriteInt32(MainHandWeaponAttackPower); } if (changesMask[95]) { - data.WriteInt32(RangedWeaponAttackPower); + data.WriteInt32(OffHandWeaponAttackPower); } } if (changesMask[96]) { if (changesMask[97]) { - data.WriteInt32(SetAttackSpeedAura); + data.WriteInt32(RangedWeaponAttackPower); } if (changesMask[98]) { - data.WriteFloat(Lifesteal); + data.WriteInt32(SetAttackSpeedAura); } if (changesMask[99]) { - data.WriteFloat(MinRangedDamage); + data.WriteFloat(Lifesteal); } if (changesMask[100]) { - data.WriteFloat(MaxRangedDamage); + data.WriteFloat(MinRangedDamage); } if (changesMask[101]) { - data.WriteFloat(ManaCostMultiplier); + data.WriteFloat(MaxRangedDamage); } if (changesMask[102]) { - data.WriteFloat(MaxHealthModifier); + data.WriteFloat(ManaCostMultiplier); } if (changesMask[103]) { - data.WriteFloat(HoverHeight); + data.WriteFloat(MaxHealthModifier); } if (changesMask[104]) { - data.WriteUInt32(MinItemLevelCutoff); + data.WriteFloat(HoverHeight); } if (changesMask[105]) { - data.WriteUInt32(MinItemLevel); + data.WriteUInt32(MinItemLevelCutoff); } if (changesMask[106]) { - data.WriteUInt32(MaxItemLevel); + data.WriteUInt32(MinItemLevel); } if (changesMask[107]) { - data.WriteInt32(AzeriteItemLevel); + data.WriteUInt32(MaxItemLevel); } if (changesMask[108]) { - data.WriteUInt32(WildBattlePetLevel); + data.WriteInt32(AzeriteItemLevel); } if (changesMask[109]) { - data.WriteUInt32(BattlePetCompanionExperience); + data.WriteUInt32(WildBattlePetLevel); } if (changesMask[110]) { - data.WriteUInt32(BattlePetCompanionNameTimestamp); + data.WriteUInt32(BattlePetCompanionExperience); } if (changesMask[111]) { - data.WriteInt32(InteractSpellID); + data.WriteUInt32(BattlePetCompanionNameTimestamp); } if (changesMask[112]) { - data.WriteInt32(ScaleDuration); + data.WriteInt32(InteractSpellID); } if (changesMask[113]) { - data.WriteInt32(LooksLikeMountID); + data.WriteInt32(ScaleDuration); } if (changesMask[114]) { - data.WriteInt32(LooksLikeCreatureID); + data.WriteInt32(LooksLikeMountID); } if (changesMask[115]) { - data.WriteInt32(LookAtControllerID); + data.WriteInt32(LooksLikeCreatureID); } if (changesMask[116]) { - data.WriteInt32(TaxiNodesID); + data.WriteInt32(LookAtControllerID); } if (changesMask[117]) { - data.WritePackedGuid(GuildGUID); + data.WriteInt32(TaxiNodesID); } if (changesMask[118]) { - data.WriteUInt32(SilencedSchoolMask); + data.WritePackedGuid(GuildGUID); } if (changesMask[119]) + { + data.WriteInt32(FlightCapabilityID); + } + if (changesMask[120]) + { + data.WriteUInt32(SilencedSchoolMask); + } + if (changesMask[121]) { data.WritePackedGuid(NameplateAttachToGUID); } } - if (changesMask[120]) + if (changesMask[122]) { for (int i = 0; i < 2; ++i) { - if (changesMask[121 + i]) + if (changesMask[123 + i]) { data.WriteUInt32(GetViewerDependentNpcFlags(this, i, owner, receiver)); } } } - if (changesMask[123]) + if (changesMask[125]) { for (int i = 0; i < 7; ++i) { - if (changesMask[124 + i]) + if (changesMask[126 + i]) { data.WriteInt32(Power[i]); } - if (changesMask[131 + i]) + if (changesMask[133 + i]) { data.WriteUInt32(MaxPower[i]); } - if (changesMask[138 + i]) + if (changesMask[140 + i]) { data.WriteFloat(PowerRegenFlatModifier[i]); } - if (changesMask[145 + i]) + if (changesMask[147 + i]) { data.WriteFloat(PowerRegenInterruptedFlatModifier[i]); } } } - if (changesMask[152]) + if (changesMask[154]) { for (int i = 0; i < 3; ++i) { - if (changesMask[153 + i]) + if (changesMask[155 + i]) { VirtualItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[156]) + if (changesMask[158]) { for (int i = 0; i < 2; ++i) { - if (changesMask[157 + i]) + if (changesMask[159 + i]) { data.WriteUInt32(AttackRoundBaseTime[i]); } } } - if (changesMask[159]) + if (changesMask[161]) { for (int i = 0; i < 4; ++i) { - if (changesMask[160 + i]) + if (changesMask[162 + i]) { data.WriteInt32(Stats[i]); } - if (changesMask[164 + i]) + if (changesMask[166 + i]) { data.WriteInt32(StatPosBuff[i]); } - if (changesMask[168 + i]) + if (changesMask[170 + i]) { data.WriteInt32(StatNegBuff[i]); } } } - if (changesMask[172]) + if (changesMask[174]) { for (int i = 0; i < 7; ++i) { - if (changesMask[173 + i]) + if (changesMask[175 + i]) { data.WriteInt32(Resistances[i]); } - if (changesMask[180 + i]) + if (changesMask[182 + i]) { data.WriteInt32(BonusResistanceMods[i]); } - if (changesMask[187 + i]) + if (changesMask[189 + i]) { data.WriteInt32(ManaCostModifier[i]); } @@ -2142,6 +2146,7 @@ namespace Game.Entities ClearChangesMask(BattlePetCompanionGUID); ClearChangesMask(BattlePetDBID); ClearChangesMask(ChannelData); + ClearChangesMask(SpellEmpowerStage); ClearChangesMask(SummonedByHomeRealm); ClearChangesMask(Race); ClearChangesMask(ClassId); @@ -2234,6 +2239,7 @@ namespace Game.Entities ClearChangesMask(LookAtControllerID); ClearChangesMask(TaxiNodesID); ClearChangesMask(GuildGUID); + ClearChangesMask(FlightCapabilityID); ClearChangesMask(SilencedSchoolMask); ClearChangesMask(NameplateAttachToGUID); ClearChangesMask(NpcFlags); @@ -2340,16 +2346,16 @@ namespace Game.Entities // Check per caster aura states to not enable using a spell in client if specified aura is not by target return unit.BuildAuraStateUpdateForTarget(receiver); } - uint GetViewerDependentPvpFlags(UnitData unitData, Unit unit, Player receiver) + byte GetViewerDependentPvpFlags(UnitData unitData, Unit unit, Player receiver) { - uint pvpFlags = unitData.PvpFlags; + byte pvpFlags = unitData.PvpFlags; if (unit.IsControlledByPlayer() && receiver != unit && WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionGroup) && unit.IsInRaidWith(receiver)) { FactionTemplateRecord ft1 = unit.GetFactionTemplateEntry(); FactionTemplateRecord ft2 = receiver.GetFactionTemplateEntry(); if (ft1 != null && ft2 != null && !ft1.IsFriendlyTo(ft2)) // Allow targeting opposite faction in party when enabled in config - pvpFlags &= (uint)UnitPVPStateFlags.Sanctuary; + pvpFlags &= (byte)UnitPVPStateFlags.Sanctuary; } return pvpFlags; @@ -2567,39 +2573,41 @@ namespace Game.Entities public DynamicUpdateField Customizations = new(0, 3); public DynamicUpdateField QuestSessionQuestLog = new(0, 4); public DynamicUpdateField ArenaCooldowns = new(0, 5); - public UpdateField DuelArbiter = new(0, 6); - public UpdateField WowAccount = new(0, 7); - public UpdateField LootTargetGUID = new(0, 8); - public UpdateField PlayerFlags = new(0, 9); - public UpdateField PlayerFlagsEx = new(0, 10); - public UpdateField GuildRankID = new(0, 11); - public UpdateField GuildDeleteDate = new(0, 12); - public UpdateField GuildLevel = new(0, 13); - public UpdateField PartyType = new(0, 14); - public UpdateField NativeSex = new(0, 15); - public UpdateField Inebriation = new(0, 16); - public UpdateField PvpTitle = new(0, 17); - public UpdateField ArenaFaction = new(0, 18); - public UpdateField DuelTeam = new(0, 19); - public UpdateField GuildTimeStamp = new(0, 20); - public UpdateField PlayerTitle = new(0, 21); - public UpdateField FakeInebriation = new(0, 22); - public UpdateField VirtualPlayerRealm = new(0, 23); - public UpdateField CurrentSpecID = new(0, 24); - public UpdateField TaxiMountAnimKitID = new(0, 25); - public UpdateField CurrentBattlePetBreedQuality = new(0, 26); - public UpdateField HonorLevel = new(0, 27); - public UpdateField Field_B0 = new(0, 28); - public UpdateField Field_B4 = new(0, 29); - public UpdateField CtrOptions = new(0, 30); - public UpdateField CovenantID = new(0, 31); - public UpdateField SoulbindID = new(32, 33); - public UpdateField DungeonScore = new(32, 34); - public UpdateFieldArray QuestLog = new(125, 35, 36); - public UpdateFieldArray VisibleItems = new(19, 161, 162); - public UpdateFieldArray AvgItemLevel = new(6, 181, 182); + public DynamicUpdateField VisualItemReplacements = new(0, 6); + public UpdateField DuelArbiter = new(0, 7); + public UpdateField WowAccount = new(0, 8); + public UpdateField LootTargetGUID = new(0, 9); + public UpdateField PlayerFlags = new(0, 10); + public UpdateField PlayerFlagsEx = new(0, 11); + public UpdateField GuildRankID = new(0, 12); + public UpdateField GuildDeleteDate = new(0, 13); + public UpdateField GuildLevel = new(0, 14); + public UpdateField PartyType = new(0, 15); + public UpdateField NativeSex = new(0, 16); + public UpdateField Inebriation = new(0, 17); + public UpdateField PvpTitle = new(0, 18); + public UpdateField ArenaFaction = new(0, 19); + public UpdateField DuelTeam = new(0, 20); + public UpdateField GuildTimeStamp = new(0, 21); + public UpdateField PlayerTitle = new(0, 22); + public UpdateField FakeInebriation = new(0, 23); + public UpdateField VirtualPlayerRealm = new(0, 24); + public UpdateField CurrentSpecID = new(0, 25); + public UpdateField TaxiMountAnimKitID = new(0, 26); + public UpdateField CurrentBattlePetBreedQuality = new(0, 27); + public UpdateField HonorLevel = new(0, 28); + public UpdateField LogoutTime = new(0, 29); + public UpdateField Field_B0 = new(0, 30); + public UpdateField Field_B4 = new(0, 31); + public UpdateField CtrOptions = new(32, 33); + public UpdateField CovenantID = new(32, 34); + public UpdateField SoulbindID = new(32, 35); + public UpdateField DungeonScore = new(32, 36); + public UpdateFieldArray QuestLog = new(125, 37, 38); + public UpdateFieldArray VisibleItems = new(19, 163, 164); + public UpdateFieldArray AvgItemLevel = new(6, 183, 184); - public PlayerData() : base(0, TypeId.Player, 188) { } + public PlayerData() : base(0, TypeId.Player, 190) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { @@ -2642,12 +2650,14 @@ namespace Game.Entities } data.WriteUInt8(CurrentBattlePetBreedQuality); data.WriteUInt32(HonorLevel); + data.WriteInt64(LogoutTime); data.WriteInt32(ArenaCooldowns.Size()); data.WriteInt32(Field_B0); data.WriteInt32(Field_B4); ((CTROptions)CtrOptions).WriteCreate(data, owner, receiver); data.WriteInt32(CovenantID); data.WriteInt32(SoulbindID); + data.WriteInt32(VisualItemReplacements.Size()); for (int i = 0; i < Customizations.Size(); ++i) { Customizations[i].WriteCreate(data, owner, receiver); @@ -2663,6 +2673,10 @@ namespace Game.Entities { ArenaCooldowns[i].WriteCreate(data, owner, receiver); } + for (int i = 0; i < VisualItemReplacements.Size(); ++i) + { + data.WriteInt32(VisualItemReplacements[i]); + } if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.PartyMember)) { data.WriteBit(HasQuestSession); @@ -2674,7 +2688,7 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { - UpdateMask allowedMaskForTarget = new(188, new[] { 0xFFFFFFEDu, 0x00000007u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0FFFFFFEu }); + UpdateMask allowedMaskForTarget = new(188, new[] { 0xFFFFFFEDu, 0x0000001Fu, 0x00000000u, 0x00000000u, 0x00000000u, 0x3FFFFFF8u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); WriteUpdate(data, _changesMask & allowedMaskForTarget, false, owner, receiver); } @@ -2682,12 +2696,12 @@ namespace Game.Entities public void AppendAllowedFieldsMaskForFlag(UpdateMask allowedMaskForTarget, UpdateFieldFlag fieldVisibilityFlags) { if (fieldVisibilityFlags.HasFlag(UpdateFieldFlag.PartyMember)) - allowedMaskForTarget.OR(new UpdateMask(188, new[] { 0x00000012u, 0xFFFFFFF8u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000001u })); + allowedMaskForTarget.OR(new UpdateMask(188, new[] { 0x00000012u, 0xFFFFFFE0u, 0xFFFFFFFFu, 0xFFFFFFFFu, 0xFFFFFFFFu, 0x00000007u })); } public void FilterDisallowedFieldsMaskForFlag(UpdateMask changesMask, UpdateFieldFlag fieldVisibilityFlags) { - UpdateMask allowedMaskForTarget = new(188, new[] { 0xFFFFFFEDu, 0x00000007u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0FFFFFFEu }); + UpdateMask allowedMaskForTarget = new(188, new[] { 0xFFFFFFEDu, 0x0000001Fu, 0x00000000u, 0x00000000u, 0x00000000u, 0x3FFFFFF8u }); AppendAllowedFieldsMaskForFlag(allowedMaskForTarget, fieldVisibilityFlags); changesMask.AND(allowedMaskForTarget); } @@ -2731,6 +2745,13 @@ namespace Game.Entities else WriteCompleteDynamicFieldUpdateMask(ArenaCooldowns.Size(), data); } + if (changesMask[6]) + { + if (!ignoreNestedChangesMask) + VisualItemReplacements.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(VisualItemReplacements.Size(), data); + } } data.FlushBits(); if (changesMask[0]) @@ -2770,125 +2791,139 @@ namespace Game.Entities } if (changesMask[6]) { - data.WritePackedGuid(DuelArbiter); + for (int i = 0; i < VisualItemReplacements.Size(); ++i) + { + if (VisualItemReplacements.HasChanged(i) || ignoreNestedChangesMask) + { + data.WriteInt32(VisualItemReplacements[i]); + } + } } if (changesMask[7]) { - data.WritePackedGuid(WowAccount); + data.WritePackedGuid(DuelArbiter); } if (changesMask[8]) { - data.WritePackedGuid(LootTargetGUID); + data.WritePackedGuid(WowAccount); } if (changesMask[9]) { - data.WriteUInt32(PlayerFlags); + data.WritePackedGuid(LootTargetGUID); } if (changesMask[10]) { - data.WriteUInt32(PlayerFlagsEx); + data.WriteUInt32(PlayerFlags); } if (changesMask[11]) { - data.WriteUInt32(GuildRankID); + data.WriteUInt32(PlayerFlagsEx); } if (changesMask[12]) { - data.WriteUInt32(GuildDeleteDate); + data.WriteUInt32(GuildRankID); } if (changesMask[13]) { - data.WriteUInt32(GuildLevel); + data.WriteUInt32(GuildDeleteDate); } if (changesMask[14]) { - data.WriteUInt8(PartyType); + data.WriteUInt32(GuildLevel); } if (changesMask[15]) { - data.WriteUInt8(NativeSex); + data.WriteUInt8(PartyType); } if (changesMask[16]) { - data.WriteUInt8(Inebriation); + data.WriteUInt8(NativeSex); } if (changesMask[17]) { - data.WriteUInt8(PvpTitle); + data.WriteUInt8(Inebriation); } if (changesMask[18]) { - data.WriteUInt8(ArenaFaction); + data.WriteUInt8(PvpTitle); } if (changesMask[19]) { - data.WriteUInt32(DuelTeam); + data.WriteUInt8(ArenaFaction); } if (changesMask[20]) { - data.WriteInt32(GuildTimeStamp); + data.WriteUInt32(DuelTeam); } if (changesMask[21]) { - data.WriteUInt32(PlayerTitle); + data.WriteInt32(GuildTimeStamp); } if (changesMask[22]) { - data.WriteInt32(FakeInebriation); + data.WriteUInt32(PlayerTitle); } if (changesMask[23]) { - data.WriteUInt32(VirtualPlayerRealm); + data.WriteInt32(FakeInebriation); } if (changesMask[24]) { - data.WriteUInt32(CurrentSpecID); + data.WriteUInt32(VirtualPlayerRealm); } if (changesMask[25]) { - data.WriteInt32(TaxiMountAnimKitID); + data.WriteUInt32(CurrentSpecID); } if (changesMask[26]) { - data.WriteUInt8(CurrentBattlePetBreedQuality); + data.WriteInt32(TaxiMountAnimKitID); } if (changesMask[27]) { - data.WriteUInt32(HonorLevel); + data.WriteUInt8(CurrentBattlePetBreedQuality); } if (changesMask[28]) { - data.WriteInt32(Field_B0); + data.WriteUInt32(HonorLevel); } if (changesMask[29]) { - data.WriteInt32(Field_B4); + data.WriteInt64(LogoutTime); } if (changesMask[30]) { - ((CTROptions)CtrOptions).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data.WriteInt32(Field_B0); } if (changesMask[31]) { - data.WriteInt32(CovenantID); + data.WriteInt32(Field_B4); } } if (changesMask[32]) { if (changesMask[33]) { - data.WriteInt32(SoulbindID); + CtrOptions.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[34]) { - DungeonScore._value.Write(data); + data.WriteInt32(CovenantID); + } + if (changesMask[35]) + { + data.WriteInt32(SoulbindID); + } + if (changesMask[36]) + { + DungeonScore.GetValue().Write(data); } } - if (changesMask[35]) + if (changesMask[37]) { for (int i = 0; i < 125; ++i) { - if (changesMask[36 + i]) + if (changesMask[38 + i]) { if (noQuestLogChangesMask) QuestLog[i].WriteCreate(data, owner, receiver); @@ -2897,21 +2932,21 @@ namespace Game.Entities } } } - if (changesMask[161]) + if (changesMask[163]) { for (int i = 0; i < 19; ++i) { - if (changesMask[162 + i]) + if (changesMask[164 + i]) { VisibleItems[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[181]) + if (changesMask[183]) { for (int i = 0; i < 6; ++i) { - if (changesMask[182 + i]) + if (changesMask[184 + i]) { data.WriteFloat(AvgItemLevel[i]); } @@ -2927,6 +2962,7 @@ namespace Game.Entities ClearChangesMask(Customizations); ClearChangesMask(QuestSessionQuestLog); ClearChangesMask(ArenaCooldowns); + ClearChangesMask(VisualItemReplacements); ClearChangesMask(DuelArbiter); ClearChangesMask(WowAccount); ClearChangesMask(LootTargetGUID); @@ -2949,6 +2985,7 @@ namespace Game.Entities ClearChangesMask(TaxiMountAnimKitID); ClearChangesMask(CurrentBattlePetBreedQuality); ClearChangesMask(HonorLevel); + ClearChangesMask(LogoutTime); ClearChangesMask(Field_B0); ClearChangesMask(Field_B4); ClearChangesMask(CtrOptions); @@ -3099,22 +3136,30 @@ namespace Game.Entities public class PVPInfo : BaseUpdateData { public UpdateField Disqualified = new(0, 1); - public UpdateField WeeklyPlayed = new(0, 2); - public UpdateField WeeklyWon = new(0, 3); - public UpdateField SeasonPlayed = new(0, 4); - public UpdateField SeasonWon = new(0, 5); - public UpdateField Rating = new(0, 6); - public UpdateField WeeklyBestRating = new(0, 7); - public UpdateField SeasonBestRating = new(0, 8); - public UpdateField PvpTierID = new(0, 9); - public UpdateField WeeklyBestWinPvpTierID = new(0, 10); - public UpdateField Field_28 = new(0, 11); - public UpdateField Field_2C = new(0, 12); + public UpdateField Bracket = new(0, 2); + public UpdateField PvpRatingID = new(0, 3); + public UpdateField WeeklyPlayed = new(0, 4); + public UpdateField WeeklyWon = new(0, 5); + public UpdateField SeasonPlayed = new(0, 6); + public UpdateField SeasonWon = new(0, 7); + public UpdateField Rating = new(0, 8); + public UpdateField WeeklyBestRating = new(0, 9); + public UpdateField SeasonBestRating = new(0, 10); + public UpdateField PvpTierID = new(0, 11); + public UpdateField WeeklyBestWinPvpTierID = new(0, 12); + public UpdateField Field_28 = new(0, 13); + public UpdateField Field_2C = new(0, 14); + public UpdateField WeeklyRoundsPlayed = new(0, 15); + public UpdateField WeeklyRoundsWon = new(0, 16); + public UpdateField SeasonRoundsPlayed = new(0, 17); + public UpdateField SeasonRoundsWon = new(0, 18); - public PVPInfo() : base(13) { } + public PVPInfo() : base(19) { } public void WriteCreate(WorldPacket data, Player owner, Player receiver) { + data.WriteInt8(Bracket); + data.WriteUInt32(PvpRatingID); data.WriteUInt32(WeeklyPlayed); data.WriteUInt32(WeeklyWon); data.WriteUInt32(SeasonPlayed); @@ -3126,6 +3171,10 @@ namespace Game.Entities data.WriteUInt32(WeeklyBestWinPvpTierID); data.WriteUInt32(Field_28); data.WriteUInt32(Field_2C); + data.WriteUInt32(WeeklyRoundsPlayed); + data.WriteUInt32(WeeklyRoundsWon); + data.WriteUInt32(SeasonRoundsPlayed); + data.WriteUInt32(SeasonRoundsWon); data.WriteBit(Disqualified); data.FlushBits(); } @@ -3136,7 +3185,7 @@ namespace Game.Entities if (ignoreChangesMask) changesMask.SetAll(); - data.WriteBits(changesMask.GetBlock(0), 13); + data.WriteBits(changesMask.GetBlock(0), 19); if (changesMask[0]) { @@ -3150,48 +3199,72 @@ namespace Game.Entities { if (changesMask[2]) { - data.WriteUInt32(WeeklyPlayed); + data.WriteInt8(Bracket); } if (changesMask[3]) { - data.WriteUInt32(WeeklyWon); + data.WriteUInt32(PvpRatingID); } if (changesMask[4]) { - data.WriteUInt32(SeasonPlayed); + data.WriteUInt32(WeeklyPlayed); } if (changesMask[5]) { - data.WriteUInt32(SeasonWon); + data.WriteUInt32(WeeklyWon); } if (changesMask[6]) { - data.WriteUInt32(Rating); + data.WriteUInt32(SeasonPlayed); } if (changesMask[7]) { - data.WriteUInt32(WeeklyBestRating); + data.WriteUInt32(SeasonWon); } if (changesMask[8]) { - data.WriteUInt32(SeasonBestRating); + data.WriteUInt32(Rating); } if (changesMask[9]) { - data.WriteUInt32(PvpTierID); + data.WriteUInt32(WeeklyBestRating); } if (changesMask[10]) { - data.WriteUInt32(WeeklyBestWinPvpTierID); + data.WriteUInt32(SeasonBestRating); } if (changesMask[11]) { - data.WriteUInt32(Field_28); + data.WriteUInt32(PvpTierID); } if (changesMask[12]) + { + data.WriteUInt32(WeeklyBestWinPvpTierID); + } + if (changesMask[13]) + { + data.WriteUInt32(Field_28); + } + if (changesMask[14]) { data.WriteUInt32(Field_2C); } + if (changesMask[15]) + { + data.WriteUInt32(WeeklyRoundsPlayed); + } + if (changesMask[16]) + { + data.WriteUInt32(WeeklyRoundsWon); + } + if (changesMask[17]) + { + data.WriteUInt32(SeasonRoundsPlayed); + } + if (changesMask[18]) + { + data.WriteUInt32(SeasonRoundsWon); + } } data.FlushBits(); } @@ -3199,6 +3272,8 @@ namespace Game.Entities public override void ClearChangesMask() { ClearChangesMask(Disqualified); + ClearChangesMask(Bracket); + ClearChangesMask(PvpRatingID); ClearChangesMask(WeeklyPlayed); ClearChangesMask(WeeklyWon); ClearChangesMask(SeasonPlayed); @@ -3210,6 +3285,10 @@ namespace Game.Entities ClearChangesMask(WeeklyBestWinPvpTierID); ClearChangesMask(Field_28); ClearChangesMask(Field_2C); + ClearChangesMask(WeeklyRoundsPlayed); + ClearChangesMask(WeeklyRoundsWon); + ClearChangesMask(SeasonRoundsPlayed); + ClearChangesMask(SeasonRoundsWon); _changesMask.ResetAll(); } } @@ -3403,49 +3482,6 @@ namespace Game.Entities } } - public class ReplayedQuest : BaseUpdateData - { - public UpdateField QuestID = new(0, 1); - public UpdateField ReplayTime = new(0, 2); - - public ReplayedQuest() : base(3) { } - - public void WriteCreate(WorldPacket data, Player owner, Player receiver) - { - data.WriteInt32(QuestID); - data.WriteUInt32(ReplayTime); - } - - public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) - { - UpdateMask changesMask = _changesMask; - if (ignoreChangesMask) - changesMask.SetAll(); - - data.WriteBits(changesMask.GetBlock(0), 3); - - data.FlushBits(); - if (changesMask[0]) - { - if (changesMask[1]) - { - data.WriteInt32(QuestID); - } - if (changesMask[2]) - { - data.WriteUInt32(ReplayTime); - } - } - } - - public override void ClearChangesMask() - { - ClearChangesMask(QuestID); - ClearChangesMask(ReplayTime); - _changesMask.ResetAll(); - } - } - public class QuestSession : BaseUpdateData { public UpdateField Owner = new(0, 1); @@ -3501,6 +3537,628 @@ namespace Game.Entities } } + public class ReplayedQuest : BaseUpdateData + { + public UpdateField QuestID = new(0, 1); + public UpdateField ReplayTime = new(0, 2); + + public ReplayedQuest() : base(3) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(QuestID); + data.WriteUInt32(ReplayTime); + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + UpdateMask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 3); + + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + data.WriteInt32(QuestID); + } + if (changesMask[2]) + { + data.WriteUInt32(ReplayTime); + } + } + } + + public override void ClearChangesMask() + { + ClearChangesMask(QuestID); + ClearChangesMask(ReplayTime); + _changesMask.ResetAll(); + } + } + + public class TraitEntry : IEquatable + { + public int TraitNodeID; + public int TraitNodeEntryID; + public int Rank; + public int GrantedRanks; + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(TraitNodeID); + data.WriteInt32(TraitNodeEntryID); + data.WriteInt32(Rank); + data.WriteInt32(GrantedRanks); + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + data.WriteInt32(TraitNodeID); + data.WriteInt32(TraitNodeEntryID); + data.WriteInt32(Rank); + data.WriteInt32(GrantedRanks); + } + + public bool Equals(TraitEntry right) + { + return TraitNodeID == right.TraitNodeID + && TraitNodeEntryID == right.TraitNodeEntryID + && Rank == right.Rank + && GrantedRanks == right.GrantedRanks; + } + } + + public class TraitConfig : BaseUpdateData + { + public DynamicUpdateField Entries = new(0, 1); + public UpdateField ID = new(0, 2); + public UpdateFieldString Name = new(0, 3); + public UpdateField Type = new(4, 5); + public UpdateField SkillLineID = new(4, 6); + public UpdateField ChrSpecializationID = new(4, 7); + public UpdateField CombatConfigFlags = new(8, 9); + public UpdateField LocalIdentifier = new(8, 10); + public UpdateField TraitSystemID = new(8, 11); + + public TraitConfig() : base(12) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(ID); + data.WriteInt32(Type); + data.WriteInt32(Entries.Size()); + if (Type == 2) + { + data.WriteInt32(SkillLineID); + } + if (Type == 1) + { + data.WriteInt32(ChrSpecializationID); + data.WriteInt32(CombatConfigFlags); + data.WriteInt32(LocalIdentifier); + } + if (Type == 3) + { + data.WriteInt32(TraitSystemID); + } + for (int i = 0; i < Entries.Size(); ++i) + { + Entries[i].WriteCreate(data, owner, receiver); + } + data.WriteBits(Name.GetValue().GetByteCount(), 9); + 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), 12); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Entries.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Entries.Size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (int i = 0; i < Entries.Size(); ++i) + { + if (Entries.HasChanged(i) || ignoreChangesMask) + { + Entries[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + if (changesMask[2]) + { + data.WriteInt32(ID); + } + } + if (changesMask[4]) + { + if (changesMask[5]) + { + data.WriteInt32(Type); + } + if (changesMask[6]) + { + if (Type == 2) + { + data.WriteInt32(SkillLineID); + } + } + if (changesMask[7]) + { + if (Type == 1) + { + data.WriteInt32(ChrSpecializationID); + } + } + } + if (changesMask[8]) + { + if (changesMask[9]) + { + if (Type == 1) + { + data.WriteInt32(CombatConfigFlags); + } + } + if (changesMask[10]) + { + if (Type == 1) + { + data.WriteInt32(LocalIdentifier); + } + } + if (changesMask[11]) + { + if (Type == 3) + { + data.WriteInt32(TraitSystemID); + } + } + } + if (changesMask[0]) + { + if (changesMask[3]) + { + data.WriteBits(Name.GetValue().GetByteCount(), 9); + data.WriteString(Name); + } + } + data.FlushBits(); + } + + public override void ClearChangesMask() + { + ClearChangesMask(Entries); + ClearChangesMask(ID); + ClearChangesMask(Name); + ClearChangesMask(Type); + ClearChangesMask(SkillLineID); + ClearChangesMask(ChrSpecializationID); + ClearChangesMask(CombatConfigFlags); + ClearChangesMask(LocalIdentifier); + ClearChangesMask(TraitSystemID); + _changesMask.ResetAll(); + } + } + + public class CraftingOrderItem : BaseUpdateData + { + public UpdateField Field_0 = new(-1, 0); + public UpdateField ItemGUID = new(-1, 1); + public UpdateField OwnerGUID = new(-1, 2); + public UpdateField ItemID = new(-1, 3); + public UpdateField Quantity = new(-1, 4); + public UpdateField ReagentQuality = new(-1, 5); + public OptionalUpdateField DataSlotIndex = new(-1, 6); + + public CraftingOrderItem() : base(7) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteUInt64(Field_0); + data.WritePackedGuid(ItemGUID); + data.WritePackedGuid(OwnerGUID); + data.WriteInt32(ItemID); + data.WriteUInt32(Quantity); + data.WriteInt32(ReagentQuality); + data.WriteBits(DataSlotIndex.HasValue(), 1); + if (DataSlotIndex.HasValue()) + { + data.WriteUInt8(DataSlotIndex); + } + } + + public void WriteUpdate(WorldPacket data, bool ignoreChangesMask, Player owner, Player receiver) + { + UpdateMask changesMask = _changesMask; + if (ignoreChangesMask) + changesMask.SetAll(); + + data.WriteBits(changesMask.GetBlock(0), 7); + + data.FlushBits(); + if (changesMask[0]) + { + data.WriteUInt64(Field_0); + } + if (changesMask[1]) + { + data.WritePackedGuid(ItemGUID); + } + if (changesMask[2]) + { + data.WritePackedGuid(OwnerGUID); + } + if (changesMask[3]) + { + data.WriteInt32(ItemID); + } + if (changesMask[4]) + { + data.WriteUInt32(Quantity); + } + if (changesMask[5]) + { + data.WriteInt32(ReagentQuality); + } + data.WriteBits(DataSlotIndex.HasValue(), 1); + if (changesMask[6]) + { + if (DataSlotIndex.HasValue()) + { + data.WriteUInt8(DataSlotIndex); + } + } + } + + public override void ClearChangesMask() + { + ClearChangesMask(Field_0); + ClearChangesMask(ItemGUID); + ClearChangesMask(OwnerGUID); + ClearChangesMask(ItemID); + ClearChangesMask(Quantity); + ClearChangesMask(ReagentQuality); + ClearChangesMask(DataSlotIndex); + _changesMask.ResetAll(); + } + } + + public class CraftingOrderData : BaseUpdateData + { + public DynamicUpdateField Reagents = new(0, 1); + public UpdateField Field_0 = new(0, 2); + public UpdateField OrderID = new(0, 3); + public UpdateField SkillLineAbilityID = new(0, 4); + public UpdateField OrderState = new(5, 6); + public UpdateField OrderType = new(5, 7); + public UpdateField MinQuality = new(5, 8); + public UpdateField ExpirationTime = new(5, 9); + public UpdateField ClaimEndTime = new(10, 11); + public UpdateField TipAmount = new(10, 12); + public UpdateField ConsortiumCut = new(10, 13); + public UpdateField Flags = new(10, 14); + public UpdateField CustomerGUID = new(15, 16); + public UpdateField CustomerAccountGUID = new(15, 17); + public UpdateField CrafterGUID = new(15, 18); + public UpdateField PersonalCrafterGUID = new(15, 19); + public UpdateFieldString CustomerNotes = new(20, 21); + public OptionalUpdateField OutputItem = new(20, 22); + public OptionalUpdateField OutputItemData = new(20, 23); + + public CraftingOrderData() : base(24) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + data.WriteInt32(Field_0); + data.WriteUInt64(OrderID); + data.WriteInt32(SkillLineAbilityID); + data.WriteUInt8(OrderState); + data.WriteUInt8(OrderType); + data.WriteUInt8(MinQuality); + data.WriteInt64(ExpirationTime); + data.WriteInt64(ClaimEndTime); + data.WriteInt64(TipAmount); + data.WriteInt64(ConsortiumCut); + data.WriteUInt32(Flags); + data.WritePackedGuid(CustomerGUID); + data.WritePackedGuid(CustomerAccountGUID); + data.WritePackedGuid(CrafterGUID); + data.WritePackedGuid(PersonalCrafterGUID); + data.WriteInt32(Reagents.Size()); + data.WriteBits(CustomerNotes.GetValue().GetByteCount(), 10); + data.WriteBits(OutputItem.HasValue(), 1); + data.WriteBits(OutputItemData.HasValue(), 1); + for (int i = 0; i < Reagents.Size(); ++i) + { + Reagents[i].WriteCreate(data, owner, receiver); + } + data.WriteString(CustomerNotes); + if (OutputItem.HasValue()) + { + OutputItem.GetValue().WriteCreate(data, owner, receiver); + } + if (OutputItemData.HasValue()) + { + OutputItemData.GetValue().Write(data); + } + 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), 24); + + if (changesMask[0]) + { + if (changesMask[1]) + { + if (!ignoreChangesMask) + Reagents.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(Reagents.Size(), data); + } + } + data.FlushBits(); + if (changesMask[0]) + { + if (changesMask[1]) + { + for (int i = 0; i < Reagents.Size(); ++i) + { + if (Reagents.HasChanged(i) || ignoreChangesMask) + { + Reagents[i].WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + } + if (changesMask[2]) + { + data.WriteInt32(Field_0); + } + if (changesMask[3]) + { + data.WriteUInt64(OrderID); + } + if (changesMask[4]) + { + data.WriteInt32(SkillLineAbilityID); + } + } + if (changesMask[5]) + { + if (changesMask[6]) + { + data.WriteUInt8(OrderState); + } + if (changesMask[7]) + { + data.WriteUInt8(OrderType); + } + if (changesMask[8]) + { + data.WriteUInt8(MinQuality); + } + if (changesMask[9]) + { + data.WriteInt64(ExpirationTime); + } + } + if (changesMask[10]) + { + if (changesMask[11]) + { + data.WriteInt64(ClaimEndTime); + } + if (changesMask[12]) + { + data.WriteInt64(TipAmount); + } + if (changesMask[13]) + { + data.WriteInt64(ConsortiumCut); + } + if (changesMask[14]) + { + data.WriteUInt32(Flags); + } + } + if (changesMask[15]) + { + if (changesMask[16]) + { + data.WritePackedGuid(CustomerGUID); + } + if (changesMask[17]) + { + data.WritePackedGuid(CustomerAccountGUID); + } + if (changesMask[18]) + { + data.WritePackedGuid(CrafterGUID); + } + if (changesMask[19]) + { + data.WritePackedGuid(PersonalCrafterGUID); + } + } + if (changesMask[20]) + { + if (changesMask[21]) + { + data.WriteBits(CustomerNotes.GetValue().GetByteCount(), 10); + data.WriteString(CustomerNotes); + } + data.WriteBits(OutputItem.HasValue(), 1); + data.WriteBits(OutputItemData.HasValue(), 1); + if (changesMask[22]) + { + if (OutputItem.HasValue()) + { + OutputItem.GetValue().WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + } + + if (changesMask[23]) + { + + if (OutputItemData.HasValue()) + { + OutputItemData.GetValue().Write(data); + } + } + } + data.FlushBits(); + } + + public override void ClearChangesMask() + { + ClearChangesMask(Reagents); + ClearChangesMask(Field_0); + ClearChangesMask(OrderID); + ClearChangesMask(SkillLineAbilityID); + ClearChangesMask(OrderState); + ClearChangesMask(OrderType); + ClearChangesMask(MinQuality); + ClearChangesMask(ExpirationTime); + ClearChangesMask(ClaimEndTime); + ClearChangesMask(TipAmount); + ClearChangesMask(ConsortiumCut); + ClearChangesMask(Flags); + ClearChangesMask(CustomerGUID); + ClearChangesMask(CustomerAccountGUID); + ClearChangesMask(CrafterGUID); + ClearChangesMask(PersonalCrafterGUID); + ClearChangesMask(CustomerNotes); + ClearChangesMask(OutputItem); + ClearChangesMask(OutputItemData); + _changesMask.ResetAll(); + } + } + + public class CraftingOrder : BaseUpdateData + { + public DynamicUpdateField Enchantments = new(-1, 0); + public DynamicUpdateField Gems = new(-1, 1); + public UpdateField Data = new(-1, 2); + public OptionalUpdateField RecraftItemInfo = new(-1, 3); + + public CraftingOrder() : base(4) { } + + public void WriteCreate(WorldPacket data, Player owner, Player receiver) + { + Data.GetValue().WriteCreate(data, owner, receiver); + data.WriteBits(RecraftItemInfo.HasValue(), 1); + data.WriteBits(Enchantments.Size(), 4); + data.WriteBits(Gems.Size(), 2); + if (RecraftItemInfo.HasValue()) + { + RecraftItemInfo.GetValue().Write(data); + } + for (int i = 0; i < Enchantments.Size(); ++i) + { + Enchantments[i].Write(data); + } + for (int i = 0; i < Gems.Size(); ++i) + { + Gems[i].Write(data); + } + 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), 4); + + if (changesMask[0]) + { + if (!ignoreChangesMask) + Enchantments.WriteUpdateMask(data, 4); + else + WriteCompleteDynamicFieldUpdateMask(Enchantments.Size(), data, 4); + } + if (changesMask[1]) + { + if (!ignoreChangesMask) + Gems.WriteUpdateMask(data, 2); + else + WriteCompleteDynamicFieldUpdateMask(Gems.Size(), data, 2); + } + data.FlushBits(); + if (changesMask[0]) + { + for (int i = 0; i < Enchantments.Size(); ++i) + { + if (Enchantments.HasChanged(i) || ignoreChangesMask) + { + Enchantments[i].Write(data); + } + } + } + if (changesMask[1]) + { + for (int i = 0; i < Gems.Size(); ++i) + { + if (Gems.HasChanged(i) || ignoreChangesMask) + { + Gems[i].Write(data); + } + } + } + + if (changesMask[2]) + { + Data.GetValue().WriteUpdate(data, ignoreChangesMask, owner, receiver); + } + data.WriteBits(RecraftItemInfo.HasValue(), 1); + if (changesMask[3]) + { + if (RecraftItemInfo.HasValue()) + { + RecraftItemInfo.GetValue().Write(data); + } + } + data.FlushBits(); + } + + public override void ClearChangesMask() + { + ClearChangesMask(Enchantments); + ClearChangesMask(Gems); + ClearChangesMask(Data); + ClearChangesMask(RecraftItemInfo); + _changesMask.ResetAll(); + } + } + public class ActivePlayerData : BaseUpdateData { public static int ExploredZonesSize; @@ -3512,129 +4170,132 @@ namespace Game.Entities public UpdateField BankAutoSortDisabled = new(0, 2); public UpdateField SortBagsRightToLeft = new(0, 3); public UpdateField InsertItemsLeftToRight = new(0, 4); - public UpdateFieldArray> Research = new(1, 27, 28); + public UpdateFieldArray> Research = new(1, 30, 31); public DynamicUpdateField KnownTitles = new(0, 5); - public DynamicUpdateField ResearchSites = new(0, 6); - public DynamicUpdateField ResearchSiteProgress = new(0, 7); - 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 DisabledSpells = new(0, 26); - public DynamicUpdateField CharacterRestrictions = new(0, 19); - public UpdateField FarsightObject = new(0, 29); - public UpdateField SummonedBattlePetGUID = new(0, 30); - public UpdateField Coinage = new(0, 31); - public UpdateField XP = new(0, 32); - public UpdateField NextLevelXP = new(0, 33); - public UpdateField TrialXP = new(34, 35); - public UpdateField Skill = new(34, 36); - public UpdateField CharacterPoints = new(34, 37); - public UpdateField MaxTalentTiers = new(34, 38); - public UpdateField TrackCreatureMask = new(34, 39); - public UpdateField MainhandExpertise = new(34, 40); - public UpdateField OffhandExpertise = new(34, 41); - public UpdateField RangedExpertise = new(34, 42); - public UpdateField CombatRatingExpertise = new(34, 43); - public UpdateField BlockPercentage = new(34, 44); - public UpdateField DodgePercentage = new(34, 45); - public UpdateField DodgePercentageFromAttribute = new(34, 46); - public UpdateField ParryPercentage = new(34, 47); - public UpdateField ParryPercentageFromAttribute = new(34, 48); - public UpdateField CritPercentage = new(34, 49); - public UpdateField RangedCritPercentage = new(34, 50); - public UpdateField OffhandCritPercentage = new(34, 51); - public UpdateField SpellCritPercentage = new(34, 52); - public UpdateField ShieldBlock = new(34, 53); - public UpdateField ShieldBlockCritPercentage = new(34, 54); - public UpdateField Mastery = new(34, 55); - public UpdateField Speed = new(34, 56); - public UpdateField Avoidance = new(34, 57); - public UpdateField Sturdiness = new(34, 58); - public UpdateField Versatility = new(34, 59); - public UpdateField VersatilityBonus = new(34, 60); - public UpdateField PvpPowerDamage = new(34, 61); - public UpdateField PvpPowerHealing = new(34, 62); - public UpdateField ModHealingDonePos = new(34, 63); - public UpdateField ModHealingPercent = new(34, 64); - public UpdateField ModPeriodicHealingDonePercent = new(34, 65); - public UpdateField ModSpellPowerPercent = new(66, 67); - public UpdateField ModResiliencePercent = new(66, 68); - public UpdateField OverrideSpellPowerByAPPercent = new(66, 69); - public UpdateField OverrideAPBySpellPowerPercent = new(66, 70); - public UpdateField ModTargetResistance = new(66, 71); - public UpdateField ModTargetPhysicalResistance = new(66, 72); - public UpdateField LocalFlags = new(66, 73); - public UpdateField GrantableLevels = new(66, 74); - public UpdateField MultiActionBars = new(66, 75); - public UpdateField LifetimeMaxRank = new(66, 76); - public UpdateField NumRespecs = new(66, 77); - public UpdateField PvpMedals = new(66, 78); - public UpdateField TodayHonorableKills = new(66, 79); - public UpdateField YesterdayHonorableKills = new(66, 80); - public UpdateField LifetimeHonorableKills = new(66, 81); - public UpdateField WatchedFactionIndex = new(66, 82); - public UpdateField MaxLevel = new(66, 83); - public UpdateField ScalingPlayerLevelDelta = new(66, 84); - public UpdateField MaxCreatureScalingLevel = new(66, 85); - public UpdateField PetSpellPower = new(66, 86); - public UpdateField UiHitModifier = new(66, 87); - public UpdateField UiSpellHitModifier = new(66, 88); - public UpdateField HomeRealmTimeOffset = new(66, 89); - public UpdateField ModPetHaste = new(66, 90); - public UpdateField JailersTowerLevelMax = new(66, 91); - public UpdateField JailersTowerLevel = new(66, 92); - public UpdateField LocalRegenFlags = new(66, 93); - public UpdateField AuraVision = new(66, 94); - public UpdateField NumBackpackSlots = new(66, 95); - public UpdateField OverrideSpellsID = new(66, 96); - public UpdateField LootSpecID = new(66, 97); - public UpdateField OverrideZonePVPType = new(98, 99); - public UpdateField BnetAccount = new(98, 100); - public UpdateField GuildClubMemberID = new(98, 101); - public UpdateField Honor = new(98, 102); - public UpdateField HonorNextLevel = new(98, 103); - public UpdateField NumBankSlots = new(98, 104); - public UpdateField Field_1410 = new(98, 106); - public OptionalUpdateField QuestSession = new(98, 105); - public UpdateField UiChromieTimeExpansionID = new(98, 107); - public UpdateField TransportServerTime = new(98, 108); - public UpdateField WeeklyRewardsPeriodSinceOrigin = new(98, 109); // week count since Cfg_RegionsEntry::ChallengeOrigin - public UpdateField DEBUGSoulbindConduitRank = new(98, 110); - public UpdateField DungeonScore = new(98, 111); - public UpdateFieldArray InvSlots = new(199, 112, 113); - public UpdateFieldArray ExploredZones = new(240, 312, 313); - public UpdateFieldArray RestInfo = new(2, 553, 554); - public UpdateFieldArray ModDamageDonePos = new(7, 556, 557); - public UpdateFieldArray ModDamageDoneNeg = new(7, 556, 564); - public UpdateFieldArray ModDamageDonePercent = new(7, 556, 571); - public UpdateFieldArray ModHealingDonePercent = new(7, 556, 578); - public UpdateFieldArray WeaponDmgMultipliers = new(3, 585, 586); - public UpdateFieldArray WeaponAtkSpeedMultipliers = new(3, 585, 589); - public UpdateFieldArray BuybackPrice = new(12, 592, 593); - public UpdateFieldArray BuybackTimestamp = new(12, 592, 605); - public UpdateFieldArray CombatRatings = new(32, 617, 618); - public UpdateFieldArray PvpInfo = new(6, 650, 651); - public UpdateFieldArray NoReagentCostMask = new(4, 657, 658); - public UpdateFieldArray ProfessionSkillLine = new(2, 662, 663); - public UpdateFieldArray BagSlotFlags = new(4, 665, 666); - public UpdateFieldArray BankBagSlotFlags = new(7, 670, 671); - public UpdateFieldArray QuestCompleted = new(875, 678, 679); + public DynamicUpdateField ResearchSites = new(0, 7); + public DynamicUpdateField ResearchSiteProgress = new(0, 8); + public DynamicUpdateField DailyQuestsCompleted = new(0, 9); + public DynamicUpdateField AvailableQuestLineXQuestIDs = new(0, 10); + public DynamicUpdateField Heirlooms = new(0, 11); + public DynamicUpdateField HeirloomFlags = new(0, 12); + public DynamicUpdateField Toys = new(0, 13); + public DynamicUpdateField ToyFlags = new(0, 14); + public DynamicUpdateField Transmog = new(0, 15); + public DynamicUpdateField ConditionalTransmog = new(0, 16); + public DynamicUpdateField SelfResSpells = new(0, 17); + public DynamicUpdateField RuneforgePowers = new(0, 18); + public DynamicUpdateField TransmogIllusions = new(0, 19); + public DynamicUpdateField SpellPctModByLabel = new(0, 21); + public DynamicUpdateField SpellFlatModByLabel = new(0, 22); + public DynamicUpdateField MawPowers = new(0, 23); + public DynamicUpdateField MultiFloorExploration = new(0, 24); + public DynamicUpdateField RecipeProgression = new(0, 25); + public DynamicUpdateField ReplayedQuests = new(0, 26); + public DynamicUpdateField DisabledSpells = new(0, 27); + public DynamicUpdateField PvpInfo = new(0, 6); + public DynamicUpdateField CharacterRestrictions = new(0, 20); + public DynamicUpdateField TraitConfigs = new(0, 28); + public DynamicUpdateField CraftingOrders = new(0, 29); + public UpdateField FarsightObject = new(0, 32); + public UpdateField SummonedBattlePetGUID = new(0, 33); + public UpdateField Coinage = new(34, 35); + public UpdateField XP = new(34, 36); + public UpdateField NextLevelXP = new(34, 37); + public UpdateField TrialXP = new(34, 38); + public UpdateField Skill = new(34, 39); + public UpdateField CharacterPoints = new(34, 40); + public UpdateField MaxTalentTiers = new(34, 41); + public UpdateField TrackCreatureMask = new(34, 42); + public UpdateField MainhandExpertise = new(34, 43); + public UpdateField OffhandExpertise = new(34, 44); + public UpdateField RangedExpertise = new(34, 45); + public UpdateField CombatRatingExpertise = new(34, 46); + public UpdateField BlockPercentage = new(34, 47); + public UpdateField DodgePercentage = new(34, 48); + public UpdateField DodgePercentageFromAttribute = new(34, 49); + public UpdateField ParryPercentage = new(34, 50); + public UpdateField ParryPercentageFromAttribute = new(34, 51); + public UpdateField CritPercentage = new(34, 52); + public UpdateField RangedCritPercentage = new(34, 53); + public UpdateField OffhandCritPercentage = new(34, 54); + public UpdateField SpellCritPercentage = new(34, 55); + public UpdateField ShieldBlock = new(34, 56); + public UpdateField ShieldBlockCritPercentage = new(34, 57); + public UpdateField Mastery = new(34, 58); + public UpdateField Speed = new(34, 59); + public UpdateField Avoidance = new(34, 60); + public UpdateField Sturdiness = new(34, 61); + public UpdateField Versatility = new(34, 62); + public UpdateField VersatilityBonus = new(34, 63); + public UpdateField PvpPowerDamage = new(34, 64); + public UpdateField PvpPowerHealing = new(34, 65); + public UpdateField ModHealingDonePos = new(66, 67); + public UpdateField ModHealingPercent = new(66, 68); + public UpdateField ModPeriodicHealingDonePercent = new(66, 69); + public UpdateField ModSpellPowerPercent = new(66, 70); + public UpdateField ModResiliencePercent = new(66, 71); + public UpdateField OverrideSpellPowerByAPPercent = new(66, 72); + public UpdateField OverrideAPBySpellPowerPercent = new(66, 73); + public UpdateField ModTargetResistance = new(66, 74); + public UpdateField ModTargetPhysicalResistance = new(66, 75); + public UpdateField LocalFlags = new(66, 76); + public UpdateField GrantableLevels = new(66, 77); + public UpdateField MultiActionBars = new(66, 78); + public UpdateField LifetimeMaxRank = new(66, 79); + public UpdateField NumRespecs = new(66, 80); + public UpdateField PvpMedals = new(66, 81); + public UpdateField TodayHonorableKills = new(66, 82); + public UpdateField YesterdayHonorableKills = new(66, 83); + public UpdateField LifetimeHonorableKills = new(66, 84); + public UpdateField WatchedFactionIndex = new(66, 85); + public UpdateField MaxLevel = new(66, 86); + public UpdateField ScalingPlayerLevelDelta = new(66, 87); + public UpdateField MaxCreatureScalingLevel = new(66, 88); + public UpdateField PetSpellPower = new(66, 89); + public UpdateField UiHitModifier = new(66, 90); + public UpdateField UiSpellHitModifier = new(66, 91); + public UpdateField HomeRealmTimeOffset = new(66, 92); + public UpdateField ModPetHaste = new(66, 93); + public UpdateField JailersTowerLevelMax = new(66, 94); + public UpdateField JailersTowerLevel = new(66, 95); + public UpdateField LocalRegenFlags = new(66, 96); + public UpdateField AuraVision = new(66, 97); + public UpdateField NumBackpackSlots = new(98, 99); + public UpdateField OverrideSpellsID = new(98, 100); + public UpdateField LootSpecID = new(98, 101); + public UpdateField OverrideZonePVPType = new(98, 102); + public UpdateField BnetAccount = new(98, 103); + public UpdateField GuildClubMemberID = new(98, 104); + public UpdateField Honor = new(98, 105); + public UpdateField HonorNextLevel = new(98, 106); + public UpdateField NumBankSlots = new(98, 107); + public UpdateField Field_1410 = new(98, 109); + public OptionalUpdateField QuestSession = new(98, 108); + public UpdateField UiChromieTimeExpansionID = new(98, 110); + public UpdateField TransportServerTime = new(98, 111); + public UpdateField WeeklyRewardsPeriodSinceOrigin = new(98, 112); // week count since Cfg_RegionsEntry::ChallengeOrigin + public UpdateField DEBUGSoulbindConduitRank = new(98, 113); + public UpdateField DungeonScore = new(98, 114); + public UpdateField ActiveCombatTraitConfigID = new(98, 115); + public UpdateFieldArray InvSlots = new(218, 116, 117); + public UpdateFieldArray ExploredZones = new(240, 335, 336); + public UpdateFieldArray RestInfo = new(2, 576, 577); + public UpdateFieldArray ModDamageDonePos = new(7, 579, 580); + public UpdateFieldArray ModDamageDoneNeg = new(7, 579, 587); + public UpdateFieldArray ModDamageDonePercent = new(7, 579, 594); + public UpdateFieldArray ModHealingDonePercent = new(7, 579, 601); + public UpdateFieldArray WeaponDmgMultipliers = new(3, 608, 609); + public UpdateFieldArray WeaponAtkSpeedMultipliers = new(3, 608, 612); + public UpdateFieldArray BuybackPrice = new(12, 615, 616); + public UpdateFieldArray BuybackTimestamp = new(12, 615, 628); + public UpdateFieldArray CombatRatings = new(32, 640, 641); + public UpdateFieldArray NoReagentCostMask = new(4, 673, 674); + public UpdateFieldArray ProfessionSkillLine = new(2, 678, 679); + public UpdateFieldArray BagSlotFlags = new(5, 681, 682); + public UpdateFieldArray BankBagSlotFlags = new(7, 687, 688); + public UpdateFieldArray QuestCompleted = new(875, 695, 696); - public ActivePlayerData() : base(0, TypeId.ActivePlayer, 1554) + public ActivePlayerData() : base(0, TypeId.ActivePlayer, 1571) { ExploredZonesSize = ExploredZones.GetSize(); ExploredZonesBits = sizeof(ulong) * 8; @@ -3645,7 +4306,7 @@ namespace Game.Entities public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Player owner, Player receiver) { - for (int i = 0; i < 199; ++i) + for (int i = 0; i < 218; ++i) { data.WritePackedGuid(InvSlots[i]); } @@ -3721,7 +4382,7 @@ namespace Game.Entities for (int i = 0; i < 12; ++i) { data.WriteUInt32(BuybackPrice[i]); - data.WriteInt64(BuybackTimestamp[i]); + data.WriteUInt64(BuybackTimestamp[i]); } data.WriteUInt16(TodayHonorableKills); data.WriteUInt16(YesterdayHonorableKills); @@ -3731,6 +4392,7 @@ namespace Game.Entities { data.WriteUInt32(CombatRatings[i]); } + data.WriteInt32(PvpInfo.Size()); data.WriteInt32(MaxLevel); data.WriteInt32(ScalingPlayerLevelDelta); data.WriteInt32(MaxCreatureScalingLevel); @@ -3757,7 +4419,7 @@ namespace Game.Entities data.WriteUInt32(OverrideZonePVPType); data.WritePackedGuid(BnetAccount); data.WriteUInt64(GuildClubMemberID); - for (int i = 0; i < 4; ++i) + for (int i = 0; i < 5; ++i) { data.WriteUInt32(BagSlotFlags[i]); } @@ -3805,6 +4467,9 @@ namespace Game.Entities data.WriteInt32(TransportServerTime); data.WriteUInt32(WeeklyRewardsPeriodSinceOrigin); data.WriteInt16(DEBUGSoulbindConduitRank); + data.WriteInt32(TraitConfigs.Size()); + data.WriteUInt32(ActiveCombatTraitConfigID); + data.WriteInt32(CraftingOrders.Size()); for (int i = 0; i < KnownTitles.Size(); ++i) { data.WriteUInt64(KnownTitles[i]); @@ -3889,10 +4554,6 @@ namespace Game.Entities { data.WriteInt32(DisabledSpells[i]); } - for (int i = 0; i < 6; ++i) - { - PvpInfo[i].WriteCreate(data, owner, receiver); - } data.FlushBits(); data.WriteBit(BackpackAutoSortDisabled); data.WriteBit(BankAutoSortDisabled); @@ -3905,10 +4566,22 @@ namespace Game.Entities QuestSession.GetValue().WriteCreate(data, owner, receiver); } DungeonScore._value.Write(data); + for (int i = 0; i < PvpInfo.Size(); ++i) + { + PvpInfo[i].WriteCreate(data, owner, receiver); + } for (int i = 0; i < CharacterRestrictions.Size(); ++i) { CharacterRestrictions[i].WriteCreate(data, owner, receiver); } + for (int i = 0; i < TraitConfigs.Size(); ++i) + { + TraitConfigs[i].WriteCreate(data, owner, receiver); + } + for (int i = 0; i < CraftingOrders.Size(); ++i) + { + CraftingOrders[i].WriteCreate(data, owner, receiver); + } data.FlushBits(); } @@ -3921,9 +4594,8 @@ namespace Game.Entities { for (uint i = 0; i < 1; ++i) data.WriteUInt32(changesMask.GetBlocksMask(i)); - - data.WriteBits(changesMask.GetBlocksMask(1), 17); - for (uint i = 0; i < 49; ++i) + data.WriteBits(changesMask.GetBlocksMask(1), 18); + for (uint i = 0; i < 50; ++i) if (changesMask.GetBlock(i) != 0) data.WriteBits(changesMask.GetBlock(i), 32); @@ -3953,111 +4625,118 @@ namespace Game.Entities WriteCompleteDynamicFieldUpdateMask(KnownTitles.Size(), data); } if (changesMask[6]) + { + if (!ignoreNestedChangesMask) + PvpInfo.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(PvpInfo.Size(), data); + } + if (changesMask[7]) { if (!ignoreNestedChangesMask) ResearchSites.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ResearchSites.Size(), data); } - if (changesMask[7]) + if (changesMask[8]) { if (!ignoreNestedChangesMask) ResearchSiteProgress.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ResearchSiteProgress.Size(), data); } - if (changesMask[8]) + if (changesMask[9]) { if (!ignoreNestedChangesMask) DailyQuestsCompleted.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DailyQuestsCompleted.Size(), data); } - if (changesMask[9]) + if (changesMask[10]) { if (!ignoreNestedChangesMask) AvailableQuestLineXQuestIDs.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(AvailableQuestLineXQuestIDs.Size(), data); } - if (changesMask[10]) + if (changesMask[11]) { if (!ignoreNestedChangesMask) Heirlooms.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Heirlooms.Size(), data); } - if (changesMask[11]) + if (changesMask[12]) { if (!ignoreNestedChangesMask) HeirloomFlags.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(HeirloomFlags.Size(), data); } - if (changesMask[12]) + if (changesMask[13]) { if (!ignoreNestedChangesMask) Toys.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Toys.Size(), data); } - if (changesMask[13]) + if (changesMask[14]) { if (!ignoreNestedChangesMask) ToyFlags.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ToyFlags.Size(), data); } - if (changesMask[14]) + if (changesMask[15]) { if (!ignoreNestedChangesMask) Transmog.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(Transmog.Size(), data); } - if (changesMask[15]) + if (changesMask[16]) { if (!ignoreNestedChangesMask) ConditionalTransmog.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ConditionalTransmog.Size(), data); } - if (changesMask[16]) + if (changesMask[17]) { if (!ignoreNestedChangesMask) SelfResSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SelfResSpells.Size(), data); } - if (changesMask[17]) + if (changesMask[18]) { if (!ignoreNestedChangesMask) RuneforgePowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RuneforgePowers.Size(), data); } - if (changesMask[18]) + if (changesMask[19]) { if (!ignoreNestedChangesMask) TransmogIllusions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(TransmogIllusions.Size(), data); } - if (changesMask[19]) + if (changesMask[20]) { if (!ignoreNestedChangesMask) CharacterRestrictions.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(CharacterRestrictions.Size(), data); } - if (changesMask[20]) + if (changesMask[21]) { if (!ignoreNestedChangesMask) SpellPctModByLabel.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(SpellPctModByLabel.Size(), data); } - if (changesMask[21]) + if (changesMask[22]) { if (!ignoreNestedChangesMask) SpellFlatModByLabel.WriteUpdateMask(data); @@ -4065,11 +4744,11 @@ namespace Game.Entities WriteCompleteDynamicFieldUpdateMask(SpellFlatModByLabel.Size(), data); } } - if (changesMask[27]) + if (changesMask[30]) { for (int i = 0; i < 1; ++i) { - if (changesMask[28 + i]) + if (changesMask[31 + i]) { if (!ignoreNestedChangesMask) Research[i].WriteUpdateMask(data); @@ -4088,41 +4767,55 @@ namespace Game.Entities data.FlushBits(); if (changesMask[0]) { - if (changesMask[22]) + if (changesMask[23]) { if (!ignoreNestedChangesMask) MawPowers.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MawPowers.Size(), data); } - if (changesMask[23]) + if (changesMask[24]) { if (!ignoreNestedChangesMask) MultiFloorExploration.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(MultiFloorExploration.Size(), data); } - if (changesMask[24]) + if (changesMask[25]) { if (!ignoreNestedChangesMask) RecipeProgression.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(RecipeProgression.Size(), data); } - if (changesMask[25]) + if (changesMask[26]) { if (!ignoreNestedChangesMask) ReplayedQuests.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(ReplayedQuests.Size(), data); } - if (changesMask[26]) + if (changesMask[27]) { if (!ignoreNestedChangesMask) DisabledSpells.WriteUpdateMask(data); else WriteCompleteDynamicFieldUpdateMask(DisabledSpells.Size(), data); } + if (changesMask[28]) + { + if (!ignoreNestedChangesMask) + TraitConfigs.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(TraitConfigs.Size(), data); + } + if (changesMask[29]) + { + if (!ignoreNestedChangesMask) + CraftingOrders.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(CraftingOrders.Size(), data); + } } data.FlushBits(); if (changesMask[0]) @@ -4137,7 +4830,7 @@ namespace Game.Entities } } } - if (changesMask[6]) + if (changesMask[7]) { for (int i = 0; i < ResearchSites.Size(); ++i) { @@ -4147,7 +4840,7 @@ namespace Game.Entities } } } - if (changesMask[7]) + if (changesMask[8]) { for (int i = 0; i < ResearchSiteProgress.Size(); ++i) { @@ -4157,7 +4850,7 @@ namespace Game.Entities } } } - if (changesMask[8]) + if (changesMask[9]) { for (int i = 0; i < DailyQuestsCompleted.Size(); ++i) { @@ -4167,7 +4860,7 @@ namespace Game.Entities } } } - if (changesMask[9]) + if (changesMask[10]) { for (int i = 0; i < AvailableQuestLineXQuestIDs.Size(); ++i) { @@ -4177,7 +4870,7 @@ namespace Game.Entities } } } - if (changesMask[10]) + if (changesMask[11]) { for (int i = 0; i < Heirlooms.Size(); ++i) { @@ -4187,7 +4880,7 @@ namespace Game.Entities } } } - if (changesMask[11]) + if (changesMask[12]) { for (int i = 0; i < HeirloomFlags.Size(); ++i) { @@ -4197,7 +4890,7 @@ namespace Game.Entities } } } - if (changesMask[12]) + if (changesMask[13]) { for (int i = 0; i < Toys.Size(); ++i) { @@ -4207,7 +4900,7 @@ namespace Game.Entities } } } - if (changesMask[13]) + if (changesMask[14]) { for (int i = 0; i < ToyFlags.Size(); ++i) { @@ -4217,7 +4910,7 @@ namespace Game.Entities } } } - if (changesMask[14]) + if (changesMask[15]) { for (int i = 0; i < Transmog.Size(); ++i) { @@ -4227,7 +4920,7 @@ namespace Game.Entities } } } - if (changesMask[15]) + if (changesMask[16]) { for (int i = 0; i < ConditionalTransmog.Size(); ++i) { @@ -4237,7 +4930,7 @@ namespace Game.Entities } } } - if (changesMask[16]) + if (changesMask[17]) { for (int i = 0; i < SelfResSpells.Size(); ++i) { @@ -4247,7 +4940,7 @@ namespace Game.Entities } } } - if (changesMask[17]) + if (changesMask[18]) { for (int i = 0; i < RuneforgePowers.Size(); ++i) { @@ -4257,7 +4950,7 @@ namespace Game.Entities } } } - if (changesMask[18]) + if (changesMask[19]) { for (int i = 0; i < TransmogIllusions.Size(); ++i) { @@ -4267,7 +4960,7 @@ namespace Game.Entities } } } - if (changesMask[20]) + if (changesMask[21]) { for (int i = 0; i < SpellPctModByLabel.Size(); ++i) { @@ -4277,7 +4970,7 @@ namespace Game.Entities } } } - if (changesMask[21]) + if (changesMask[22]) { for (int i = 0; i < SpellFlatModByLabel.Size(); ++i) { @@ -4287,7 +4980,7 @@ namespace Game.Entities } } } - if (changesMask[22]) + if (changesMask[23]) { for (int i = 0; i < MawPowers.Size(); ++i) { @@ -4297,7 +4990,7 @@ namespace Game.Entities } } } - if (changesMask[23]) + if (changesMask[24]) { for (int i = 0; i < MultiFloorExploration.Size(); ++i) { @@ -4307,7 +5000,7 @@ namespace Game.Entities } } } - if (changesMask[24]) + if (changesMask[25]) { for (int i = 0; i < RecipeProgression.Size(); ++i) { @@ -4317,7 +5010,7 @@ namespace Game.Entities } } } - if (changesMask[25]) + if (changesMask[26]) { for (int i = 0; i < ReplayedQuests.Size(); ++i) { @@ -4327,7 +5020,7 @@ namespace Game.Entities } } } - if (changesMask[26]) + if (changesMask[27]) { for (int i = 0; i < DisabledSpells.Size(); ++i) { @@ -4337,7 +5030,17 @@ namespace Game.Entities } } } - if (changesMask[19]) + if (changesMask[6]) + { + for (int i = 0; i < PvpInfo.Size(); ++i) + { + if (PvpInfo.HasChanged(i) || ignoreNestedChangesMask) + { + PvpInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } + if (changesMask[20]) { for (int i = 0; i < CharacterRestrictions.Size(); ++i) { @@ -4347,493 +5050,507 @@ namespace Game.Entities } } } + if (changesMask[28]) + { + for (int i = 0; i < TraitConfigs.Size(); ++i) + { + if (TraitConfigs.HasChanged(i) || ignoreNestedChangesMask) + { + TraitConfigs[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } + } if (changesMask[29]) { - data.WritePackedGuid(FarsightObject); - } - if (changesMask[30]) - { - data.WritePackedGuid(SummonedBattlePetGUID); - } - if (changesMask[31]) - { - data.WriteUInt64(Coinage); + for (int i = 0; i < CraftingOrders.Size(); ++i) + { + if (CraftingOrders.HasChanged(i) || ignoreNestedChangesMask) + { + CraftingOrders[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + } } if (changesMask[32]) { - data.WriteUInt32(XP); + data.WritePackedGuid(FarsightObject); } if (changesMask[33]) { - data.WriteUInt32(NextLevelXP); + data.WritePackedGuid(SummonedBattlePetGUID); } } if (changesMask[34]) { if (changesMask[35]) { - data.WriteInt32(TrialXP); + data.WriteUInt64(Coinage); } if (changesMask[36]) { - ((SkillInfo)Skill).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data.WriteUInt32(XP); } if (changesMask[37]) { - data.WriteUInt32(CharacterPoints); + data.WriteUInt32(NextLevelXP); } if (changesMask[38]) { - data.WriteUInt32(MaxTalentTiers); + data.WriteInt32(TrialXP); } if (changesMask[39]) { - data.WriteUInt32(TrackCreatureMask); + Skill.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (changesMask[40]) { - data.WriteFloat(MainhandExpertise); + data.WriteUInt32(CharacterPoints); } if (changesMask[41]) { - data.WriteFloat(OffhandExpertise); + data.WriteUInt32(MaxTalentTiers); } if (changesMask[42]) { - data.WriteFloat(RangedExpertise); + data.WriteUInt32(TrackCreatureMask); } if (changesMask[43]) { - data.WriteFloat(CombatRatingExpertise); + data.WriteFloat(MainhandExpertise); } if (changesMask[44]) { - data.WriteFloat(BlockPercentage); + data.WriteFloat(OffhandExpertise); } if (changesMask[45]) { - data.WriteFloat(DodgePercentage); + data.WriteFloat(RangedExpertise); } if (changesMask[46]) { - data.WriteFloat(DodgePercentageFromAttribute); + data.WriteFloat(CombatRatingExpertise); } if (changesMask[47]) { - data.WriteFloat(ParryPercentage); + data.WriteFloat(BlockPercentage); } if (changesMask[48]) { - data.WriteFloat(ParryPercentageFromAttribute); + data.WriteFloat(DodgePercentage); } if (changesMask[49]) { - data.WriteFloat(CritPercentage); + data.WriteFloat(DodgePercentageFromAttribute); } if (changesMask[50]) { - data.WriteFloat(RangedCritPercentage); + data.WriteFloat(ParryPercentage); } if (changesMask[51]) { - data.WriteFloat(OffhandCritPercentage); + data.WriteFloat(ParryPercentageFromAttribute); } if (changesMask[52]) { - data.WriteFloat(SpellCritPercentage); + data.WriteFloat(CritPercentage); } if (changesMask[53]) { - data.WriteUInt32(ShieldBlock); + data.WriteFloat(RangedCritPercentage); } if (changesMask[54]) { - data.WriteFloat(ShieldBlockCritPercentage); + data.WriteFloat(OffhandCritPercentage); } if (changesMask[55]) { - data.WriteFloat(Mastery); + data.WriteFloat(SpellCritPercentage); } if (changesMask[56]) { - data.WriteFloat(Speed); + data.WriteUInt32(ShieldBlock); } if (changesMask[57]) { - data.WriteFloat(Avoidance); + data.WriteFloat(ShieldBlockCritPercentage); } if (changesMask[58]) { - data.WriteFloat(Sturdiness); + data.WriteFloat(Mastery); } if (changesMask[59]) { - data.WriteInt32(Versatility); + data.WriteFloat(Speed); } if (changesMask[60]) { - data.WriteFloat(VersatilityBonus); + data.WriteFloat(Avoidance); } if (changesMask[61]) { - data.WriteFloat(PvpPowerDamage); + data.WriteFloat(Sturdiness); } if (changesMask[62]) { - data.WriteFloat(PvpPowerHealing); + data.WriteInt32(Versatility); } if (changesMask[63]) { - data.WriteInt32(ModHealingDonePos); + data.WriteFloat(VersatilityBonus); } if (changesMask[64]) { - data.WriteFloat(ModHealingPercent); + data.WriteFloat(PvpPowerDamage); } if (changesMask[65]) { - data.WriteFloat(ModPeriodicHealingDonePercent); + data.WriteFloat(PvpPowerHealing); } } if (changesMask[66]) { if (changesMask[67]) { - data.WriteFloat(ModSpellPowerPercent); + data.WriteInt32(ModHealingDonePos); } if (changesMask[68]) { - data.WriteFloat(ModResiliencePercent); + data.WriteFloat(ModHealingPercent); } if (changesMask[69]) { - data.WriteFloat(OverrideSpellPowerByAPPercent); + data.WriteFloat(ModPeriodicHealingDonePercent); } if (changesMask[70]) { - data.WriteFloat(OverrideAPBySpellPowerPercent); + data.WriteFloat(ModSpellPowerPercent); } if (changesMask[71]) { - data.WriteInt32(ModTargetResistance); + data.WriteFloat(ModResiliencePercent); } if (changesMask[72]) { - data.WriteInt32(ModTargetPhysicalResistance); + data.WriteFloat(OverrideSpellPowerByAPPercent); } if (changesMask[73]) { - data.WriteUInt32(LocalFlags); + data.WriteFloat(OverrideAPBySpellPowerPercent); } if (changesMask[74]) { - data.WriteUInt8(GrantableLevels); + data.WriteInt32(ModTargetResistance); } if (changesMask[75]) { - data.WriteUInt8(MultiActionBars); + data.WriteInt32(ModTargetPhysicalResistance); } if (changesMask[76]) { - data.WriteUInt8(LifetimeMaxRank); + data.WriteUInt32(LocalFlags); } if (changesMask[77]) { - data.WriteUInt8(NumRespecs); + data.WriteUInt8(GrantableLevels); } if (changesMask[78]) { - data.WriteUInt32(PvpMedals); + data.WriteUInt8(MultiActionBars); } if (changesMask[79]) { - data.WriteUInt16(TodayHonorableKills); + data.WriteUInt8(LifetimeMaxRank); } if (changesMask[80]) { - data.WriteUInt16(YesterdayHonorableKills); + data.WriteUInt8(NumRespecs); } if (changesMask[81]) { - data.WriteUInt32(LifetimeHonorableKills); + data.WriteUInt32(PvpMedals); } if (changesMask[82]) { - data.WriteUInt32(WatchedFactionIndex); + data.WriteUInt16(TodayHonorableKills); } if (changesMask[83]) { - data.WriteInt32(MaxLevel); + data.WriteUInt16(YesterdayHonorableKills); } if (changesMask[84]) { - data.WriteInt32(ScalingPlayerLevelDelta); + data.WriteUInt32(LifetimeHonorableKills); } if (changesMask[85]) { - data.WriteInt32(MaxCreatureScalingLevel); + data.WriteUInt32(WatchedFactionIndex); } if (changesMask[86]) { - data.WriteUInt32(PetSpellPower); + data.WriteInt32(MaxLevel); } if (changesMask[87]) { - data.WriteFloat(UiHitModifier); + data.WriteInt32(ScalingPlayerLevelDelta); } if (changesMask[88]) { - data.WriteFloat(UiSpellHitModifier); + data.WriteInt32(MaxCreatureScalingLevel); } if (changesMask[89]) { - data.WriteInt32(HomeRealmTimeOffset); + data.WriteUInt32(PetSpellPower); } if (changesMask[90]) { - data.WriteFloat(ModPetHaste); + data.WriteFloat(UiHitModifier); } if (changesMask[91]) { - data.WriteInt8(JailersTowerLevelMax); + data.WriteFloat(UiSpellHitModifier); } if (changesMask[92]) { - data.WriteInt8(JailersTowerLevel); + data.WriteInt32(HomeRealmTimeOffset); } if (changesMask[93]) { - data.WriteUInt8(LocalRegenFlags); + data.WriteFloat(ModPetHaste); } if (changesMask[94]) { - data.WriteUInt8(AuraVision); + data.WriteInt8(JailersTowerLevelMax); } if (changesMask[95]) { - data.WriteUInt8(NumBackpackSlots); + data.WriteInt8(JailersTowerLevel); } if (changesMask[96]) { - data.WriteUInt32(OverrideSpellsID); + data.WriteUInt8(LocalRegenFlags); } if (changesMask[97]) { - data.WriteUInt16(LootSpecID); + data.WriteUInt8(AuraVision); } } if (changesMask[98]) { if (changesMask[99]) { - data.WriteUInt32(OverrideZonePVPType); + data.WriteUInt8(NumBackpackSlots); } if (changesMask[100]) { - data.WritePackedGuid(BnetAccount); + data.WriteUInt32(OverrideSpellsID); } if (changesMask[101]) { - data.WriteUInt64(GuildClubMemberID); + data.WriteUInt16(LootSpecID); } if (changesMask[102]) { - data.WriteUInt32(Honor); + data.WriteUInt32(OverrideZonePVPType); } if (changesMask[103]) { - data.WriteUInt32(HonorNextLevel); + data.WritePackedGuid(BnetAccount); } if (changesMask[104]) { - data.WriteUInt8(NumBankSlots); + data.WriteUInt64(GuildClubMemberID); + } + if (changesMask[105]) + { + data.WriteUInt32(Honor); + } + if (changesMask[106]) + { + data.WriteUInt32(HonorNextLevel); } if (changesMask[107]) { - data.WriteInt32(UiChromieTimeExpansionID); - } - if (changesMask[108]) - { - data.WriteInt32(TransportServerTime); - } - if (changesMask[109]) - { - data.WriteUInt32(WeeklyRewardsPeriodSinceOrigin); + data.WriteUInt8(NumBankSlots); } if (changesMask[110]) + { + data.WriteInt32(UiChromieTimeExpansionID); + } + if (changesMask[111]) + { + data.WriteInt32(TransportServerTime); + } + if (changesMask[112]) + { + data.WriteUInt32(WeeklyRewardsPeriodSinceOrigin); + } + if (changesMask[113]) { data.WriteInt16(DEBUGSoulbindConduitRank); } + if (changesMask[115]) + { + data.WriteUInt32(ActiveCombatTraitConfigID); + } } if (changesMask[98]) { data.WriteBits(QuestSession.HasValue(), 1); - if (changesMask[106]) + if (changesMask[109]) { - ((ActivePlayerUnk901)Field_1410).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + Field_1410.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[105]) + if (changesMask[108]) { if (QuestSession.HasValue()) { QuestSession.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } - if (changesMask[111]) + if (changesMask[114]) { - DungeonScore._value.Write(data); + DungeonScore.GetValue().Write(data); } } - if (changesMask[112]) + if (changesMask[116]) { - for (int i = 0; i < 199; ++i) + for (int i = 0; i < 218; ++i) { - if (changesMask[113 + i]) + if (changesMask[117 + i]) { data.WritePackedGuid(InvSlots[i]); } } } - if (changesMask[312]) + if (changesMask[335]) { for (int i = 0; i < 240; ++i) { - if (changesMask[313 + i]) + if (changesMask[336 + i]) { data.WriteUInt64(ExploredZones[i]); } } } - if (changesMask[553]) + if (changesMask[576]) { for (int i = 0; i < 2; ++i) { - if (changesMask[554 + i]) + if (changesMask[577 + i]) { RestInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } - if (changesMask[556]) + if (changesMask[579]) { for (int i = 0; i < 7; ++i) { - if (changesMask[557 + i]) + if (changesMask[580 + i]) { data.WriteInt32(ModDamageDonePos[i]); } - if (changesMask[564 + i]) + if (changesMask[587 + i]) { data.WriteInt32(ModDamageDoneNeg[i]); } - if (changesMask[571 + i]) + if (changesMask[594 + i]) { data.WriteFloat(ModDamageDonePercent[i]); } - if (changesMask[578 + i]) + if (changesMask[601 + i]) { data.WriteFloat(ModHealingDonePercent[i]); } } } - if (changesMask[585]) + if (changesMask[608]) { for (int i = 0; i < 3; ++i) { - if (changesMask[586 + i]) + if (changesMask[609 + i]) { data.WriteFloat(WeaponDmgMultipliers[i]); } - if (changesMask[589 + i]) + if (changesMask[612 + i]) { data.WriteFloat(WeaponAtkSpeedMultipliers[i]); } } } - if (changesMask[592]) + if (changesMask[615]) { for (int i = 0; i < 12; ++i) { - if (changesMask[593 + i]) + if (changesMask[616 + i]) { data.WriteUInt32(BuybackPrice[i]); } - if (changesMask[605 + i]) + if (changesMask[628 + i]) { - data.WriteInt64(BuybackTimestamp[i]); + data.WriteUInt64(BuybackTimestamp[i]); } } } - if (changesMask[617]) + if (changesMask[640]) { for (int i = 0; i < 32; ++i) { - if (changesMask[618 + i]) + if (changesMask[641 + i]) { data.WriteUInt32(CombatRatings[i]); } } } - if (changesMask[657]) + if (changesMask[673]) { for (int i = 0; i < 4; ++i) { - if (changesMask[658 + i]) + if (changesMask[674 + i]) { data.WriteUInt32(NoReagentCostMask[i]); } } } - if (changesMask[662]) + if (changesMask[678]) { for (int i = 0; i < 2; ++i) { - if (changesMask[663 + i]) + if (changesMask[679 + i]) { data.WriteUInt32(ProfessionSkillLine[i]); } } } - if (changesMask[665]) + if (changesMask[681]) { - for (int i = 0; i < 4; ++i) + for (int i = 0; i < 5; ++i) { - if (changesMask[666 + i]) + if (changesMask[682 + i]) { data.WriteUInt32(BagSlotFlags[i]); } } } - if (changesMask[670]) + if (changesMask[687]) { for (int i = 0; i < 7; ++i) { - if (changesMask[671 + i]) + if (changesMask[688 + i]) { data.WriteUInt32(BankBagSlotFlags[i]); } } } - if (changesMask[678]) + if (changesMask[695]) { for (int i = 0; i < 875; ++i) { - if (changesMask[679 + i]) + if (changesMask[696 + i]) { data.WriteUInt64(QuestCompleted[i]); } } } - if (changesMask[650]) - { - for (int i = 0; i < 6; ++i) - { - if (changesMask[651 + i]) - { - PvpInfo[i].WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); - } - } - } data.FlushBits(); } @@ -4865,7 +5582,10 @@ namespace Game.Entities ClearChangesMask(RecipeProgression); ClearChangesMask(ReplayedQuests); ClearChangesMask(DisabledSpells); + ClearChangesMask(PvpInfo); ClearChangesMask(CharacterRestrictions); + ClearChangesMask(TraitConfigs); + ClearChangesMask(CraftingOrders); ClearChangesMask(FarsightObject); ClearChangesMask(SummonedBattlePetGUID); ClearChangesMask(Coinage); @@ -4946,6 +5666,7 @@ namespace Game.Entities ClearChangesMask(WeeklyRewardsPeriodSinceOrigin); ClearChangesMask(DEBUGSoulbindConduitRank); ClearChangesMask(DungeonScore); + ClearChangesMask(ActiveCombatTraitConfigID); ClearChangesMask(InvSlots); ClearChangesMask(ExploredZones); ClearChangesMask(RestInfo); @@ -4958,7 +5679,6 @@ namespace Game.Entities ClearChangesMask(BuybackPrice); ClearChangesMask(BuybackTimestamp); ClearChangesMask(CombatRatings); - ClearChangesMask(PvpInfo); ClearChangesMask(NoReagentCostMask); ClearChangesMask(ProfessionSkillLine); ClearChangesMask(BagSlotFlags); @@ -4972,26 +5692,30 @@ namespace Game.Entities { public UpdateField> StateWorldEffectIDs = new(0, 1); public DynamicUpdateField EnableDoodadSets = new(0, 2); - public UpdateField DisplayID = new(0, 3); - public UpdateField SpellVisualID = new(0, 4); - public UpdateField StateSpellVisualID = new(0, 5); - public UpdateField SpawnTrackingStateAnimID = new(0, 6); - public UpdateField SpawnTrackingStateAnimKitID = new(0, 7); - public UpdateField StateWorldEffectsQuestObjectiveID = new(0, 8); - public UpdateField CreatedBy = new(0, 9); - public UpdateField GuildGUID = new(0, 10); - public UpdateField Flags = new(0, 11); - public UpdateField ParentRotation = new(0, 12); - public UpdateField FactionTemplate = new(0, 13); - public UpdateField State = new(0, 14); - public UpdateField TypeID = new(0, 15); - public UpdateField PercentHealth = new(0, 16); - public UpdateField ArtKit = new(0, 17); - public UpdateField CustomParam = new(0, 18); - public UpdateField Level = new(0, 19); - public UpdateField AnimGroupInstance = new(0, 20); + public DynamicUpdateField WorldEffects = new(0, 3); + public UpdateField DisplayID = new(0, 4); + public UpdateField SpellVisualID = new(0, 5); + public UpdateField StateSpellVisualID = new(0, 6); + public UpdateField SpawnTrackingStateAnimID = new(0, 7); + public UpdateField SpawnTrackingStateAnimKitID = new(0, 8); + public UpdateField StateWorldEffectsQuestObjectiveID = new(0, 9); + public UpdateField CreatedBy = new(0, 10); + public UpdateField GuildGUID = new(0, 11); + public UpdateField Flags = new(0, 12); + public UpdateField ParentRotation = new(0, 13); + public UpdateField FactionTemplate = new(0, 14); + public UpdateField State = new(0, 15); + public UpdateField TypeID = new(0, 16); + public UpdateField PercentHealth = new(0, 17); + public UpdateField ArtKit = new(0, 18); + public UpdateField CustomParam = new(0, 19); + public UpdateField Level = new(0, 20); + public UpdateField AnimGroupInstance = new(0, 21); + public UpdateField UiWidgetItemID = new(0, 22); + public UpdateField UiWidgetItemQuality = new(0, 23); + public UpdateField UiWidgetItemUnknown1000 = new(0, 24); - public GameObjectFieldData() : base(0, TypeId.GameObject, 21) { } + public GameObjectFieldData() : base(0, TypeId.GameObject, 25) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, GameObject owner, Player receiver) { @@ -5023,10 +5747,18 @@ namespace Game.Entities data.WriteUInt32(CustomParam); data.WriteUInt32(Level); data.WriteUInt32(AnimGroupInstance); + data.WriteUInt32(UiWidgetItemID); + data.WriteUInt32(UiWidgetItemQuality); + data.WriteUInt32(UiWidgetItemUnknown1000); + data.WriteInt32(WorldEffects.Size()); for (int i = 0; i < EnableDoodadSets.Size(); ++i) { data.WriteInt32(EnableDoodadSets[i]); } + for (int i = 0; i < WorldEffects.Size(); ++i) + { + data.WriteInt32(WorldEffects[i]); + } } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, GameObject owner, Player receiver) @@ -5036,7 +5768,7 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateMask changesMask, bool ignoreNestedChangesMask, GameObject owner, Player receiver) { - data.WriteBits(changesMask.GetBlock(0), 21); + data.WriteBits(changesMask.GetBlock(0), 25); if (changesMask[0]) { @@ -5059,6 +5791,13 @@ namespace Game.Entities else WriteCompleteDynamicFieldUpdateMask(EnableDoodadSets.Size(), data); } + if (changesMask[3]) + { + if (!ignoreNestedChangesMask) + WorldEffects.WriteUpdateMask(data); + else + WriteCompleteDynamicFieldUpdateMask(WorldEffects.Size(), data); + } } data.FlushBits(); if (changesMask[0]) @@ -5075,79 +5814,101 @@ namespace Game.Entities } if (changesMask[3]) { - data.WriteUInt32(DisplayID); + for (int i = 0; i < WorldEffects.Size(); ++i) + { + if (WorldEffects.HasChanged(i) || ignoreNestedChangesMask) + { + data.WriteInt32(WorldEffects[i]); + } + } } if (changesMask[4]) { - data.WriteUInt32(SpellVisualID); + data.WriteUInt32(DisplayID); } if (changesMask[5]) { - data.WriteUInt32(StateSpellVisualID); + data.WriteUInt32(SpellVisualID); } if (changesMask[6]) { - data.WriteUInt32(SpawnTrackingStateAnimID); + data.WriteUInt32(StateSpellVisualID); } if (changesMask[7]) { - data.WriteUInt32(SpawnTrackingStateAnimKitID); + data.WriteUInt32(SpawnTrackingStateAnimID); } if (changesMask[8]) { - data.WriteUInt32(StateWorldEffectsQuestObjectiveID); + data.WriteUInt32(SpawnTrackingStateAnimKitID); } if (changesMask[9]) { - data.WritePackedGuid(CreatedBy); + data.WriteUInt32(StateWorldEffectsQuestObjectiveID); } if (changesMask[10]) { - data.WritePackedGuid(GuildGUID); + data.WritePackedGuid(CreatedBy); } if (changesMask[11]) { - data.WriteUInt32(GetViewerGameObjectFlags(this, owner, receiver)); + data.WritePackedGuid(GuildGUID); } if (changesMask[12]) + { + data.WriteUInt32(GetViewerGameObjectFlags(this, owner, receiver)); + } + if (changesMask[13]) { data.WriteFloat(((Quaternion)ParentRotation).X); data.WriteFloat(((Quaternion)ParentRotation).Y); data.WriteFloat(((Quaternion)ParentRotation).Z); data.WriteFloat(((Quaternion)ParentRotation).W); } - if (changesMask[13]) + if (changesMask[14]) { data.WriteUInt32(FactionTemplate); } - if (changesMask[14]) + if (changesMask[15]) { data.WriteInt8(GetViewerGameObjectState(this, owner, receiver)); } - if (changesMask[15]) + if (changesMask[16]) { data.WriteInt8(TypeID); } - if (changesMask[16]) + if (changesMask[17]) { data.WriteUInt8(PercentHealth); } - if (changesMask[17]) + if (changesMask[18]) { data.WriteUInt32(ArtKit); } - if (changesMask[18]) + if (changesMask[19]) { data.WriteUInt32(CustomParam); } - if (changesMask[19]) + if (changesMask[20]) { data.WriteUInt32(Level); } - if (changesMask[20]) + if (changesMask[21]) { data.WriteUInt32(AnimGroupInstance); } + if (changesMask[22]) + { + data.WriteUInt32(UiWidgetItemID); + } + if (changesMask[23]) + { + data.WriteUInt32(UiWidgetItemQuality); + } + if (changesMask[24]) + { + data.WriteUInt32(UiWidgetItemUnknown1000); + } } } @@ -5155,6 +5916,7 @@ namespace Game.Entities { ClearChangesMask(StateWorldEffectIDs); ClearChangesMask(EnableDoodadSets); + ClearChangesMask(WorldEffects); ClearChangesMask(DisplayID); ClearChangesMask(SpellVisualID); ClearChangesMask(StateSpellVisualID); @@ -5173,6 +5935,9 @@ namespace Game.Entities ClearChangesMask(CustomParam); ClearChangesMask(Level); ClearChangesMask(AnimGroupInstance); + ClearChangesMask(UiWidgetItemID); + ClearChangesMask(UiWidgetItemQuality); + ClearChangesMask(UiWidgetItemUnknown1000); _changesMask.ResetAll(); } @@ -5555,36 +6320,42 @@ namespace Game.Entities { public UpdateField OverrideScaleCurve = new(0, 1); public UpdateField ExtraScaleCurve = new(0, 2); - public UpdateField Caster = new(0, 3); - public UpdateField Duration = new(0, 4); - public UpdateField TimeToTarget = new(0, 5); - public UpdateField TimeToTargetScale = new(0, 6); - public UpdateField TimeToTargetExtraScale = new(0, 7); - public UpdateField SpellID = new(0, 8); - public UpdateField SpellForVisuals = new(0, 9); - public UpdateField SpellVisual = new(0, 10); - public UpdateField BoundsRadius2D = new(0, 11); - public UpdateField DecalPropertiesID = new(0, 12); - public UpdateField CreatingEffectGUID = new(0, 13); - public UpdateField Field_80 = new(0, 14); - public UpdateField Field_84 = new(0, 15); - public UpdateField Field_88 = new(0, 16); - public UpdateField VisualAnim = new(0, 17); + public UpdateField Field_C38 = new(0, 3); + public UpdateField Field_C54 = new(0, 4); + public UpdateField Field_C70 = new(0, 5); + public UpdateField Caster = new(0, 6); + public UpdateField Duration = new(0, 7); + public UpdateField TimeToTarget = new(0, 8); + public UpdateField TimeToTargetScale = new(0, 9); + public UpdateField TimeToTargetExtraScale = new(0, 10); + public UpdateField Field_B0 = new(0, 11); + public UpdateField SpellID = new(0, 12); + public UpdateField SpellForVisuals = new(0, 13); + public UpdateField SpellVisual = new(0, 14); + public UpdateField BoundsRadius2D = new(0, 15); + public UpdateField DecalPropertiesID = new(0, 16); + public UpdateField CreatingEffectGUID = new(0, 17); + public UpdateField Field_80 = new(0, 18); + public UpdateField Field_84 = new(0, 19); + public UpdateField Field_88 = new(0, 20); + public UpdateField Field_F8 = new(0, 21); + public UpdateField VisualAnim = new(0, 22); - public AreaTriggerFieldData() : base(0, TypeId.AreaTrigger, 18) { } + public AreaTriggerFieldData() : base(0, TypeId.AreaTrigger, 23) { } public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) { - ((ScaleCurve)OverrideScaleCurve).WriteCreate(data, owner, receiver); + OverrideScaleCurve.GetValue().WriteCreate(data, owner, receiver); data.WritePackedGuid(Caster); data.WriteUInt32(Duration); data.WriteUInt32(TimeToTarget); data.WriteUInt32(TimeToTargetScale); data.WriteUInt32(TimeToTargetExtraScale); + data.WriteUInt32(Field_B0); data.WriteUInt32(SpellID); data.WriteUInt32(SpellForVisuals); - ((SpellCastVisualField)SpellVisual).WriteCreate(data, owner, receiver); + SpellVisual.GetValue().WriteCreate(data, owner, receiver); data.WriteFloat(BoundsRadius2D); data.WriteUInt32(DecalPropertiesID); @@ -5592,8 +6363,12 @@ namespace Game.Entities data.WriteUInt32(Field_80); data.WriteUInt32(Field_84); data.WritePackedGuid(Field_88); - ((ScaleCurve)ExtraScaleCurve).WriteCreate(data, owner, receiver); - ((VisualAnim)VisualAnim).WriteCreate(data, owner, receiver); + data.WriteVector3(Field_F8); + ExtraScaleCurve.GetValue().WriteCreate(data, owner, receiver); + Field_C38.GetValue().WriteCreate(data, owner, receiver); + Field_C54.GetValue().WriteCreate(data, owner, receiver); + Field_C70.GetValue().WriteCreate(data, owner, receiver); + VisualAnim.GetValue().WriteCreate(data, owner, receiver); } public void WriteUpdate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, AreaTrigger owner, Player receiver) @@ -5603,78 +6378,98 @@ namespace Game.Entities public void WriteUpdate(WorldPacket data, UpdateMask changesMask, bool ignoreNestedChangesMask, AreaTrigger owner, Player receiver) { - data.WriteBits(_changesMask.GetBlock(0), 18); + data.WriteBits(_changesMask.GetBlock(0), 23); data.FlushBits(); if (_changesMask[0]) { if (_changesMask[1]) { - ((ScaleCurve)OverrideScaleCurve).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); - } - if (_changesMask[3]) - { - data.WritePackedGuid(Caster); - } - if (_changesMask[4]) - { - data.WriteUInt32(Duration); - } - if (_changesMask[5]) - { - data.WriteUInt32(TimeToTarget); + OverrideScaleCurve.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } if (_changesMask[6]) { - data.WriteUInt32(TimeToTargetScale); + data.WritePackedGuid(Caster); } if (_changesMask[7]) { - data.WriteUInt32(TimeToTargetExtraScale); + data.WriteUInt32(Duration); } if (_changesMask[8]) { - data.WriteUInt32(SpellID); + data.WriteUInt32(TimeToTarget); } if (_changesMask[9]) { - data.WriteUInt32(SpellForVisuals); + data.WriteUInt32(TimeToTargetScale); } if (_changesMask[10]) { - ((SpellCastVisualField)SpellVisual).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + data.WriteUInt32(TimeToTargetExtraScale); } if (_changesMask[11]) { - data.WriteFloat(BoundsRadius2D); + data.WriteUInt32(Field_B0); } - if (_changesMask[12]) + if (changesMask[12]) { - data.WriteUInt32(DecalPropertiesID); + data.WriteUInt32(SpellID); } if (_changesMask[13]) + { + data.WriteUInt32(SpellForVisuals); + } + if (_changesMask[14]) + { + SpellVisual.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (_changesMask[15]) + { + data.WriteFloat(BoundsRadius2D); + } + if (_changesMask[16]) + { + data.WriteUInt32(DecalPropertiesID); + } + if (_changesMask[17]) { data.WritePackedGuid(CreatingEffectGUID); } - if (changesMask[14]) + if (changesMask[18]) { data.WriteUInt32(Field_80); } - if (changesMask[15]) + if (changesMask[19]) { data.WriteUInt32(Field_84); } - if (changesMask[16]) + if (changesMask[20]) { data.WritePackedGuid(Field_88); } + if (changesMask[21]) + { + data.WriteVector3(Field_F8); + } if (_changesMask[2]) { - ((ScaleCurve)ExtraScaleCurve).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + ExtraScaleCurve.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } - if (changesMask[17]) + if (changesMask[3]) { - ((VisualAnim)VisualAnim).WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + Field_C38.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[4]) + { + Field_C54.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[5]) + { + Field_C70.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); + } + if (changesMask[22]) + { + VisualAnim.GetValue().WriteUpdate(data, ignoreNestedChangesMask, owner, receiver); } } } @@ -5683,11 +6478,15 @@ namespace Game.Entities { ClearChangesMask(OverrideScaleCurve); ClearChangesMask(ExtraScaleCurve); + ClearChangesMask(Field_C38); + ClearChangesMask(Field_C54); + ClearChangesMask(Field_C70); ClearChangesMask(Caster); ClearChangesMask(Duration); ClearChangesMask(TimeToTarget); ClearChangesMask(TimeToTargetScale); ClearChangesMask(TimeToTargetExtraScale); + ClearChangesMask(Field_B0); ClearChangesMask(SpellID); ClearChangesMask(SpellForVisuals); ClearChangesMask(SpellVisual); @@ -5697,6 +6496,7 @@ namespace Game.Entities ClearChangesMask(Field_80); ClearChangesMask(Field_84); ClearChangesMask(Field_88); + ClearChangesMask(Field_F8); ClearChangesMask(VisualAnim); _changesMask.ResetAll(); } @@ -5847,12 +6647,12 @@ namespace Game.Entities public void WriteCreate(WorldPacket data, UpdateFieldFlag fieldVisibilityFlags, Conversation owner, Player receiver) { - data.WriteInt32(((List)Lines).Count); + data.WriteInt32(Lines.GetValue().Count); data.WriteUInt32(GetViewerLastLineEndTime(this, owner, receiver)); data.WriteUInt32(Progress); - for (int i = 0; i < ((List)Lines).Count; ++i) + for (int i = 0; i < Lines.GetValue().Count; ++i) { - ((List)Lines)[i].WriteCreate(data, owner, receiver); + Lines.GetValue()[i].WriteCreate(data, owner, receiver); } data.WriteBit(DontPlayBroadcastTextSounds); data.WriteInt32(Actors.Size()); diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index 7bc6e3de1..f668d413c 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -278,6 +278,7 @@ namespace Game.Entities bool HasFall = HasFallDirection || unit.m_movementInfo.jump.fallTime != 0; bool HasSpline = unit.IsSplineEnabled(); bool HasInertia = unit.m_movementInfo.inertia.HasValue; + bool HasAdvFlying = unit.m_movementInfo.advFlying.HasValue; data.WritePackedGuid(GetGUID()); // MoverGUID @@ -312,11 +313,17 @@ namespace Game.Entities if (HasInertia) { - data.WritePackedGuid(unit.m_movementInfo.inertia.Value.guid); + data.WriteInt32(unit.m_movementInfo.inertia.Value.id); data.WriteXYZ(unit.m_movementInfo.inertia.Value.force); data.WriteUInt32(unit.m_movementInfo.inertia.Value.lifetime); } + if (HasAdvFlying) + { + data.WriteFloat(unit.m_movementInfo.advFlying.Value.forwardVelocity); + data.WriteFloat(unit.m_movementInfo.advFlying.Value.upVelocity); + } + if (HasFall) { data.WriteUInt32(unit.m_movementInfo.jump.fallTime); // Time @@ -352,6 +359,24 @@ namespace Game.Entities data.WriteFloat(1.0f); // MovementForcesModMagnitude } + data.WriteFloat(2.0f); // advFlyingAirFriction + data.WriteFloat(65.0f); // advFlyingMaxVel + data.WriteFloat(1.0f); // advFlyingLiftCoefficient + data.WriteFloat(3.0f); // advFlyingDoubleJumpVelMod + data.WriteFloat(10.0f); // advFlyingGlideStartMinHeight + data.WriteFloat(100.0f); // advFlyingAddImpulseMaxSpeed + data.WriteFloat(90.0f); // advFlyingMinBankingRate + data.WriteFloat(140.0f); // advFlyingMaxBankingRate + data.WriteFloat(180.0f); // advFlyingMinPitchingRateDown + data.WriteFloat(360.0f); // advFlyingMaxPitchingRateDown + data.WriteFloat(90.0f); // advFlyingMinPitchingRateUp + data.WriteFloat(270.0f); // advFlyingMaxPitchingRateUp + data.WriteFloat(30.0f); // advFlyingMinTurnVelocityThreshold + data.WriteFloat(80.0f); // advFlyingMaxTurnVelocityThreshold + data.WriteFloat(2.75f); // advFlyingSurfaceFriction + data.WriteFloat(7.0f); // advFlyingOverMaxDeceleration + data.WriteFloat(0.4f); // advFlyingLaunchSpeedCoefficient + data.WriteBit(HasSpline); data.FlushBits(); @@ -425,6 +450,7 @@ namespace Game.Entities bool hasFaceMovementDir = areaTriggerTemplate != null && areaTriggerTemplate.HasFlag(AreaTriggerFlags.HasFaceMovementDir); bool hasFollowsTerrain = areaTriggerTemplate != null && areaTriggerTemplate.HasFlag(AreaTriggerFlags.HasFollowsTerrain); bool hasUnk1 = areaTriggerTemplate != null && areaTriggerTemplate.HasFlag(AreaTriggerFlags.Unk1); + bool hasUnk2 = false; bool hasTargetRollPitchYaw = areaTriggerTemplate != null && areaTriggerTemplate.HasFlag(AreaTriggerFlags.HasTargetRollPitchYaw); bool hasScaleCurveID = createProperties != null && createProperties.ScaleCurveId != 0; bool hasMorphCurveID = createProperties != null && createProperties.MorphCurveId != 0; @@ -435,6 +461,7 @@ namespace Game.Entities bool hasAreaTriggerPolygon = createProperties != null && shape.IsPolygon(); bool hasAreaTriggerCylinder = shape.IsCylinder(); bool hasDisk = shape.IsDisk(); + bool hasBoundedPlane = shape.IsBoudedPlane(); bool hasAreaTriggerSpline = areaTrigger.HasSplines(); bool hasOrbit = areaTrigger.HasOrbit(); bool hasMovementScript = false; @@ -445,6 +472,7 @@ namespace Game.Entities data.WriteBit(hasFaceMovementDir); data.WriteBit(hasFollowsTerrain); data.WriteBit(hasUnk1); + data.WriteBit(hasUnk2); data.WriteBit(hasTargetRollPitchYaw); data.WriteBit(hasScaleCurveID); data.WriteBit(hasMorphCurveID); @@ -455,6 +483,7 @@ namespace Game.Entities data.WriteBit(hasAreaTriggerPolygon); data.WriteBit(hasAreaTriggerCylinder); data.WriteBit(hasDisk); + data.WriteBit(hasBoundedPlane); data.WriteBit(hasAreaTriggerSpline); data.WriteBit(hasOrbit); data.WriteBit(hasMovementScript); @@ -540,6 +569,17 @@ namespace Game.Entities data.WriteFloat(shape.DiskDatas.LocationZOffsetTarget); } + if (hasBoundedPlane) + { + unsafe + { + data.WriteFloat(shape.BoundedPlaneDatas.Extents[0]); + data.WriteFloat(shape.BoundedPlaneDatas.Extents[1]); + data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[0]); + data.WriteFloat(shape.BoundedPlaneDatas.ExtentsTarget[1]); + } + } + //if (hasMovementScript) // *data << *areaTrigger.GetMovementScript(); // AreaTriggerMovementScriptInfo @@ -3745,6 +3785,7 @@ namespace Game.Entities public Inertia? inertia; public JumpInfo jump; public float stepUpStartElevation { get; set; } + public AdvFlying? advFlying; public MovementInfo() { @@ -3810,7 +3851,7 @@ namespace Game.Entities } public struct Inertia { - public ObjectGuid guid; + public int id; public Position force; public uint lifetime; } @@ -3828,6 +3869,12 @@ namespace Game.Entities public float cosAngle; public float xyspeed; } + // advflying + public struct AdvFlying + { + public float forwardVelocity; + public float upVelocity; + } } public class MovementForce diff --git a/Source/Game/Entities/Player/CollectionManager.cs b/Source/Game/Entities/Player/CollectionManager.cs index 5c934555a..47d3384d6 100644 --- a/Source/Game/Entities/Player/CollectionManager.cs +++ b/Source/Game/Entities/Player/CollectionManager.cs @@ -328,7 +328,7 @@ namespace Game.Entities return; } - List bonusListIDs = item.m_itemData.BonusListIDs; + List bonusListIDs = item.GetBonusListIDs(); foreach (uint bonusId in bonusListIDs) { if (bonusId != data.bonusId) diff --git a/Source/Game/Entities/Player/Player.DB.cs b/Source/Game/Entities/Player/Player.DB.cs index 7f230be95..8443c2d25 100644 --- a/Source/Game/Entities/Player/Player.DB.cs +++ b/Source/Game/Entities/Player/Player.DB.cs @@ -1363,7 +1363,7 @@ namespace Game.Entities eqSet.Data.AssignedSpecIndex = result.Read(5); eqSet.state = EquipmentSetUpdateState.Unchanged; - for (int i = 0; i < EquipmentSlot.End; ++i) + for (int i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) { ulong guid = result.Read(6 + i); if (guid != 0) @@ -1400,7 +1400,7 @@ namespace Game.Entities eqSet.Data.IgnoreMask = result.Read(4); eqSet.state = EquipmentSetUpdateState.Unchanged; - for (int i = 0; i < EquipmentSlot.End; ++i) + for (int i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) eqSet.Data.Appearances[i] = result.Read(5 + i); for (int i = 0; i < eqSet.Data.Enchants.Length; ++i) @@ -2298,7 +2298,7 @@ namespace Game.Entities stmt.AddValue(j++, eqSet.Data.IgnoreMask); stmt.AddValue(j++, eqSet.Data.AssignedSpecIndex); - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) stmt.AddValue(j++, eqSet.Data.Pieces[i].GetCounter()); stmt.AddValue(j++, GetGUID().GetCounter()); @@ -2312,7 +2312,7 @@ namespace Game.Entities stmt.AddValue(j++, eqSet.Data.SetIcon); stmt.AddValue(j++, eqSet.Data.IgnoreMask); - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) stmt.AddValue(j++, eqSet.Data.Appearances[i]); for (int i = 0; i < eqSet.Data.Enchants.Length; ++i) @@ -2338,7 +2338,7 @@ namespace Game.Entities stmt.AddValue(j++, eqSet.Data.IgnoreMask); stmt.AddValue(j++, eqSet.Data.AssignedSpecIndex); - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) stmt.AddValue(j++, eqSet.Data.Pieces[i].GetCounter()); } else @@ -2351,7 +2351,7 @@ namespace Game.Entities stmt.AddValue(j++, eqSet.Data.SetIcon); stmt.AddValue(j++, eqSet.Data.IgnoreMask); - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) stmt.AddValue(j++, eqSet.Data.Appearances[i]); for (int i = 0; i < eqSet.Data.Enchants.Length; ++i) @@ -2680,15 +2680,6 @@ namespace Game.Entities InitDisplayIds(); - // cleanup inventory related item value fields (its will be filled correctly in _LoadInventory) - for (byte slot = EquipmentSlot.Start; slot < EquipmentSlot.End; ++slot) - { - SetInvSlot(slot, ObjectGuid.Empty); - SetVisibleItemSlot(slot, null); - - m_items[slot] = null; - } - //Need to call it to initialize m_team (m_team can be calculated from race) //Other way is to saves m_team into characters table. SetFactionForRace(GetRace()); @@ -2982,6 +2973,8 @@ namespace Game.Entities long now = GameTime.GetGameTime(); long logoutTime = logout_time; + SetUpdateFieldValue(m_values.ModifyValue(m_playerData).ModifyValue(m_playerData.LogoutTime), logoutTime); + // since last logout (in seconds) uint time_diff = (uint)(now - logoutTime); @@ -3431,7 +3424,7 @@ namespace Game.Entities ss.Clear(); // cache equipment... - for (byte i = 0; i < InventorySlots.BagEnd; ++i) + for (byte i = 0; i < InventorySlots.ReagentBagEnd; ++i) { Item item = GetItemByPos(InventorySlots.Bag0, i); if (item != null) @@ -3577,7 +3570,7 @@ namespace Game.Entities ss.Clear(); // cache equipment... - for (byte i = 0; i < InventorySlots.BagEnd; ++i) + for (byte i = 0; i < InventorySlots.ReagentBagEnd; ++i) { Item item = GetItemByPos(InventorySlots.Bag0, i); if (item != null) diff --git a/Source/Game/Entities/Player/Player.Fields.cs b/Source/Game/Entities/Player/Player.Fields.cs index 6605dd521..60bb98d37 100644 --- a/Source/Game/Entities/Player/Player.Fields.cs +++ b/Source/Game/Entities/Player/Player.Fields.cs @@ -294,6 +294,7 @@ namespace Game.Entities public CreatePosition createPosition; public CreatePosition? createPositionNPE; + public ItemContext itemContext; public List item = new(); public List customSpells = new(); public List[] castSpells = new List[(int)PlayerCreateMode.Max]; diff --git a/Source/Game/Entities/Player/Player.Items.cs b/Source/Game/Entities/Player/Player.Items.cs index c0496dafe..327327fa7 100644 --- a/Source/Game/Entities/Player/Player.Items.cs +++ b/Source/Game/Entities/Player/Player.Items.cs @@ -1219,42 +1219,41 @@ namespace Game.Entities return lastItem; } - bool StoreNewItemInBestSlots(uint titem_id, uint titem_amount) + bool StoreNewItemInBestSlots(uint itemId, uint amount, ItemContext context) { - Log.outDebug(LogFilter.Player, "STORAGE: Creating initial item, itemId = {0}, count = {1}", titem_id, titem_amount); + Log.outDebug(LogFilter.Player, "STORAGE: Creating initial item, itemId = {0}, count = {1}", itemId, amount); - ItemContext itemContext = ItemContext.NewCharacter; - var bonusListIDs = Global.DB2Mgr.GetDefaultItemBonusTree(titem_id, itemContext); + var bonusListIDs = Global.DB2Mgr.GetDefaultItemBonusTree(itemId, context); InventoryResult msg; // attempt equip by one - while (titem_amount > 0) + while (amount > 0) { - msg = CanEquipNewItem(ItemConst.NullSlot, out ushort eDest, titem_id, false); + msg = CanEquipNewItem(ItemConst.NullSlot, out ushort eDest, itemId, false); if (msg != InventoryResult.Ok) break; - Item item = EquipNewItem(eDest, titem_id, itemContext, true); + Item item = EquipNewItem(eDest, itemId, context, true); item.SetBonuses(bonusListIDs); AutoUnequipOffhandIfNeed(); - titem_amount--; + --amount; } - if (titem_amount == 0) + if (amount == 0) return true; // equipped // attempt store List sDest = new(); // store in main bag to simplify second pass (special bags can be not equipped yet at this moment) - msg = CanStoreNewItem(InventorySlots.Bag0, ItemConst.NullSlot, sDest, titem_id, titem_amount); + msg = CanStoreNewItem(InventorySlots.Bag0, ItemConst.NullSlot, sDest, itemId, amount); if (msg == InventoryResult.Ok) { - StoreNewItem(sDest, titem_id, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(titem_id), null, itemContext, bonusListIDs); + StoreNewItem(sDest, itemId, true, ItemEnchantmentManager.GenerateItemRandomBonusListId(itemId), null, context, bonusListIDs); return true; // stored } // item can't be added - Log.outError(LogFilter.Player, "STORAGE: Can't equip or store initial item {0} for race {1} class {2}, error msg = {3}", titem_id, GetRace(), GetClass(), msg); + Log.outError(LogFilter.Player, "STORAGE: Can't equip or store initial item {0} for race {1} class {2}, error msg = {3}", itemId, GetRace(), GetClass(), msg); return false; } public Item StoreNewItem(List pos, uint itemId, bool update, uint randomBonusListId = 0, List allowedLooters = null, ItemContext context = 0, List bonusListIDs = null, bool addToCollection = true) @@ -1878,7 +1877,7 @@ namespace Game.Entities pItem.RemoveItemFlag2(ItemFieldFlags2.Equipped); // remove item dependent auras and casts (only weapon and armor slots) - if (slot < EquipmentSlot.End) + if (slot < ProfessionSlots.End) { // update expertise if (slot == EquipmentSlot.MainHand) @@ -2789,10 +2788,18 @@ namespace Game.Entities if (slot < EquipmentSlot.End) return true; + // profession equipment + if (slot >= ProfessionSlots.Start && slot < ProfessionSlots.End) + return true; + // bag equip slots if (slot >= InventorySlots.BagStart && slot < InventorySlots.BagEnd) return true; + // reagent bag equip slots + if (slot >= InventorySlots.ReagentBagStart && slot < InventorySlots.ReagentBagEnd) + return true; + // backpack slots if (slot >= InventorySlots.ItemStart && slot < InventorySlots.ItemStart + GetInventorySlotCount()) return true; @@ -3010,7 +3017,7 @@ namespace Game.Entities // if current back slot non-empty search oldest or free if (m_items[slot] != null) { - long oldest_time = m_activePlayerData.BuybackTimestamp[0]; + ulong oldest_time = m_activePlayerData.BuybackTimestamp[0]; uint oldest_slot = InventorySlots.BuyBackStart; for (byte i = InventorySlots.BuyBackStart + 1; i < InventorySlots.BuyBackEnd; ++i) @@ -3022,7 +3029,7 @@ namespace Game.Entities break; } - long i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart]; + ulong i_time = m_activePlayerData.BuybackTimestamp[i - InventorySlots.BuyBackStart]; if (oldest_time > i_time) { oldest_time = i_time; @@ -3473,7 +3480,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, long timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); } + public void SetBuybackTimestamp(uint slot, ulong timestamp) { SetUpdateFieldValue(ref m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.BuybackTimestamp, (int)slot), timestamp); } public Item GetItemFromBuyBackSlot(uint slot) { @@ -4523,10 +4530,16 @@ namespace Game.Entities uint freeSlotCount = 0; if (location.HasFlag(ItemSearchLocation.Equipment)) + { for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; ++i) if (GetItemByPos(InventorySlots.Bag0, i) == null) ++freeSlotCount; + for (byte i = ProfessionSlots.Start; i < ProfessionSlots.End; ++i) + if (!GetItemByPos(InventorySlots.Bag0, i)) + ++freeSlotCount; + } + if (location.HasFlag(ItemSearchLocation.Inventory)) { int inventoryEnd = InventorySlots.ItemStart + GetInventorySlotCount(); @@ -4565,9 +4578,20 @@ namespace Game.Entities } if (location.HasFlag(ItemSearchLocation.ReagentBank)) + { + for (byte i = InventorySlots.ReagentBagStart; i < InventorySlots.ReagentBagEnd; ++i) + { + Bag bag = GetBagByPos(i); + if (bag != null) + for (byte j = 0; j < bag.GetBagSize(); ++j) + if (bag.GetItemByPos(j) == null) + ++freeSlotCount; + } + for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i) if (GetItemByPos(InventorySlots.Bag0, i) == null) ++freeSlotCount; + } return freeSlotCount; } @@ -4608,7 +4632,8 @@ namespace Game.Entities public Bag GetBagByPos(byte bag) { if ((bag >= InventorySlots.BagStart && bag < InventorySlots.BagEnd) - || (bag >= InventorySlots.BankBagStart && bag < InventorySlots.BankBagEnd)) + || (bag >= InventorySlots.BankBagStart && bag < InventorySlots.BankBagEnd) + || (bag >= InventorySlots.ReagentBagStart && bag < InventorySlots.ReagentBagEnd)) { Item item = GetItemByPos(InventorySlots.Bag0, bag); if (item != null) @@ -4624,6 +4649,8 @@ namespace Game.Entities return true; if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BankBagStart && slot < InventorySlots.BankBagEnd)) return true; + if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentBagStart && slot < InventorySlots.ReagentBagEnd)) + return true; return false; } InventoryResult CanStoreItem_InBag(byte bag, List dest, ItemTemplate pProto, ref uint count, bool merge, bool non_specialized, Item pSrcItem, byte skip_bag, byte skip_slot) @@ -4712,8 +4739,12 @@ namespace Game.Entities { if (bag == InventorySlots.Bag0 && (slot < EquipmentSlot.End)) return true; + if (bag == InventorySlots.Bag0 && (slot >= ProfessionSlots.Start && slot < ProfessionSlots.End)) + return true; if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.BagStart && slot < InventorySlots.BagEnd)) return true; + if (bag == InventorySlots.Bag0 && (slot >= InventorySlots.ReagentBagStart && slot < InventorySlots.ReagentBagEnd)) + return true; return false; } byte FindEquipSlot(Item item, uint slot, bool swap) @@ -5246,8 +5277,10 @@ namespace Game.Entities { AddTemporarySpell(artifactPowerRank.SpellID); LearnedSpells learnedSpells = new(); + LearnedSpellInfo learnedSpellInfo = new(); + learnedSpellInfo.SpellID = artifactPowerRank.SpellID; learnedSpells.SuppressMessaging = true; - learnedSpells.SpellID.Add(artifactPowerRank.SpellID); + learnedSpells.ClientLearnedSpellData.Add(learnedSpellInfo); SendPacket(learnedSpells); } else if (!apply) @@ -6314,6 +6347,14 @@ namespace Game.Entities if (!callback(item)) return false; } + + for (byte i = ProfessionSlots.Start; i < ProfessionSlots.End; ++i) + { + Item pItem = GetItemByPos(InventorySlots.Bag0, i); + if (pItem != null) + if (!callback(pItem)) + return false; + } } if (location.HasAnyFlag(ItemSearchLocation.Inventory)) @@ -6379,6 +6420,21 @@ namespace Game.Entities if (location.HasAnyFlag(ItemSearchLocation.ReagentBank)) { + for (byte i = InventorySlots.ReagentBagStart; i < InventorySlots.ReagentBagEnd; ++i) + { + Bag bag = GetBagByPos(i); + if (bag != null) + { + for (byte j = 0; j < bag.GetBagSize(); ++j) + { + Item pItem = bag.GetItemByPos(j); + if (pItem != null) + if (!callback(pItem)) + return false; + } + } + } + for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i) { Item item = GetItemByPos(InventorySlots.Bag0, i); @@ -6471,7 +6527,7 @@ namespace Game.Entities ForEachItem(ItemSearchLocation.Everywhere, item => { ItemTemplate itemTemplate = item.GetTemplate(); - if (itemTemplate != null) + if (itemTemplate != null && itemTemplate.GetInventoryType() < InventoryType.ProfessionTool) { ushort dest; if (item.IsEquipped()) diff --git a/Source/Game/Entities/Player/Player.Quest.cs b/Source/Game/Entities/Player/Player.Quest.cs index 2af534234..971133272 100644 --- a/Source/Game/Entities/Player/Player.Quest.cs +++ b/Source/Game/Entities/Player/Player.Quest.cs @@ -3114,14 +3114,5 @@ namespace Game.Entities SendPacket(displayToast); } - - void SendGarrisonOpenTalentNpc(ObjectGuid guid, int garrTalentTreeId, int friendshipFactionId) - { - GarrisonOpenTalentNpc openTalentNpc = new(); - openTalentNpc.NpcGUID = guid; - openTalentNpc.GarrTalentTreeID = garrTalentTreeId; - openTalentNpc.FriendshipFactionID = friendshipFactionId; - SendPacket(openTalentNpc); - } } } diff --git a/Source/Game/Entities/Player/Player.Spells.cs b/Source/Game/Entities/Player/Player.Spells.cs index 34c96dded..addb93506 100644 --- a/Source/Game/Entities/Player/Player.Spells.cs +++ b/Source/Game/Entities/Player/Player.Spells.cs @@ -2058,10 +2058,12 @@ namespace Game.Entities // prevent duplicated entires in spell book, also not send if not in world (loading) if (learning && IsInWorld) { - LearnedSpells packet = new(); - packet.SpellID.Add(spellId); - packet.SuppressMessaging = suppressMessaging; - SendPacket(packet); + LearnedSpells learnedSpells = new(); + LearnedSpellInfo learnedSpellInfo = new(); + learnedSpellInfo.SpellID = spellId; + learnedSpells.SuppressMessaging = suppressMessaging; + learnedSpells.ClientLearnedSpellData.Add(learnedSpellInfo); + SendPacket(learnedSpells); } // learn all disabled higher ranks and required spells (recursive) @@ -3046,8 +3048,10 @@ namespace Game.Entities void SendSupercededSpell(uint oldSpell, uint newSpell) { SupercededSpells supercededSpells = new(); - supercededSpells.SpellID.Add(newSpell); - supercededSpells.Superceded.Add(oldSpell); + LearnedSpellInfo learnedSpellInfo = new(); + learnedSpellInfo.SpellID = newSpell; + learnedSpellInfo.Superceded = (int)oldSpell; + supercededSpells.ClientLearnedSpellData.Add(learnedSpellInfo); SendPacket(supercededSpells); } diff --git a/Source/Game/Entities/Player/Player.Talents.cs b/Source/Game/Entities/Player/Player.Talents.cs index 68093a609..2f5af1574 100644 --- a/Source/Game/Entities/Player/Player.Talents.cs +++ b/Source/Game/Entities/Player/Player.Talents.cs @@ -698,6 +698,11 @@ namespace Game.Entities if (HasPvpTalent(talentID, GetActiveTalentGroup())) return TalentLearnResult.FailedUnknown; + PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(talentInfo.PlayerConditionID); + if (playerCondition != null) + if (!ConditionManager.IsPlayerMeetingCondition(this, playerCondition)) + return TalentLearnResult.FailedCantDoThatRightNow; + PvpTalentRecord talent = CliDB.PvpTalentStorage.LookupByKey(GetPvpTalentMap(GetActiveTalentGroup())[slot]); if (talent != null) { diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index 633a22487..36ae5c947 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -296,7 +296,7 @@ namespace Game.Entities // original items foreach (PlayerCreateInfoItem initialItem in info.item) - StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount); + StoreNewItemInBestSlots(initialItem.item_id, initialItem.item_amount, info.itemContext); // bags and main-hand weapon must equipped at this moment // now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon) @@ -685,7 +685,7 @@ namespace Game.Entities if (target == this) { - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < InventorySlots.BankBagEnd; ++i) { if (m_items[i] == null) continue; @@ -693,23 +693,7 @@ namespace Game.Entities m_items[i].DestroyForPlayer(target); } - for (byte i = InventorySlots.BagStart; i < InventorySlots.BagEnd; ++i) - { - if (m_items[i] == null) - continue; - - m_items[i].DestroyForPlayer(target); - } - - for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i) - { - if (m_items[i] == null) - continue; - - m_items[i].DestroyForPlayer(target); - } - - for (byte i = InventorySlots.ChildEquipmentStart; i < InventorySlots.ChildEquipmentEnd; ++i) + for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ChildEquipmentEnd; ++i) { if (m_items[i] == null) continue; @@ -2329,7 +2313,7 @@ namespace Game.Entities { switch (gossipMenuItem.OptionNpc) { - case GossipOptionNpc.TaxiNode: + case GossipOptionNpc.Taxinode: if (GetSession().SendLearnNewTaxiNode(creature)) return; break; @@ -2337,7 +2321,7 @@ namespace Game.Entities if (!IsDead()) canTalk = false; break; - case GossipOptionNpc.BattleMaster: + case GossipOptionNpc.Battlemaster: if (!creature.CanInteractWithBattleMaster(this, false)) canTalk = false; break; @@ -2347,7 +2331,7 @@ namespace Game.Entities if (!creature.CanResetTalents(this)) canTalk = false; break; - case GossipOptionNpc.StableMaster: + case GossipOptionNpc.Stablemaster: case GossipOptionNpc.PetSpecializationMaster: if (GetClass() != Class.Hunter) canTalk = false; @@ -2376,32 +2360,32 @@ namespace Game.Entities canTalk = false; // Deprecated break; case GossipOptionNpc.GuildBanker: - case GossipOptionNpc.SpellClick: - case GossipOptionNpc.WorldPVPQueue: + case GossipOptionNpc.Spellclick: + case GossipOptionNpc.WorldPvPQueue: case GossipOptionNpc.LFGDungeon: case GossipOptionNpc.ArtifactRespec: case GossipOptionNpc.QueueScenario: case GossipOptionNpc.GarrisonArchitect: - case GossipOptionNpc.GarrisonMission: + case GossipOptionNpc.GarrisonMissionNpc: case GossipOptionNpc.ShipmentCrafter: - case GossipOptionNpc.GarrisonTradeskill: + case GossipOptionNpc.GarrisonTradeskillNpc: case GossipOptionNpc.GarrisonRecruitment: case GossipOptionNpc.AdventureMap: case GossipOptionNpc.GarrisonTalent: case GossipOptionNpc.ContributionCollector: - case GossipOptionNpc.IslandsMission: + case GossipOptionNpc.IslandsMissionNpc: case GossipOptionNpc.UIItemInteraction: case GossipOptionNpc.WorldMap: case GossipOptionNpc.Soulbind: - case GossipOptionNpc.ChromieTime: - case GossipOptionNpc.CovenantPreview: + case GossipOptionNpc.ChromieTimeNpc: + case GossipOptionNpc.CovenantPreviewNpc: case GossipOptionNpc.RuneforgeLegendaryCrafting: case GossipOptionNpc.NewPlayerGuide: case GossipOptionNpc.RuneforgeLegendaryUpgrade: - case GossipOptionNpc.CovenantRenown: + case GossipOptionNpc.CovenantRenownNpc: break; // NYI default: - Log.outError(LogFilter.Sql, $"Creature entry {creature.GetEntry()} has an unknown gossip option icon {gossipMenuItem.OptionNpc} for menu {gossipMenuItem.MenuId}."); + Log.outError(LogFilter.Sql, $"Creature entry {creature.GetEntry()} has an unknown gossip option icon {gossipMenuItem.OptionNpc} for menu {gossipMenuItem.MenuID}."); canTalk = false; break; } @@ -2421,45 +2405,7 @@ namespace Game.Entities } if (canTalk) - { - string strOptionText; - string strBoxText; - BroadcastTextRecord optionBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(gossipMenuItem.OptionBroadcastTextId); - BroadcastTextRecord boxBroadcastText = CliDB.BroadcastTextStorage.LookupByKey(gossipMenuItem.BoxBroadcastTextId); - Locale locale = GetSession().GetSessionDbLocaleIndex(); - - if (optionBroadcastText != null) - strOptionText = Global.DB2Mgr.GetBroadcastTextValue(optionBroadcastText, locale, GetGender()); - else - strOptionText = gossipMenuItem.OptionText; - - if (boxBroadcastText != null) - strBoxText = Global.DB2Mgr.GetBroadcastTextValue(boxBroadcastText, locale, GetGender()); - else - strBoxText = gossipMenuItem.BoxText; - - if (locale != Locale.enUS) - { - if (optionBroadcastText == null) - { - // Find localizations from database. - GossipMenuItemsLocale gossipMenuLocale = Global.ObjectMgr.GetGossipMenuItemsLocale(menuId, gossipMenuItem.OptionId); - if (gossipMenuLocale != null) - ObjectManager.GetLocaleString(gossipMenuLocale.OptionText, locale, ref strOptionText); - } - - if (boxBroadcastText == null) - { - // Find localizations from database. - GossipMenuItemsLocale gossipMenuLocale = Global.ObjectMgr.GetGossipMenuItemsLocale(menuId, gossipMenuItem.OptionId); - if (gossipMenuLocale != null) - ObjectManager.GetLocaleString(gossipMenuLocale.BoxText, locale, ref strBoxText); - } - } - - menu.GetGossipMenu().AddMenuItem((int)gossipMenuItem.OptionId, gossipMenuItem.OptionNpc, strOptionText, 0, (uint)gossipMenuItem.OptionNpc, strBoxText, gossipMenuItem.BoxMoney, gossipMenuItem.BoxCoded); - menu.GetGossipMenu().AddGossipMenuItemData(gossipMenuItem.OptionId, gossipMenuItem.ActionMenuId, gossipMenuItem.ActionPoiId); - } + menu.GetGossipMenu().AddMenuItem(gossipMenuItem, gossipMenuItem.MenuID, gossipMenuItem.OrderIndex); } } public void SendPreparedGossip(WorldObject source) @@ -2486,7 +2432,7 @@ namespace Game.Entities PlayerTalkClass.SendGossipMenu(textId, source.GetGUID()); } - public void OnGossipSelect(WorldObject source, uint gossipListId, uint menuId) + public void OnGossipSelect(WorldObject source, int gossipOptionId, uint menuId) { GossipMenu gossipMenu = PlayerTalkClass.GetGossipMenu(); @@ -2494,7 +2440,7 @@ namespace Game.Entities if (menuId != gossipMenu.GetMenuId()) return; - GossipMenuItem item = gossipMenu.GetItem(gossipListId); + GossipMenuItem item = gossipMenu.GetItem(gossipOptionId); if (item == null) return; @@ -2510,10 +2456,6 @@ namespace Game.Entities } } - GossipMenuItemData menuItemData = gossipMenu.GetItemData(gossipListId); - if (menuItemData == null) - return; - long cost = item.BoxMoney; if (!HasEnoughMoney(cost)) { @@ -2522,51 +2464,37 @@ namespace Game.Entities return; } + if (item.ActionPoiID != 0) + PlayerTalkClass.SendPointOfInterest(item.ActionPoiID); + + if (item.ActionMenuID != 0) + { + PrepareGossipMenu(source, item.ActionMenuID); + SendPreparedGossip(source); + } + + // types that have their dedicated open opcode dont send WorldPackets::NPC::GossipOptionNPCInteraction + bool handled = true; switch (gossipOptionNpc) { - case GossipOptionNpc.None: - { - if (menuItemData.GossipActionPoi != 0) - PlayerTalkClass.SendPointOfInterest(menuItemData.GossipActionPoi); - - if (menuItemData.GossipActionMenuId != 0) - { - PrepareGossipMenu(source, menuItemData.GossipActionMenuId); - SendPreparedGossip(source); - } - - break; - } case GossipOptionNpc.Vendor: GetSession().SendListInventory(guid); break; - case GossipOptionNpc.TaxiNode: + case GossipOptionNpc.Taxinode: GetSession().SendTaxiMenu(source.ToCreature()); break; case GossipOptionNpc.Trainer: - GetSession().SendTrainerList(source.ToCreature(), Global.ObjectMgr.GetCreatureTrainerForGossipOption(source.GetEntry(), menuId, gossipListId)); + GetSession().SendTrainerList(source.ToCreature(), Global.ObjectMgr.GetCreatureTrainerForGossipOption(source.GetEntry(), menuId, (uint)gossipOptionId)); break; case GossipOptionNpc.SpiritHealer: - if (IsDead()) - source.ToCreature().CastSpell(source.ToCreature(), 17251, new CastSpellExtraArgs(TriggerCastFlags.FullMask) - .SetOriginalCaster(GetGUID())); - break; - case GossipOptionNpc.Binder: - PlayerTalkClass.SendCloseGossip(); - SetBindPoint(guid); - break; - case GossipOptionNpc.Banker: - GetSession().SendShowBank(guid); + source.CastSpell(source.ToCreature(), 17251, new CastSpellExtraArgs(TriggerCastFlags.FullMask).SetOriginalCaster(GetGUID())); + handled = false; break; case GossipOptionNpc.PetitionVendor: PlayerTalkClass.SendCloseGossip(); GetSession().SendPetitionShowList(guid); break; - case GossipOptionNpc.TabardVendor: - PlayerTalkClass.SendCloseGossip(); - GetSession().SendTabardVendorActivate(guid); - break; - case GossipOptionNpc.BattleMaster: + case GossipOptionNpc.Battlemaster: { BattlegroundTypeId bgTypeId = Global.BattlegroundMgr.GetBattleMasterBG(source.GetEntry()); @@ -2586,13 +2514,25 @@ namespace Game.Entities PlayerTalkClass.SendCloseGossip(); SendRespecWipeConfirm(guid, WorldConfig.GetBoolValue(WorldCfg.NoResetTalentCost) ? 0 : GetNextResetTalentsCost(), SpecResetType.Talents); break; - case GossipOptionNpc.StableMaster: + case GossipOptionNpc.Stablemaster: GetSession().SendStablePet(guid); break; case GossipOptionNpc.PetSpecializationMaster: PlayerTalkClass.SendCloseGossip(); SendRespecWipeConfirm(guid, WorldConfig.GetBoolValue(WorldCfg.NoResetTalentCost) ? 0 : GetNextResetTalentsCost(), SpecResetType.PetTalents); break; + case GossipOptionNpc.GuildBanker: + Guild guild = GetGuild(); + if (guild != null) + guild.SendBankList(GetSession(), 0, true); + else + Guild.SendCommandResult(GetSession(), GuildCommandType.ViewTab, GuildCommandError.PlayerNotInGuild); + break; + case GossipOptionNpc.Spellclick: + Unit sourceUnit = source.ToUnit(); + if (sourceUnit != null) + sourceUnit.HandleSpellClick(this); + break; case GossipOptionNpc.DisableXPGain: PlayerTalkClass.SendCloseGossip(); CastSpell(null, PlayerConst.SpellExperienceEliminated, true); @@ -2603,9 +2543,6 @@ namespace Game.Entities RemoveAurasDueToSpell(PlayerConst.SpellExperienceEliminated); RemovePlayerFlag(PlayerFlags.NoXPGain); break; - case GossipOptionNpc.Mailbox: - GetSession().SendShowMailBox(guid); - break; case GossipOptionNpc.SpecializationMaster: PlayerTalkClass.SendCloseGossip(); SendRespecWipeConfirm(guid, 0, SpecResetType.Specialization); @@ -2614,22 +2551,74 @@ namespace Game.Entities PlayerTalkClass.SendCloseGossip(); SendRespecWipeConfirm(guid, 0, SpecResetType.Glyphs); break; - case GossipOptionNpc.GarrisonTalent: + case GossipOptionNpc.GarrisonTradeskillNpc: // NYI + break; + case GossipOptionNpc.GarrisonRecruitment: // NYI + break; + case GossipOptionNpc.ChromieTimeNpc: // NYI + break; + case GossipOptionNpc.RuneforgeLegendaryCrafting: // NYI + break; + case GossipOptionNpc.RuneforgeLegendaryUpgrade: // NYI + break; + case GossipOptionNpc.ProfessionsCraftingOrder: // NYI + break; + case GossipOptionNpc.ProfessionsCustomerOrder: // NYI + break; + case GossipOptionNpc.BarbersChoice: // NYI - unknown if needs sending + default: + handled = false; + break; + } + + if (!handled) + { + if (item.GossipNpcOptionID.HasValue) { GossipMenuAddon addon = Global.ObjectMgr.GetGossipMenuAddon(menuId); - GossipMenuItemAddon itemAddon = Global.ObjectMgr.GetGossipMenuItemAddon(menuId, gossipListId); - SendGarrisonOpenTalentNpc(guid, itemAddon != null ? itemAddon.GarrTalentTreeID.GetValueOrDefault(0) : 0, addon != null ? addon.FriendshipFactionID : 0); - break; + + GossipOptionNPCInteraction npcInteraction = new(); + npcInteraction.GossipGUID = source.GetGUID(); + npcInteraction.GossipNpcOptionID = item.GossipNpcOptionID.Value; + if (addon != null && addon.FriendshipFactionID != 0) + npcInteraction.FriendshipFactionID = addon.FriendshipFactionID; + + SendPacket(npcInteraction); + } + else + { + PlayerInteractionType[] GossipOptionNpcToInteractionType = + { + PlayerInteractionType.None, PlayerInteractionType.Vendor, PlayerInteractionType.TaxiNode, + PlayerInteractionType.Trainer, PlayerInteractionType.SpiritHealer, PlayerInteractionType.Binder, + PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.TabardVendor, + PlayerInteractionType.BattleMaster, PlayerInteractionType.Auctioneer, PlayerInteractionType.TalentMaster, + PlayerInteractionType.StableMaster, PlayerInteractionType.None, PlayerInteractionType.GuildBanker, + PlayerInteractionType.None, PlayerInteractionType.None, PlayerInteractionType.None, + PlayerInteractionType.MailInfo, PlayerInteractionType.None, PlayerInteractionType.LFGDungeon, + PlayerInteractionType.ArtifactForge, PlayerInteractionType.None, PlayerInteractionType.SpecializationMaster, + PlayerInteractionType.None, PlayerInteractionType.None, PlayerInteractionType.GarrArchitect, + PlayerInteractionType.GarrMission, PlayerInteractionType.ShipmentCrafter, PlayerInteractionType.GarrTradeskill, + PlayerInteractionType.GarrRecruitment, PlayerInteractionType.AdventureMap, PlayerInteractionType.GarrTalent, + PlayerInteractionType.ContributionCollector, PlayerInteractionType.Transmogrifier, PlayerInteractionType.AzeriteRespec, + PlayerInteractionType.IslandQueue, PlayerInteractionType.ItemInteraction, PlayerInteractionType.WorldMap, + PlayerInteractionType.Soulbind, PlayerInteractionType.ChromieTime, PlayerInteractionType.CovenantPreview, + PlayerInteractionType.LegendaryCrafting, PlayerInteractionType.NewPlayerGuide, PlayerInteractionType.LegendaryCrafting, + PlayerInteractionType.Renown, PlayerInteractionType.BlackMarketAuctioneer, PlayerInteractionType.PerksProgramVendor, + PlayerInteractionType.ProfessionsCraftingOrder, PlayerInteractionType.Professions, PlayerInteractionType.ProfessionsCustomerOrder, + PlayerInteractionType.TraitSystem, PlayerInteractionType.BarbersChoice, PlayerInteractionType.MajorFactionRenown + }; + + PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[(int)gossipOptionNpc]; + if (interactionType != PlayerInteractionType.None) + { + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = source.GetGUID(); + npcInteraction.InteractionType = interactionType; + npcInteraction.Success = true; + SendPacket(npcInteraction); + } } - case GossipOptionNpc.Transmogrify: - GetSession().SendOpenTransmogrifier(guid); - break; - case GossipOptionNpc.AzeriteRespec: - PlayerTalkClass.SendCloseGossip(); - GetSession().SendAzeriteRespecNPC(guid); - break; - default: - break; } ModifyMoney(-cost); @@ -2916,8 +2905,11 @@ namespace Game.Entities } public void SetBindPoint(ObjectGuid guid) { - BinderConfirm packet = new(guid); - SendPacket(packet); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.Binder; + npcInteraction.Success = true; + SendPacket(npcInteraction); } public void SendBindPointUpdate() { @@ -4021,7 +4013,7 @@ namespace Game.Entities corpse.SetDisplayId(GetNativeDisplayId()); corpse.SetFactionTemplate(CliDB.ChrRacesStorage.LookupByKey(GetRace()).FactionID); - for (byte i = 0; i < EquipmentSlot.End; i++) + for (byte i = EquipmentSlot.Start; i < EquipmentSlot.End; i++) { if (m_items[i] != null) { @@ -6240,7 +6232,6 @@ namespace Game.Entities packet.Reason = victim ? PlayerLogXPReason.Kill : PlayerLogXPReason.NoKill; packet.Amount = (int)xp; packet.GroupBonus = group_rate; - packet.ReferAFriendBonusType = (byte)(recruitAFriend ? 1 : 0); SendPacket(packet); uint nextLvlXP = GetXPForNextLevel(); @@ -7238,7 +7229,7 @@ namespace Game.Entities { if (target == this) { - for (byte i = 0; i < EquipmentSlot.End; ++i) + for (byte i = EquipmentSlot.Start; i < InventorySlots.BankBagEnd; ++i) { if (m_items[i] == null) continue; @@ -7246,23 +7237,7 @@ namespace Game.Entities m_items[i].BuildCreateUpdateBlockForPlayer(data, target); } - for (byte i = InventorySlots.BagStart; i < InventorySlots.BankBagEnd; ++i) - { - if (m_items[i] == null) - continue; - - m_items[i].BuildCreateUpdateBlockForPlayer(data, target); - } - - for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ReagentEnd; ++i) - { - if (m_items[i] == null) - continue; - - m_items[i].BuildCreateUpdateBlockForPlayer(data, target); - } - - for (byte i = InventorySlots.ChildEquipmentStart; i < InventorySlots.ChildEquipmentEnd; ++i) + for (byte i = InventorySlots.ReagentStart; i < InventorySlots.ChildEquipmentEnd; ++i) { if (m_items[i] == null) continue; @@ -7392,9 +7367,18 @@ namespace Game.Entities } //Helpers - public void AddGossipItem(GossipOptionNpc icon, string message, uint sender, uint action) { PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, icon, message, sender, action, "", 0); } - public void AddGossipItem(uint menuId, uint menuItemId, uint sender, uint action) { PlayerTalkClass.GetGossipMenu().AddMenuItem(menuId, menuItemId, sender, action); } - public void ADD_GOSSIP_ITEM_EXTENDED(GossipOptionNpc icon, string message, uint sender, uint action, string boxmessage, uint boxmoney, bool coded) { PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, icon, message, sender, action, boxmessage, boxmoney, coded); } + public void AddGossipItem(GossipOptionNpc optionNpc, string text, uint sender, uint action) + { + PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, false, 0, "", null, null, sender, action); + } + public void AddGossipItem(GossipOptionNpc optionNpc, string text, uint sender, uint action, string popupText, uint popupMoney, bool coded) + { + PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, coded, popupMoney, popupText, null, null, sender, action); + } + public void AddGossipItem(uint gossipMenuID, uint gossipMenuItemID, uint sender, uint action) + { + PlayerTalkClass.GetGossipMenu().AddMenuItem(gossipMenuID, gossipMenuItemID, sender, action); + } // This fuction Sends the current menu to show to client, a - NPCTEXTID(uint32), b - npc guid(uint64) public void SendGossipMenu(uint titleId, ObjectGuid objGUID) { PlayerTalkClass.SendGossipMenu(titleId, objGUID); } diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index 37ffbd86c..5b0f13f2c 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -1634,7 +1634,9 @@ namespace Game.Entities 0.9830f, // Warlock 0.9830f, // Monk 0.9720f, // Druid - 0.9830f // Demon Hunter + 0.9830f, // Demon Hunter + 0.9880f, // Evoker + 1.0f, // Adventurer }; // 1 1 k cx @@ -1670,7 +1672,9 @@ namespace Game.Entities 0.0f, // Warlock 90.6425f, // Monk 0.0f, // Druid - 65.631440f // Demon Hunter + 65.631440f, // Demon Hunter + 0.0f, // Evoker + 0.0f, // Adventurer }; public void UpdateParryPercentage() @@ -1708,7 +1712,9 @@ namespace Game.Entities 150.375940f, // Warlock 145.560408f, // Monk 116.890707f, // Druid - 145.560408f // Demon Hunter + 145.560408f, // Demon Hunter + 145.560408f, // Evoker + 0.0f, // Adventurer }; public void UpdateDodgePercentage() diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 14d38f381..018e66ed2 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -301,6 +301,11 @@ namespace Game.Entities { return aurEff.GetCasterGUID() == caster.GetGUID() && aurEff.IsAffectingSpell(spellProto); }); + + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModDamageTakenFromCasterByLabel, aurEff => + { + return aurEff.GetCasterGUID() == caster.GetGUID() && spellProto.HasLabel((uint)aurEff.GetMiscValue()); + }); } if (damagetype == DamageEffectType.DOT) diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 73c0cf91d..91c051656 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -380,6 +380,8 @@ namespace Game if (!result.IsEmpty()) { Dictionary>> temp = new(); + byte[] minRequirementForClass = new byte[(int)Class.Max]; + Array.Fill(minRequirementForClass, (byte)Expansion.Max); uint count = 0; do { @@ -418,6 +420,7 @@ namespace Game temp[raceID] = new Dictionary>(); temp[raceID][classID] = Tuple.Create(activeExpansionLevel, accountExpansionLevel); + minRequirementForClass[classID] = Math.Min(minRequirementForClass[classID], activeExpansionLevel); ++count; } @@ -434,6 +437,7 @@ namespace Game classAvailability.ClassID = class_.Key; classAvailability.ActiveExpansionLevel = class_.Value.Item1; classAvailability.AccountExpansionLevel = class_.Value.Item2; + classAvailability.MinActiveExpansionLevel = minRequirementForClass[class_.Key]; raceClassAvailability.Classes.Add(classAvailability); } @@ -530,6 +534,15 @@ namespace Game return classAvailability; } + public ClassAvailability GetClassExpansionRequirementFallback(byte classId) + { + foreach (RaceClassAvailability raceClassAvailability in _classExpansionRequirementStorage) + foreach (ClassAvailability classAvailability in raceClassAvailability.Classes) + if (classAvailability.ClassID == classId) + return classAvailability; + + return null; + } public PlayerChoice GetPlayerChoice(int choiceId) { return _playerChoices.LookupByKey(choiceId); @@ -578,9 +591,10 @@ namespace Game gossipMenuItemsStorage.Clear(); - // 0 1 2 3 4 5 6 7 8 9 10 11 - SQLResult result = DB.World.Query("SELECT MenuID, OptionID, OptionNpc, OptionText, OptionBroadcastTextID, Language, ActionMenuID, ActionPoiID, BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID " + - "FROM gossip_menu_option ORDER BY MenuID, OptionID"); + // 0 1 2 3 4 5 6 7 8 9 10 + SQLResult result = DB.World.Query("SELECT MenuID, GossipOptionID, OptionID, OptionNpc, OptionText, OptionBroadcastTextID, Language, Flags, ActionMenuID, ActionPoiID, GossipNpcOptionID, " + + //11 12 13 14 15 16 + "BoxCoded, BoxMoney, BoxText, BoxBroadcastTextID, SpellID, OverrideIconID FROM gossip_menu_option ORDER BY MenuID, OptionID"); if (result.IsEmpty()) { @@ -588,26 +602,40 @@ namespace Game return; } + Dictionary optionToNpcOption = new(); + foreach (var (_, npcOption) in CliDB.GossipNPCOptionStorage) + optionToNpcOption[npcOption.GossipOptionID] = npcOption.Id; + do { GossipMenuItems gMenuItem = new(); - gMenuItem.MenuId = result.Read(0); - gMenuItem.OptionId = result.Read(1); - gMenuItem.OptionNpc = (GossipOptionNpc)result.Read(2); - gMenuItem.OptionText = result.Read(3); - gMenuItem.OptionBroadcastTextId = result.Read(4); - gMenuItem.Language = result.Read(5); - gMenuItem.ActionMenuId = result.Read(6); - gMenuItem.ActionPoiId = result.Read(7); - gMenuItem.BoxCoded = result.Read(8); - gMenuItem.BoxMoney = result.Read(9); - gMenuItem.BoxText = result.Read(10); - gMenuItem.BoxBroadcastTextId = result.Read(11); + gMenuItem.MenuID = result.Read(0); + gMenuItem.GossipOptionID = result.Read(1); + gMenuItem.OrderIndex = result.Read(2); + gMenuItem.OptionNpc = (GossipOptionNpc)result.Read(3); + gMenuItem.OptionText = result.Read(4); + gMenuItem.OptionBroadcastTextId = result.Read(5); + gMenuItem.Language = result.Read(6); + gMenuItem.Flags = (GossipOptionFlags)result.Read(7); + gMenuItem.ActionMenuID = result.Read(8); + gMenuItem.ActionPoiID = result.Read(9); + if (!result.IsNull(10)) + gMenuItem.GossipNpcOptionID = result.Read(10); + + gMenuItem.BoxCoded = result.Read(11); + gMenuItem.BoxMoney = result.Read(12); + gMenuItem.BoxText = result.Read(13); + gMenuItem.BoxBroadcastTextId = result.Read(14); + if (!result.IsNull(15)) + gMenuItem.SpellID = result.Read(15); + + if (!result.IsNull(16)) + gMenuItem.OverrideIconID = result.Read(16); if (gMenuItem.OptionNpc >= GossipOptionNpc.Max) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuId}, id {gMenuItem.OptionId} has unknown NPC option id {gMenuItem.OptionNpc}. Replacing with GossipOptionNpc.None"); + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} has unknown NPC option id {gMenuItem.OptionNpc}. Replacing with GossipOptionNpc.None"); gMenuItem.OptionNpc = GossipOptionNpc.None; } @@ -615,47 +643,71 @@ namespace Game { if (!CliDB.BroadcastTextStorage.ContainsKey(gMenuItem.OptionBroadcastTextId)) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for MenuId {gMenuItem.MenuId}, OptionIndex {gMenuItem.OptionId} has non-existing or incompatible OptionBroadcastTextId {gMenuItem.OptionBroadcastTextId}, ignoring."); + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for MenuId {gMenuItem.MenuID}, OptionIndex {gMenuItem.OrderIndex} has non-existing or incompatible OptionBroadcastTextId {gMenuItem.OptionBroadcastTextId}, ignoring."); gMenuItem.OptionBroadcastTextId = 0; } } if (gMenuItem.Language != 0 && !CliDB.LanguagesStorage.ContainsKey(gMenuItem.Language)) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuId}, id {gMenuItem.OptionId} use non-existing Language {gMenuItem.Language}, ignoring"); + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} use non-existing Language {gMenuItem.Language}, ignoring"); gMenuItem.Language = 0; } - if (gMenuItem.ActionMenuId != 0 && gMenuItem.OptionNpc != GossipOptionNpc.None) + if (gMenuItem.ActionMenuID != 0 && gMenuItem.OptionNpc != GossipOptionNpc.None) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuId}, id {gMenuItem.OptionId} can not use ActionMenuID for GossipOptionNpc different from GossipOptionNpc.None, ignoring"); - gMenuItem.ActionMenuId = 0; + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} can not use ActionMenuID for GossipOptionNpc different from GossipOptionNpc.None, ignoring"); + gMenuItem.ActionMenuID = 0; } - if (gMenuItem.ActionPoiId != 0) + if (gMenuItem.ActionPoiID != 0) { if (gMenuItem.OptionNpc != GossipOptionNpc.None) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuId}, id {gMenuItem.OptionId} can not use ActionPoiID for GossipOptionNpc different from GossipOptionNpc.None, ignoring"); - gMenuItem.ActionPoiId = 0; + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} can not use ActionPoiID for GossipOptionNpc different from GossipOptionNpc.None, ignoring"); + gMenuItem.ActionPoiID = 0; } - else if (GetPointOfInterest(gMenuItem.ActionPoiId) == null) + else if (GetPointOfInterest(gMenuItem.ActionPoiID) == null) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuId}, id {gMenuItem.OptionId} use non-existing ActionPoiID {gMenuItem.ActionPoiId}, ignoring"); - gMenuItem.ActionPoiId = 0; + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} use non-existing ActionPoiID {gMenuItem.ActionPoiID}, ignoring"); + gMenuItem.ActionPoiID = 0; } } + if (gMenuItem.GossipNpcOptionID.HasValue) + { + if (!CliDB.GossipNPCOptionStorage.ContainsKey(gMenuItem.GossipNpcOptionID.Value)) + { + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} use non-existing GossipNPCOption {gMenuItem.GossipNpcOptionID}, ignoring"); + gMenuItem.GossipNpcOptionID = null; + } + } + else + { + uint npcOptionId = optionToNpcOption.LookupByKey(gMenuItem.GossipOptionID); + if (npcOptionId != 0) + gMenuItem.GossipNpcOptionID = (int)npcOptionId; + } + if (gMenuItem.BoxBroadcastTextId != 0) { if (!CliDB.BroadcastTextStorage.ContainsKey(gMenuItem.BoxBroadcastTextId)) { - Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for MenuId {gMenuItem.MenuId}, OptionIndex {gMenuItem.OptionId} has non-existing or incompatible BoxBroadcastTextId {gMenuItem.BoxBroadcastTextId}, ignoring."); + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for MenuId {gMenuItem.MenuID}, OptionIndex {gMenuItem.OrderIndex} has non-existing or incompatible BoxBroadcastTextId {gMenuItem.BoxBroadcastTextId}, ignoring."); gMenuItem.BoxBroadcastTextId = 0; } } - gossipMenuItemsStorage.Add(gMenuItem.MenuId, gMenuItem); + if (gMenuItem.SpellID.HasValue) + { + if (!Global.SpellMgr.HasSpellInfo((uint)gMenuItem.SpellID.Value, Difficulty.None)) + { + Log.outError(LogFilter.Sql, $"Table `gossip_menu_option` for menu {gMenuItem.MenuID}, id {gMenuItem.OrderIndex} use non-existing Spell {gMenuItem.SpellID}, ignoring"); + gMenuItem.SpellID = null; + } + } + + gossipMenuItemsStorage.Add(gMenuItem.MenuID, gMenuItem); } while (result.NextRow()); Log.outInfo(LogFilter.ServerLoading, $"Loaded {gossipMenuItemsStorage.Count} gossip_menu_option entries in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); @@ -700,42 +752,6 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {_gossipMenuAddonStorage.Count} gossip_menu_addon IDs in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } - public void LoadGossipMenuItemAddon() - { - uint oldMSTime = Time.GetMSTime(); - - _gossipMenuItemAddonStorage.Clear(); - - // 0 1 2 - SQLResult result = DB.World.Query("SELECT MenuID, OptionId, GarrTalentTreeID FROM gossip_menu_option_addon"); - if (result.IsEmpty()) - { - Log.outInfo(LogFilter.ServerLoading, "Loaded 0 gossip_menu_option_addon IDs. DB table `gossip_menu_option_addon` is empty!"); - return; - } - - do - { - uint menuId = result.Read(0); - uint optionId = result.Read(1); - GossipMenuItemAddon addon = new(); - if (!result.IsNull(2)) - { - addon.GarrTalentTreeID = result.Read(2); - - if (!CliDB.GarrTalentTreeStorage.ContainsKey(addon.GarrTalentTreeID.Value)) - { - Log.outError(LogFilter.Sql, $"Table gossip_menu_option_addon: MenuID {menuId} OptionID {optionId} is using non-existing GarrTalentTree {addon.GarrTalentTreeID.Value}"); - addon.GarrTalentTreeID = null; - } - } - - _gossipMenuItemAddonStorage[Tuple.Create(menuId, optionId)] = addon; - - } while (result.NextRow()); - - Log.outInfo(LogFilter.ServerLoading, $"Loaded {_gossipMenuItemAddonStorage.Count} gossip_menu_option_addon IDs in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); - } public void LoadPointsOfInterest() { @@ -791,10 +807,6 @@ namespace Game { return _gossipMenuAddonStorage.LookupByKey(menuId); } - public GossipMenuItemAddon GetGossipMenuItemAddon(uint menuId, uint optionId) - { - return _gossipMenuItemAddonStorage.LookupByKey(Tuple.Create(menuId, optionId)); - } public PointOfInterest GetPointOfInterest(uint id) { return pointsOfInterestStorage.LookupByKey(id); @@ -3392,7 +3404,7 @@ namespace Game var gossipMenuItems = GetGossipMenuItemsMapBounds(gossipMenuId); var gossipOptionItr = gossipMenuItems.Find(entry => { - return entry.OptionId == gossipOptionIndex; + return entry.OrderIndex == gossipOptionIndex; }); if (gossipOptionItr == null) @@ -4999,6 +5011,12 @@ namespace Game 0.00f, // INVTYPE_RANGEDRIGHT 0.00f, // INVTYPE_QUIVER 0.00f, // INVTYPE_RELIC + 0.00f, // INVTYPE_PROFESSION_TOOL + 0.00f, // INVTYPE_PROFESSION_GEAR + 0.00f, // INVTYPE_EQUIPABLE_SPELL_OFFENSIVE + 0.00f, // INVTYPE_EQUIPABLE_SPELL_UTILITY + 0.00f, // INVTYPE_EQUIPABLE_SPELL_DEFENSIVE + 0.00f, // INVTYPE_EQUIPABLE_SPELL_MOBILITY }; static float[] weaponMultipliers = new float[] @@ -5944,9 +5962,6 @@ namespace Game //Player public void LoadPlayerInfo() { - for (uint race = 0; race < (int)Race.Max; ++race) - _playerInfo[race] = new PlayerInfo[(int)Class.Max]; - var time = Time.GetMSTime(); // Load playercreate { @@ -6059,7 +6074,7 @@ namespace Game Log.outError(LogFilter.Sql, $"Invalid NPE intro scene id {introSceneId} for class {currentclass} race {currentrace} pair in `playercreateinfo` table, ignoring."); } - _playerInfo[currentrace][currentclass] = info; + _playerInfo[Tuple.Create((Race)currentrace, (Class)currentclass)] = info; ++count; } while (result.NextRow()); @@ -6092,9 +6107,11 @@ namespace Game if (!characterLoadout.RaceMask.HasAnyFlag(SharedConst.GetMaskForRace(raceIndex))) continue; - PlayerInfo playerInfo = _playerInfo[(int)raceIndex][characterLoadout.ChrClassID]; + var playerInfo = _playerInfo.LookupByKey(Tuple.Create((Race)raceIndex, (Class)characterLoadout.ChrClassID)); if (playerInfo != null) { + playerInfo.itemContext = (ItemContext)characterLoadout.ItemContext; + foreach (ItemTemplate itemTemplate in items) { // BuyCount by default @@ -6200,11 +6217,11 @@ namespace Game { if (rcInfo.RaceMask == -1 || Convert.ToBoolean(SharedConst.GetMaskForRace(raceIndex) & rcInfo.RaceMask)) { - for (int classIndex = (int)Class.Warrior; classIndex < (int)Class.Max; ++classIndex) + for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { - if (rcInfo.ClassMask == -1 || Convert.ToBoolean((1 << (classIndex - 1)) & rcInfo.ClassMask)) + if (rcInfo.ClassMask == -1 || Convert.ToBoolean((1 << ((int)classIndex - 1)) & rcInfo.ClassMask)) { - PlayerInfo info = _playerInfo[(int)raceIndex][classIndex]; + PlayerInfo info = _playerInfo.LookupByKey(Tuple.Create(raceIndex, classIndex)); if (info != null) info.skills.Add(rcInfo); } @@ -6251,14 +6268,14 @@ namespace Game { if (raceMask == 0 || Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(raceIndex) & raceMask)) { - for (int classIndex = (int)Class.Warrior; classIndex < (int)Class.Max; ++classIndex) + for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { - if (classMask == 0 || Convert.ToBoolean((1 << (classIndex - 1)) & classMask)) + if (classMask == 0 || Convert.ToBoolean((1 << ((int)classIndex - 1)) & classMask)) { - PlayerInfo info = _playerInfo[(int)raceIndex][classIndex]; - if (info != null) + PlayerInfo playerInfo = _playerInfo.LookupByKey(Tuple.Create(raceIndex, classIndex)); + if (playerInfo != null) { - info.customSpells.Add(spellId); + playerInfo.customSpells.Add(spellId); ++count; } // We need something better here, the check is not accounting for spells used by multiple races/classes but not all of them. @@ -6316,11 +6333,11 @@ namespace Game { if (raceMask == 0 || Convert.ToBoolean((ulong)SharedConst.GetMaskForRace(raceIndex) & raceMask)) { - for (int classIndex = (int)Class.Warrior; classIndex < (int)Class.Max; ++classIndex) + for (Class classIndex = Class.Warrior; classIndex < Class.Max; ++classIndex) { - if (classMask == 0 || Convert.ToBoolean((1 << (classIndex - 1)) & classMask)) + if (classMask == 0 || Convert.ToBoolean((1 << ((int)classIndex - 1)) & classMask)) { - PlayerInfo info = _playerInfo[(int)raceIndex][classIndex]; + PlayerInfo info = _playerInfo.LookupByKey(Tuple.Create(raceIndex, classIndex)); if (info != null) { info.castSpells[playerCreateMode].Add(spellId); @@ -6350,20 +6367,20 @@ namespace Game uint count = 0; do { - uint currentrace = result.Read(0); - if (currentrace >= (int)Race.Max) + Race currentrace = (Race)result.Read(0); + if (currentrace >= Race.Max) { Log.outError(LogFilter.Sql, "Wrong race {0} in `playercreateinfo_action` table, ignoring.", currentrace); continue; } - uint currentclass = result.Read(1); - if (currentclass >= (int)Class.Max) + Class currentclass = (Class)result.Read(1); + if (currentclass >= Class.Max) { Log.outError(LogFilter.Sql, "Wrong class {0} in `playercreateinfo_action` table, ignoring.", currentclass); continue; } - PlayerInfo info = _playerInfo[currentrace][currentclass]; + PlayerInfo info = _playerInfo.LookupByKey(Tuple.Create(currentrace, currentclass)); if (info != null) info.action.Add(new PlayerCreateInfoAction(result.Read(2), result.Read(3), result.Read(4))); @@ -6381,7 +6398,6 @@ namespace Game for (var i = 0; i < (int)Race.Max; ++i) raceStatModifiers[i] = new short[(int)Stats.Max]; - // 0 1 2 3 4 SQLResult result = DB.World.Query("SELECT race, str, agi, sta, inte FROM player_racestats"); if (result.IsEmpty()) @@ -6393,15 +6409,15 @@ namespace Game do { - uint currentrace = result.Read(0); - if (currentrace >= (int)Race.Max) + Race currentrace = (Race)result.Read(0); + if (currentrace >= Race.Max) { Log.outError(LogFilter.Sql, $"Wrong race {currentrace} in `player_racestats` table, ignoring."); continue; } for (int i = 0; i < (int)Stats.Max; ++i) - raceStatModifiers[currentrace][i] = result.Read(i + 1); + raceStatModifiers[(int)currentrace][i] = result.Read(i + 1); } while (result.NextRow()); @@ -6418,8 +6434,8 @@ namespace Game do { - uint currentclass = result.Read(0); - if (currentclass >= (int)Class.Max) + Class currentclass = (Class)result.Read(0); + if (currentclass >= Class.Max) { Log.outError(LogFilter.Sql, "Wrong class {0} in `player_classlevelstats` table, ignoring.", currentclass); continue; @@ -6438,14 +6454,14 @@ namespace Game for (var race = 0; race < raceStatModifiers.Length; ++race) { - var pInfo = _playerInfo[race][currentclass]; - if (pInfo == null) + var playerInfo = _playerInfo.LookupByKey(Tuple.Create((Race)race, currentclass)); + if (playerInfo == null) continue; - if (pInfo.levelInfo[currentlevel - 1] == null) - pInfo.levelInfo[currentlevel - 1] = new PlayerLevelInfo(); + if (playerInfo.levelInfo[currentlevel - 1] == null) + playerInfo.levelInfo[currentlevel - 1] = new PlayerLevelInfo(); - var levelinfo = pInfo.levelInfo[currentlevel - 1]; + var levelinfo = playerInfo.levelInfo[currentlevel - 1]; for (var i = 0; i < (int)Stats.Max; i++) levelinfo.stats[i] = (ushort)(result.Read(i + 2) + raceStatModifiers[race][i]); @@ -6455,38 +6471,38 @@ namespace Game } while (result.NextRow()); // Fill gaps and check integrity - for (uint race = 0; race < (int)Race.Max; ++race) + for (Race race = 0; race < Race.Max; ++race) { // skip non existed races - if (!CliDB.ChrRacesStorage.ContainsKey(race) || _playerInfo[race][0] == null) + if (!CliDB.ChrRacesStorage.ContainsKey(race)) continue; - for (uint _class = 0; _class < (int)Class.Max; ++_class) + for (Class _class = 0; _class < Class.Max; ++_class) { // skip non existed classes - if (CliDB.ChrClassesStorage.LookupByKey(_class) == null || _playerInfo[race][_class] == null) + if (CliDB.ChrClassesStorage.LookupByKey(_class) == null) continue; - PlayerInfo pInfo = _playerInfo[race][_class]; - if (pInfo == null) + var playerInfo = _playerInfo.LookupByKey(Tuple.Create(race, _class)); + if (playerInfo == null) continue; // skip expansion races if not playing with expansion - if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.BurningCrusade && (race == (int)Race.BloodElf || race == (int)Race.Draenei)) + if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.BurningCrusade && (race == Race.BloodElf || race == Race.Draenei)) continue; // skip expansion classes if not playing with expansion - if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.WrathOfTheLichKing && _class == (int)Class.Deathknight) + if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.WrathOfTheLichKing && _class == Class.Deathknight) continue; - if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.MistsOfPandaria && (race == (int)Race.PandarenNeutral || race == (int)Race.PandarenHorde || race == (int)Race.PandarenAlliance)) + if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.MistsOfPandaria && (race == Race.PandarenNeutral || race == Race.PandarenHorde || race == Race.PandarenAlliance)) continue; - if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.Legion && _class == (int)Class.DemonHunter) + if (WorldConfig.GetIntValue(WorldCfg.Expansion) < (int)Expansion.Legion && _class == Class.DemonHunter) continue; // fatal error if no level 1 data - if (pInfo.levelInfo == null || pInfo.levelInfo[0] == null) + if (playerInfo.levelInfo == null || playerInfo.levelInfo[0].stats[0] == 0) { Log.outError(LogFilter.Sql, "Race {0} Class {1} Level 1 does not have stats data!", race, _class); Global.WorldMgr.StopNow(); @@ -6496,10 +6512,10 @@ namespace Game // fill level gaps for (var level = 1; level < WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel); ++level) { - if (pInfo.levelInfo[level] == null) + if (playerInfo.levelInfo[level].stats[0] == 0) { Log.outError(LogFilter.Sql, "Race {0} Class {1} Level {2} does not have stats data. Using stats data of level {3}.", race, _class, level + 1, level); - pInfo.levelInfo[level] = pInfo.levelInfo[level - 1]; + playerInfo.levelInfo[level] = playerInfo.levelInfo[level - 1]; } } } @@ -6561,18 +6577,18 @@ namespace Game } void PlayerCreateInfoAddItemHelper(uint race, uint class_, uint itemId, int count) { - if (_playerInfo[race][class_] == null) + var playerInfo = _playerInfo.LookupByKey(Tuple.Create((Race)race, (Class)class_)); + if (playerInfo == null) return; if (count > 0) - _playerInfo[race][class_].item.Add(new PlayerCreateInfoItem(itemId, (uint)count)); + playerInfo.item.Add(new PlayerCreateInfoItem(itemId, (uint)count)); else { if (count < -1) Log.outError(LogFilter.Sql, "Invalid count {0} specified on item {1} be removed from original player create info (use -1)!", count, itemId); - var items = _playerInfo[race][class_].item; - items.RemoveAll(item => { return item.item_id == itemId; }); + playerInfo.item.RemoveAll(item => item.item_id == itemId); } } @@ -6584,7 +6600,7 @@ namespace Game if (classId >= Class.Max) return null; - var info = _playerInfo[(int)raceId][(int)classId]; + var info = _playerInfo.LookupByKey(Tuple.Create(raceId, classId)); if (info == null) return null; @@ -6613,7 +6629,7 @@ namespace Game if (level < 1 || race >= Race.Max || _class >= Class.Max) return null; - PlayerInfo pInfo = _playerInfo[(int)race][(int)_class]; + PlayerInfo pInfo = _playerInfo.LookupByKey(Tuple.Create(race, _class)); if (pInfo == null) return null; @@ -6626,7 +6642,7 @@ namespace Game PlayerLevelInfo BuildPlayerLevelInfo(Race race, Class _class, uint level) { // base data (last known level) - var info = _playerInfo[(byte)race][(int)_class].levelInfo[WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) - 1]; + var info = _playerInfo.LookupByKey(Tuple.Create(race, _class)).levelInfo[WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) - 1]; for (int lvl = WorldConfig.GetIntValue(WorldCfg.MaxPlayerLevel) - 1; lvl < level; ++lvl) { @@ -10911,7 +10927,6 @@ namespace Game MultiMap gossipMenusStorage = new(); MultiMap gossipMenuItemsStorage = new(); Dictionary _gossipMenuAddonStorage = new(); - Dictionary, GossipMenuItemAddon> _gossipMenuItemAddonStorage = new(); Dictionary pointsOfInterestStorage = new(); //Creature @@ -10946,7 +10961,7 @@ namespace Game Dictionary ItemTemplateStorage = new(); //Player - PlayerInfo[][] _playerInfo = new PlayerInfo[(int)Race.Max][]; + Dictionary, PlayerInfo> _playerInfo = new(); //Faction Change public Dictionary FactionChangeAchievements = new(); @@ -12007,6 +12022,7 @@ namespace Game public byte ClassID; public byte ActiveExpansionLevel; public byte AccountExpansionLevel; + public byte MinActiveExpansionLevel; } public class RaceClassAvailability diff --git a/Source/Game/Handlers/AuthenticationHandler.cs b/Source/Game/Handlers/AuthenticationHandler.cs index 2a8324b59..c9ae682e2 100644 --- a/Source/Game/Handlers/AuthenticationHandler.cs +++ b/Source/Game/Handlers/AuthenticationHandler.cs @@ -86,6 +86,7 @@ namespace Game SetTimeZoneInformation packet = new(); packet.ServerTimeTZ = "Europe/Paris"; packet.GameTimeTZ = "Europe/Paris"; + packet.ServerRegionalTZ = "Europe/Paris"; SendPacket(packet);//enabled it } diff --git a/Source/Game/Handlers/AzeriteHandler.cs b/Source/Game/Handlers/AzeriteHandler.cs index 035e9fbfe..1211a5577 100644 --- a/Source/Game/Handlers/AzeriteHandler.cs +++ b/Source/Game/Handlers/AzeriteHandler.cs @@ -246,7 +246,11 @@ namespace Game public void SendAzeriteRespecNPC(ObjectGuid npc) { - SendPacket(new AzeriteRespecNPC(npc)); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = npc; + npcInteraction.InteractionType = PlayerInteractionType.AzeriteRespec; + npcInteraction.Success = true; + SendPacket(npcInteraction); } } } diff --git a/Source/Game/Handlers/BankHandler.cs b/Source/Game/Handlers/BankHandler.cs index 2c8811a9f..c85cf65f6 100644 --- a/Source/Game/Handlers/BankHandler.cs +++ b/Source/Game/Handlers/BankHandler.cs @@ -297,10 +297,11 @@ namespace Game public void SendShowBank(ObjectGuid guid) { - m_currentBankerGUID = guid; - ShowBank packet = new(); - packet.Guid = guid; - SendPacket(packet); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.Banker; + npcInteraction.Success = true; + SendPacket(npcInteraction); } } } diff --git a/Source/Game/Handlers/BlackMarketHandlers.cs b/Source/Game/Handlers/BlackMarketHandlers.cs index 1c9339d34..756e1d14a 100644 --- a/Source/Game/Handlers/BlackMarketHandlers.cs +++ b/Source/Game/Handlers/BlackMarketHandlers.cs @@ -45,10 +45,11 @@ namespace Game void SendBlackMarketOpenResult(ObjectGuid guid, Creature auctioneer) { - BlackMarketOpenResult packet = new(); - packet.Guid = guid; - packet.Enable = Global.BlackMarketMgr.IsEnabled(); - SendPacket(packet); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.BlackMarketAuctioneer; + npcInteraction.Success = Global.BlackMarketMgr.IsEnabled(); + SendPacket(npcInteraction); } [WorldPacketHandler(ClientOpcodes.BlackMarketRequestItems)] diff --git a/Source/Game/Handlers/CharacterHandler.cs b/Source/Game/Handlers/CharacterHandler.cs index 2d85ed435..4ae08e62f 100644 --- a/Source/Game/Handlers/CharacterHandler.cs +++ b/Source/Game/Handlers/CharacterHandler.cs @@ -192,6 +192,15 @@ namespace Game if (req.ItemModifiedAppearanceID != 0 && !GetCollectionMgr().HasItemAppearance(req.ItemModifiedAppearanceID).PermAppearance) return false; + if (req.QuestID != 0) + { + if (!_player) + return false; + + if (!_player.IsQuestRewarded((uint)req.QuestID)) + return false; + } + if (checkRequiredDependentChoices) { var requiredChoices = Global.DB2Mgr.GetRequiredCustomizationChoices(req.Id); @@ -318,14 +327,14 @@ namespace Game RaceUnlockRequirement raceExpansionRequirement = Global.ObjectMgr.GetRaceUnlockRequirement(charCreate.CreateInfo.RaceId); if (raceExpansionRequirement == null) { - Log.outError(LogFilter.Player, $"Account {GetAccountId()} tried to create character with unavailable race {charCreate.CreateInfo.RaceId}"); - SendCharCreate(ResponseCodes.AccountCreateFailed); + Log.outError(LogFilter.Cheat, $"Account {GetAccountId()} tried to create character with unavailable race {charCreate.CreateInfo.RaceId}"); + SendCharCreate(ResponseCodes.CharCreateFailed); return; } if (raceExpansionRequirement.Expansion > (byte)GetAccountExpansion()) { - Log.outError(LogFilter.Player, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {raceExpansionRequirement.Expansion} race ({charCreate.CreateInfo.RaceId})"); + Log.outError(LogFilter.Cheat, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character with expansion {raceExpansionRequirement.Expansion} race ({charCreate.CreateInfo.RaceId})"); SendCharCreate(ResponseCodes.CharCreateExpansion); return; } @@ -338,18 +347,33 @@ namespace Game // return; //} - // prevent character creating Expansion class without Expansion account - ClassAvailability classExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirement(charCreate.CreateInfo.RaceId, charCreate.CreateInfo.ClassId); - if (classExpansionRequirement == null) + // prevent character creating Expansion race without Expansion account + ClassAvailability raceClassExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirement(charCreate.CreateInfo.RaceId, charCreate.CreateInfo.ClassId); + if (raceClassExpansionRequirement != null) { - Log.outError(LogFilter.Player, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character for race/class combination that is missing requirements in db ({charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId})"); - SendCharCreate(ResponseCodes.CharCreateExpansionClass); - return; + if (raceClassExpansionRequirement.ActiveExpansionLevel > (byte)GetExpansion() || raceClassExpansionRequirement.AccountExpansionLevel > (byte)GetAccountExpansion()) + { + Log.outError(LogFilter.Cheat, $"Account:[{GetAccountId()}] tried to create character with race/class {charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId} without required expansion " + + $"(had {GetExpansion()}/{GetAccountExpansion()}, required {raceClassExpansionRequirement.ActiveExpansionLevel}/{raceClassExpansionRequirement.AccountExpansionLevel})"); + SendCharCreate(ResponseCodes.CharCreateExpansionClass); + return; + } } - - if (classExpansionRequirement.ActiveExpansionLevel > (int)GetExpansion() || classExpansionRequirement.AccountExpansionLevel > (int)GetAccountExpansion()) + else { - Log.outError(LogFilter.Player, $"Account:[{GetAccountId()}] tried to create character with race/class {charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId} without required expansion(had {GetExpansion()}/{GetAccountExpansion()}, required {classExpansionRequirement.ActiveExpansionLevel}/{classExpansionRequirement.AccountExpansionLevel})"); + ClassAvailability classExpansionRequirement = Global.ObjectMgr.GetClassExpansionRequirementFallback((byte)charCreate.CreateInfo.ClassId); + if (classExpansionRequirement != null) + { + if (classExpansionRequirement.MinActiveExpansionLevel > (byte)GetExpansion() || classExpansionRequirement.AccountExpansionLevel > (byte)GetAccountExpansion()) + { + Log.outError(LogFilter.Cheat, $"Account:[{GetAccountId()}] tried to create character with race/class {charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId} without required expansion " + + $"(had {GetExpansion()}/{GetAccountExpansion()}, required {classExpansionRequirement.ActiveExpansionLevel}/{classExpansionRequirement.AccountExpansionLevel})"); + SendCharCreate(ResponseCodes.CharCreateExpansionClass); + return; + } + } + else + Log.outError(LogFilter.Cheat, $"Expansion {GetAccountExpansion()} account:[{GetAccountId()}] tried to Create character for race/class combination that is missing requirements in db ({charCreate.CreateInfo.RaceId}/{charCreate.CreateInfo.ClassId})"); SendCharCreate(ResponseCodes.CharCreateExpansionClass); return; } @@ -450,9 +474,14 @@ namespace Game int demonHunterReqLevel = WorldConfig.GetIntValue(WorldCfg.CharacterCreatingMinLevelForDemonHunter); bool hasDemonHunterReqLevel = demonHunterReqLevel == 0; + uint evokerReqLevel = WorldConfig.GetUIntValue(WorldCfg.CharacterCreatingMinLevelForEvoker); + bool hasEvokerReqLevel = (evokerReqLevel == 0); bool allowTwoSideAccounts = !Global.WorldMgr.IsPvPRealm() || HasPermission(RBACPermissions.TwoSideCharacterCreation); int skipCinematics = WorldConfig.GetIntValue(WorldCfg.SkipCinematics); - bool checkDemonHunterReqs = createInfo.ClassId == Class.DemonHunter && !HasPermission(RBACPermissions.SkipCheckCharacterCreationDemonHunter); + bool checkClassLevelReqs = (createInfo.ClassId == Class.DemonHunter || createInfo.ClassId == Class.Evoker) + && !HasPermission(RBACPermissions.SkipCheckCharacterCreationDemonHunter); + int evokerLimit = WorldConfig.GetIntValue(WorldCfg.CharacterCreatingEvokersPerRealm); + bool hasEvokerLimit = evokerLimit != 0; void finalizeCharacterCreation(SQLResult result1) { @@ -461,8 +490,9 @@ namespace Game { Team team = Player.TeamForRace(createInfo.RaceId); byte accRace = result1.Read(1); + byte accClass = result1.Read(2); - if (checkDemonHunterReqs) + if (checkClassLevelReqs) { if (!hasDemonHunterReqLevel) { @@ -470,8 +500,17 @@ namespace Game if (accLevel >= demonHunterReqLevel) hasDemonHunterReqLevel = true; } + if (!hasEvokerReqLevel) + { + byte accLevel = result1.Read(0); + if (accLevel >= evokerReqLevel) + hasEvokerReqLevel = true; + } } + if (accClass == (byte)Class.Evoker) + --evokerLimit; + // need to check team only for first character // @todo what to if account already has characters of both races? if (!allowTwoSideAccounts) @@ -489,17 +528,18 @@ namespace Game // search same race for cinematic or same class if need // @todo check if cinematic already shown? (already logged in?; cinematic field) - while ((skipCinematics == 1 && !haveSameRace) || createInfo.ClassId == Class.DemonHunter) + while ((skipCinematics == 1 && !haveSameRace) || createInfo.ClassId == Class.DemonHunter || createInfo.ClassId == Class.Evoker) { if (!result1.NextRow()) break; accRace = result1.Read(1); + accClass = result1.Read(2); if (!haveSameRace) haveSameRace = createInfo.RaceId == (Race)accRace; - if (checkDemonHunterReqs) + if (checkClassLevelReqs) { if (!hasDemonHunterReqLevel) { @@ -507,11 +547,33 @@ namespace Game if (acc_level >= demonHunterReqLevel) hasDemonHunterReqLevel = true; } + if (!hasEvokerReqLevel) + { + byte accLevel = result1.Read(0); + if (accLevel >= evokerReqLevel) + hasEvokerReqLevel = true; + } } + if (accClass == (byte)Class.Evoker) + --evokerLimit; } } - if (checkDemonHunterReqs && !hasDemonHunterReqLevel) + if (checkClassLevelReqs) + { + if (!hasDemonHunterReqLevel) + { + SendCharCreate(ResponseCodes.CharCreateNewPlayer); + return; + } + if (!hasEvokerReqLevel) + { + SendCharCreate(ResponseCodes.CharCreateDracthyrLevelRequirement); + return; + } + } + + if (createInfo.ClassId == Class.Evoker && hasEvokerLimit && evokerLimit < 1) { SendCharCreate(ResponseCodes.CharCreateNewPlayer); return; @@ -520,7 +582,7 @@ namespace Game // Check name uniqueness in the same step as saving to database if (Global.CharacterCacheStorage.GetCharacterCacheByName(createInfo.Name) != null) { - SendCharCreate(ResponseCodes.CharCreateNameInUse); + SendCharCreate(ResponseCodes.CharCreateDracthyrDuplicate); return; } @@ -580,7 +642,7 @@ namespace Game stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_CREATE_INFO); stmt.AddValue(0, GetAccountId()); - stmt.AddValue(1, (skipCinematics == 1 || createInfo.ClassId == Class.DemonHunter) ? 1200 : 1); // 200 (max chars per realm) + 1000 (max deleted chars per realm) + stmt.AddValue(1, (skipCinematics == 1 || createInfo.ClassId == Class.DemonHunter || createInfo.ClassId == Class.Evoker) ? 1200 : 1); // 200 (max chars per realm) + 1000 (max deleted chars per realm) queryCallback.WithCallback(finalizeCharacterCreation).SetNextQuery(DB.Characters.AsyncQuery(stmt)); })); } diff --git a/Source/Game/Handlers/ItemHandler.cs b/Source/Game/Handlers/ItemHandler.cs index 2f2f674d6..1f8bbf7b4 100644 --- a/Source/Game/Handlers/ItemHandler.cs +++ b/Source/Game/Handlers/ItemHandler.cs @@ -808,8 +808,8 @@ namespace Game gems[i] = gem; gemData[i].ItemId = gem.GetEntry(); gemData[i].Context = (byte)gem.m_itemData.Context; - for (int b = 0; b < ((List)gem.m_itemData.BonusListIDs).Count && b < 16; ++b) - gemData[i].BonusListIDs[b] = (ushort)((List)gem.m_itemData.BonusListIDs)[b]; + for (int b = 0; b < gem.GetBonusListIDs().Count && b < 16; ++b) + gemData[i].BonusListIDs[b] = (ushort)gem.GetBonusListIDs()[b]; gemProperties[i] = CliDB.GemPropertiesStorage.LookupByKey(gem.GetTemplate().GetGemProperties()); } diff --git a/Source/Game/Handlers/MailHandler.cs b/Source/Game/Handlers/MailHandler.cs index 4500fe061..9ed4272af 100644 --- a/Source/Game/Handlers/MailHandler.cs +++ b/Source/Game/Handlers/MailHandler.cs @@ -682,9 +682,11 @@ namespace Game public void SendShowMailBox(ObjectGuid guid) { - ShowMailbox packet = new(); - packet.PostmasterGUID = guid; - SendPacket(packet); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.MailInfo; + npcInteraction.Success = true; + SendPacket(npcInteraction); } } } diff --git a/Source/Game/Handlers/NPCHandler.cs b/Source/Game/Handlers/NPCHandler.cs index 1088475d3..3d7f17f37 100644 --- a/Source/Game/Handlers/NPCHandler.cs +++ b/Source/Game/Handlers/NPCHandler.cs @@ -20,6 +20,7 @@ using Framework.Database; using Game.BattleGrounds; using Game.DataStorage; using Game.Entities; +using Game.Misc; using Game.Networking; using Game.Networking.Packets; using System; @@ -48,9 +49,11 @@ namespace Game public void SendTabardVendorActivate(ObjectGuid guid) { - PlayerTabardVendorActivate packet = new(); - packet.Vendor = guid; - SendPacket(packet); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.TabardVendor; + npcInteraction.Success = true; + SendPacket(npcInteraction); } [WorldPacketHandler(ClientOpcodes.TrainerList, Processing = PacketProcessing.Inplace)] @@ -172,7 +175,8 @@ namespace Game [WorldPacketHandler(ClientOpcodes.GossipSelectOption)] void HandleGossipSelectOption(GossipSelectOption packet) { - if (GetPlayer().PlayerTalkClass.GetGossipMenu().GetItem(packet.GossipIndex) == null) + GossipMenuItem gossipMenuItem = _player.PlayerTalkClass.GetGossipMenu().GetItem(packet.GossipOptionID); + if (gossipMenuItem == null) return; // Prevent cheating on C# scripted menus @@ -224,26 +228,26 @@ namespace Game { if (unit != null) { - if (!unit.GetAI().OnGossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode)) - GetPlayer().OnGossipSelect(unit, packet.GossipIndex, packet.GossipID); + if (!unit.GetAI().OnGossipSelectCode(_player, packet.GossipID, gossipMenuItem.OrderIndex, packet.PromotionCode)) + GetPlayer().OnGossipSelect(unit, packet.GossipOptionID, packet.GossipID); } else { - if (!go.GetAI().OnGossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode)) - _player.OnGossipSelect(go, packet.GossipIndex, packet.GossipID); + if (!go.GetAI().OnGossipSelectCode(_player, packet.GossipID, gossipMenuItem.OrderIndex, packet.PromotionCode)) + _player.OnGossipSelect(go, packet.GossipOptionID, packet.GossipID); } } else { if (unit != null) { - if (!unit.GetAI().OnGossipSelect(_player, packet.GossipID, packet.GossipIndex)) - GetPlayer().OnGossipSelect(unit, packet.GossipIndex, packet.GossipID); + if (!unit.GetAI().OnGossipSelect(_player, packet.GossipID, gossipMenuItem.OrderIndex)) + GetPlayer().OnGossipSelect(unit, packet.GossipOptionID, packet.GossipID); } else { - if (!go.GetAI().OnGossipSelect(_player, packet.GossipID, packet.GossipIndex)) - GetPlayer().OnGossipSelect(go, packet.GossipIndex, packet.GossipID); + if (!go.GetAI().OnGossipSelect(_player, packet.GossipID, gossipMenuItem.OrderIndex)) + GetPlayer().OnGossipSelect(go, packet.GossipOptionID, packet.GossipID); } } } diff --git a/Source/Game/Handlers/TransmogrificationHandler.cs b/Source/Game/Handlers/TransmogrificationHandler.cs index c688ae92b..003935249 100644 --- a/Source/Game/Handlers/TransmogrificationHandler.cs +++ b/Source/Game/Handlers/TransmogrificationHandler.cs @@ -342,7 +342,11 @@ namespace Game public void SendOpenTransmogrifier(ObjectGuid guid) { - SendPacket(new TransmogrifyNPC(guid)); + NPCInteractionOpenResult npcInteraction = new(); + npcInteraction.Npc = guid; + npcInteraction.InteractionType = PlayerInteractionType.Transmogrifier; + npcInteraction.Success = true; + SendPacket(npcInteraction); } } } diff --git a/Source/Game/Handlers/VoidStorageHandler.cs b/Source/Game/Handlers/VoidStorageHandler.cs index 81d3d2ff1..d683819e9 100644 --- a/Source/Game/Handlers/VoidStorageHandler.cs +++ b/Source/Game/Handlers/VoidStorageHandler.cs @@ -157,7 +157,7 @@ namespace Game VoidStorageItem itemVS = new(Global.ObjectMgr.GenerateVoidStorageItemId(), item.GetEntry(), item.GetCreator(), item.GetItemRandomBonusListId(), item.GetModifier(ItemModifier.TimewalkerLevel), item.GetModifier(ItemModifier.ArtifactKnowledgeLevel), - item.GetContext(), item.m_itemData.BonusListIDs); + item.GetContext(), item.GetBonusListIDs()); VoidItem voidItem; voidItem.Guid = ObjectGuid.Create(HighGuid.Item, itemVS.ItemId); diff --git a/Source/Game/Maps/TransportManager.cs b/Source/Game/Maps/TransportManager.cs index 0b49d9bf9..f5cf096a5 100644 --- a/Source/Game/Maps/TransportManager.cs +++ b/Source/Game/Maps/TransportManager.cs @@ -370,11 +370,7 @@ namespace Game.Maps { foreach (uint mapId in transport.MapIds) Cypher.Assert(!CliDB.MapStorage.LookupByKey(mapId).Instanceable()); - - transport.InInstance = false; } - else - transport.InInstance = CliDB.MapStorage.LookupByKey(transport.MapIds.First()).Instanceable(); transport.TotalPathTime = totalTime; } @@ -424,6 +420,12 @@ namespace Game.Maps return null; } + if (!tInfo.MapIds.Contains(map.GetId())) + { + Log.outError(LogFilter.Transport, $"Transport {entry} attempted creation on map it has no path for {map.GetId()}!"); + return null; + } + Position startingPosition = tInfo.ComputePosition(0, out _, out _); if (startingPosition == null) { @@ -435,7 +437,6 @@ namespace Game.Maps Transport trans = new(); // ...at first waypoint - uint mapId = tInfo.PathLegs.First().MapId; float x = startingPosition.GetPositionX(); float y = startingPosition.GetPositionY(); float z = startingPosition.GetPositionZ(); @@ -448,16 +449,6 @@ namespace Game.Maps PhasingHandler.InitDbPhaseShift(trans.GetPhaseShift(), phaseUseFlags, phaseId, phaseGroupId); - MapRecord mapEntry = CliDB.MapStorage.LookupByKey(mapId); - if (mapEntry != null) - { - if (mapEntry.Instanceable() != tInfo.InInstance) - { - Log.outError(LogFilter.Transport, "Transport {0} (name: {1}) attempted creation in instance map (id: {2}) but it is not an instanced transport!", entry, trans.GetName(), mapId); - //return null; - } - } - // use preset map for instances (need to know which instance) trans.SetMap(map); if (instanceMap != null) @@ -536,7 +527,6 @@ namespace Game.Maps public List Events = new(); public HashSet MapIds = new(); - public bool InInstance; public Position ComputePosition(uint time, out TransportMovementState moveState, out int legIndex) { diff --git a/Source/Game/Networking/Packets/AuctionHousePackets.cs b/Source/Game/Networking/Packets/AuctionHousePackets.cs index 94d8de6a5..fffbb0c3b 100644 --- a/Source/Game/Networking/Packets/AuctionHousePackets.cs +++ b/Source/Game/Networking/Packets/AuctionHousePackets.cs @@ -784,12 +784,12 @@ namespace Game.Networking.Packets public struct AuctionListFilterSubClass { public int ItemSubclass; - public uint InvTypeMask; + public ulong InvTypeMask; public AuctionListFilterSubClass(WorldPacket data) { + InvTypeMask = data.ReadUInt64(); ItemSubclass = data.ReadInt32(); - InvTypeMask = data.ReadUInt32(); } } diff --git a/Source/Game/Networking/Packets/AuthenticationPackets.cs b/Source/Game/Networking/Packets/AuthenticationPackets.cs index 24386aeb1..831e6146a 100644 --- a/Source/Game/Networking/Packets/AuthenticationPackets.cs +++ b/Source/Game/Networking/Packets/AuthenticationPackets.cs @@ -138,6 +138,7 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt8(classAvailability.ClassID); _worldPacket.WriteUInt8(classAvailability.ActiveExpansionLevel); _worldPacket.WriteUInt8(classAvailability.AccountExpansionLevel); + _worldPacket.WriteUInt8(classAvailability.MinActiveExpansionLevel); } } @@ -166,7 +167,7 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt16(SuccessInfo.NumPlayersAlliance.Value); if(SuccessInfo.ExpansionTrialExpiration.HasValue) - _worldPacket.WriteInt32(SuccessInfo.ExpansionTrialExpiration.Value); + _worldPacket.WriteInt64(SuccessInfo.ExpansionTrialExpiration.Value); foreach (VirtualRealmInfo virtualRealm in SuccessInfo.VirtualRealms) virtualRealm.Write(_worldPacket); @@ -220,7 +221,7 @@ namespace Game.Networking.Packets public bool ForceCharacterTemplate; // forces the client to always use a character template when creating a new character. @see Templates. @todo implement 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 int? ExpansionTrialExpiration; // expansion trial expiration unix timestamp + public long? ExpansionTrialExpiration; // expansion trial expiration unix timestamp public struct GameTime { diff --git a/Source/Game/Networking/Packets/AzeritePackets.cs b/Source/Game/Networking/Packets/AzeritePackets.cs index 25c4c01b1..ed64bc853 100644 --- a/Source/Game/Networking/Packets/AzeritePackets.cs +++ b/Source/Game/Networking/Packets/AzeritePackets.cs @@ -34,25 +34,6 @@ namespace Game.Networking.Packets public ulong XP; } - class OpenHeartForge : ServerPacket - { - public OpenHeartForge() : base(ServerOpcodes.OpenHeartForge) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(ForgeGUID); - } - - public ObjectGuid ForgeGUID; - } - - class CloseHeartForge : ServerPacket - { - public CloseHeartForge() : base(ServerOpcodes.CloseHeartForge) { } - - public override void Write() { } - } - class AzeriteEssenceUnlockMilestone : ClientPacket { public AzeriteEssenceUnlockMilestone(WorldPacket packet) : base(packet) { } @@ -141,19 +122,4 @@ namespace Game.Networking.Packets public bool IsHeartEquipped; } - - class AzeriteRespecNPC : ServerPacket - { - public AzeriteRespecNPC(ObjectGuid npcGuid) : base(ServerOpcodes.AzeriteRespecNpc) - { - NpcGUID = npcGuid; - } - - public override void Write() - { - _worldPacket.WritePackedGuid(NpcGUID); - } - - public ObjectGuid NpcGUID; - } } diff --git a/Source/Game/Networking/Packets/BattleGroundPackets.cs b/Source/Game/Networking/Packets/BattleGroundPackets.cs index ac49820df..3e4a129ac 100644 --- a/Source/Game/Networking/Packets/BattleGroundPackets.cs +++ b/Source/Game/Networking/Packets/BattleGroundPackets.cs @@ -573,12 +573,15 @@ namespace Game.Networking.Packets public int Unused2; public int WeeklyPlayed; public int WeeklyWon; + public int RoundsSeasonPlayed; + public int RoundsSeasonWon; + public int RoundsWeeklyPlayed; + public int RoundsWeeklyWon; public int BestWeeklyRating; public int LastWeeksBestRating; public int BestSeasonRating; public int PvpTierID; public int Unused3; - public int WeeklyBestWinPvpTierID; public int Unused4; public int Rank; public bool Disqualified; @@ -593,12 +596,15 @@ namespace Game.Networking.Packets data.WriteInt32(Unused2); data.WriteInt32(WeeklyPlayed); data.WriteInt32(WeeklyWon); + data.WriteInt32(RoundsSeasonPlayed); + data.WriteInt32(RoundsSeasonWon); + data.WriteInt32(RoundsWeeklyPlayed); + data.WriteInt32(RoundsWeeklyWon); data.WriteInt32(BestWeeklyRating); data.WriteInt32(LastWeeksBestRating); data.WriteInt32(BestSeasonRating); data.WriteInt32(PvpTierID); data.WriteInt32(Unused3); - data.WriteInt32(WeeklyBestWinPvpTierID); data.WriteInt32(Unused4); data.WriteInt32(Rank); data.WriteBit(Disqualified); diff --git a/Source/Game/Networking/Packets/BlackMarketPackets.cs b/Source/Game/Networking/Packets/BlackMarketPackets.cs index c85630ff0..a7a668d26 100644 --- a/Source/Game/Networking/Packets/BlackMarketPackets.cs +++ b/Source/Game/Networking/Packets/BlackMarketPackets.cs @@ -33,21 +33,6 @@ namespace Game.Networking.Packets public ObjectGuid Guid; } - class BlackMarketOpenResult : ServerPacket - { - public BlackMarketOpenResult() : base(ServerOpcodes.BlackMarketOpenResult) { } - - public override void Write() - { - _worldPacket .WritePackedGuid(Guid); - _worldPacket.WriteBit(Enable); - _worldPacket.FlushBits(); - } - - public ObjectGuid Guid; - public bool Enable = true; - } - class BlackMarketRequestItems : ClientPacket { public BlackMarketRequestItems(WorldPacket packet) : base(packet) { } diff --git a/Source/Game/Networking/Packets/CharacterPackets.cs b/Source/Game/Networking/Packets/CharacterPackets.cs index a0a71bb85..2de02379b 100644 --- a/Source/Game/Networking/Packets/CharacterPackets.cs +++ b/Source/Game/Networking/Packets/CharacterPackets.cs @@ -44,12 +44,14 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(IsNewPlayerRestrictionSkipped); _worldPacket.WriteBit(IsNewPlayerRestricted); _worldPacket.WriteBit(IsNewPlayer); + _worldPacket.WriteBit(IsTrialAccountRestricted); _worldPacket.WriteBit(DisabledClassesMask.HasValue); _worldPacket.WriteBit(IsAlliedRacesCreationAllowed); _worldPacket.WriteInt32(Characters.Count); _worldPacket.WriteInt32(MaxCharacterLevel); _worldPacket.WriteInt32(RaceUnlockData.Count); _worldPacket.WriteInt32(UnlockedConditionalAppearances.Count); + _worldPacket.WriteInt32(RaceLimitDisables.Count); if (DisabledClassesMask.HasValue) _worldPacket.WriteUInt32(DisabledClassesMask.Value); @@ -57,6 +59,9 @@ namespace Game.Networking.Packets foreach (UnlockedConditionalAppearance unlockedConditionalAppearance in UnlockedConditionalAppearances) unlockedConditionalAppearance.Write(_worldPacket); + foreach (RaceLimitDisableInfo raceLimitDisableInfo in RaceLimitDisables) + raceLimitDisableInfo.Write(_worldPacket); + foreach (CharacterInfo charInfo in Characters) charInfo.Write(_worldPacket); @@ -69,6 +74,7 @@ namespace Game.Networking.Packets public bool IsNewPlayerRestrictionSkipped; // allows client to skip new player restrictions public bool IsNewPlayerRestricted; // forbids using level boost and class trials public bool IsNewPlayer; // forbids hero classes and allied races + public bool IsTrialAccountRestricted; public bool IsAlliedRacesCreationAllowed; public int MaxCharacterLevel = 1; @@ -77,6 +83,7 @@ namespace Game.Networking.Packets public List Characters = new(); // all characters on the list public List RaceUnlockData = new(); // public List UnlockedConditionalAppearances = new(); + public List RaceLimitDisables = new(); public class CharacterInfo { @@ -147,11 +154,11 @@ namespace Game.Networking.Packets var spec = Global.DB2Mgr.GetChrSpecializationByIndex(ClassId, fields.Read(21)); if (spec != null) - SpecID = (ushort)spec.Id; + SpecID = (short)spec.Id; - LastLoginVersion = fields.Read(22); + LastLoginVersion = fields.Read(22); - for (byte slot = 0; slot < InventorySlots.BagEnd; ++slot) + for (byte slot = 0; slot < InventorySlots.ReagentBagEnd; ++slot) { VisualItems[slot].InvType = (byte)equipment.NextUInt32(); VisualItems[slot].DisplayId = equipment.NextUInt32(); @@ -190,9 +197,9 @@ namespace Game.Networking.Packets visualItem.Write(data); data.WriteInt64(LastPlayedTime); - data.WriteUInt16(SpecID); - data.WriteUInt32(Unknown703); - data.WriteUInt32(LastLoginVersion); + data.WriteInt16(SpecID); + data.WriteInt32(Unknown703); + data.WriteInt32(LastLoginVersion); data.WriteUInt32(Flags4); data.WriteInt32(MailSenders.Count); data.WriteInt32(MailSenderTypes.Count); @@ -244,16 +251,16 @@ namespace Game.Networking.Packets public bool FirstLogin; public byte unkWod61x; public long LastPlayedTime; - public ushort SpecID; - public uint Unknown703; - public uint LastLoginVersion; + public short SpecID; + public int Unknown703; + public int LastLoginVersion; public uint OverrideSelectScreenFileDataID; public uint PetCreatureDisplayId; public uint PetExperienceLevel; public uint PetCreatureFamilyId; public bool BoostInProgress; // @todo public uint[] ProfessionIds = new uint[2]; // @todo - public VisualItemInfo[] VisualItems = new VisualItemInfo[InventorySlots.BagEnd]; + public VisualItemInfo[] VisualItems = new VisualItemInfo[InventorySlots.ReagentBagEnd]; public List MailSenders = new(); public List MailSenderTypes = new(); @@ -311,6 +318,24 @@ namespace Game.Networking.Packets public int AchievementID; public int Unused; } + + public struct RaceLimitDisableInfo + { + enum blah + { + Server, + Level + } + + public int RaceID; + public int BlockReason; + + public void Write(WorldPacket data) + { + data.WriteInt32(RaceID); + data.WriteInt32(BlockReason); + } + } } class CheckCharacterNameAvailability : ClientPacket @@ -500,6 +525,7 @@ namespace Game.Networking.Packets RaceOrFactionChangeInfo.Guid = _worldPacket.ReadPackedGuid(); RaceOrFactionChangeInfo.SexID = (Gender)_worldPacket.ReadUInt8(); RaceOrFactionChangeInfo.RaceID = (Race)_worldPacket.ReadUInt8(); + RaceOrFactionChangeInfo.InitialRaceID = (Race)_worldPacket.ReadUInt8(); var customizationCount = _worldPacket.ReadUInt32(); RaceOrFactionChangeInfo.Name = _worldPacket.ReadString(nameLength); @@ -851,6 +877,7 @@ namespace Game.Networking.Packets { var customizationCount = _worldPacket.ReadUInt32(); NewSex = _worldPacket.ReadUInt8(); + CustomizedRace = _worldPacket.ReadInt32(); for (var i = 0; i < customizationCount; ++i) { @@ -866,6 +893,7 @@ namespace Game.Networking.Packets public byte NewSex; public Array Customizations = new(50); + public int CustomizedRace; } public class BarberShopResult : ServerPacket @@ -902,7 +930,6 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt8((byte)Reason); _worldPacket.WriteInt32(Amount); _worldPacket.WriteFloat(GroupBonus); - _worldPacket.WriteUInt8(ReferAFriendBonusType); } public ObjectGuid Victim; @@ -910,7 +937,6 @@ namespace Game.Networking.Packets public PlayerLogXPReason Reason; public int Amount; public float GroupBonus; - public byte ReferAFriendBonusType; // 1 - 300% of normal XP; 2 - 150% of normal XP } class TitleEarned : ServerPacket @@ -1105,6 +1131,7 @@ namespace Game.Networking.Packets public class CharRaceOrFactionChangeInfo { public Race RaceID = Race.None; + public Race InitialRaceID = Race.None; public Gender SexID = Gender.None; public ObjectGuid Guid; public bool FactionChange; diff --git a/Source/Game/Networking/Packets/ChatPackets.cs b/Source/Game/Networking/Packets/ChatPackets.cs index 432e6a9f1..01987967c 100644 --- a/Source/Game/Networking/Packets/ChatPackets.cs +++ b/Source/Game/Networking/Packets/ChatPackets.cs @@ -31,7 +31,7 @@ namespace Game.Networking.Packets public override void Read() { Language = (Language)_worldPacket.ReadInt32(); - uint len = _worldPacket.ReadBits(9); + uint len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } @@ -47,7 +47,7 @@ namespace Game.Networking.Packets { Language = (Language)_worldPacket.ReadInt32(); uint targetLen = _worldPacket.ReadBits(9); - uint textLen = _worldPacket.ReadBits(9); + uint textLen = _worldPacket.ReadBits(11); Target = _worldPacket.ReadString(targetLen); Text = _worldPacket.ReadString(textLen); } @@ -66,7 +66,7 @@ namespace Game.Networking.Packets Language = (Language)_worldPacket.ReadInt32(); ChannelGUID = _worldPacket.ReadPackedGuid(); uint targetLen = _worldPacket.ReadBits(9); - uint textLen = _worldPacket.ReadBits(9); + uint textLen = _worldPacket.ReadBits(11); Target = _worldPacket.ReadString(targetLen); Text = _worldPacket.ReadString(textLen); } @@ -112,7 +112,7 @@ namespace Game.Networking.Packets public override void Read() { - uint len = _worldPacket.ReadBits(9); + uint len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } @@ -125,7 +125,7 @@ namespace Game.Networking.Packets public override void Read() { - uint len = _worldPacket.ReadBits(9); + uint len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } @@ -138,7 +138,7 @@ namespace Game.Networking.Packets public override void Read() { - uint len = _worldPacket.ReadBits(9); + uint len = _worldPacket.ReadBits(11); Text = _worldPacket.ReadString(len); } diff --git a/Source/Game/Networking/Packets/CraftingPackets.cs b/Source/Game/Networking/Packets/CraftingPackets.cs new file mode 100644 index 000000000..8372bf562 --- /dev/null +++ b/Source/Game/Networking/Packets/CraftingPackets.cs @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2012-2020 CypherCore + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Game.Entities; +using System.Collections.Generic; + +namespace Game.Networking.Packets +{ + struct SpellReducedReagent + { + public int ItemID; + public int Quantity; + + public void Write(WorldPacket data) + { + data.WriteInt32(ItemID); + data.WriteInt32(Quantity); + } + } + + class CraftingData + { + public int CraftingQualityID; + public int field_4; + public int field_8; + public int Multicraft; + public int field_10; + public int field_14; + public int CritBonusSkill; + public float field_1C; + public ulong field_20; + public bool IsCrit; + public bool field_29; + public bool field_2A; + public bool BonusCraft; + public List ResourcesReturned = new(); + public uint OperationID; + public ObjectGuid ItemGUID; + public int Quantity; + public ItemInstance OldItem = new(); + public ItemInstance NewItem = new(); + public int EnchantID; + + public void Write(WorldPacket data) + { + data.WriteInt32(CraftingQualityID); + data.WriteInt32(field_4); + data.WriteInt32(field_8); + data.WriteInt32(Multicraft); + data.WriteInt32(field_10); + data.WriteInt32(field_14); + data.WriteInt32(CritBonusSkill); + data.WriteFloat(field_1C); + data.WriteUInt64(field_20); + data.WriteInt32(ResourcesReturned.Count); + data.WriteUInt32(OperationID); + data.WritePackedGuid(ItemGUID); + data.WriteInt32(Quantity); + data.WriteInt32(EnchantID); + + foreach (SpellReducedReagent spellReducedReagent in ResourcesReturned) + spellReducedReagent.Write(data); + + data.WriteBit(IsCrit); + data.WriteBit(field_29); + data.WriteBit(field_2A); + data.WriteBit(BonusCraft); + data.FlushBits(); + + OldItem.Write(data); + NewItem.Write(data); + } + } +} diff --git a/Source/Game/Networking/Packets/GameObjectPackets.cs b/Source/Game/Networking/Packets/GameObjectPackets.cs index 468f240f3..6e22ee0de 100644 --- a/Source/Game/Networking/Packets/GameObjectPackets.cs +++ b/Source/Game/Networking/Packets/GameObjectPackets.cs @@ -27,9 +27,11 @@ namespace Game.Networking.Packets public override void Read() { Guid = _worldPacket.ReadPackedGuid(); + IsSoftInteract = _worldPacket.HasBit(); } public ObjectGuid Guid; + public bool IsSoftInteract; } public class GameObjReportUse : ClientPacket @@ -39,9 +41,11 @@ namespace Game.Networking.Packets public override void Read() { Guid = _worldPacket.ReadPackedGuid(); + IsSoftInteract = _worldPacket.HasBit(); } public ObjectGuid Guid; + public bool IsSoftInteract; } class GameObjectDespawn : ServerPacket @@ -136,22 +140,6 @@ namespace Game.Networking.Packets public bool PlayAsDespawn; } - class GameObjectUILink : ServerPacket - { - public GameObjectUILink() : base(ServerOpcodes.GameObjectUiLink, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(ObjectGUID); - _worldPacket.WriteInt32(UILink); - _worldPacket.WriteInt32(UIItemInteractionID); - } - - public ObjectGuid ObjectGUID; - public int UILink; - public int UIItemInteractionID; - } - class GameObjectPlaySpellVisual : ServerPacket { public GameObjectPlaySpellVisual() : base(ServerOpcodes.GameObjectPlaySpellVisual) { } @@ -181,4 +169,29 @@ namespace Game.Networking.Packets public ObjectGuid ObjectGUID; public byte State; } + + class GameObjectInteraction : ServerPacket + { + public ObjectGuid ObjectGUID; + public PlayerInteractionType InteractionType; + + public GameObjectInteraction() : base(ServerOpcodes.GameObjectInteraction) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(ObjectGUID); + _worldPacket.WriteInt32((int)InteractionType); + } + } + class GameObjectCloseInteraction : ServerPacket + { + public PlayerInteractionType InteractionType; + + public GameObjectCloseInteraction() : base(ServerOpcodes.GameObjectCloseInteraction) { } + + public override void Write() + { + _worldPacket.WriteInt32((int)InteractionType); + } + } } diff --git a/Source/Game/Networking/Packets/GarrisonPackets.cs b/Source/Game/Networking/Packets/GarrisonPackets.cs index d28d24636..c9362e0b8 100644 --- a/Source/Game/Networking/Packets/GarrisonPackets.cs +++ b/Source/Game/Networking/Packets/GarrisonPackets.cs @@ -316,22 +316,6 @@ namespace Game.Networking.Packets public uint GarrPlotInstanceID; } - - class GarrisonOpenTalentNpc : ServerPacket - { - public GarrisonOpenTalentNpc() : base(ServerOpcodes.GarrisonOpenTalentNpc, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(NpcGUID); - _worldPacket.WriteInt32(GarrTalentTreeID); - _worldPacket.WriteInt32(FriendshipFactionID); - } - - public ObjectGuid NpcGUID; - public int GarrTalentTreeID; - public int FriendshipFactionID; // Always 0 except on The Deaths of Chromie Scenario - } //Structs public struct GarrisonPlotInfo diff --git a/Source/Game/Networking/Packets/InspectPackets.cs b/Source/Game/Networking/Packets/InspectPackets.cs index ba1512e0b..2870298d2 100644 --- a/Source/Game/Networking/Packets/InspectPackets.cs +++ b/Source/Game/Networking/Packets/InspectPackets.cs @@ -75,7 +75,9 @@ namespace Game.Networking.Packets GuildData.Value.Write(_worldPacket); if (AzeriteLevel.HasValue) - _worldPacket.WriteUInt32((uint)AzeriteLevel); + _worldPacket.WriteUInt32(AzeriteLevel.Value); + + TalentTraits.Write(_worldPacket); } public PlayerModelDisplayInfo DisplayInfo; @@ -83,7 +85,7 @@ namespace Game.Networking.Packets public List Talents = new(); public Array PvpTalents = new(PlayerConst.MaxPvpTalentSlots, 0); public InspectGuildData? GuildData; - public Array Bracket = new(6, default); + public Array Bracket = new(7, default); public uint? AzeriteLevel; public int ItemLevel; public uint LifetimeHK; @@ -91,6 +93,7 @@ namespace Game.Networking.Packets public ushort TodayHK; public ushort YesterdayHK; public byte LifetimeMaxRank; + public TraitInspectInfo TalentTraits; } public class QueryInspectAchievements : ClientPacket @@ -290,6 +293,7 @@ namespace Game.Networking.Packets public void Write(WorldPacket data) { data.WriteUInt8(Bracket); + data.WriteInt32(Unused3); data.WriteInt32(Rating); data.WriteInt32(Rank); data.WriteInt32(WeeklyPlayed); @@ -302,6 +306,10 @@ namespace Game.Networking.Packets data.WriteInt32(WeeklyBestWinPvpTierID); data.WriteInt32(Unused1); data.WriteInt32(Unused2); + data.WriteInt32(RoundsSeasonPlayed); + data.WriteInt32(RoundsSeasonWon); + data.WriteInt32(RoundsWeeklyPlayed); + data.WriteInt32(RoundsWeeklyWon); data.WriteBit(Disqualified); data.FlushBits(); } @@ -318,10 +326,29 @@ namespace Game.Networking.Packets public int WeeklyBestWinPvpTierID; public int Unused1; public int Unused2; + public int Unused3; + public int RoundsSeasonPlayed; + public int RoundsSeasonWon; + public int RoundsWeeklyPlayed; + public int RoundsWeeklyWon; public byte Bracket; public bool Disqualified; } + public struct TraitInspectInfo + { + public int Level; + public int ChrSpecializationID; + public TraitConfig Config; + + public void Write(WorldPacket data) + { + data . WriteInt32(Level); + data . WriteInt32(ChrSpecializationID); + Config.Write(data); + } + } + public struct AzeriteEssenceData { public uint Index; diff --git a/Source/Game/Networking/Packets/ItemPackets.cs b/Source/Game/Networking/Packets/ItemPackets.cs index 710e9b238..5dd72a41d 100644 --- a/Source/Game/Networking/Packets/ItemPackets.cs +++ b/Source/Game/Networking/Packets/ItemPackets.cs @@ -20,6 +20,7 @@ using Framework.Dynamic; using Game.Entities; using System.Collections.Generic; using System.Linq; +using System; namespace Game.Networking.Packets { @@ -429,14 +430,26 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(BattlePetBreedQuality); _worldPacket.WriteInt32(BattlePetLevel); _worldPacket.WritePackedGuid(ItemGUID); + _worldPacket.WriteInt32(Toasts.Count); + foreach (UiEventToast uiEventToast in Toasts) + uiEventToast.Write(_worldPacket); + _worldPacket.WriteBit(Pushed); _worldPacket.WriteBit(Created); _worldPacket.WriteBits((uint)DisplayText, 3); _worldPacket.WriteBit(IsBonusRoll); _worldPacket.WriteBit(IsEncounterLoot); + _worldPacket.WriteBit(CraftingData != null); + _worldPacket.WriteBit(FirstCraftOperationID.HasValue); _worldPacket.FlushBits(); - Item.Write(_worldPacket); + Item.Write(_worldPacket); + + if (FirstCraftOperationID.HasValue) + _worldPacket.WriteUInt32(FirstCraftOperationID.Value); + + if (CraftingData != null) + CraftingData.Write(_worldPacket); } public ObjectGuid PlayerGUID; @@ -444,7 +457,7 @@ namespace Game.Networking.Packets public int SlotInBag; public ItemInstance Item; public int QuestLogItemID;// Item ID used for updating quest progress - // only set if different than real ID (similar to CreatureTemplate.KillCredit) + // only set if different than real ID (similar to CreatureTemplate.KillCredit) public uint Quantity; public uint QuantityInInventory; public int DungeonEncounterID; @@ -453,6 +466,9 @@ namespace Game.Networking.Packets public uint BattlePetBreedQuality; public int BattlePetLevel; public ObjectGuid ItemGUID; + public List Toasts = new(); + public CraftingData CraftingData; + public uint? FirstCraftOperationID; public bool Pushed; public DisplayType DisplayText; public bool Created; @@ -528,7 +544,7 @@ namespace Game.Networking.Packets public EnchantmentLog() : base(ServerOpcodes.EnchantmentLog, ConnectionType.Instance) { } public override void Write() - { + { _worldPacket.WritePackedGuid(Owner); _worldPacket.WritePackedGuid(Caster); _worldPacket.WritePackedGuid(ItemGUID); @@ -572,7 +588,7 @@ namespace Game.Networking.Packets public uint SpellID; public uint Cooldown; } - + class ItemEnchantTimeUpdate : ServerPacket { public ItemEnchantTimeUpdate() : base(ServerOpcodes.ItemEnchantTimeUpdate, ConnectionType.Instance) { } @@ -741,7 +757,7 @@ namespace Game.Networking.Packets } public class ItemMod - { + { public uint Value; public ItemModifier Type; @@ -858,7 +874,7 @@ namespace Game.Networking.Packets public ItemInstance(Item item) { ItemID = item.GetEntry(); - List bonusListIds = item.m_itemData.BonusListIDs; + List bonusListIds = item.GetBonusListIDs(); if (!bonusListIds.Empty()) { ItemBonus = new(); @@ -984,8 +1000,44 @@ namespace Game.Networking.Packets } } + public class ItemBonusKey : IEquatable + { + public uint ItemID; + public List BonusListIDs = new(); + public List Modifications = new(); + + public void Write(WorldPacket data) + { + data.WriteUInt32(ItemID); + data.WriteInt32(BonusListIDs.Count); + data.WriteInt32(Modifications.Count); + + if (!BonusListIDs.Empty()) + foreach (var id in BonusListIDs) + data.WriteUInt32(id); + + foreach (ItemMod modification in Modifications) + modification.Write(data); + } + + public bool Equals(ItemBonusKey right) + { + if (ItemID != right.ItemID) + return false; + + if (BonusListIDs != right.BonusListIDs) + return false; + + if (Modifications != right.Modifications) + return false; + + return true; + } + } + public class ItemEnchantData { + public ItemEnchantData() { } public ItemEnchantData(uint id, uint expiration, int charges, byte slot) { ID = id; @@ -1093,4 +1145,16 @@ namespace Game.Networking.Packets public ItemPurchaseRefundItem[] Items = new ItemPurchaseRefundItem[5]; public ItemPurchaseRefundCurrency[] Currencies = new ItemPurchaseRefundCurrency[5]; } + + public struct UiEventToast + { + public int UiEventToastID; + public int Asset; + + public void Write(WorldPacket data) + { + data.WriteInt32(UiEventToastID); + data.WriteInt32(Asset); + } + } } diff --git a/Source/Game/Networking/Packets/LootPackets.cs b/Source/Game/Networking/Packets/LootPackets.cs index 7db9c5182..6cfb591b9 100644 --- a/Source/Game/Networking/Packets/LootPackets.cs +++ b/Source/Game/Networking/Packets/LootPackets.cs @@ -29,9 +29,11 @@ namespace Game.Networking.Packets public override void Read() { Unit = _worldPacket.ReadPackedGuid(); + IsSoftInteract = _worldPacket.HasBit(); } public ObjectGuid Unit; + public bool IsSoftInteract; } public class LootResponse : ServerPacket @@ -273,6 +275,9 @@ namespace Game.Networking.Packets _worldPacket.WriteInt32(MapID); _worldPacket.WriteUInt32(RollTime); _worldPacket.WriteUInt8((byte)ValidRolls); + foreach (var reason in LootRollIneligibleReason) + _worldPacket.WriteUInt32((uint)reason); + _worldPacket.WriteUInt8((byte)Method); Item.Write(_worldPacket); } @@ -282,6 +287,7 @@ namespace Game.Networking.Packets public uint RollTime; public LootMethod Method; public RollMask ValidRolls; + public Array LootRollIneligibleReason = new Array(4); public LootItemData Item = new(); } diff --git a/Source/Game/Networking/Packets/MailPackets.cs b/Source/Game/Networking/Packets/MailPackets.cs index 3105ff452..0b75af587 100644 --- a/Source/Game/Networking/Packets/MailPackets.cs +++ b/Source/Game/Networking/Packets/MailPackets.cs @@ -293,18 +293,6 @@ namespace Game.Networking.Packets public float Delay = 0.0f; } - class ShowMailbox : ServerPacket - { - public ShowMailbox() : base(ServerOpcodes.ShowMailbox) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(PostmasterGUID); - } - - public ObjectGuid PostmasterGUID; - } - //Structs public class MailAttachedItem { diff --git a/Source/Game/Networking/Packets/MiscPackets.cs b/Source/Game/Networking/Packets/MiscPackets.cs index deb053007..9a3980851 100644 --- a/Source/Game/Networking/Packets/MiscPackets.cs +++ b/Source/Game/Networking/Packets/MiscPackets.cs @@ -58,21 +58,6 @@ namespace Game.Networking.Packets uint AreaID; } - public class BinderConfirm : ServerPacket - { - public BinderConfirm(ObjectGuid unit) : base(ServerOpcodes.BinderConfirm) - { - Unit = unit; - } - - public override void Write() - { - _worldPacket.WritePackedGuid(Unit); - } - - ObjectGuid Unit; - } - public class InvalidatePlayer : ServerPacket { public InvalidatePlayer() : base(ServerOpcodes.InvalidatePlayer) { } @@ -124,11 +109,13 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(WeeklyQuantity.HasValue); _worldPacket.WriteBit(TrackedQuantity.HasValue); _worldPacket.WriteBit(MaxQuantity.HasValue); - _worldPacket.WriteBit(Unused901.HasValue); + _worldPacket.WriteBit(TotalEarned.HasValue); _worldPacket.WriteBit(SuppressChatLog); _worldPacket.WriteBit(QuantityChange.HasValue); - _worldPacket.WriteBit(QuantityGainSource.HasValue); _worldPacket.WriteBit(QuantityLostSource.HasValue); + _worldPacket.WriteBit(QuantityGainSource.HasValue); + _worldPacket.WriteBit(FirstCraftOperationID.HasValue); + _worldPacket.WriteBit(LastSpendTime.HasValue); _worldPacket.FlushBits(); if (WeeklyQuantity.HasValue) @@ -140,29 +127,38 @@ namespace Game.Networking.Packets if (MaxQuantity.HasValue) _worldPacket.WriteInt32(MaxQuantity.Value); - if (Unused901.HasValue) - _worldPacket.WriteInt32(Unused901.Value); + if (TotalEarned.HasValue) + _worldPacket.WriteInt32(TotalEarned.Value); if (QuantityChange.HasValue) _worldPacket.WriteInt32(QuantityChange.Value); + if (QuantityLostSource.HasValue) + _worldPacket.WriteInt32(QuantityLostSource.Value); + if (QuantityGainSource.HasValue) _worldPacket.WriteInt32(QuantityGainSource.Value); - if (QuantityLostSource.HasValue) - _worldPacket.WriteInt32(QuantityLostSource.Value); + if (FirstCraftOperationID.HasValue) + _worldPacket.WriteUInt32(FirstCraftOperationID.Value); + + if (LastSpendTime.HasValue) + _worldPacket.WriteInt64(LastSpendTime.Value); } public uint Type; public int Quantity; public uint Flags; + public List Toasts = new(); public int? WeeklyQuantity; public int? TrackedQuantity; public int? MaxQuantity; - public int? Unused901; + public int? TotalEarned; public int? QuantityChange; public int? QuantityGainSource; public int? QuantityLostSource; + public uint? FirstCraftOperationID; + public long? LastSpendTime; public bool SuppressChatLog; } @@ -209,7 +205,8 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(data.MaxWeeklyQuantity.HasValue); _worldPacket.WriteBit(data.TrackedQuantity.HasValue); _worldPacket.WriteBit(data.MaxQuantity.HasValue); - _worldPacket.WriteBit(data.Unused901.HasValue); + _worldPacket.WriteBit(data.TotalEarned.HasValue); + _worldPacket.WriteBit(data.LastSpendTime.HasValue); _worldPacket.WriteBits(data.Flags, 5); _worldPacket.FlushBits(); @@ -221,8 +218,10 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(data.TrackedQuantity.Value); if (data.MaxQuantity.HasValue) _worldPacket.WriteInt32(data.MaxQuantity.Value); - if (data.Unused901.HasValue) - _worldPacket.WriteInt32(data.Unused901.Value); + if (data.TotalEarned.HasValue) + _worldPacket.WriteInt32(data.TotalEarned.Value); + if (data.LastSpendTime.HasValue) + _worldPacket.WriteInt64(data.LastSpendTime.Value); } } @@ -236,7 +235,8 @@ namespace Game.Networking.Packets public uint? MaxWeeklyQuantity; // Weekly Currency cap. public uint? TrackedQuantity; public int? MaxQuantity; - public int? Unused901; + public int? TotalEarned; + public long? LastSpendTime; public byte Flags; // 0 = none, } } diff --git a/Source/Game/Networking/Packets/MovementPackets.cs b/Source/Game/Networking/Packets/MovementPackets.cs index d26561c70..b3acddfb8 100644 --- a/Source/Game/Networking/Packets/MovementPackets.cs +++ b/Source/Game/Networking/Packets/MovementPackets.cs @@ -106,6 +106,7 @@ namespace Game.Networking.Packets data.ReadBit(); // HeightChangeFailed data.ReadBit(); // RemoteTimeValid bool hasInertia = data.HasBit(); + bool hasAdvFlying = data.HasBit(); if (hasTransport) ReadTransportInfo(data, ref movementInfo.transport); @@ -113,13 +114,22 @@ namespace Game.Networking.Packets if (hasInertia) { MovementInfo.Inertia inertia = new(); - inertia.guid = data.ReadPackedGuid(); + inertia.id = data.ReadInt32(); inertia.force = data.ReadPosition(); inertia.lifetime = data.ReadUInt32(); movementInfo.inertia = inertia; } + if (hasAdvFlying) + { + MovementInfo.AdvFlying advFlying = new(); + + advFlying.forwardVelocity = data.ReadFloat(); + advFlying.upVelocity = data.ReadFloat(); + movementInfo.advFlying = advFlying; + } + if (hasFall) { movementInfo.jump.fallTime = data.ReadUInt32(); @@ -146,6 +156,7 @@ namespace Game.Networking.Packets bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0; bool hasSpline = false; // todo 6.x send this infos bool hasInertia = movementInfo.inertia.HasValue; + bool hasAdvFlying = movementInfo.advFlying.HasValue; data.WritePackedGuid(movementInfo.Guid); data.WriteUInt32((uint)movementInfo.GetMovementFlags()); @@ -176,6 +187,7 @@ namespace Game.Networking.Packets data.WriteBit(false); // HeightChangeFailed data.WriteBit(false); // RemoteTimeValid data.WriteBit(hasInertia); + data.WriteBit(hasAdvFlying); data.FlushBits(); if (hasTransportData) @@ -183,11 +195,17 @@ namespace Game.Networking.Packets if (hasInertia) { - data.WritePackedGuid(movementInfo.inertia.Value.guid); + data.WriteInt32(movementInfo.inertia.Value.id); data.WriteXYZ(movementInfo.inertia.Value.force); data.WriteUInt32(movementInfo.inertia.Value.lifetime); } + if (hasAdvFlying) + { + data.WriteFloat(movementInfo.advFlying.Value.forwardVelocity); + data.WriteFloat(movementInfo.advFlying.Value.upVelocity); + } + if (hasFallData) { data.WriteUInt32(movementInfo.jump.fallTime); @@ -514,7 +532,7 @@ namespace Game.Networking.Packets } public ObjectGuid MoverGUID; - public uint SequenceIndex = 0; // Unit movement packet index, incremented each time + public uint SequenceIndex; // Unit movement packet index, incremented each time public float Speed = 1.0f; } @@ -555,7 +573,7 @@ namespace Game.Networking.Packets } public ObjectGuid MoverGUID; - public uint SequenceIndex = 0; // Unit movement packet index, incremented each time + public uint SequenceIndex; // Unit movement packet index, incremented each time } public class TransferPending : ServerPacket @@ -1167,6 +1185,12 @@ namespace Game.Networking.Packets public float InitVertSpeed; } + public class SpeedRange + { + public float Min; + public float Max; + } + public class MoveStateChange { public MoveStateChange(ServerOpcodes messageId, uint sequenceIndex) @@ -1180,12 +1204,13 @@ namespace Game.Networking.Packets data.WriteUInt16((ushort)MessageID); data.WriteUInt32(SequenceIndex); data.WriteBit(Speed.HasValue); + data.WriteBit(SpeedRange != null); data.WriteBit(KnockBack.HasValue); data.WriteBit(VehicleRecID.HasValue); data.WriteBit(CollisionHeight.HasValue); data.WriteBit(@MovementForce != null); data.WriteBit(MovementForceGUID.HasValue); - data.WriteBit(MovementInertiaGUID.HasValue); + data.WriteBit(MovementInertiaID.HasValue); data.WriteBit(MovementInertiaLifetimeMs.HasValue); data.FlushBits(); @@ -1195,6 +1220,12 @@ namespace Game.Networking.Packets if (Speed.HasValue) data.WriteFloat(Speed.Value); + if (SpeedRange != null) + { + data.WriteFloat(SpeedRange.Min); + data.WriteFloat(SpeedRange.Max); + } + if (KnockBack.HasValue) { data.WriteFloat(KnockBack.Value.HorzSpeed); @@ -1216,8 +1247,8 @@ namespace Game.Networking.Packets if (MovementForceGUID.HasValue) data.WritePackedGuid(MovementForceGUID.Value); - if (MovementInertiaGUID.HasValue) - data.WritePackedGuid(MovementInertiaGUID.Value); + if (MovementInertiaID.HasValue) + data.WriteInt32(MovementInertiaID.Value); if (MovementInertiaLifetimeMs.HasValue) data.WriteUInt32(MovementInertiaLifetimeMs.Value); @@ -1226,12 +1257,13 @@ namespace Game.Networking.Packets public ServerOpcodes MessageID; public uint SequenceIndex; public float? Speed; + public SpeedRange SpeedRange; public KnockBackInfo? KnockBack; public int? VehicleRecID; public CollisionHeightInfo? CollisionHeight; public MovementForce MovementForce; public ObjectGuid? MovementForceGUID; - public ObjectGuid? MovementInertiaGUID; + public int? MovementInertiaID; public uint? MovementInertiaLifetimeMs; } } diff --git a/Source/Game/Networking/Packets/NPCPackets.cs b/Source/Game/Networking/Packets/NPCPackets.cs index 55aca1edf..5d9a7d65b 100644 --- a/Source/Game/Networking/Packets/NPCPackets.cs +++ b/Source/Game/Networking/Packets/NPCPackets.cs @@ -43,6 +43,23 @@ namespace Game.Networking.Packets public ObjectGuid Unit; } + public class NPCInteractionOpenResult : ServerPacket + { + public NPCInteractionOpenResult() : base(ServerOpcodes.NpcInteractionOpenResult) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(Npc); + _worldPacket.WriteInt32((int)InteractionType); + _worldPacket.WriteBit(Success); + _worldPacket.FlushBits(); + } + + public ObjectGuid Npc; + public PlayerInteractionType InteractionType; + public bool Success = true; + } + public class GossipMessagePkt : ServerPacket { public GossipMessagePkt() : base(ServerOpcodes.GossipMessage) { } @@ -52,33 +69,20 @@ namespace Game.Networking.Packets _worldPacket.WritePackedGuid(GossipGUID); _worldPacket.WriteUInt32(GossipID); _worldPacket.WriteInt32(FriendshipFactionID); - _worldPacket.WriteInt32(TextID); - _worldPacket.WriteInt32(GossipOptions.Count); _worldPacket.WriteInt32(GossipText.Count); + _worldPacket.WriteBit(TextID.HasValue); + _worldPacket.WriteBit(TextID2.HasValue); + _worldPacket.FlushBits(); foreach (ClientGossipOptions options in GossipOptions) - { - _worldPacket.WriteInt32(options.ClientOption); - _worldPacket.WriteUInt8((byte)options.OptionNPC); - _worldPacket.WriteUInt8(options.OptionFlags); - _worldPacket.WriteInt32(options.OptionCost); - _worldPacket.WriteUInt32(options.OptionLanguage); + options.Write(_worldPacket); - _worldPacket.WriteBits(options.Text.GetByteCount(), 12); - _worldPacket.WriteBits(options.Confirm.GetByteCount(), 12); - _worldPacket.WriteBits((byte)options.Status, 2); - _worldPacket.WriteBit(options.SpellID.HasValue); - _worldPacket.FlushBits(); + if (TextID.HasValue) + _worldPacket.WriteInt32(TextID.Value); - options.Treasure.Write(_worldPacket); - - _worldPacket.WriteString(options.Text); - _worldPacket.WriteString(options.Confirm); - - if (options.SpellID.HasValue) - _worldPacket.WriteInt32(options.SpellID.Value); - } + if (TextID2.HasValue) + _worldPacket.WriteInt32(TextID2.Value); foreach (ClientGossipText text in GossipText) text.Write(_worldPacket); @@ -88,7 +92,8 @@ namespace Game.Networking.Packets public int FriendshipFactionID; public ObjectGuid GossipGUID; public List GossipText = new(); - public int TextID; + public int? TextID; + public int? TextID2; public uint GossipID; } @@ -100,18 +105,38 @@ namespace Game.Networking.Packets { GossipUnit = _worldPacket.ReadPackedGuid(); GossipID = _worldPacket.ReadUInt32(); - GossipIndex = _worldPacket.ReadUInt32(); + GossipOptionID = _worldPacket.ReadInt32(); uint length = _worldPacket.ReadBits(8); PromotionCode = _worldPacket.ReadString(length); } public ObjectGuid GossipUnit; - public uint GossipIndex; + public int GossipOptionID; public uint GossipID; public string PromotionCode; } + class GossipOptionNPCInteraction : ServerPacket + { + public GossipOptionNPCInteraction() : base(ServerOpcodes.GossipOptionNpcInteraction) { } + + public override void Write() + { + _worldPacket.WritePackedGuid(GossipGUID); + _worldPacket.WriteInt32(GossipNpcOptionID); + _worldPacket.WriteBit(FriendshipFactionID.HasValue); + _worldPacket.FlushBits(); + + if (FriendshipFactionID.HasValue) + _worldPacket.WriteInt32(FriendshipFactionID.Value); + } + + public ObjectGuid GossipGUID; + public int GossipNpcOptionID; + public int? FriendshipFactionID; + } + public class GossipComplete : ServerPacket { public bool SuppressSound; @@ -181,30 +206,6 @@ namespace Game.Networking.Packets public string Greeting; } - public class ShowBank : ServerPacket - { - public ShowBank() : base(ServerOpcodes.ShowBank, ConnectionType.Instance) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(Guid); - } - - public ObjectGuid Guid; - } - - public class PlayerTabardVendorActivate : ServerPacket - { - public PlayerTabardVendorActivate() : base(ServerOpcodes.PlayerTabardVendorActivate) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(Vendor); - } - - public ObjectGuid Vendor; - } - class GossipPOI : ServerPacket { public GossipPOI() : base(ServerOpcodes.GossipPoi) { } @@ -243,18 +244,6 @@ namespace Game.Networking.Packets public ObjectGuid Healer; } - public class SpiritHealerConfirm : ServerPacket - { - public SpiritHealerConfirm() : base(ServerOpcodes.SpiritHealerConfirm) { } - - public override void Write() - { - _worldPacket.WritePackedGuid(Unit); - } - - public ObjectGuid Unit; - } - class TrainerBuySpell : ClientPacket { public TrainerBuySpell(WorldPacket packet) : base(packet) { } @@ -344,16 +333,47 @@ namespace Game.Networking.Packets public class ClientGossipOptions { - public int ClientOption; + public int GossipOptionID; public GossipOptionNpc OptionNPC; public byte OptionFlags; public int OptionCost; public uint OptionLanguage; + public GossipOptionFlags Flags; + public int OrderIndex; public GossipOptionStatus Status; - public string Text; - public string Confirm; + public string Text = ""; + public string Confirm = ""; public TreasureLootList Treasure = new(); public int? SpellID; + public int? OverrideIconID; + + public void Write(WorldPacket data) + { + data.WriteInt32(GossipOptionID); + data.WriteUInt8((byte)OptionNPC); + data.WriteInt8((sbyte)OptionFlags); + data.WriteInt32(OptionCost); + data.WriteUInt32(OptionLanguage); + data.WriteInt32((int)Flags); + data.WriteInt32(OrderIndex); + data.WriteBits(Text.GetByteCount(), 12); + data.WriteBits(Confirm.GetByteCount(), 12); + data.WriteBits((byte)Status, 2); + data.WriteBit(SpellID.HasValue); + data.WriteBit(OverrideIconID.HasValue); + data.FlushBits(); + + Treasure.Write(data); + + data.WriteString(Text); + data.WriteString(Confirm); + + if (SpellID.HasValue) + data.WriteInt32(SpellID.Value); + + if (OverrideIconID.HasValue) + data.WriteInt32(OverrideIconID.Value); + } } public class ClientGossipText @@ -386,19 +406,20 @@ namespace Game.Networking.Packets { public void Write(WorldPacket data) { - data.WriteInt32(MuID); - data.WriteInt32(Type); - data.WriteInt32(Quantity); data.WriteUInt64(Price); + data.WriteInt32(MuID); data.WriteInt32(Durability); data.WriteInt32(StackCount); + data.WriteInt32(Quantity); data.WriteInt32(ExtendedCostID); data.WriteInt32(PlayerConditionFailed); - Item.Write(data); + data.WriteBits(Type, 3); data.WriteBit(Locked); data.WriteBit(DoNotFilterOnVendor); data.WriteBit(Refundable); data.FlushBits(); + + Item.Write(data); } public int MuID; diff --git a/Source/Game/Networking/Packets/QuestPackets.cs b/Source/Game/Networking/Packets/QuestPackets.cs index d40ec2037..5960ec068 100644 --- a/Source/Game/Networking/Packets/QuestPackets.cs +++ b/Source/Game/Networking/Packets/QuestPackets.cs @@ -197,6 +197,10 @@ namespace Game.Networking.Packets _worldPacket.WriteInt32(Info.Expansion); _worldPacket.WriteInt32(Info.ManagedWorldStateID); _worldPacket.WriteInt32(Info.QuestSessionBonus); + _worldPacket.WriteInt32(Info.QuestGiverCreatureID); + + _worldPacket.WriteInt32(Info.ConditionalQuestDescription.Count); + _worldPacket.WriteInt32(Info.ConditionalQuestCompletionLog.Count); foreach (QuestCompleteDisplaySpell rewardDisplaySpell in Info.RewardDisplaySpell) rewardDisplaySpell.Write(_worldPacket); @@ -243,6 +247,12 @@ namespace Game.Networking.Packets _worldPacket.WriteString(Info.PortraitTurnInText); _worldPacket.WriteString(Info.PortraitTurnInName); _worldPacket.WriteString(Info.QuestCompletionLog); + + foreach (ConditionalQuestText conditionalQuestText in Info.ConditionalQuestDescription) + conditionalQuestText.Write(_worldPacket); + + foreach (ConditionalQuestText conditionalQuestText in Info.ConditionalQuestCompletionLog) + conditionalQuestText.Write(_worldPacket); } } @@ -315,6 +325,8 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(PortraitGiverMount); _worldPacket.WriteInt32(PortraitGiverModelSceneID); _worldPacket.WriteUInt32(PortraitTurnIn); + _worldPacket.WriteUInt32(QuestGiverCreatureID); + _worldPacket.WriteInt32(ConditionalRewardText.Count); _worldPacket.WriteBits(QuestTitle.GetByteCount(), 9); _worldPacket.WriteBits(RewardText.GetByteCount(), 12); @@ -322,6 +334,10 @@ namespace Game.Networking.Packets _worldPacket.WriteBits(PortraitGiverName.GetByteCount(), 8); _worldPacket.WriteBits(PortraitTurnInText.GetByteCount(), 10); _worldPacket.WriteBits(PortraitTurnInName.GetByteCount(), 8); + _worldPacket.FlushBits(); + + foreach (ConditionalQuestText conditionalQuestText in ConditionalRewardText) + conditionalQuestText.Write(_worldPacket); _worldPacket.WriteString(QuestTitle); _worldPacket.WriteString(RewardText); @@ -335,12 +351,14 @@ namespace Game.Networking.Packets public uint PortraitGiver; public uint PortraitGiverMount; public int PortraitGiverModelSceneID; + public uint QuestGiverCreatureID; public string QuestTitle = ""; public string RewardText = ""; public string PortraitGiverText = ""; public string PortraitGiverName = ""; public string PortraitTurnInText = ""; public string PortraitTurnInName = ""; + public List ConditionalRewardText = new(); public QuestGiverOfferReward QuestData; public uint QuestPackageID; } @@ -437,12 +455,15 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(PortraitTurnIn); _worldPacket.WriteUInt32(QuestFlags[0]); // Flags _worldPacket.WriteUInt32(QuestFlags[1]); // FlagsEx + _worldPacket.WriteUInt32(QuestFlags[2]); // FlagsEx _worldPacket.WriteUInt32(SuggestedPartyMembers); _worldPacket.WriteInt32(LearnSpells.Count); _worldPacket.WriteInt32(DescEmotes.Count); _worldPacket.WriteInt32(Objectives.Count); _worldPacket.WriteInt32(QuestStartItemID); _worldPacket.WriteInt32(QuestSessionBonus); + _worldPacket.WriteInt32(QuestGiverCreatureID); + _worldPacket.WriteInt32(ConditionalDescriptionText.Count); foreach (uint spell in LearnSpells) _worldPacket.WriteUInt32(spell); @@ -483,13 +504,16 @@ namespace Game.Networking.Packets _worldPacket.WriteString(PortraitGiverName); _worldPacket.WriteString(PortraitTurnInText); _worldPacket.WriteString(PortraitTurnInName); + + foreach (ConditionalQuestText conditionalQuestText in ConditionalDescriptionText) + conditionalQuestText.Write(_worldPacket); } public ObjectGuid QuestGiverGUID; public ObjectGuid InformUnit; public uint QuestID; public int QuestPackageID; - public uint[] QuestFlags = new uint[2]; + public uint[] QuestFlags = new uint[3]; public uint SuggestedPartyMembers; public QuestRewards Rewards = new(); public List Objectives = new(); @@ -501,6 +525,7 @@ namespace Game.Networking.Packets public int PortraitGiverModelSceneID; public int QuestStartItemID; public int QuestSessionBonus; + public int QuestGiverCreatureID; public string PortraitGiverText = ""; public string PortraitGiverName = ""; public string PortraitTurnInText = ""; @@ -508,6 +533,7 @@ namespace Game.Networking.Packets public string QuestTitle = ""; public string LogDescription = ""; public string DescriptionText = ""; + public List ConditionalDescriptionText = new(); public bool DisplayPopup; public bool StartCheat; public bool AutoLaunched; @@ -526,6 +552,7 @@ namespace Game.Networking.Packets _worldPacket.WriteUInt32(CompEmoteType); _worldPacket.WriteUInt32(QuestFlags[0]); _worldPacket.WriteUInt32(QuestFlags[1]); + _worldPacket.WriteUInt32(QuestFlags[2]); _worldPacket.WriteUInt32(SuggestPartyMembers); _worldPacket.WriteInt32(MoneyToGet); _worldPacket.WriteInt32(Collect.Count); @@ -547,8 +574,15 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(AutoLaunched); _worldPacket.FlushBits(); + _worldPacket.WriteUInt32(QuestGiverCreatureID); + _worldPacket.WriteInt32(ConditionalCompletionText.Count); + _worldPacket.WriteBits(QuestTitle.GetByteCount(), 9); _worldPacket.WriteBits(CompletionText.GetByteCount(), 12); + _worldPacket.FlushBits(); + + foreach (ConditionalQuestText conditionalQuestText in ConditionalCompletionText) + conditionalQuestText.Write(_worldPacket); _worldPacket.WriteString(QuestTitle); _worldPacket.WriteString(CompletionText); @@ -565,9 +599,10 @@ namespace Game.Networking.Packets public List Collect = new(); public List Currency = new(); public int StatusFlags; - public uint[] QuestFlags = new uint[2]; + public uint[] QuestFlags = new uint[3]; public string QuestTitle = ""; public string CompletionText = ""; + public List ConditionalCompletionText = new(); } public class QuestGiverRequestReward : ClientPacket @@ -937,6 +972,30 @@ namespace Game.Networking.Packets } } + public class ConditionalQuestText + { + public int PlayerConditionID; + public int QuestGiverCreatureID; + public string Text = ""; + + public ConditionalQuestText(int playerConditionID, int questGiverCreatureID, string text) + { + PlayerConditionID = playerConditionID; + QuestGiverCreatureID = questGiverCreatureID; + Text = text; + } + + public void Write(WorldPacket data) + { + data.WriteInt32(PlayerConditionID); + data.WriteInt32(QuestGiverCreatureID); + data.WriteBits(Text.GetByteCount(), 12); + data.FlushBits(); + + data.WriteString(Text); + } + } + public class QuestInfo { public QuestInfo() @@ -1008,7 +1067,10 @@ namespace Game.Networking.Packets public int Expansion; public int ManagedWorldStateID; public int QuestSessionBonus; + public int QuestGiverCreatureID; // used to select ConditionalQuestText public List Objectives = new(); + public List ConditionalQuestDescription = new(); + public List ConditionalQuestCompletionLog = new(); public uint[] RewardItems = new uint[SharedConst.QuestRewardItemCount]; public uint[] RewardAmount = new uint[SharedConst.QuestRewardItemCount]; public int[] ItemDrop = new int[SharedConst.QuestItemDropCount]; @@ -1144,6 +1206,7 @@ namespace Game.Networking.Packets data.WriteUInt32(QuestID); data.WriteUInt32(QuestFlags[0]); // Flags data.WriteUInt32(QuestFlags[1]); // FlagsEx + data.WriteUInt32(QuestFlags[2]); // FlagsEx2 data.WriteUInt32(SuggestedPartyMembers); data.WriteInt32(Emotes.Count); @@ -1167,7 +1230,7 @@ namespace Game.Networking.Packets public uint SuggestedPartyMembers = 0; public QuestRewards Rewards = new(); public List Emotes = new(); - public uint[] QuestFlags = new uint[2]; // Flags and FlagsEx + public uint[] QuestFlags = new uint[3]; // Flags and FlagsEx } public struct QuestObjectiveSimple diff --git a/Source/Game/Networking/Packets/ReputationPackets.cs b/Source/Game/Networking/Packets/ReputationPackets.cs index 5c9906b59..a568ce175 100644 --- a/Source/Game/Networking/Packets/ReputationPackets.cs +++ b/Source/Game/Networking/Packets/ReputationPackets.cs @@ -22,7 +22,7 @@ namespace Game.Networking.Packets { public class InitializeFactions : ServerPacket { - const ushort FactionCount = 400; + const ushort FactionCount = 443; public InitializeFactions() : base(ServerOpcodes.InitializeFactions, ConnectionType.Instance) { } @@ -30,7 +30,7 @@ namespace Game.Networking.Packets { for (ushort i = 0; i < FactionCount; ++i) { - _worldPacket.WriteUInt8((byte)((ushort)FactionFlags[i] & 0xFF)); + _worldPacket.WriteUInt16((ushort)((ushort)FactionFlags[i] & 0xFF)); _worldPacket.WriteInt32(FactionStandings[i]); } @@ -72,7 +72,6 @@ namespace Game.Networking.Packets public override void Write() { - _worldPacket.WriteFloat(ReferAFriendBonus); _worldPacket.WriteFloat(BonusFromAchievementSystem); _worldPacket.WriteInt32(Faction.Count); @@ -83,7 +82,6 @@ namespace Game.Networking.Packets _worldPacket.FlushBits(); } - public float ReferAFriendBonus; public float BonusFromAchievementSystem; public List Faction = new(); public bool ShowVisual; diff --git a/Source/Game/Networking/Packets/SpellPackets.cs b/Source/Game/Networking/Packets/SpellPackets.cs index f0399932d..67fad6368 100644 --- a/Source/Game/Networking/Packets/SpellPackets.cs +++ b/Source/Game/Networking/Packets/SpellPackets.cs @@ -305,23 +305,13 @@ namespace Game.Networking.Packets public override void Write() { - _worldPacket.WriteInt32(SpellID.Count); - _worldPacket.WriteInt32(Superceded.Count); - _worldPacket.WriteInt32(FavoriteSpellID.Count); + _worldPacket.WriteInt32(ClientLearnedSpellData.Count); - foreach (var spellId in SpellID) - _worldPacket.WriteUInt32(spellId); - - foreach (var spellId in Superceded) - _worldPacket.WriteUInt32(spellId); - - foreach (var spellId in FavoriteSpellID) - _worldPacket.WriteInt32(spellId); + foreach (LearnedSpellInfo spell in ClientLearnedSpellData) + spell.Write(_worldPacket); } - public List SpellID = new(); - public List Superceded = new(); - public List FavoriteSpellID = new(); + public List ClientLearnedSpellData = new(); } public class LearnedSpells : ServerPacket @@ -330,22 +320,16 @@ namespace Game.Networking.Packets public override void Write() { - _worldPacket.WriteInt32(SpellID.Count); - _worldPacket.WriteInt32(FavoriteSpellID.Count); + _worldPacket.WriteInt32(ClientLearnedSpellData.Count); _worldPacket.WriteUInt32(SpecializationID); - - foreach (uint spell in SpellID) - _worldPacket.WriteUInt32(spell); - - foreach (int spell in FavoriteSpellID) - _worldPacket.WriteInt32(spell); - _worldPacket.WriteBit(SuppressMessaging); _worldPacket.FlushBits(); + + foreach (LearnedSpellInfo spell in ClientLearnedSpellData) + spell.Write(_worldPacket); } - public List SpellID = new(); - public List FavoriteSpellID = new(); + public List ClientLearnedSpellData = new(); public uint SpecializationID; public bool SuppressMessaging; } @@ -998,10 +982,12 @@ namespace Game.Networking.Packets { SpellClickUnitGuid = _worldPacket.ReadPackedGuid(); TryAutoDismount = _worldPacket.HasBit(); + IsSoftInteract = _worldPacket.HasBit(); } public ObjectGuid SpellClickUnitGuid; public bool TryAutoDismount; + public bool IsSoftInteract; } class ResyncRunes : ServerPacket @@ -1520,7 +1506,7 @@ namespace Game.Networking.Packets { public void Read(WorldPacket data) { - Flags = (SpellCastTargetFlags)data.ReadBits(26); + Flags = (SpellCastTargetFlags)data.ReadBits(28); if (data.HasBit()) SrcLocation = new(); @@ -1552,7 +1538,7 @@ namespace Game.Networking.Packets public void Write(WorldPacket data) { - data.WriteBits((uint)Flags, 26); + data.WriteBits((uint)Flags, 28); data.WriteBit(SrcLocation != null); data.WriteBit(DstLocation != null); data.WriteBit(Orientation.HasValue); @@ -1607,15 +1593,20 @@ namespace Game.Networking.Packets public uint Quantity; } - public struct SpellOptionalReagent + public struct SpellCraftingReagent { public int ItemID; - public int Slot; + public int DataSlotIndex; + public int Quantity; + public byte? Unknown_1000; public void Read(WorldPacket data) { ItemID = data.ReadInt32(); - Slot = data.ReadInt32(); + DataSlotIndex = data.ReadInt32(); + Quantity = data.ReadInt32(); + if (data.HasBit()) + Unknown_1000 = data.ReadUInt8(); } } @@ -1641,8 +1632,9 @@ namespace Game.Networking.Packets public MissileTrajectoryRequest MissileTrajectory; public MovementInfo MoveUpdate; public List Weight = new(); - public Array OptionalReagents = new(3); + public Array OptionalReagents = new(3); public Array OptionalCurrencies = new(5 /*MAX_ITEM_EXT_COST_CURRENCIES*/); + public ulong? CraftingOrderID; public ObjectGuid CraftingNPC; public uint[] Misc = new uint[2]; @@ -1658,21 +1650,25 @@ namespace Game.Networking.Packets MissileTrajectory.Read(data); CraftingNPC = data.ReadPackedGuid(); - var optionalReagents = data.ReadUInt32(); var optionalCurrencies = data.ReadUInt32(); - - for (var i = 0; i < optionalReagents; ++i) - OptionalReagents[i].Read(data); + var optionalReagents = data.ReadUInt32(); for (var i = 0; i < optionalCurrencies; ++i) OptionalCurrencies[i].Read(data); SendCastFlags = data.ReadBits(5); bool hasMoveUpdate = data.HasBit(); - + bool hasCraftingOrderID = data.HasBit(); var weightCount = data.ReadBits(2); + Target.Read(data); + if (hasCraftingOrderID) + CraftingOrderID = data.ReadUInt64(); + + for (var i = 0; i < optionalReagents; ++i) + OptionalReagents[i].Read(data); + if (hasMoveUpdate) MoveUpdate = MovementExtensions.ReadMovementInfo(data); @@ -1884,6 +1880,34 @@ namespace Game.Networking.Packets public SpellHealPrediction Predict; } + public struct LearnedSpellInfo + { + public uint SpellID; + public bool IsFavorite; + public int? field_8; + public int? Superceded; + public int? TraitDefinitionID; + + public void Write(WorldPacket data) + { + data.WriteUInt32(SpellID); + data.WriteBit(IsFavorite); + data.WriteBit(field_8.HasValue); + data.WriteBit(Superceded.HasValue); + data.WriteBit(TraitDefinitionID.HasValue); + data.FlushBits(); + + if (field_8.HasValue) + data.WriteInt32(field_8.Value); + + if (Superceded.HasValue) + data.WriteInt32(Superceded.Value); + + if (TraitDefinitionID.HasValue) + data.WriteInt32(TraitDefinitionID.Value); + } + } + public struct SpellModifierData { public float ModifierValue; diff --git a/Source/Game/Networking/Packets/SystemPackets.cs b/Source/Game/Networking/Packets/SystemPackets.cs index b088f42a3..55b8977bc 100644 --- a/Source/Game/Networking/Packets/SystemPackets.cs +++ b/Source/Game/Networking/Packets/SystemPackets.cs @@ -58,6 +58,7 @@ namespace Game.Networking.Packets _worldPacket.WriteInt16(MaxPlayerNameQueriesPerPacket); _worldPacket.WriteInt16(PlayerNameQueryTelemetryInterval); + _worldPacket.WriteUInt32((uint)PlayerNameQueryInterval.TotalSeconds); foreach (GameRuleValuePair gameRuleValue in GameRuleValues) gameRuleValue.Write(_worldPacket); @@ -70,6 +71,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(BpayStoreDisabledByParentalControls); _worldPacket.WriteBit(ItemRestorationButtonEnabled); _worldPacket.WriteBit(BrowserEnabled); + _worldPacket.WriteBit(SessionAlert.HasValue); _worldPacket.WriteBit(RAFSystem.Enabled); _worldPacket.WriteBit(RAFSystem.RecruitingEnabled); @@ -78,6 +80,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(CommerceSystemEnabled); _worldPacket.WriteBit(TutorialsEnabled); _worldPacket.WriteBit(TwitterEnabled); + _worldPacket.WriteBit(Unk67); _worldPacket.WriteBit(WillKickFromWorld); _worldPacket.WriteBit(KioskModeEnabled); @@ -86,6 +89,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(WarModeFeatureEnabled); _worldPacket.WriteBit(ClubsEnabled); _worldPacket.WriteBit(ClubsBattleNetClubTypeAllowed); + _worldPacket.WriteBit(ClubsCharacterClubTypeAllowed); _worldPacket.WriteBit(ClubsPresenceUpdateEnabled); _worldPacket.WriteBit(VoiceChatDisabledByParentalControl); @@ -94,10 +98,14 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(IsMuted); _worldPacket.WriteBit(ClubFinderEnabled); _worldPacket.WriteBit(Unknown901CheckoutRelated); + _worldPacket.WriteBit(TextToSpeechFeatureEnabled); _worldPacket.WriteBit(ChatDisabledByDefault); _worldPacket.WriteBit(ChatDisabledByPlayer); _worldPacket.WriteBit(LFGListCustomRequiresAuthenticator); + _worldPacket.WriteBit(AddonsDisabled); + _worldPacket.WriteBit(Unused1000); + _worldPacket.FlushBits(); { @@ -164,6 +172,7 @@ namespace Game.Networking.Packets public int ActiveSeason; // Currently active Classic season public short MaxPlayerNameQueriesPerPacket = 50; public short PlayerNameQueryTelemetryInterval = 600; + public TimeSpan PlayerNameQueryInterval = TimeSpan.FromSeconds(10); public bool ItemRestorationButtonEnabled; public bool CharUndeleteEnabled; // Implemented public bool BpayStoreDisabledByParentalControls; @@ -192,6 +201,8 @@ namespace Game.Networking.Packets public bool ChatDisabledByDefault; public bool ChatDisabledByPlayer; public bool LFGListCustomRequiresAuthenticator; + public bool AddonsDisabled; + public bool Unused1000; public SocialQueueConfig QuickJoinConfig; public SquelchInfo Squelch; @@ -264,6 +275,7 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(Unk14); _worldPacket.WriteBit(WillKickFromWorld); _worldPacket.WriteBit(IsExpansionPreorderInStore); + _worldPacket.WriteBit(KioskModeEnabled); _worldPacket.WriteBit(CompetitiveModeEnabled); _worldPacket.WriteBit(TrialBoostEnabled); @@ -272,9 +284,12 @@ namespace Game.Networking.Packets _worldPacket.WriteBit(LiveRegionCharacterCopyEnabled); _worldPacket.WriteBit(LiveRegionAccountCopyEnabled); _worldPacket.WriteBit(LiveRegionKeyBindingsCopyEnabled); + _worldPacket.WriteBit(Unknown901CheckoutRelated); _worldPacket.WriteBit(EuropaTicketSystemStatus.HasValue); _worldPacket.WriteBit(LaunchETA.HasValue); + _worldPacket.WriteBit(AddonsDisabled); + _worldPacket.WriteBit(Unused1000); _worldPacket.FlushBits(); if (EuropaTicketSystemStatus.HasValue) @@ -294,6 +309,7 @@ namespace Game.Networking.Packets _worldPacket.WriteInt32(GameRuleValues.Count); _worldPacket.WriteInt16(MaxPlayerNameQueriesPerPacket); _worldPacket.WriteInt16(PlayerNameQueryTelemetryInterval); + _worldPacket.WriteUInt32((uint)PlayerNameQueryInterval.TotalSeconds); if (LaunchETA.HasValue) _worldPacket.WriteInt32(LaunchETA.Value); @@ -320,8 +336,10 @@ namespace Game.Networking.Packets public bool LiveRegionCharacterListEnabled; // NYI public bool LiveRegionCharacterCopyEnabled; // NYI public bool LiveRegionAccountCopyEnabled; // NYI - public bool LiveRegionKeyBindingsCopyEnabled = false; - public bool Unknown901CheckoutRelated = false; // NYI + public bool LiveRegionKeyBindingsCopyEnabled; + public bool Unknown901CheckoutRelated; // NYI + public bool AddonsDisabled; + public bool Unused1000; public EuropaTicketConfig? EuropaTicketSystemStatus; public List LiveRegionCharacterCopySourceRegions = new(); public uint TokenPollTimeSeconds; // NYI @@ -337,6 +355,7 @@ namespace Game.Networking.Packets public List GameRuleValues = new(); public short MaxPlayerNameQueriesPerPacket = 50; public short PlayerNameQueryTelemetryInterval = 600; + public TimeSpan PlayerNameQueryInterval = TimeSpan.FromSeconds(10); public int? LaunchETA; } @@ -368,12 +387,18 @@ namespace Game.Networking.Packets { _worldPacket.WriteBits(ServerTimeTZ.GetByteCount(), 7); _worldPacket.WriteBits(GameTimeTZ.GetByteCount(), 7); + _worldPacket.WriteBits(ServerRegionalTZ.GetByteCount(), 7); + _worldPacket.FlushBits(); + _worldPacket.WriteString(ServerTimeTZ); _worldPacket.WriteString(GameTimeTZ); + _worldPacket.WriteString(ServerRegionalTZ); + } public string ServerTimeTZ; public string GameTimeTZ; + public string ServerRegionalTZ; } public struct SavedThrottleObjectState diff --git a/Source/Game/Networking/Packets/TraitPacketsCommon.cs b/Source/Game/Networking/Packets/TraitPacketsCommon.cs new file mode 100644 index 000000000..82dead96b --- /dev/null +++ b/Source/Game/Networking/Packets/TraitPacketsCommon.cs @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2012-2020 CypherCore + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +using Framework.Constants; +using Game.Entities; +using System.Collections.Generic; +using System; + +namespace Game.Networking.Packets +{ + public struct TraitEntry + { + public int TraitNodeID; + public int TraitNodeEntryID; + public int Rank; + public int GrantedRanks; + + public void Write(WorldPacket data) + { + data.WriteInt32(TraitNodeID); + data.WriteInt32(TraitNodeEntryID); + data.WriteInt32(Rank); + data.WriteInt32(GrantedRanks); + } + } + + public class TraitConfig + { + public int ID; + public TraitConfigType Type; + public int ChrSpecializationID = 0; + public TraitCombatConfigFlags CombatConfigFlags; + public int LocalIdentifier; // Local to specialization + public int SkillLineID; + public int TraitSystemID; + public List Entries = new(); + public string Name = ""; + + public void Write(WorldPacket data) + { + data.WriteInt32(ID); + data.WriteInt32((int)Type); + data.WriteInt32(Entries.Count); + switch (Type) + { + case TraitConfigType.Combat: + data.WriteInt32(ChrSpecializationID); + data.WriteInt32((int)CombatConfigFlags); + data.WriteInt32(LocalIdentifier); + break; + case TraitConfigType.Profession: + data.WriteInt32(SkillLineID); + break; + case TraitConfigType.Generic: + data.WriteInt32(TraitSystemID); + break; + default: + break; + } + + foreach (TraitEntry traitEntry in Entries) + traitEntry.Write(data); + + data.WriteBits(Name.GetByteCount(), 9); + data.FlushBits(); + + data.WriteString(Name); + } + } +} diff --git a/Source/Game/Networking/Packets/TransmogrificationPackets.cs b/Source/Game/Networking/Packets/TransmogrificationPackets.cs index 087679f39..001233f71 100644 --- a/Source/Game/Networking/Packets/TransmogrificationPackets.cs +++ b/Source/Game/Networking/Packets/TransmogrificationPackets.cs @@ -69,21 +69,6 @@ namespace Game.Networking.Packets public List NewAppearances = new(); } - class TransmogrifyNPC : ServerPacket - { - public TransmogrifyNPC(ObjectGuid guid) : base(ServerOpcodes.TransmogrifyNpc, ConnectionType.Instance) - { - Guid = guid; - } - - public override void Write() - { - _worldPacket.WritePackedGuid(Guid); - } - - ObjectGuid Guid; - } - struct TransmogrifyItem { public void Read(WorldPacket data) diff --git a/Source/Game/Quest/Quest.cs b/Source/Game/Quest/Quest.cs index b72349a80..a239163dd 100644 --- a/Source/Game/Quest/Quest.cs +++ b/Source/Game/Quest/Quest.cs @@ -279,6 +279,93 @@ namespace Game } } + void LoadConditionalConditionalQuestDescription(SQLFields fields) + { + Locale locale = fields.Read(4).ToEnum(); + if (locale >= Locale.Total) + { + Log.outError(LogFilter.Sql, $"Table `quest_description_conditional` has invalid locale {fields.Read(4)} set for quest {fields.Read(0)}. Skipped."); + return; + } + + QuestConditionalText text = ConditionalQuestDescription.Find(text => text.PlayerConditionId == fields.Read(1) && text.QuestgiverCreatureId == fields.Read(2)); + if (text == null) + { + text = new(); + ConditionalQuestDescription.Add(text); + } + + text.PlayerConditionId = fields.Read(1); + text.QuestgiverCreatureId = fields.Read(2); + ObjectManager.AddLocaleString(fields.Read(3), locale, text.Text); + } + + void LoadConditionalConditionalRequestItemsText(SQLFields fields) + { + Locale locale = fields.Read(4).ToEnum(); + if (locale >= Locale.Total) + { + Log.outError(LogFilter.Sql, $"Table `quest_request_items_conditional` has invalid locale {fields.Read(4)} set for quest {fields.Read(0)}. Skipped."); + return; + } + + QuestConditionalText text = ConditionalRequestItemsText.Find(text => text.PlayerConditionId == fields.Read(1) && text.QuestgiverCreatureId == fields.Read(2)); + + if (text == null) + { + text = new(); + ConditionalRequestItemsText.Add(text); + } + + text.PlayerConditionId = fields.Read(1); + text.QuestgiverCreatureId = fields.Read(2); + ObjectManager.AddLocaleString(fields.Read(3), locale, text.Text); + } + + void LoadConditionalConditionalOfferRewardText(SQLFields fields) + { + Locale locale = fields.Read(4).ToEnum(); + if (locale >= Locale.Total) + { + Log.outError(LogFilter.Sql, $"Table `quest_offer_reward_conditional` has invalid locale {fields.Read(4)} set for quest {fields.Read(0)}. Skipped."); + return; + } + + QuestConditionalText text = ConditionalOfferRewardText.Find(text => text.PlayerConditionId == fields.Read(1) && text.QuestgiverCreatureId == fields.Read(2)); + + if (text == null) + { + text = new(); + ConditionalOfferRewardText.Add(text); + } + + text.PlayerConditionId = fields.Read(1); + text.QuestgiverCreatureId = fields.Read(2); + ObjectManager.AddLocaleString(fields.Read(3), locale, text.Text); + } + + void LoadConditionalConditionalQuestCompletionLog(SQLFields fields) + { + Locale locale = fields.Read(4).ToEnum(); + if (locale >= Locale.Total) + { + Log.outError(LogFilter.Sql, $"Table `quest_completion_log_conditional` has invalid locale {fields.Read(4)} set for quest {fields.Read(0)}. Skipped."); + return; + } + + QuestConditionalText text = ConditionalQuestCompletionLog.Find(text => text.PlayerConditionId == fields.Read(1) && text.QuestgiverCreatureId == fields.Read(2)); + + if (text == null) + { + text = new(); + ConditionalQuestCompletionLog.Add(text); + } + + text.PlayerConditionId = fields.Read(1); + text.QuestgiverCreatureId = fields.Read(2); + ObjectManager.AddLocaleString(fields.Read(3), locale, text.Text); + } + public uint XPValue(Player player) { if (player) @@ -498,6 +585,20 @@ namespace Game response.Info.PortraitTurnInText = PortraitTurnInText; response.Info.PortraitTurnInName = PortraitTurnInName; + response.Info.ConditionalQuestDescription = ConditionalQuestDescription.Select(text => + { + string content = text.Text[(int)Locale.enUS]; + ObjectManager.GetLocaleString(text.Text, loc, ref content); + return new ConditionalQuestText(text.PlayerConditionId, text.QuestgiverCreatureId, content); + }).ToList(); + + response.Info.ConditionalQuestCompletionLog = ConditionalQuestCompletionLog.Select(text => + { + string content = text.Text[(int)Locale.enUS]; + ObjectManager.GetLocaleString(text.Text, loc, ref content); + return new ConditionalQuestText(text.PlayerConditionId, text.QuestgiverCreatureId, content); + }).ToList(); + if (loc != Locale.enUS) { var questTemplateLocale = Global.ObjectMgr.GetQuestLocale(Id); @@ -596,6 +697,7 @@ namespace Game response.Info.Expansion = Expansion; response.Info.ManagedWorldStateID = ManagedWorldStateID; response.Info.QuestSessionBonus = 0; //GetQuestSessionBonus(); // this is only sent while quest session is active + response.Info.QuestGiverCreatureID = 0; // only sent during npc interaction foreach (QuestObjective questObjective in Objectives) { @@ -744,6 +846,12 @@ namespace Game public string PortraitTurnInName = ""; public string QuestCompletionLog = ""; + // quest_description_conditional + public List ConditionalQuestDescription = new(); + + // quest_completion_log_conditional + public List ConditionalQuestCompletionLog = new(); + // quest_detais table public uint[] DetailsEmote = new uint[SharedConst.QuestEmoteCount]; public uint[] DetailsEmoteDelay = new uint[SharedConst.QuestEmoteCount]; @@ -755,11 +863,17 @@ namespace Game public uint EmoteOnIncompleteDelay; public string RequestItemsText = ""; + // quest_request_items_conditional + public List ConditionalRequestItemsText = new(); + // quest_offer_reward table public int[] OfferRewardEmote = new int[SharedConst.QuestEmoteCount]; public uint[] OfferRewardEmoteDelay = new uint[SharedConst.QuestEmoteCount]; public string OfferRewardText = ""; + // quest_offer_reward_conditional + public List ConditionalOfferRewardText = new(); + // quest_template_addon table (custom data) public uint MaxLevel { get; set; } public uint AllowableClasses { get; set; } @@ -864,6 +978,13 @@ namespace Game } } + public class QuestConditionalText + { + public int PlayerConditionId; + public int QuestgiverCreatureId; + public StringArray Text = new((int)Locale.Total); + } + public class QuestObjective { public uint Id; diff --git a/Source/Game/Reputation/ReputationManager.cs b/Source/Game/Reputation/ReputationManager.cs index 3392a1ba2..f581ce8fc 100644 --- a/Source/Game/Reputation/ReputationManager.cs +++ b/Source/Game/Reputation/ReputationManager.cs @@ -239,7 +239,6 @@ namespace Game public void SendState(FactionState faction) { SetFactionStanding setFactionStanding = new(); - setFactionStanding.ReferAFriendBonus = 0.0f; setFactionStanding.BonusFromAchievementSystem = 0.0f; if (faction != null) setFactionStanding.Faction.Add(new FactionStandingData((int)faction.ReputationListID, faction.Standing)); diff --git a/Source/Game/Scripting/CoreScripts.cs b/Source/Game/Scripting/CoreScripts.cs index 07666eb3a..ca25f0a6f 100644 --- a/Source/Game/Scripting/CoreScripts.cs +++ b/Source/Game/Scripting/CoreScripts.cs @@ -59,12 +59,12 @@ namespace Game.Scripting // Using provided text, not from DB public static void AddGossipItemFor(Player player, GossipOptionNpc optionNpc, string text, uint sender, uint action) { - player.PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, optionNpc, text, sender, action, "", 0); + player.PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, false, 0, "", null, null, sender, action); } // Using provided texts, not from DB public static void AddGossipItemFor(Player player, GossipOptionNpc optionNpc, string text, uint sender, uint action, string popupText, uint popupMoney, bool coded) { - player.PlayerTalkClass.GetGossipMenu().AddMenuItem(-1, optionNpc, text, sender, action, popupText, popupMoney, coded); + player.PlayerTalkClass.GetGossipMenu().AddMenuItem(0, -1, optionNpc, text, 0, GossipOptionFlags.None, null, coded, popupMoney, popupText, null, null, sender, action); } // Uses gossip item info from DB public static void AddGossipItemFor(Player player, uint gossipMenuID, uint gossipMenuItemID, uint sender, uint action) diff --git a/Source/Game/Server/WorldConfig.cs b/Source/Game/Server/WorldConfig.cs index 1402f836b..19cf8b51c 100644 --- a/Source/Game/Server/WorldConfig.cs +++ b/Source/Game/Server/WorldConfig.cs @@ -372,7 +372,7 @@ namespace Game Values[WorldCfg.CharacterCreatingDisabledRacemask] = GetDefaultValue("CharacterCreating.Disabled.RaceMask", 0); Values[WorldCfg.CharacterCreatingDisabledClassmask] = GetDefaultValue("CharacterCreating.Disabled.ClassMask", 0); - Values[WorldCfg.CharactersPerRealm] = GetDefaultValue("CharactersPerRealm", 50); + Values[WorldCfg.CharactersPerRealm] = GetDefaultValue("CharactersPerRealm", 60); if ((int)Values[WorldCfg.CharactersPerRealm] < 1 || (int)Values[WorldCfg.CharactersPerRealm] > 200) { Log.outError(LogFilter.ServerLoading, "CharactersPerRealm ({0}) must be in range 1..200. Set to 200.", Values[WorldCfg.CharactersPerRealm]); @@ -380,14 +380,22 @@ namespace Game } // must be after CharactersPerRealm - Values[WorldCfg.CharactersPerAccount] = GetDefaultValue("CharactersPerAccount", 50); + Values[WorldCfg.CharactersPerAccount] = GetDefaultValue("CharactersPerAccount", 60); if ((int)Values[WorldCfg.CharactersPerAccount] < (int)Values[WorldCfg.CharactersPerRealm]) { Log.outError(LogFilter.ServerLoading, "CharactersPerAccount ({0}) can't be less than CharactersPerRealm ({1}).", Values[WorldCfg.CharactersPerAccount], Values[WorldCfg.CharactersPerRealm]); Values[WorldCfg.CharactersPerAccount] = Values[WorldCfg.CharactersPerRealm]; } + Values[WorldCfg.CharacterCreatingEvokersPerRealm] = GetDefaultValue("CharacterCreating.EvokersPerRealm", 1); + if ((int)Values[WorldCfg.CharacterCreatingEvokersPerRealm] < 0 || (int)Values[WorldCfg.CharacterCreatingEvokersPerRealm] > 10) + { + Log.outError(LogFilter.ServerLoading, $"CharacterCreating.EvokersPerRealm ({Values[WorldCfg.CharacterCreatingEvokersPerRealm]}) must be in range 0..10. Set to 1."); + Values[WorldCfg.CharacterCreatingEvokersPerRealm] = 1; + } + Values[WorldCfg.CharacterCreatingMinLevelForDemonHunter] = GetDefaultValue("CharacterCreating.MinLevelForDemonHunter", 0); + Values[WorldCfg.CharacterCreatingMinLevelForEvoker] = GetDefaultValue("CharacterCreating.MinLevelForEvoker", 50); Values[WorldCfg.CharacterCreatingDisableAlliedRaceAchievementRequirement] = GetDefaultValue("CharacterCreating.DisableAlliedRaceAchievementRequirement", false); Values[WorldCfg.SkipCinematics] = GetDefaultValue("SkipCinematics", 0); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index fb0951a2a..d09f1b149 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4763,6 +4763,11 @@ namespace Game.Spells if (m_spellInfo.ExcludeCasterAuraSpell != 0 && unitCaster.HasAura(m_spellInfo.ExcludeCasterAuraSpell)) return SpellCastResult.CasterAurastate; + if (m_spellInfo.CasterAuraType != 0 && !unitCaster.HasAuraType(m_spellInfo.CasterAuraType)) + return SpellCastResult.CasterAurastate; + if (m_spellInfo.ExcludeCasterAuraType != 0 && unitCaster.HasAuraType(m_spellInfo.ExcludeCasterAuraType)) + return SpellCastResult.CasterAurastate; + if (reqCombat && unitCaster.IsInCombat() && !m_spellInfo.CanBeUsedInCombat()) return SpellCastResult.AffectingCombat; } @@ -5589,21 +5594,15 @@ namespace Game.Spells if (spellEffectInfo.Effect == SpellEffectName.ChangeBattlepetQuality) { + var qualityRecord = CliDB.BattlePetBreedQualityStorage.Values.FirstOrDefault(a1 => a1.MaxQualityRoll < spellEffectInfo.BasePoints); + BattlePetBreedQuality quality = BattlePetBreedQuality.Poor; - switch (spellEffectInfo.BasePoints) - { - case 85: - quality = BattlePetBreedQuality.Rare; - break; - case 75: - quality = BattlePetBreedQuality.Uncommon; - break; - default: - // Ignore Epic Battle-Stones - break; - } + if (qualityRecord != null) + quality = (BattlePetBreedQuality)qualityRecord.QualityEnum; + if (battlePet.PacketInfo.Quality >= (byte)quality) return SpellCastResult.CantUpgradeBattlePet; + } if (spellEffectInfo.Effect == SpellEffectName.GrantBattlepetLevel || spellEffectInfo.Effect == SpellEffectName.GrantBattlepetExperience) @@ -6634,21 +6633,21 @@ namespace Game.Spells { Item item = m_targets.GetItemTarget(); if (!item) - return SpellCastResult.CantBeDisenchanted; + return SpellCastResult.CantBeSalvaged; // prevent disenchanting in trade slot if (item.GetOwnerGUID() != player.GetGUID()) - return SpellCastResult.CantBeDisenchanted; + return SpellCastResult.CantBeSalvaged; ItemTemplate itemProto = item.GetTemplate(); if (itemProto == null) - return SpellCastResult.CantBeDisenchanted; + return SpellCastResult.CantBeSalvaged; ItemDisenchantLootRecord itemDisenchantLoot = item.GetDisenchantLoot(m_caster.ToPlayer()); if (itemDisenchantLoot == null) - return SpellCastResult.CantBeDisenchanted; + return SpellCastResult.CantBeSalvaged; if (itemDisenchantLoot.SkillRequired > player.GetSkillValue(SkillType.Enchanting)) - return SpellCastResult.LowCastlevel; + return SpellCastResult.CantBeSalvagedSkill; break; } case SpellEffectName.Prospecting: diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 27ed8b28a..722603c19 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -2127,30 +2127,7 @@ namespace Game.Spells } // select enchantment duration - uint duration; - - // rogue family enchantments exception by duration - if (m_spellInfo.Id == 38615) - duration = 1800; // 30 mins - // other rogue family enchantments always 1 hour (some have spell damage=0, but some have wrong data in EffBasePoints) - else if (m_spellInfo.SpellFamilyName == SpellFamilyNames.Rogue) - duration = 3600; // 1 hour - // shaman family enchantments - else if (m_spellInfo.SpellFamilyName == SpellFamilyNames.Shaman) - duration = 3600; // 30 mins - // other cases with this SpellVisual already selected - else if (m_spellInfo.GetSpellVisual() == 215) - duration = 1800; // 30 mins - // some fishing pole bonuses except Glow Worm which lasts full hour - else if (m_spellInfo.GetSpellVisual() == 563 && m_spellInfo.Id != 64401) - duration = 600; // 10 mins - else if (m_spellInfo.Id == 29702) - duration = 300; // 5 mins - else if (m_spellInfo.Id == 37360) - duration = 300; // 5 mins - // default case - else - duration = 3600; // 1 hour + uint duration = (uint)pEnchant.Duration; // item can be in trade slot and have owner diff. from caster Player item_owner = itemTarget.GetOwner(); @@ -5208,19 +5185,11 @@ namespace Game.Spells if (unitTarget == null || !unitTarget.IsCreature()) return; - var quality = BattlePetBreedQuality.Poor; - switch (damage) - { - case 85: - quality = BattlePetBreedQuality.Rare; - break; - case 75: - quality = BattlePetBreedQuality.Uncommon; - break; - default: - // Ignore Epic Battle-Stones - break; - } + var qualityRecord = CliDB.BattlePetBreedQualityStorage.Values.FirstOrDefault(a1 => a1.MaxQualityRoll < damage); + + BattlePetBreedQuality quality = BattlePetBreedQuality.Poor; + if (qualityRecord != null) + quality = (BattlePetBreedQuality)qualityRecord.QualityEnum; playerCaster.GetSession().GetBattlePetMgr().ChangeBattlePetQuality(unitTarget.GetBattlePetCompanionGUID(), quality); } @@ -5634,6 +5603,79 @@ namespace Game.Spells player.GetSession().GetCollectionMgr().AddTransmogIllusion(illusionId); } + + [SpellEffectHandler(SpellEffectName.ModifyAuraStacks)] + void EffectModifyAuraStacks() + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + Aura targetAura = unitTarget.GetAura(effectInfo.TriggerSpell); + if (targetAura == null) + return; + + switch (effectInfo.MiscValue) + { + case 0: + targetAura.ModStackAmount(damage); + break; + case 1: + targetAura.SetStackAmount((byte)damage); + break; + default: + break; + } + } + + [SpellEffectHandler(SpellEffectName.ModifyCooldown)] + void EffectModifyCooldown() + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + unitTarget.GetSpellHistory().ModifyCooldown(effectInfo.TriggerSpell, TimeSpan.FromMilliseconds(damage)); + } + + [SpellEffectHandler(SpellEffectName.ModifyCooldowns)] + void EffectModifyCooldowns() + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + unitTarget.GetSpellHistory().ModifyCoooldowns(itr => + { + SpellInfo spellOnCooldown = Global.SpellMgr.GetSpellInfo(itr.SpellId, Difficulty.None); + if ((int)spellOnCooldown.SpellFamilyName != effectInfo.MiscValue) + return false; + + int bitIndex = effectInfo.MiscValueB - 1; + if (bitIndex < 0 || bitIndex >= sizeof(uint) * 8) + return false; + + FlagArray128 reqFlag = new(); + reqFlag[bitIndex / 32] = 1u << (bitIndex % 32); + return (spellOnCooldown.SpellFamilyFlags & reqFlag); + }, TimeSpan.FromMilliseconds(damage)); + } + + [SpellEffectHandler(SpellEffectName.ModifyCooldownsByCategory)] + void EffectModifyCooldownsByCategory() + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + unitTarget.GetSpellHistory().ModifyCoooldowns(itr => Global.SpellMgr.GetSpellInfo(itr.SpellId, Difficulty.None).CategoryId == effectInfo.MiscValue, TimeSpan.FromMilliseconds(damage)); + } + + [SpellEffectHandler(SpellEffectName.ModifyCharges)] + void EffectModifySpellCharges() + { + if (effectHandleMode != SpellEffectHandleMode.HitTarget) + return; + + for (int i = 0; i < damage; ++i) + unitTarget.GetSpellHistory().RestoreCharge((uint)effectInfo.MiscValue); + } } public class DispelableAura diff --git a/Source/Game/Spells/SpellHistory.cs b/Source/Game/Spells/SpellHistory.cs index 3ba9d7bc8..9119396c4 100644 --- a/Source/Game/Spells/SpellHistory.cs +++ b/Source/Game/Spells/SpellHistory.cs @@ -514,20 +514,25 @@ namespace Game.Spells } } - public void ModifySpellCooldown(uint spellId, TimeSpan offset, bool withoutCategoryCooldown = false) + public void ModifySpellCooldown(uint spellId, TimeSpan cooldownMod, bool withoutCategoryCooldown) { var cooldownEntry = _spellCooldowns.LookupByKey(spellId); - if (offset.TotalMilliseconds == 0 || cooldownEntry == null) + if (cooldownMod.TotalMilliseconds == 0 || cooldownEntry == null) return; + ModifySpellCooldown(cooldownEntry, cooldownMod, withoutCategoryCooldown); + } + + void ModifySpellCooldown(CooldownEntry cooldownEntry, TimeSpan cooldownMod, bool withoutCategoryCooldown) + { DateTime now = GameTime.GetSystemTime(); - cooldownEntry.CooldownEnd += offset; + cooldownEntry.CooldownEnd += cooldownMod; if (cooldownEntry.CategoryId != 0) { if (!withoutCategoryCooldown) - cooldownEntry.CategoryEnd += offset; + cooldownEntry.CategoryEnd += cooldownMod; // Because category cooldown existence is tied to regular cooldown, we cannot allow a situation where regular cooldown is shorter than category if (cooldownEntry.CooldownEnd < cooldownEntry.CategoryEnd) @@ -535,9 +540,9 @@ namespace Game.Spells } if (cooldownEntry.CooldownEnd <= now) - { + { _categoryCooldowns.Remove(cooldownEntry.CategoryId); - _spellCooldowns.Remove(spellId); + _spellCooldowns.Remove(cooldownEntry.SpellId); } Player playerOwner = GetPlayerOwner(); @@ -545,8 +550,8 @@ namespace Game.Spells { ModifyCooldown modifyCooldown = new(); modifyCooldown.IsPet = _owner != playerOwner; - modifyCooldown.SpellID = spellId; - modifyCooldown.DeltaTime = (int)offset.TotalMilliseconds; + modifyCooldown.SpellID = cooldownEntry.SpellId; + modifyCooldown.DeltaTime = (int)cooldownMod.TotalMilliseconds; modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown; playerOwner.SendPacket(modifyCooldown); } @@ -569,7 +574,16 @@ namespace Game.Spells else ModifySpellCooldown(spellInfo.Id, cooldownMod, withoutCategoryCooldown); } - + + public void ModifyCoooldowns(Func predicate, TimeSpan cooldownMod, bool withoutCategoryCooldown = false) + { + foreach (var cooldownEntry in _spellCooldowns.Values.ToList()) + { + if (predicate(cooldownEntry)) + ModifySpellCooldown(cooldownEntry, cooldownMod, withoutCategoryCooldown); + } + } + public void ResetCooldown(uint spellId, bool update = false) { var entry = _spellCooldowns.LookupByKey(spellId); @@ -635,6 +649,9 @@ namespace Game.Spells if (_spellCooldowns.ContainsKey(spellInfo.Id)) return true; + if (spellInfo.CooldownAuraSpellId != 0 && _owner.HasAura(spellInfo.CooldownAuraSpellId)) + return true; + uint category = 0; GetCooldownDurations(spellInfo, itemId, ref category); diff --git a/Source/Game/Spells/SpellInfo.cs b/Source/Game/Spells/SpellInfo.cs index b48a1606f..cbcf6798a 100644 --- a/Source/Game/Spells/SpellInfo.cs +++ b/Source/Game/Spells/SpellInfo.cs @@ -120,6 +120,10 @@ namespace Game.Spells TargetAuraSpell = _aura.TargetAuraSpell; ExcludeCasterAuraSpell = _aura.ExcludeCasterAuraSpell; ExcludeTargetAuraSpell = _aura.ExcludeTargetAuraSpell; + CasterAuraType = (AuraType)_aura.CasterAuraType; + TargetAuraType = (AuraType)_aura.TargetAuraType; + ExcludeCasterAuraType = (AuraType)_aura.ExcludeCasterAuraType; + ExcludeTargetAuraType = (AuraType)_aura.ExcludeTargetAuraType; } RequiredAreasID = -1; @@ -161,6 +165,7 @@ namespace Game.Spells RecoveryTime = _cooldowns.RecoveryTime; CategoryRecoveryTime = _cooldowns.CategoryRecoveryTime; StartRecoveryTime = _cooldowns.StartRecoveryTime; + CooldownAuraSpellId = _cooldowns.AuraSpellID; } EquippedItemClass = ItemClass.None; @@ -2855,7 +2860,7 @@ namespace Game.Spells } Log.outError(LogFilter.Spells, $"SpellInfo.CalcPowerCost: Unknown power type '{power.PowerType}' in spell {Id}"); - return default; + return null; } } } @@ -2863,6 +2868,36 @@ namespace Game.Spells else { powerCost = (int)power.OptionalCost; + + if (power.OptionalCostPct != 0) + { + switch (power.PowerType) + { + // health as power used + case PowerType.Health: + powerCost += (int)MathFunctions.CalculatePct(unitCaster.GetMaxHealth(), power.OptionalCostPct); + break; + case PowerType.Mana: + powerCost += (int)MathFunctions.CalculatePct(unitCaster.GetCreateMana(), power.OptionalCostPct); + break; + case PowerType.AlternatePower: + Log.outError(LogFilter.Spells, $"SpellInfo::CalcPowerCost: Unsupported power type POWER_ALTERNATE_POWER in spell {Id} for optional cost percent"); + return null; + default: + { + var powerTypeEntry = Global.DB2Mgr.GetPowerTypeEntry(power.PowerType); + if (powerTypeEntry != null) + { + powerCost += (int)MathFunctions.CalculatePct(powerTypeEntry.MaxBasePower, power.OptionalCostPct); + break; + } + + Log.outError(LogFilter.Spells, $"SpellInfo::CalcPowerCost: Unknown power type '{power.PowerType}' in spell {Id} for optional cost percent"); + return null; + } + } + } + powerCost += unitCaster.GetTotalAuraModifier(AuraType.ModAdditionalPowerCost, aurEff => { return aurEff.GetMiscValue() == (int)power.PowerType && aurEff.IsAffectingSpell(this); @@ -3964,11 +3999,16 @@ namespace Game.Spells public uint TargetAuraSpell { get; set; } public uint ExcludeCasterAuraSpell { get; set; } public uint ExcludeTargetAuraSpell { get; set; } + public AuraType CasterAuraType { get; set; } + public AuraType TargetAuraType { get; set; } + public AuraType ExcludeCasterAuraType { get; set; } + public AuraType ExcludeTargetAuraType { get; set; } public SpellCastTimesRecord CastTimeEntry { get; set; } public uint RecoveryTime { get; set; } public uint CategoryRecoveryTime { get; set; } public uint StartRecoveryCategory { get; set; } public uint StartRecoveryTime { get; set; } + public uint CooldownAuraSpellId { get; set; } public SpellInterruptFlags InterruptFlags { get; set; } public SpellAuraInterruptFlags AuraInterruptFlags { get; set; } public SpellAuraInterruptFlags2 AuraInterruptFlags2 { get; set; } @@ -4777,8 +4817,23 @@ namespace Game.Spells new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 285 SPELL_EFFECT_MODIFY_KEYSTONE_2 new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 286 SPELL_EFFECT_GRANT_BATTLEPET_EXPERIENCE new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 287 SPELL_EFFECT_SET_GARRISON_FOLLOWER_LEVEL - new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 288 SPELL_EFFECT_288 - new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 289 SPELL_EFFECT_289 + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 288 SPELL_EFFECT_CRAFT_ITEM + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 289 SPELL_EFFECT_MODIFY_AURA_STACKS + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 290 SPELL_EFFECT_MODIFY_COOLDOWN + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 291 SPELL_EFFECT_MODIFY_COOLDOWNS + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 292 SPELL_EFFECT_MODIFY_COOLDOWNS_BY_CATEGORY + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 293 SPELL_EFFECT_MODIFY_CHARGES + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 294 SPELL_EFFECT_CRAFT_LOOT + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 295 SPELL_EFFECT_SALVAGE_ITEM + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 296 SPELL_EFFECT_CRAFT_SALVAGE_ITEM + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 297 SPELL_EFFECT_RECRAFT_ITEM + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Unit), // 298 SPELL_EFFECT_CANCEL_ALL_PRIVATE_CONVERSATIONS + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 299 SPELL_EFFECT_299 + new StaticData(SpellEffectImplicitTargetTypes.None, SpellTargetObjectTypes.None), // 300 SPELL_EFFECT_300 + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.Item), // 301 SPELL_EFFECT_CRAFT_ENCHANT + new StaticData(SpellEffectImplicitTargetTypes.Explicit, SpellTargetObjectTypes.None), // 302 SPELL_EFFECT_GATHERING + 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 }; #region Fields diff --git a/Source/Game/Spells/SpellManager.cs b/Source/Game/Spells/SpellManager.cs index 881ca3f6b..81548f2f1 100644 --- a/Source/Game/Spells/SpellManager.cs +++ b/Source/Game/Spells/SpellManager.cs @@ -2471,17 +2471,19 @@ namespace Game.Entities "AttributesEx4, AttributesEx5, AttributesEx6, AttributesEx7, AttributesEx8, AttributesEx9, AttributesEx10, AttributesEx11, AttributesEx12, AttributesEx13, " + //19 20 21 22 23 24 25 26 27 "AttributesEx14, Stances, StancesNot, Targets, TargetCreatureType, RequiresSpellFocus, FacingCasterFlags, CasterAuraState, TargetAuraState, " + - //28 29 30 31 32 33 34 - "ExcludeCasterAuraState, ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, CastingTimeIndex, " + - //35 36 37 38 39 40 41 + //28 29 30 31 32 33 + "ExcludeCasterAuraState, ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell, " + + //34 35 36 37 38 + "CasterAuraType, TargetAuraType, ExcludeCasterAuraType, ExcludeTargetAuraType, CastingTimeIndex, " + + //39 40 41 42 43 44 45 "RecoveryTime, CategoryRecoveryTime, StartRecoveryCategory, StartRecoveryTime, InterruptFlags, AuraInterruptFlags1, AuraInterruptFlags2, " + - //42 43 44 45 46 47 48 49 50 51 52 + //46 47 48 49 50 51 52 53 54 55 56 "ChannelInterruptFlags1, ChannelInterruptFlags2, ProcFlags, ProcFlags2, ProcChance, ProcCharges, ProcCooldown, ProcBasePPM, MaxLevel, BaseLevel, SpellLevel, " + - //53 54 55 56 57 58 59 60 61 + //57 58 59 60 61 62 63 64 65 "DurationIndex, RangeIndex, Speed, LaunchDelay, StackAmount, EquippedItemClass, EquippedItemSubClassMask, EquippedItemInventoryTypeMask, ContentTuningId, " + - //62 63 64 65 66 67 68 69 70 71 + //66 67 68 69 70 71 72 73 74 75 "SpellName, ConeAngle, ConeWidth, MaxTargetLevel, MaxAffectedTargets, SpellFamilyName, SpellFamilyFlags1, SpellFamilyFlags2, SpellFamilyFlags3, SpellFamilyFlags4, " + - //72 73 74 75 76 + //76 77 78 79 80 "DmgClass, PreventionType, AreaGroupId, SchoolMask, ChargeCategoryId FROM serverside_spell"); if (!spellsResult.IsEmpty()) @@ -2496,7 +2498,7 @@ namespace Game.Entities continue; } - mServersideSpellNames.Add(new(spellId, spellsResult.Read(62))); + mServersideSpellNames.Add(new(spellId, spellsResult.Read(66))); SpellInfo spellInfo = new(mServersideSpellNames.Last().Name, difficulty, spellEffects[(spellId, difficulty)]); spellInfo.CategoryId = spellsResult.Read(2); @@ -2531,44 +2533,48 @@ namespace Game.Entities spellInfo.TargetAuraSpell = spellsResult.Read(31); spellInfo.ExcludeCasterAuraSpell = spellsResult.Read(32); spellInfo.ExcludeTargetAuraSpell = spellsResult.Read(33); - spellInfo.CastTimeEntry = CliDB.SpellCastTimesStorage.LookupByKey(spellsResult.Read(34)); - spellInfo.RecoveryTime = spellsResult.Read(35); - spellInfo.CategoryRecoveryTime = spellsResult.Read(36); - spellInfo.StartRecoveryCategory = spellsResult.Read(37); - spellInfo.StartRecoveryTime = spellsResult.Read(38); - spellInfo.InterruptFlags = (SpellInterruptFlags)spellsResult.Read(39); - spellInfo.AuraInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read(40); - spellInfo.AuraInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read(41); - spellInfo.ChannelInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read(42); - spellInfo.ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read(43); - spellInfo.ProcFlags = new ProcFlagsInit(spellsResult.Read(44), spellsResult.Read(45)); - spellInfo.ProcChance = spellsResult.Read(46); - spellInfo.ProcCharges = spellsResult.Read(47); - spellInfo.ProcCooldown = spellsResult.Read(48); - spellInfo.ProcBasePPM = spellsResult.Read(49); - spellInfo.MaxLevel = spellsResult.Read(50); - spellInfo.BaseLevel = spellsResult.Read(51); - spellInfo.SpellLevel = spellsResult.Read(52); - spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(spellsResult.Read(53)); - spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(spellsResult.Read(54)); - spellInfo.Speed = spellsResult.Read(55); - spellInfo.LaunchDelay = spellsResult.Read(56); - spellInfo.StackAmount = spellsResult.Read(57); - spellInfo.EquippedItemClass = (ItemClass)spellsResult.Read(58); - spellInfo.EquippedItemSubClassMask = spellsResult.Read(59); - spellInfo.EquippedItemInventoryTypeMask = spellsResult.Read(60); - spellInfo.ContentTuningId = spellsResult.Read(61); - spellInfo.ConeAngle = spellsResult.Read(63); - spellInfo.Width = spellsResult.Read(64); - spellInfo.MaxTargetLevel = spellsResult.Read(65); - spellInfo.MaxAffectedTargets = spellsResult.Read(66); - spellInfo.SpellFamilyName = (SpellFamilyNames)spellsResult.Read(67); - spellInfo.SpellFamilyFlags = new FlagArray128(spellsResult.Read(68), spellsResult.Read(69), spellsResult.Read(70), spellsResult.Read(71)); - spellInfo.DmgClass = (SpellDmgClass)spellsResult.Read(72); - spellInfo.PreventionType = (SpellPreventionType)spellsResult.Read(73); - spellInfo.RequiredAreasID = spellsResult.Read(74); - spellInfo.SchoolMask = (SpellSchoolMask)spellsResult.Read(75); - spellInfo.ChargeCategoryId = spellsResult.Read(76); + spellInfo.CasterAuraType = (AuraType)spellsResult.Read(34); + spellInfo.TargetAuraType = (AuraType)spellsResult.Read(35); + spellInfo.ExcludeCasterAuraType = (AuraType)spellsResult.Read(36); + spellInfo.ExcludeTargetAuraType = (AuraType)spellsResult.Read(37); + spellInfo.CastTimeEntry = CliDB.SpellCastTimesStorage.LookupByKey(spellsResult.Read(38)); + spellInfo.RecoveryTime = spellsResult.Read(39); + spellInfo.CategoryRecoveryTime = spellsResult.Read(40); + spellInfo.StartRecoveryCategory = spellsResult.Read(41); + spellInfo.StartRecoveryTime = spellsResult.Read(42); + spellInfo.InterruptFlags = (SpellInterruptFlags)spellsResult.Read(43); + spellInfo.AuraInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read(44); + spellInfo.AuraInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read(45); + spellInfo.ChannelInterruptFlags = (SpellAuraInterruptFlags)spellsResult.Read(46); + spellInfo.ChannelInterruptFlags2 = (SpellAuraInterruptFlags2)spellsResult.Read(47); + spellInfo.ProcFlags = new ProcFlagsInit(spellsResult.Read(48), spellsResult.Read(49)); + spellInfo.ProcChance = spellsResult.Read(50); + spellInfo.ProcCharges = spellsResult.Read(51); + spellInfo.ProcCooldown = spellsResult.Read(52); + spellInfo.ProcBasePPM = spellsResult.Read(53); + spellInfo.MaxLevel = spellsResult.Read(54); + spellInfo.BaseLevel = spellsResult.Read(55); + spellInfo.SpellLevel = spellsResult.Read(56); + spellInfo.DurationEntry = CliDB.SpellDurationStorage.LookupByKey(spellsResult.Read(57)); + spellInfo.RangeEntry = CliDB.SpellRangeStorage.LookupByKey(spellsResult.Read(58)); + spellInfo.Speed = spellsResult.Read(59); + spellInfo.LaunchDelay = spellsResult.Read(60); + spellInfo.StackAmount = spellsResult.Read(61); + spellInfo.EquippedItemClass = (ItemClass)spellsResult.Read(62); + spellInfo.EquippedItemSubClassMask = spellsResult.Read(63); + spellInfo.EquippedItemInventoryTypeMask = spellsResult.Read(64); + spellInfo.ContentTuningId = spellsResult.Read(65); + spellInfo.ConeAngle = spellsResult.Read(67); + spellInfo.Width = spellsResult.Read(68); + spellInfo.MaxTargetLevel = spellsResult.Read(69); + spellInfo.MaxAffectedTargets = spellsResult.Read(70); + spellInfo.SpellFamilyName = (SpellFamilyNames)spellsResult.Read(71); + spellInfo.SpellFamilyFlags = new FlagArray128(spellsResult.Read(72), spellsResult.Read(73), spellsResult.Read(74), spellsResult.Read(75)); + spellInfo.DmgClass = (SpellDmgClass)spellsResult.Read(76); + spellInfo.PreventionType = (SpellPreventionType)spellsResult.Read(77); + spellInfo.RequiredAreasID = spellsResult.Read(78); + spellInfo.SchoolMask = (SpellSchoolMask)spellsResult.Read(79); + spellInfo.ChargeCategoryId = spellsResult.Read(80); mSpellInfoMap.Add(spellId, spellInfo); diff --git a/Source/Game/World/WorldManager.cs b/Source/Game/World/WorldManager.cs index befc5eb5a..173bdebb1 100644 --- a/Source/Game/World/WorldManager.cs +++ b/Source/Game/World/WorldManager.cs @@ -890,9 +890,6 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu addon..."); Global.ObjectMgr.LoadGossipMenuAddon(); - Log.outInfo(LogFilter.ServerLoading, "Loading Gossip menu item addon..."); - Global.ObjectMgr.LoadGossipMenuItemAddon(); - Log.outInfo(LogFilter.ServerLoading, "Loading Creature trainers..."); Global.ObjectMgr.LoadCreatureTrainers(); // must be after LoadGossipMenuItems diff --git a/Source/Scripts/Spells/Generic.cs b/Source/Scripts/Spells/Generic.cs index b5f7c68d1..6db16bf9c 100644 --- a/Source/Scripts/Spells/Generic.cs +++ b/Source/Scripts/Spells/Generic.cs @@ -3281,8 +3281,10 @@ namespace Scripts.Spells.Generic Unit target = GetHitUnit(); if (target) { - SpiritHealerConfirm spiritHealerConfirm = new(); - spiritHealerConfirm.Unit = target.GetGUID(); + NPCInteractionOpenResult spiritHealerConfirm = new(); + spiritHealerConfirm.Npc = target.GetGUID(); + spiritHealerConfirm.InteractionType = PlayerInteractionType.SpiritHealer; + spiritHealerConfirm.Success = true; originalCaster.SendPacket(spiritHealerConfirm); } } diff --git a/Source/WorldServer/WorldServer.conf.dist b/Source/WorldServer/WorldServer.conf.dist index 8bbe81f95..8c952672e 100644 --- a/Source/WorldServer/WorldServer.conf.dist +++ b/Source/WorldServer/WorldServer.conf.dist @@ -806,9 +806,17 @@ CharactersPerAccount = 50 # CharactersPerRealm # Description: Limit number of characters per account on this realm. # Range: 1-200 -# Default: 50 +# Default: 60 -CharactersPerRealm = 50 +CharactersPerRealm = 60 + +# +# CharacterCreating.EvokersPerRealm +# Description: Limit number of death knight characters per account on this realm. +# Range: 1-60 +# Default: 1 + +CharacterCreating.EvokersPerRealm = 1 # # CharacterCreating.MinLevelForDemonHunter @@ -819,6 +827,15 @@ CharactersPerRealm = 50 CharacterCreating.MinLevelForDemonHunter = 0 +# +# CharacterCreating.MinLevelForEvoker +# Description: Limit creating demon hunters only for account with another +# character of specific level. +# Default: 50 - (Enabled, Requires at least another level 50 character) +# 0 - (Disabled, No requirement) + +CharacterCreating.MinLevelForEvoker = 0 + # # CharacterCreating.DisableAlliedRaceAchievementRequirement # Description: Disable achievement requirements for allied race character creation