aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/bnetserver/Packets/AuthenticationPackets.h8
-rw-r--r--src/server/bnetserver/Packets/BitStream.h1
-rw-r--r--src/server/bnetserver/Packets/CachePackets.cpp2
-rw-r--r--src/server/bnetserver/Packets/CachePackets.h6
-rw-r--r--src/server/bnetserver/Packets/ConnectionPackets.h6
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.cpp4
-rw-r--r--src/server/bnetserver/Packets/FriendsPackets.h2
-rw-r--r--src/server/bnetserver/Packets/WoWRealmPackets.h2
-rw-r--r--src/server/bnetserver/Server/Session.cpp3
-rw-r--r--src/server/bnetserver/Server/Session.h2
-rw-r--r--src/server/game/AI/CoreAI/PetAI.cpp2
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.cpp51
-rw-r--r--src/server/game/AI/CoreAI/UnitAI.h6
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h16
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp29
-rw-r--r--src/server/game/Accounts/AccountMgr.cpp2
-rw-r--r--src/server/game/Accounts/RBAC.h2
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp10
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp36
-rw-r--r--src/server/game/Battlegrounds/Battleground.h1
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp2
-rw-r--r--src/server/game/Chat/Channels/Channel.cpp661
-rw-r--r--src/server/game/Chat/Channels/Channel.h185
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.cpp53
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.h21
-rw-r--r--src/server/game/Chat/Chat.cpp172
-rw-r--r--src/server/game/Chat/Chat.h10
-rw-r--r--src/server/game/Combat/ThreatManager.cpp4
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp481
-rw-r--r--src/server/game/Conditions/ConditionMgr.h20
-rw-r--r--src/server/game/Conditions/DisableMgr.cpp14
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp18
-rw-r--r--src/server/game/DataStores/DB2Stores.h3
-rw-r--r--src/server/game/DataStores/DB2Structure.h92
-rw-r--r--src/server/game/DataStores/DB2Utility.cpp44
-rw-r--r--src/server/game/DataStores/DB2fmt.h6
-rw-r--r--src/server/game/DataStores/DBCEnums.h52
-rw-r--r--src/server/game/DataStores/DBCStores.cpp276
-rw-r--r--src/server/game/DataStores/DBCStores.h73
-rw-r--r--src/server/game/DataStores/DBCStructure.h38
-rw-r--r--src/server/game/DataStores/DBCfmt.h6
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp4
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h2
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp59
-rw-r--r--src/server/game/Entities/Creature/Creature.h18
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp64
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp6
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp73
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.h1
-rw-r--r--src/server/game/Entities/Item/ItemPrototype.h8
-rw-r--r--src/server/game/Entities/Object/Object.cpp18
-rw-r--r--src/server/game/Entities/Object/Object.h6
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.cpp4
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.cpp2
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp17
-rw-r--r--src/server/game/Entities/Player/Player.cpp1105
-rw-r--r--src/server/game/Entities/Player/Player.h205
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp8
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp15
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp1188
-rw-r--r--src/server/game/Entities/Unit/Unit.h90
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp249
-rw-r--r--src/server/game/Globals/ObjectMgr.h14
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h5
-rw-r--r--src/server/game/Groups/Group.cpp18
-rw-r--r--src/server/game/Groups/Group.h6
-rw-r--r--src/server/game/Guilds/Guild.cpp33
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.cpp28
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.h4
-rw-r--r--src/server/game/Handlers/AuthHandler.cpp16
-rw-r--r--src/server/game/Handlers/BattlefieldHandler.cpp10
-rw-r--r--src/server/game/Handlers/ChannelHandler.cpp103
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp154
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp628
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp8
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp127
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp92
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp35
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp87
-rw-r--r--src/server/game/Handlers/PetHandler.cpp10
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp115
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp35
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp57
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp74
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp4
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h2
-rw-r--r--src/server/game/Instances/InstanceScript.cpp2
-rw-r--r--src/server/game/Maps/Map.h6
-rw-r--r--src/server/game/Maps/MapInstanced.cpp4
-rw-r--r--src/server/game/Maps/MapManager.cpp2
-rw-r--r--src/server/game/Maps/TransportMgr.h1
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h539
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp32
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp146
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.h6
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h8
-rw-r--r--src/server/game/Quests/QuestDef.cpp3
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp32
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp106
-rw-r--r--src/server/game/Scripting/ScriptMgr.h10
-rw-r--r--src/server/game/Server/Packet.cpp158
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.cpp56
-rw-r--r--src/server/game/Server/Packets/AuthenticationPackets.h10
-rw-r--r--src/server/game/Server/Packets/ChannelPackets.cpp41
-rw-r--r--src/server/game/Server/Packets/ChannelPackets.h59
-rw-r--r--src/server/game/Server/Packets/CharacterPackets.cpp32
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp136
-rw-r--r--src/server/game/Server/Packets/ChatPackets.h199
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.cpp43
-rw-r--r--src/server/game/Server/Packets/CombatLogPackets.h52
-rw-r--r--src/server/game/Server/Packets/CombatPackets.cpp119
-rw-r--r--src/server/game/Server/Packets/CombatPackets.h126
-rw-r--r--src/server/game/Server/Packets/EquipmentSetPackets.cpp65
-rw-r--r--src/server/game/Server/Packets/EquipmentSetPackets.h58
-rw-r--r--src/server/game/Server/Packets/GuildPackets.cpp24
-rw-r--r--src/server/game/Server/Packets/ItemPackets.cpp59
-rw-r--r--src/server/game/Server/Packets/ItemPackets.h58
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp70
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h88
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp448
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h243
-rw-r--r--src/server/game/Server/Packets/NPCPackets.cpp120
-rw-r--r--src/server/game/Server/Packets/NPCPackets.h133
-rw-r--r--src/server/game/Server/Packets/QueryPackets.cpp59
-rw-r--r--src/server/game/Server/Packets/QueryPackets.h59
-rw-r--r--src/server/game/Server/Packets/QuestPackets.cpp43
-rw-r--r--src/server/game/Server/Packets/QuestPackets.h80
-rw-r--r--src/server/game/Server/Packets/ReputationPackets.cpp34
-rw-r--r--src/server/game/Server/Packets/ReputationPackets.h48
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp435
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h286
-rw-r--r--src/server/game/Server/Packets/SystemPackets.cpp24
-rw-r--r--src/server/game/Server/Packets/TalentPackets.cpp14
-rw-r--r--src/server/game/Server/Packets/TalentPackets.h13
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp1598
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h330
-rw-r--r--src/server/game/Server/WorldPacket.h6
-rw-r--r--src/server/game/Server/WorldSession.cpp80
-rw-r--r--src/server/game/Server/WorldSession.h173
-rw-r--r--src/server/game/Server/WorldSocket.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h123
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp318
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h27
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp297
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h67
-rw-r--r--src/server/game/Spells/Spell.cpp982
-rw-r--r--src/server/game/Spells/Spell.h55
-rw-r--r--src/server/game/Spells/SpellEffects.cpp599
-rw-r--r--src/server/game/Spells/SpellInfo.cpp698
-rw-r--r--src/server/game/Spells/SpellInfo.h99
-rw-r--r--src/server/game/Spells/SpellMgr.cpp524
-rw-r--r--src/server/game/Spells/SpellMgr.h23
-rw-r--r--src/server/game/Spells/SpellScript.cpp31
-rw-r--r--src/server/game/Spells/SpellScript.h1
-rw-r--r--src/server/game/Texts/ChatTextBuilder.h15
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp15
-rw-r--r--src/server/game/Texts/CreatureTextMgr.h27
-rw-r--r--src/server/game/Tools/PlayerDump.cpp8
-rw-r--r--src/server/game/World/World.cpp30
-rw-r--r--src/server/ipc/Commands.cpp8
-rw-r--r--src/server/ipc/Commands.h8
-rw-r--r--src/server/ipc/ZMQTask.h4
-rw-r--r--src/server/ipc/ZmqMux.cpp10
-rw-r--r--src/server/ipc/ZmqMux.h2
-rw-r--r--src/server/ipc/ZmqWorker.cpp5
-rw-r--r--src/server/ipc/ZmqWorker.h6
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp10
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp4
-rw-r--r--src/server/scripts/Commands/cs_learn.cpp2
-rw-r--r--src/server/scripts/Commands/cs_list.cpp14
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp65
-rw-r--r--src/server/scripts/Commands/cs_message.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp56
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp4
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp8
-rw-r--r--src/server/scripts/Commands/cs_quest.cpp8
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp12
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp30
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp9
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp3
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp618
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h9
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp6
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp93
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp1
-rw-r--r--src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp2
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp2
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp18
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp1
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp2
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp4
-rw-r--r--src/server/scripts/Kalimdor/zone_felwood.cpp8
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp2
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp10
-rw-r--r--src/server/scripts/Maelstrom/Stonecore/stonecore.cpp2
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp8
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp3
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp4
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp2
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp85
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp4
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp2
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp5
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp45
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp9
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp4
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp6
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp6
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp10
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp108
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_noth.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp152
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h50
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp26
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp10
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp166
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp12
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp4
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp38
-rw-r--r--src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h8
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp4
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp25
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h6
-rw-r--r--src/server/scripts/Outland/GruulsLair/boss_gruul.cpp2
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp4
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp2
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp29
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp28
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp48
-rw-r--r--src/server/scripts/Spells/spell_holiday.cpp2
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp76
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp26
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp59
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp12
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp12
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp10
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp103
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp77
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp102
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp134
-rw-r--r--src/server/scripts/World/action_ip_logger.cpp5
-rw-r--r--src/server/scripts/World/npc_professions.cpp7
-rw-r--r--src/server/scripts/World/npcs_special.cpp4
-rw-r--r--src/server/shared/Common.h4
-rw-r--r--src/server/shared/Networking/Socket.h4
-rw-r--r--src/server/shared/Networking/SocketMgr.h11
-rw-r--r--src/server/shared/Utilities/Util.h8
-rw-r--r--src/server/worldserver/worldserver.conf.dist65
276 files changed, 11865 insertions, 8660 deletions
diff --git a/src/server/bnetserver/Packets/AuthenticationPackets.h b/src/server/bnetserver/Packets/AuthenticationPackets.h
index bcaa0e72011..fd5838720ab 100644
--- a/src/server/bnetserver/Packets/AuthenticationPackets.h
+++ b/src/server/bnetserver/Packets/AuthenticationPackets.h
@@ -60,7 +60,7 @@ namespace Battlenet
std::string Locale;
std::vector<Component> Components;
std::string Login;
- uint8 Region;
+ uint8 Region = 0;
std::string GameAccountName;
};
@@ -98,7 +98,7 @@ namespace Battlenet
std::string Locale;
std::vector<Component> Components;
std::string Login;
- uint64 Compatibility;
+ uint64 Compatibility = 0;
};
class ResponseFailure
@@ -138,8 +138,8 @@ namespace Battlenet
{
public:
LogonResponse() : ServerPacket(PacketHeader(SMSG_LOGON_RESPONSE, AUTHENTICATION)),
- PingTimeout(120000), FirstName(""), LastName(""), AccountId(0), Region(2), Flags(0),
- GameAccountRegion(2), GameAccountName(""), FailedLogins(0)
+ PingTimeout(120000), AccountId(0), Region(2), Flags(0),
+ GameAccountRegion(2), GameAccountFlags(0), FailedLogins(0)
{
}
diff --git a/src/server/bnetserver/Packets/BitStream.h b/src/server/bnetserver/Packets/BitStream.h
index 54c61ab3bbf..ef2c85a63c8 100644
--- a/src/server/bnetserver/Packets/BitStream.h
+++ b/src/server/bnetserver/Packets/BitStream.h
@@ -217,6 +217,7 @@ namespace Battlenet
uint8* GetBuffer() { return _buffer.data(); }
uint8 const* GetBuffer() const { return _buffer.data(); }
+ uint32 GetReadPos() const { return _readPos; }
size_t GetSize() const { return ((_writePos + 7) & ~7) / 8; }
// These methods are meant to only be used when their corresponding actions in the client ignore the value completely
diff --git a/src/server/bnetserver/Packets/CachePackets.cpp b/src/server/bnetserver/Packets/CachePackets.cpp
index deacfd34065..8ae489fe47c 100644
--- a/src/server/bnetserver/Packets/CachePackets.cpp
+++ b/src/server/bnetserver/Packets/CachePackets.cpp
@@ -21,7 +21,7 @@
void Battlenet::Cache::GetStreamItemsRequest::Read()
{
- _stream.WriteSkip(31);
+ _stream.ReadSkip(31);
Index = _stream.Read<uint32>(32);
ReferenceTime = _stream.Read<int32>(32) - std::numeric_limits<int32>::min();
_stream.Read<bool>(1); // StreamDirection
diff --git a/src/server/bnetserver/Packets/CachePackets.h b/src/server/bnetserver/Packets/CachePackets.h
index a65ab2651c8..57ccd448081 100644
--- a/src/server/bnetserver/Packets/CachePackets.h
+++ b/src/server/bnetserver/Packets/CachePackets.h
@@ -54,8 +54,8 @@ namespace Battlenet
std::string Channel;
std::string ItemName;
std::string Locale;
- uint32 Index;
- int32 ReferenceTime;
+ uint32 Index = 0;
+ int32 ReferenceTime = 0;
};
class GetStreamItemsResponse final : public ServerPacket
@@ -70,7 +70,7 @@ namespace Battlenet
void Write() override;
std::string ToString() const override;
- uint32 Index;
+ uint32 Index = 0;
std::vector<ModuleInfo*> Modules;
};
}
diff --git a/src/server/bnetserver/Packets/ConnectionPackets.h b/src/server/bnetserver/Packets/ConnectionPackets.h
index 8572cd5d854..238b2bff760 100644
--- a/src/server/bnetserver/Packets/ConnectionPackets.h
+++ b/src/server/bnetserver/Packets/ConnectionPackets.h
@@ -63,6 +63,8 @@ namespace Battlenet
void Read() override { }
std::string ToString() const override;
void CallHandler(Session* session) override;
+ uint8* GetRemainingData() { return _stream.GetBuffer() + (((_stream.GetReadPos() + 7) & ~7) / 8); }
+ size_t GetRemainingSize() { return _stream.GetSize() - (((_stream.GetReadPos() + 7) & ~7) / 8); }
};
class LogoutRequest final : public ClientPacket
@@ -89,8 +91,8 @@ namespace Battlenet
void Read() override;
std::string ToString() const override;
- uint16 Timeout;
- uint32 Tick;
+ uint16 Timeout = 0;
+ uint32 Tick = 0;
};
class ConnectionClosing final : public ClientPacket
diff --git a/src/server/bnetserver/Packets/FriendsPackets.cpp b/src/server/bnetserver/Packets/FriendsPackets.cpp
index 2659ec6204f..8b5d92389af 100644
--- a/src/server/bnetserver/Packets/FriendsPackets.cpp
+++ b/src/server/bnetserver/Packets/FriendsPackets.cpp
@@ -20,8 +20,8 @@
void Battlenet::Friends::GetFriendsOfFriend::Read()
{
- uint8 unk = _stream.Read<uint8>(2);
- uint32 unk1 = _stream.Read<uint32>(32);
+ _stream.Read<uint8>(2);
+ _stream.Read<uint32>(32);
}
std::string Battlenet::Friends::GetFriendsOfFriend::ToString() const
diff --git a/src/server/bnetserver/Packets/FriendsPackets.h b/src/server/bnetserver/Packets/FriendsPackets.h
index ea4d6d2ea92..12935ddc4da 100644
--- a/src/server/bnetserver/Packets/FriendsPackets.h
+++ b/src/server/bnetserver/Packets/FriendsPackets.h
@@ -78,7 +78,7 @@ namespace Battlenet
std::string ToString() const override;
void CallHandler(Session* session) override;
- uint32 SocialNetworkId;
+ uint32 SocialNetworkId = 0;
};
class RealIdFriendInvite final : public ClientPacket
diff --git a/src/server/bnetserver/Packets/WoWRealmPackets.h b/src/server/bnetserver/Packets/WoWRealmPackets.h
index b411c63100a..dc958db501b 100644
--- a/src/server/bnetserver/Packets/WoWRealmPackets.h
+++ b/src/server/bnetserver/Packets/WoWRealmPackets.h
@@ -78,7 +78,7 @@ namespace Battlenet
std::string ToString() const override;
void CallHandler(Session* session) override;
- uint32 ClientSeed;
+ uint32 ClientSeed = 0;
RealmId Realm;
};
diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp
index 0a5a2de499a..fd6784152e8 100644
--- a/src/server/bnetserver/Server/Session.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -393,9 +393,10 @@ void Battlenet::Session::HandlePing(Connection::Ping const& /*ping*/)
AsyncWrite(new Connection::Pong());
}
-void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption const& /*enableEncryption*/)
+void Battlenet::Session::HandleEnableEncryption(Connection::EnableEncryption& enableEncryption)
{
_crypt.Init(&K);
+ _crypt.DecryptRecv(enableEncryption.GetRemainingData(), enableEncryption.GetRemainingSize());
}
void Battlenet::Session::HandleLogoutRequest(Connection::LogoutRequest const& /*logoutRequest*/)
diff --git a/src/server/bnetserver/Server/Session.h b/src/server/bnetserver/Server/Session.h
index ded5170ae32..4a1feb7c8a8 100644
--- a/src/server/bnetserver/Server/Session.h
+++ b/src/server/bnetserver/Server/Session.h
@@ -69,7 +69,7 @@ namespace Battlenet
// Connection
void HandlePing(Connection::Ping const& ping);
- void HandleEnableEncryption(Connection::EnableEncryption const& enableEncryption);
+ void HandleEnableEncryption(Connection::EnableEncryption& enableEncryption);
void HandleLogoutRequest(Connection::LogoutRequest const& logoutRequest);
void HandleConnectionClosing(Connection::ConnectionClosing const& connectionClosing);
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index e808f91db55..b6d15a9632c 100644
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -181,7 +181,7 @@ void PetAI::UpdateAI(uint32 diff)
}
}
- if (spellInfo->HasEffect(SPELL_EFFECT_JUMP_DEST))
+ if (spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_JUMP_DEST))
{
if (!spellUsed)
delete spell;
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index 33772c2c165..a9d428a0489 100644
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -62,16 +62,16 @@ void UnitAI::DoMeleeAttackIfReady()
}
}
-bool UnitAI::DoSpellAttackIfReady(uint32 spell)
+bool UnitAI::DoSpellAttackIfReady(uint32 spellId)
{
if (me->HasUnitState(UNIT_STATE_CASTING) || !me->isAttackReady())
return true;
- if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell))
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId))
{
if (me->IsWithinCombatRange(me->GetVictim(), spellInfo->GetMaxRange(false)))
{
- me->CastSpell(me->GetVictim(), spell, false);
+ me->CastSpell(me->GetVictim(), spellInfo, TRIGGERED_NONE);
me->resetAttackTimer();
return true;
}
@@ -90,40 +90,6 @@ void UnitAI::SelectTargetList(std::list<Unit*>& targetList, uint32 num, SelectAg
SelectTargetList(targetList, DefaultTargetSelector(me, dist, playerOnly, aura), num, targetType);
}
-float UnitAI::DoGetSpellMaxRange(uint32 spellId, bool positive)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- return spellInfo ? spellInfo->GetMaxRange(positive) : 0;
-}
-
-void UnitAI::DoAddAuraToAllHostilePlayers(uint32 spellid)
-{
- if (me->IsInCombat())
- {
- ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
- for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
- {
- if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
- if (unit->GetTypeId() == TYPEID_PLAYER)
- me->AddAura(spellid, unit);
- }
- }
-}
-
-void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered)
-{
- if (me->IsInCombat())
- {
- ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList();
- for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
- {
- if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
- if (unit->GetTypeId() == TYPEID_PLAYER)
- me->CastSpell(unit, spellid, triggered);
- }
- }
-}
-
void UnitAI::DoCast(uint32 spellId)
{
Unit* target = NULL;
@@ -227,9 +193,12 @@ void UnitAI::FillAISpellInfo()
UPDATE_TARGET(AITARGET_SELF)
else
{
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- uint32 targetType = spellInfo->Effects[j].TargetA.GetTarget();
+ if (!effect)
+ continue;
+
+ uint32 targetType = effect->TargetA.GetTarget();
if (targetType == TARGET_UNIT_TARGET_ENEMY
|| targetType == TARGET_DEST_TARGET_ENEMY)
@@ -237,7 +206,7 @@ void UnitAI::FillAISpellInfo()
else if (targetType == TARGET_UNIT_DEST_AREA_ENEMY)
UPDATE_TARGET(AITARGET_ENEMY)
- if (spellInfo->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
if (targetType == TARGET_UNIT_TARGET_ENEMY)
UPDATE_TARGET(AITARGET_DEBUFF)
@@ -282,7 +251,7 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
}
SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) :
- _caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster))
+ _caster(caster), _spellInfo(sSpellMgr->GetSpellInfo(spellId))
{
ASSERT(_spellInfo);
}
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 5d67c9546aa..79ba8cbdbbc 100644
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -238,17 +238,13 @@ class UnitAI
void AttackStartCaster(Unit* victim, float dist);
- void DoAddAuraToAllHostilePlayers(uint32 spellid);
void DoCast(uint32 spellId);
void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
- void DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false);
void DoCastVictim(uint32 spellId, bool triggered = false);
void DoCastAOE(uint32 spellId, bool triggered = false);
- float DoGetSpellMaxRange(uint32 spellId, bool positive = false);
-
void DoMeleeAttackIfReady();
- bool DoSpellAttackIfReady(uint32 spell);
+ bool DoSpellAttackIfReady(uint32 spellId);
static AISpellInfoType* AISpellInfo;
static void FillAISpellInfo();
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 5bf3c41df41..6d8e5d67ebb 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -282,9 +282,9 @@ struct ScriptedAI : public CreatureAI
{
switch (_difficulty)
{
- case DUNGEON_DIFFICULTY_NORMAL:
+ case DIFFICULTY_NORMAL:
return normal5;
- case DUNGEON_DIFFICULTY_HEROIC:
+ case DIFFICULTY_HEROIC:
return heroic10;
default:
break;
@@ -298,9 +298,9 @@ struct ScriptedAI : public CreatureAI
{
switch (_difficulty)
{
- case RAID_DIFFICULTY_10MAN_NORMAL:
+ case DIFFICULTY_10_N:
return normal10;
- case RAID_DIFFICULTY_25MAN_NORMAL:
+ case DIFFICULTY_25_N:
return normal25;
default:
break;
@@ -314,13 +314,13 @@ struct ScriptedAI : public CreatureAI
{
switch (_difficulty)
{
- case RAID_DIFFICULTY_10MAN_NORMAL:
+ case DIFFICULTY_10_N:
return normal10;
- case RAID_DIFFICULTY_25MAN_NORMAL:
+ case DIFFICULTY_25_N:
return normal25;
- case RAID_DIFFICULTY_10MAN_HEROIC:
+ case DIFFICULTY_10_HC:
return heroic10;
- case RAID_DIFFICULTY_25MAN_HEROIC:
+ case DIFFICULTY_25_HC:
return heroic25;
default:
break;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index cc7864f1f4e..d1a590e24b1 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -823,13 +823,13 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(e.action.cast.spell);
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
+ if (effect && (effect->IsEffect(SPELL_EFFECT_KILL_CREDIT) || effect->IsEffect(SPELL_EFFECT_KILL_CREDIT2)))
{
- if (spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry " SI64FMTD " SourceType %u Event %u Action %u Effect: SPELL_EFFECT_KILL_CREDIT: (SpellId: %u targetA: %u - targetB: %u) has invalid target for this Action",
- e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.cast.spell, spellInfo->Effects[j].TargetA.GetTarget(), spellInfo->Effects[j].TargetB.GetTarget());
+ e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.action.cast.spell, effect->TargetA.GetTarget(), effect->TargetB.GetTarget());
}
}
break;
@@ -1277,19 +1277,22 @@ void SmartAIMgr::LoadHelperStores()
if (!spellInfo)
continue;
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_SUMMON))
- SummonCreatureSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j))));
+ if (!effect)
+ continue;
+
+ if (effect->IsEffect(SPELL_EFFECT_SUMMON))
+ SummonCreatureSpellStore.insert(std::make_pair(uint32(effect->MiscValue), std::make_pair(i, SpellEffIndex(effect->EffectIndex))));
- else if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_SUMMON_OBJECT_WILD))
- SummonGameObjectSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j))));
+ else if (effect->IsEffect(SPELL_EFFECT_SUMMON_OBJECT_WILD))
+ SummonGameObjectSpellStore.insert(std::make_pair(uint32(effect->MiscValue), std::make_pair(i, SpellEffIndex(effect->EffectIndex))));
- else if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT) || spellInfo->Effects[j].IsEffect(SPELL_EFFECT_KILL_CREDIT2))
- KillCreditSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].MiscValue), std::make_pair(i, SpellEffIndex(j))));
+ else if (effect->IsEffect(SPELL_EFFECT_KILL_CREDIT) || effect->IsEffect(SPELL_EFFECT_KILL_CREDIT2))
+ KillCreditSpellStore.insert(std::make_pair(uint32(effect->MiscValue), std::make_pair(i, SpellEffIndex(effect->EffectIndex))));
- else if (spellInfo->Effects[j].IsEffect(SPELL_EFFECT_CREATE_ITEM))
- CreateItemSpellStore.insert(std::make_pair(uint32(spellInfo->Effects[j].ItemType), std::make_pair(i, SpellEffIndex(j))));
+ else if (effect->IsEffect(SPELL_EFFECT_CREATE_ITEM))
+ CreateItemSpellStore.insert(std::make_pair(uint32(effect->ItemType), std::make_pair(i, SpellEffIndex(effect->EffectIndex))));
}
}
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp
index 55f19d1612e..8b2365079c7 100644
--- a/src/server/game/Accounts/AccountMgr.cpp
+++ b/src/server/game/Accounts/AccountMgr.cpp
@@ -456,7 +456,7 @@ void AccountMgr::LoadRBAC()
while (result->NextRow());
TC_LOG_DEBUG("rbac", "AccountMgr::LoadRBAC: Loading default permissions");
- result = LoginDatabase.Query("SELECT secId, permissionId FROM rbac_default_permissions ORDER BY secId ASC");
+ result = LoginDatabase.PQuery("SELECT secId, permissionId FROM rbac_default_permissions WHERE (realmId = %u OR realmId = -1) ORDER BY secId ASC", realmHandle.Index);
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 default permission definitions. DB table `rbac_default_permissions` is empty.");
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 650bd998028..bb347113e60 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -595,7 +595,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS = 689,
RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED = 690,
RBAC_PERM_COMMAND_RELOAD_SPELL_AREA = 691,
- RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA = 692,
+ // REUSE
RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP = 693,
RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL = 694,
RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE = 695,
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 8fe96be26fb..35fb5ec4d76 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -138,13 +138,14 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id);
return false;
}
- if (aura.effect_idx >= 3)
+ SpellEffectInfo const* effect = spellEntry->GetEffect(DIFFICULTY_NONE, aura.effect_idx);
+ if (!effect)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell effect index in value2 (%u), ignored.",
criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx);
return false;
}
- if (!spellEntry->Effects[aura.effect_idx].ApplyAuraName)
+ if (!effect->ApplyAuraName)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has non-aura spell effect (ID: %u Effect: %u), ignores.",
criteria->ID, criteria->type, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id, aura.effect_idx);
@@ -2533,7 +2534,7 @@ bool AchievementMgr<T>::RequirementsSatisfied(AchievementCriteriaEntry const* ac
if (!achievIdForDungeon[j][2])
break; // for
}
- else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
+ else if (referencePlayer->GetDungeonDifficulty() == DIFFICULTY_NORMAL)
{
// dungeon in normal mode accepted
if (!achievIdForDungeon[j][1])
@@ -2882,6 +2883,7 @@ bool AchievementMgr<T>::AdditionalRequirementsSatisfied(AchievementCriteriaEntry
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE: // 41
if (!unit || unit->GetZoneId() != reqValue)
return false;
+ break;
case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: // 46
if (!unit || unit->GetHealthPct() >= reqValue)
return false;
@@ -3227,7 +3229,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
uint32 dataType = fields[1].GetUInt8();
std::string scriptName = fields[4].GetString();
uint32 scriptId = 0;
- if (scriptName.length()) // not empty
+ if (!scriptName.empty())
{
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 7f9359053a1..49bd25e6252 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -70,7 +70,9 @@ namespace Trinity
private:
void do_helper(WorldPacket& data, char const* text)
{
- ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, text);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, text);
+ data = *packet.Write();
}
ChatMsg _msgtype;
@@ -94,7 +96,9 @@ namespace Trinity
char str[2048];
snprintf(str, 2048, text, arg1str, arg2str);
- ChatHandler::BuildChatPacket(data, _msgtype, LANG_UNIVERSAL, _source, _source, str);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgtype, LANG_UNIVERSAL, _source, _source, str);
+ data = *packet.Write();
}
private:
@@ -507,7 +511,7 @@ inline void Battleground::_ProcessJoin(uint32 diff)
StartingEventOpenDoors();
- SendWarningToAll(StartMessageIds[BG_STARTING_EVENT_FOURTH]);
+ SendMessageToAll(StartMessageIds[BG_STARTING_EVENT_FOURTH], CHAT_MSG_RAID_BOSS_EMOTE);
SetStatus(STATUS_IN_PROGRESS);
SetStartDelayTime(StartDelayTimes[BG_STARTING_EVENT_FOURTH]);
@@ -1688,32 +1692,6 @@ void Battleground::PSendMessageToAll(uint32 entry, ChatMsg type, Player const* s
va_end(ap);
}
-void Battleground::SendWarningToAll(uint32 entry, ...)
-{
- if (!entry)
- return;
-
- std::map<uint32, WorldPacket> localizedPackets;
- for (BattlegroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
- if (Player* player = _GetPlayer(itr, "SendWarningToAll"))
- {
- if (localizedPackets.find(player->GetSession()->GetSessionDbLocaleIndex()) == localizedPackets.end())
- {
- char const* format = sObjectMgr->GetTrinityString(entry, player->GetSession()->GetSessionDbLocaleIndex());
-
- char str[1024];
- va_list ap;
- va_start(ap, entry);
- vsnprintf(str, 1024, format, ap);
- va_end(ap);
-
- ChatHandler::BuildChatPacket(localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()], CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str);
- }
-
- player->SendDirectMessage(&localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()]);
- }
-}
-
void Battleground::SendMessage2ToAll(uint32 entry, ChatMsg type, Player const* source, uint32 arg1, uint32 arg2)
{
Trinity::Battleground2ChatBuilder bg_builder(type, entry, source, arg1, arg2);
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index 5bd18977c3d..05873f5f2fc 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -365,7 +365,6 @@ class Battleground
virtual void EndBattleground(uint32 winner);
void BlockMovement(Player* player);
- void SendWarningToAll(uint32 entry, ...);
void SendMessageToAll(uint32 entry, ChatMsg type, Player const* source = NULL);
void PSendMessageToAll(uint32 entry, ChatMsg type, Player const* source, ...);
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index ced77d06514..ee5b14a7f1c 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -894,7 +894,7 @@ void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, ObjectGuid
data->WriteBit(guid[3]);
data->WriteBit(0); // unk
data->WriteBit(guid[5]);
- data->WriteBit(0); // unk
+ data->WriteBit(1); // hide battleground list window
data->FlushBits();
diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp
index 65f07b625e1..a316c8630dc 100644
--- a/src/server/game/Chat/Channels/Channel.cpp
+++ b/src/server/game/Chat/Channels/Channel.cpp
@@ -31,18 +31,16 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team):
_IsSaved(false),
_flags(0),
_channelId(channelId),
- _Team(team),
- _ownerGUID(),
- _name(name),
- _password("")
+ _team(team),
+ _name(name)
{
// set special flags if built-in channel
if (ChatChannelsEntry const* ch = sChatChannelsStore.LookupEntry(channelId)) // check whether it's a built-in channel
{
- _announce = false; // no join/leave announces
- _ownership = false; // no ownership handout
+ _announce = false; // no join/leave announces
+ _ownership = false; // no ownership handout
- _flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
+ _flags |= CHANNEL_FLAG_GENERAL; // for all built-in channels
if (ch->Flags & CHANNEL_DBC_FLAG_TRADE) // for trade channel
_flags |= CHANNEL_FLAG_TRADE;
@@ -62,31 +60,31 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team):
// If storing custom channels in the db is enabled either load or save the channel
if (sWorld->getBoolConfig(CONFIG_PRESERVE_CUSTOM_CHANNELS))
{
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _Team);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHANNEL);
+ stmt->setString(0, _name);
+ stmt->setUInt32(1, _team);
PreparedQueryResult result = CharacterDatabase.Query(stmt);
- if (result) //load
+ if (result) // load
{
Field* fields = result->Fetch();
_announce = fields[0].GetBool();
_ownership = fields[1].GetBool();
_password = fields[2].GetString();
- const char* db_BannedList = fields[3].GetCString();
+ std::string bannedList = fields[3].GetString();
- if (db_BannedList)
+ if (!bannedList.empty())
{
- Tokenizer tokens(db_BannedList, ' ');
+ Tokenizer tokens(bannedList, ' ');
for (Tokenizer::const_iterator i = tokens.begin(); i != tokens.end(); ++i)
{
std::string bannedGuidStr(*i);
- ObjectGuid banned_guid;
- banned_guid.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), NULL, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), NULL, 16)));
- if (!banned_guid.IsEmpty())
+ ObjectGuid bannedGuid;
+ bannedGuid.SetRawValue(uint64(strtoull(bannedGuidStr.substr(0, 16).c_str(), nullptr, 16)), uint64(strtoull(bannedGuidStr.substr(16).c_str(), nullptr, 16)));
+ if (!bannedGuid.IsEmpty())
{
- TC_LOG_DEBUG("chat.system", "Channel(%s) loaded bannedStore %s", name.c_str(), banned_guid.ToString().c_str());
- bannedStore.insert(banned_guid);
+ TC_LOG_DEBUG("chat.system", "Channel (%s) loaded bannedStore %s", _name.c_str(), bannedGuid.ToString().c_str());
+ _bannedStore.insert(bannedGuid);
}
}
}
@@ -94,10 +92,10 @@ Channel::Channel(std::string const& name, uint32 channelId, uint32 team):
else // save
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHANNEL);
- stmt->setString(0, name);
- stmt->setUInt32(1, _Team);
+ stmt->setString(0, _name);
+ stmt->setUInt32(1, _team);
CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("chat.system", "Channel(%s) saved in database", name.c_str());
+ TC_LOG_DEBUG("chat.system", "Channel (%s) saved in database", _name.c_str());
}
_IsSaved = true;
@@ -110,22 +108,19 @@ void Channel::UpdateChannelInDB() const
if (_IsSaved)
{
std::ostringstream banlist;
- BannedContainer::const_iterator iter;
- for (iter = bannedStore.begin(); iter != bannedStore.end(); ++iter)
- banlist << *iter << ' ';
-
- std::string banListStr = banlist.str();
+ for (ObjectGuid const& guid : _bannedStore)
+ banlist << guid << ' ';
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL);
stmt->setBool(0, _announce);
stmt->setBool(1, _ownership);
stmt->setString(2, _password);
- stmt->setString(3, banListStr);
+ stmt->setString(3, banlist.str());
stmt->setString(4, _name);
- stmt->setUInt32(5, _Team);
+ stmt->setUInt32(5, _team);
CharacterDatabase.Execute(stmt);
- TC_LOG_DEBUG("chat.system", "Channel(%s) updated in database", _name.c_str());
+ TC_LOG_DEBUG("chat.system", "Channel (%s) updated in database", _name.c_str());
}
}
@@ -133,7 +128,7 @@ void Channel::UpdateChannelUseageInDB() const
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHANNEL_USAGE);
stmt->setString(0, _name);
- stmt->setUInt32(1, _Team);
+ stmt->setUInt32(1, _team);
CharacterDatabase.Execute(stmt);
}
@@ -151,32 +146,32 @@ void Channel::CleanOldChannelsInDB()
void Channel::JoinChannel(Player* player, std::string const& pass)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (IsOn(guid))
{
// Do not send error message for built-in channels
if (!IsConstant())
{
- WorldPacket data;
- MakePlayerAlreadyMember(&data, guid);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerAlreadyMember(notify, guid);
+ player->SendDirectMessage(notify.Write());
}
return;
}
if (IsBanned(guid))
{
- WorldPacket data;
- MakeBanned(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeBanned(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
if (!_password.empty() && pass != _password)
{
- WorldPacket data;
- MakeWrongPassword(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeWrongPassword(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -185,9 +180,9 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
AccountMgr::IsPlayerAccount(player->GetSession()->GetSecurity()) && //FIXME: Move to RBAC
player->GetGroup())
{
- WorldPacket data;
- MakeNotInLfg(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotInLfg(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -195,73 +190,90 @@ void Channel::JoinChannel(Player* player, std::string const& pass)
if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakeJoined(&data, guid);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeJoined(notify, guid);
+ SendToAll(notify.Write());
}
- PlayerInfo pinfo;
- pinfo.player = guid;
- pinfo.flags = MEMBER_FLAG_NONE;
- playersStore[guid] = pinfo;
+ PlayerInfo playerInfo;
+ playerInfo.PlayerGuid = guid;
+ _playersStore[guid] = playerInfo;
- WorldPacket data;
- MakeYouJoined(&data);
- SendToOne(&data, guid);
+ /*
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeYouJoined(notify);
+ player->SendDirectMessage(notify.Write());
+ */
- JoinNotify(guid);
+ WorldPackets::Channel::ChannelNotifyJoined notify;
+ //notify.ChannelWelcomeMsg = "";
+ notify.ChatChannelID = _channelId;
+ //notify.InstanceID = 0;
+ notify._ChannelFlags = _flags;
+ notify._Channel = _name;
+ player->SendDirectMessage(notify.Write());
+
+ JoinNotify(player);
// Custom channel handling
if (!IsConstant())
{
// Update last_used timestamp in db
- if (!playersStore.empty())
+ if (!_playersStore.empty())
UpdateChannelUseageInDB();
// If the channel has no owner yet and ownership is allowed, set the new owner.
- if (!_ownerGUID && _ownership)
+ if (_ownerGUID.IsEmpty() && _ownership)
{
- SetOwner(guid, playersStore.size() > 1);
- playersStore[guid].SetModerator(true);
+ SetOwner(guid, _playersStore.size() > 1);
+ _playersStore[guid].SetModerator(true);
}
}
}
void Channel::LeaveChannel(Player* player, bool send)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (!IsOn(guid))
{
if (send)
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
}
return;
}
+ player->LeftChannel(this);
+
if (send)
{
- WorldPacket data;
- MakeYouLeft(&data);
- SendToOne(&data, guid);
- player->LeftChannel(this);
- data.clear();
+ /*
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeYouLeft(notify);
+ player->SendDirectMessage(notify.Write());
+ */
+
+ WorldPackets::Channel::ChannelNotifyLeft notify;
+ notify.Channel = _name;
+ notify.ChatChannelID = 0;
+ //notify.Suspended = false;
+ player->SendDirectMessage(notify.Write());
}
- bool changeowner = playersStore[guid].IsOwner();
+ bool changeowner = _playersStore[guid].IsOwner();
- playersStore.erase(guid);
+ _playersStore.erase(guid);
if (_announce && !player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakeLeft(&data, guid);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeLeft(notify, guid);
+ SendToAll(notify.Write());
}
- LeaveNotify(guid);
+ LeaveNotify(player);
if (!IsConstant())
{
@@ -269,10 +281,10 @@ void Channel::LeaveChannel(Player* player, bool send)
UpdateChannelUseageInDB();
// If the channel owner left and there are still playersStore inside, pick a new owner
- if (changeowner && _ownership && !playersStore.empty())
+ if (changeowner && _ownership && !_playersStore.empty())
{
- ObjectGuid newowner = playersStore.begin()->second.player;
- playersStore[newowner].SetModerator(true);
+ ObjectGuid const& newowner = _playersStore.begin()->second.PlayerGuid;
+ _playersStore[newowner].SetModerator(true);
SetOwner(newowner);
}
}
@@ -280,21 +292,21 @@ void Channel::LeaveChannel(Player* player, bool send)
void Channel::KickOrBan(Player const* player, std::string const& badname, bool ban)
{
- ObjectGuid good = player->GetGUID();
+ ObjectGuid const& good = player->GetGUID();
if (!IsOn(good))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
+ if (!_playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotModerator(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -302,9 +314,9 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
if (!victim || !IsOn(victim))
{
- WorldPacket data;
- MakePlayerNotFound(&data, badname);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerNotFound(notify, badname);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -312,154 +324,152 @@ void Channel::KickOrBan(Player const* player, std::string const& badname, bool b
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && changeowner && good != _ownerGUID)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotOwner(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
if (ban && !IsBanned(victim))
{
- bannedStore.insert(victim);
+ _bannedStore.insert(victim);
UpdateChannelInDB();
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakePlayerBanned(&data, victim, good);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerBanned(notify, victim, good);
+ SendToAll(notify.Write());
}
}
else if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_SILENTLY_JOIN_CHANNEL))
{
- WorldPacket data;
- MakePlayerKicked(&data, victim, good);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerKicked(notify, victim, good);
+ SendToAll(notify.Write());
}
- playersStore.erase(victim);
+ _playersStore.erase(victim);
bad->LeftChannel(this);
- if (changeowner && _ownership && !playersStore.empty())
+ if (changeowner && _ownership && !_playersStore.empty())
{
- ObjectGuid newowner = good;
- playersStore[newowner].SetModerator(true);
- SetOwner(newowner);
+ _playersStore[good].SetModerator(true);
+ SetOwner(good);
}
}
void Channel::UnBan(Player const* player, std::string const& badname)
{
- ObjectGuid good = player->GetGUID();
+ ObjectGuid const& good = player->GetGUID();
if (!IsOn(good))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (!playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
+ if (!_playersStore[good].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotModerator(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
Player* bad = ObjectAccessor::FindConnectedPlayerByName(badname);
ObjectGuid victim = bad ? bad->GetGUID() : ObjectGuid::Empty;
- if (!victim || !IsBanned(victim))
+ if (victim.IsEmpty() || !IsBanned(victim))
{
- WorldPacket data;
- MakePlayerNotFound(&data, badname);
- SendToOne(&data, good);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerNotFound(notify, badname);
+ player->SendDirectMessage(notify.Write());
return;
}
- bannedStore.erase(victim);
+ _bannedStore.erase(victim);
- WorldPacket data;
- MakePlayerUnbanned(&data, victim, good);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerUnbanned(notify, victim, good);
+ SendToAll(notify.Write());
UpdateChannelInDB();
}
void Channel::Password(Player const* player, std::string const& pass)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
- ChatHandler chat(player->GetSession());
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
+ if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotModerator(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
_password = pass;
- WorldPacket data;
- MakePasswordChanged(&data, guid);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePasswordChanged(notify, guid);
+ SendToAll(notify.Write());
UpdateChannelInDB();
}
void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bool set)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
+ if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotModerator(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (guid == _ownerGUID && std::string(p2n) == player->GetName() && mod)
+ if (guid == _ownerGUID && p2n == player->GetName() && mod)
return;
Player* newp = ObjectAccessor::FindConnectedPlayerByName(p2n);
ObjectGuid victim = newp ? newp->GetGUID() : ObjectGuid::Empty;
- if (!victim || !IsOn(victim) ||
+ if (victim.IsEmpty() || !IsOn(victim) ||
(player->GetTeam() != newp->GetTeam() &&
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))
{
- WorldPacket data;
- MakePlayerNotFound(&data, p2n);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerNotFound(notify, p2n);
+ player->SendDirectMessage(notify.Write());
return;
}
if (_ownerGUID == victim && _ownerGUID != guid)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotOwner(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -471,21 +481,21 @@ void Channel::SetMode(Player const* player, std::string const& p2n, bool mod, bo
void Channel::SetOwner(Player const* player, std::string const& newname)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
if (!player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR) && guid != _ownerGUID)
{
- WorldPacket data;
- MakeNotOwner(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotOwner(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -497,55 +507,50 @@ void Channel::SetOwner(Player const* player, std::string const& newname)
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL))))
{
- WorldPacket data;
- MakePlayerNotFound(&data, newname);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerNotFound(notify, newname);
+ player->SendDirectMessage(notify.Write());
return;
}
- playersStore[victim].SetModerator(true);
+ _playersStore[victim].SetModerator(true);
SetOwner(victim);
}
-void Channel::SendWhoOwner(ObjectGuid guid)
+void Channel::SendWhoOwner(Player const* player)
{
- WorldPacket data;
- if (IsOn(guid))
- MakeChannelOwner(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ if (IsOn(player->GetGUID()))
+ MakeChannelOwner(notify);
else
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
}
void Channel::List(Player const* player)
{
- ObjectGuid guid = player->GetGUID();
-
- if (!IsOn(guid))
+ if (!IsOn(player->GetGUID()))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
TC_LOG_DEBUG("chat.system", "SMSG_CHANNEL_LIST %s Channel: %s",
player->GetSession()->GetPlayerInfo().c_str(), GetName().c_str());
- WorldPacket data(SMSG_CHANNEL_LIST, 1+(GetName().size()+1)+1+4+playersStore.size()*(8+1));
- data << uint8(1); // channel type?
- data << GetName(); // channel name
- data << uint8(GetFlags()); // channel flags?
-
- size_t pos = data.wpos();
- data << uint32(0); // size of list, placeholder
+ WorldPackets::Channel::ChannelListResponse list;
+ list._Display = true; /// always true?
+ list._Channel = GetName();
+ list._ChannelFlags = GetFlags();
uint32 gmLevelInWhoList = sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST);
- uint32 count = 0;
- for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
+ list._Members.reserve(_playersStore.size());
+ for (PlayerContainer::value_type const& i : _playersStore)
{
- Player* member = ObjectAccessor::FindConnectedPlayer(i->first);
+ Player* member = ObjectAccessor::FindConnectedPlayer(i.first);
// PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all
@@ -554,50 +559,46 @@ void Channel::List(Player const* player)
member->GetSession()->GetSecurity() <= AccountTypes(gmLevelInWhoList)) &&
member->IsVisibleGloballyFor(player))
{
- data << i->first;
- data << uint8(i->second.flags); // flags seems to be changed...
- ++count;
+ list._Members.emplace_back(i.second.PlayerGuid, GetVirtualRealmAddress(), i.second.GetFlags());
}
}
- data.put<uint32>(pos, count);
-
- SendToOne(&data, guid);
+ player->SendDirectMessage(list.Write());
}
void Channel::Announce(Player const* player)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
- if (!playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
+ if (!_playersStore[guid].IsModerator() && !player->GetSession()->HasPermission(rbac::RBAC_PERM_CHANGE_CHANNEL_NOT_MODERATOR))
{
- WorldPacket data;
- MakeNotModerator(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotModerator(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
_announce = !_announce;
- WorldPacket data;
+ WorldPackets::Channel::ChannelNotify notify;
if (_announce)
- MakeAnnouncementsOn(&data, guid);
+ MakeAnnouncementsOn(notify, guid);
else
- MakeAnnouncementsOff(&data, guid);
- SendToAll(&data);
+ MakeAnnouncementsOff(notify, guid);
+ SendToAll(notify.Write());
UpdateChannelInDB();
}
-void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang)
+void Channel::Say(ObjectGuid const& guid, std::string const& what, uint32 lang)
{
if (what.empty())
return;
@@ -608,55 +609,59 @@ void Channel::Say(ObjectGuid guid, std::string const& what, uint32 lang)
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ SendToOne(notify.Write(), guid);
return;
}
- if (playersStore[guid].IsMuted())
+ if (_playersStore[guid].IsMuted())
{
- WorldPacket data;
- MakeMuted(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeMuted(notify);
+ SendToOne(notify.Write(), guid);
return;
}
- WorldPacket data;
+ WorldPackets::Chat::Chat packet;
if (Player* player = ObjectAccessor::FindConnectedPlayer(guid))
- ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name);
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), player, player, what, 0, _name);
else
- ChatHandler::BuildChatPacket(data, CHAT_MSG_CHANNEL, Language(lang), guid, guid, what, 0, "", "", 0, false, _name);
+ {
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_CHANNEL, Language(lang), NULL, NULL, what, 0, _name);
+ packet.SenderGUID = guid;
+ packet.TargetGUID = guid;
+ }
- SendToAll(&data, !playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty);
+ SendToAll(packet.Write(), !_playersStore[guid].IsModerator() ? guid : ObjectGuid::Empty);
}
void Channel::Invite(Player const* player, std::string const& newname)
{
- ObjectGuid guid = player->GetGUID();
+ ObjectGuid const& guid = player->GetGUID();
if (!IsOn(guid))
{
- WorldPacket data;
- MakeNotMember(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeNotMember(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
Player* newp = ObjectAccessor::FindConnectedPlayerByName(newname);
if (!newp || !newp->isGMVisible())
{
- WorldPacket data;
- MakePlayerNotFound(&data, newname);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerNotFound(notify, newname);
+ player->SendDirectMessage(notify.Write());
return;
}
if (IsBanned(newp->GetGUID()))
{
- WorldPacket data;
- MakePlayerInviteBanned(&data, newname);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerInviteBanned(notify, newname);
+ player->SendDirectMessage(notify.Write());
return;
}
@@ -664,169 +669,167 @@ void Channel::Invite(Player const* player, std::string const& newname)
(!player->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL) ||
!newp->GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHANNEL)))
{
- WorldPacket data;
- MakeInviteWrongFaction(&data);
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeInviteWrongFaction(notify);
+ player->SendDirectMessage(notify.Write());
return;
}
if (IsOn(newp->GetGUID()))
{
- WorldPacket data;
- MakePlayerAlreadyMember(&data, newp->GetGUID());
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerAlreadyMember(notify, newp->GetGUID());
+ player->SendDirectMessage(notify.Write());
return;
}
if (!newp->GetSocial()->HasIgnore(guid))
{
- WorldPacket data;
- MakeInvite(&data, guid);
- SendToOne(&data, newp->GetGUID());
- data.clear();
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeInvite(notify, guid);
+ newp->SendDirectMessage(notify.Write());
}
- WorldPacket data;
- MakePlayerInvited(&data, newp->GetName());
- SendToOne(&data, guid);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakePlayerInvited(notify, newp->GetName());
+ player->SendDirectMessage(notify.Write());
}
-void Channel::SetOwner(ObjectGuid guid, bool exclaim)
+void Channel::SetOwner(ObjectGuid const& guid, bool exclaim)
{
if (!_ownerGUID.IsEmpty())
{
// [] will re-add player after it possible removed
- PlayerContainer::iterator p_itr = playersStore.find(_ownerGUID);
- if (p_itr != playersStore.end())
- p_itr->second.SetOwner(false);
+ PlayerContainer::iterator itr = _playersStore.find(_ownerGUID);
+ if (itr != _playersStore.end())
+ itr->second.SetOwner(false);
}
_ownerGUID = guid;
if (!_ownerGUID.IsEmpty())
{
- uint8 oldFlag = GetPlayerFlags(_ownerGUID);
- playersStore[_ownerGUID].SetModerator(true);
- playersStore[_ownerGUID].SetOwner(true);
+ uint8 oldFlag = _playersStore[_ownerGUID].GetFlags();
+ _playersStore[_ownerGUID].SetModerator(true);
+ _playersStore[_ownerGUID].SetOwner(true);
- WorldPacket data;
- MakeModeChange(&data, _ownerGUID, oldFlag);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify notify;
+ MakeModeChange(notify, _ownerGUID, oldFlag, _playersStore[_ownerGUID].GetFlags());
+ SendToAll(notify.Write());
if (exclaim)
{
- MakeOwnerChanged(&data, _ownerGUID);
- SendToAll(&data);
+ MakeOwnerChanged(notify, _ownerGUID);
+ SendToAll(notify.Write());
}
UpdateChannelInDB();
}
}
-void Channel::SendToAll(WorldPacket* data, ObjectGuid guid)
+void Channel::SendToAll(WorldPacket const* data, ObjectGuid const& guid)
{
- for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
- if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
- if (!guid || !player->GetSocial()->HasIgnore(guid))
- player->GetSession()->SendPacket(data);
+ for (PlayerContainer::value_type const& i : _playersStore)
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i.first))
+ if (guid.IsEmpty() || !player->GetSocial()->HasIgnore(guid))
+ player->SendDirectMessage(data);
}
-void Channel::SendToAllButOne(WorldPacket* data, ObjectGuid who)
+void Channel::SendToAllButOne(WorldPacket const* data, ObjectGuid const& who)
{
- for (PlayerContainer::const_iterator i = playersStore.begin(); i != playersStore.end(); ++i)
- if (i->first != who)
- if (Player* player = ObjectAccessor::FindConnectedPlayer(i->first))
- player->GetSession()->SendPacket(data);
+ for (PlayerContainer::value_type const& i : _playersStore)
+ if (i.first != who)
+ if (Player* player = ObjectAccessor::FindConnectedPlayer(i.first))
+ player->SendDirectMessage(data);
}
-void Channel::SendToOne(WorldPacket* data, ObjectGuid who)
+void Channel::SendToOne(WorldPacket const* data, ObjectGuid const& who)
{
if (Player* player = ObjectAccessor::FindConnectedPlayer(who))
- player->GetSession()->SendPacket(data);
+ player->SendDirectMessage(data);
}
-void Channel::Voice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/)
+void Channel::Voice(ObjectGuid const& /*guid1*/, ObjectGuid const& /*guid2*/)
{
}
-void Channel::DeVoice(ObjectGuid /*guid1*/, ObjectGuid /*guid2*/)
+void Channel::DeVoice(ObjectGuid const& /*guid1*/, ObjectGuid const& /*guid2*/)
{
}
-void Channel::MakeNotifyPacket(WorldPacket* data, uint8 notify_type)
+void Channel::MakeNotifyPacket(WorldPackets::Channel::ChannelNotify& data, uint8 notifyType)
{
- data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + _name.size());
- *data << uint8(notify_type);
- *data << _name;
+ data.Type = notifyType;
+ data._Channel = _name;
}
-void Channel::MakeJoined(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeJoined(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_JOINED_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeLeft(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeLeft(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_LEFT_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeYouJoined(WorldPacket* data)
+void Channel::MakeYouJoined(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_YOU_JOINED_NOTICE);
- *data << uint8(GetFlags());
- *data << uint32(GetChannelId());
- *data << uint32(0);
+ //*data << uint8(GetFlags());
+ data.ChatChannelID = GetChannelId();
+ //*data << uint32(0);
}
-void Channel::MakeYouLeft(WorldPacket* data)
+void Channel::MakeYouLeft(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_YOU_LEFT_NOTICE);
- *data << uint32(GetChannelId());
- *data << uint8(IsConstant());
+ data.ChatChannelID = GetChannelId();
+ //*data << uint8(IsConstant());
}
-void Channel::MakeWrongPassword(WorldPacket* data)
+void Channel::MakeWrongPassword(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_WRONG_PASSWORD_NOTICE);
}
-void Channel::MakeNotMember(WorldPacket* data)
+void Channel::MakeNotMember(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_MEMBER_NOTICE);
}
-void Channel::MakeNotModerator(WorldPacket* data)
+void Channel::MakeNotModerator(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_MODERATOR_NOTICE);
}
-void Channel::MakePasswordChanged(WorldPacket* data, ObjectGuid guid)
+void Channel::MakePasswordChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_PASSWORD_CHANGED_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeOwnerChanged(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeOwnerChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_OWNER_CHANGED_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakePlayerNotFound(WorldPacket* data, std::string const& name)
+void Channel::MakePlayerNotFound(WorldPackets::Channel::ChannelNotify& data, std::string const& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_NOT_FOUND_NOTICE);
- *data << name;
+ data.Sender = name;
}
-void Channel::MakeNotOwner(WorldPacket* data)
+void Channel::MakeNotOwner(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_OWNER_NOTICE);
}
-void Channel::MakeChannelOwner(WorldPacket* data)
+void Channel::MakeChannelOwner(WorldPackets::Channel::ChannelNotify& data)
{
std::string name;
@@ -834,139 +837,140 @@ void Channel::MakeChannelOwner(WorldPacket* data)
name = "PLAYER_NOT_FOUND";
MakeNotifyPacket(data, CHAT_CHANNEL_OWNER_NOTICE);
- *data << ((IsConstant() || !_ownerGUID) ? "Nobody" : name);
+ data.Sender = ((IsConstant() || !_ownerGUID) ? "Nobody" : name);
}
-void Channel::MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags)
+void Channel::MakeModeChange(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid, uint8 oldFlags, uint8 newFlags)
{
MakeNotifyPacket(data, CHAT_MODE_CHANGE_NOTICE);
- *data << guid;
- *data << uint8(oldflags);
- *data << uint8(GetPlayerFlags(guid));
+ data.SenderGuid = guid;
+ data.OldFlags = oldFlags;
+ data.NewFlags = newFlags;
}
-void Channel::MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeAnnouncementsOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_ON_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeAnnouncementsOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_ANNOUNCEMENTS_OFF_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeMuted(WorldPacket* data)
+void Channel::MakeMuted(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_MUTED_NOTICE);
}
-void Channel::MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good)
+void Channel::MakePlayerKicked(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good)
{
MakeNotifyPacket(data, CHAT_PLAYER_KICKED_NOTICE);
- *data << bad;
- *data << good;
+ data.SenderGuid = good;
+ data.TargetGuid = bad;
}
-void Channel::MakeBanned(WorldPacket* data)
+void Channel::MakeBanned(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_BANNED_NOTICE);
}
-void Channel::MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good)
+void Channel::MakePlayerBanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good)
{
MakeNotifyPacket(data, CHAT_PLAYER_BANNED_NOTICE);
- *data << bad;
- *data << good;
+ data.SenderGuid = good;
+ data.TargetGuid = bad;
}
-void Channel::MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good)
+void Channel::MakePlayerUnbanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good)
{
MakeNotifyPacket(data, CHAT_PLAYER_UNBANNED_NOTICE);
- *data << bad;
- *data << good;
+ data.SenderGuid = good;
+ data.TargetGuid = bad;
}
-void Channel::MakePlayerNotBanned(WorldPacket* data, const std::string &name)
+void Channel::MakePlayerNotBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE);
- *data << name;
+ data.Sender = name;
}
-void Channel::MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid)
+void Channel::MakePlayerAlreadyMember(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_PLAYER_ALREADY_MEMBER_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeInvite(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeInvite(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_INVITE_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeInviteWrongFaction(WorldPacket* data)
+void Channel::MakeInviteWrongFaction(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_INVITE_WRONG_FACTION_NOTICE);
}
-void Channel::MakeWrongFaction(WorldPacket* data)
+void Channel::MakeWrongFaction(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_WRONG_FACTION_NOTICE);
}
-void Channel::MakeInvalidName(WorldPacket* data)
+void Channel::MakeInvalidName(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_INVALID_NAME_NOTICE);
}
-void Channel::MakeNotModerated(WorldPacket* data)
+void Channel::MakeNotModerated(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_MODERATED_NOTICE);
}
-void Channel::MakePlayerInvited(WorldPacket* data, const std::string& name)
+void Channel::MakePlayerInvited(WorldPackets::Channel::ChannelNotify& data, std::string const& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_INVITED_NOTICE);
- *data << name;
+ data.Sender = name;
}
-void Channel::MakePlayerInviteBanned(WorldPacket* data, const std::string& name)
+void Channel::MakePlayerInviteBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name)
{
MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE);
- *data << name;
+ data.Sender = name;
}
-void Channel::MakeThrottled(WorldPacket* data)
+void Channel::MakeThrottled(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_THROTTLED_NOTICE);
}
-void Channel::MakeNotInArea(WorldPacket* data)
+void Channel::MakeNotInArea(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_IN_AREA_NOTICE);
}
-void Channel::MakeNotInLfg(WorldPacket* data)
+void Channel::MakeNotInLfg(WorldPackets::Channel::ChannelNotify& data)
{
MakeNotifyPacket(data, CHAT_NOT_IN_LFG_NOTICE);
}
-void Channel::MakeVoiceOn(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeVoiceOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_VOICE_ON_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::MakeVoiceOff(WorldPacket* data, ObjectGuid guid)
+void Channel::MakeVoiceOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid)
{
MakeNotifyPacket(data, CHAT_VOICE_OFF_NOTICE);
- *data << guid;
+ data.SenderGuid = guid;
}
-void Channel::JoinNotify(ObjectGuid guid)
+void Channel::JoinNotify(Player const* player)
{
+ ObjectGuid const& guid = player->GetGUID();
WorldPacket data(IsConstant() ? SMSG_USERLIST_ADD : SMSG_USERLIST_UPDATE, 8 + 1 + 1 + 4 + GetName().size());
data << guid;
data << uint8(GetPlayerFlags(guid));
@@ -980,8 +984,9 @@ void Channel::JoinNotify(ObjectGuid guid)
SendToAll(&data);
}
-void Channel::LeaveNotify(ObjectGuid guid)
+void Channel::LeaveNotify(Player const* player)
{
+ ObjectGuid const& guid = player->GetGUID();
WorldPacket data(SMSG_USERLIST_REMOVE, 8 + 1 + 4 + GetName().size());
data << guid;
data << uint8(GetFlags());
diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h
index 6489c8b47ad..4ee83b8fbb2 100644
--- a/src/server/game/Chat/Channels/Channel.h
+++ b/src/server/game/Chat/Channels/Channel.h
@@ -19,14 +19,11 @@
#ifndef _CHANNEL_H
#define _CHANNEL_H
-#include <list>
-#include <map>
-#include <string>
-
#include "Common.h"
#include "WorldSession.h"
-#include "WorldPacket.h"
+
+#include "Packets/ChannelPackets.h"
class Player;
@@ -122,33 +119,47 @@ class Channel
{
struct PlayerInfo
{
- ObjectGuid player;
- uint8 flags;
+ ObjectGuid PlayerGuid;
+
+ uint8 GetFlags() const { return _flags; }
+ inline bool HasFlag(uint8 flag) const { return (_flags & flag) != 0; }
+ inline void SetFlag(uint8 flag) { _flags |= flag; }
+ inline void RemoveFlag(uint8 flag) { _flags &= ~flag; }
- bool HasFlag(uint8 flag) const { return (flags & flag) != 0; }
- void SetFlag(uint8 flag) { flags |= flag; }
- bool IsOwner() const { return (flags & MEMBER_FLAG_OWNER) != 0; }
+ bool IsOwner() const { return HasFlag(MEMBER_FLAG_OWNER); }
void SetOwner(bool state)
{
- if (state) flags |= MEMBER_FLAG_OWNER;
- else flags &= ~MEMBER_FLAG_OWNER;
+ if (state)
+ SetFlag(MEMBER_FLAG_OWNER);
+ else
+ RemoveFlag(MEMBER_FLAG_OWNER);
}
- bool IsModerator() const { return (flags & MEMBER_FLAG_MODERATOR) != 0; }
+
+ bool IsModerator() const { return HasFlag(MEMBER_FLAG_MODERATOR); }
void SetModerator(bool state)
{
- if (state) flags |= MEMBER_FLAG_MODERATOR;
- else flags &= ~MEMBER_FLAG_MODERATOR;
+ if (state)
+ SetFlag(MEMBER_FLAG_MODERATOR);
+ else
+ RemoveFlag(MEMBER_FLAG_MODERATOR);
}
- bool IsMuted() const { return (flags & MEMBER_FLAG_MUTED) != 0; }
+
+ bool IsMuted() const { return HasFlag(MEMBER_FLAG_MUTED); }
void SetMuted(bool state)
{
- if (state) flags |= MEMBER_FLAG_MUTED;
- else flags &= ~MEMBER_FLAG_MUTED;
+ if (state)
+ SetFlag(MEMBER_FLAG_MUTED);
+ else
+ RemoveFlag(MEMBER_FLAG_MUTED);
}
+
+ private:
+ uint8 _flags = MEMBER_FLAG_NONE;
};
public:
Channel(std::string const& name, uint32 channel_id, uint32 Team = 0);
+
std::string const& GetName() const { return _name; }
uint32 GetChannelId() const { return _channelId; }
bool IsConstant() const { return _channelId != 0; }
@@ -157,7 +168,7 @@ class Channel
std::string const& GetPassword() const { return _password; }
void SetPassword(std::string const& npassword) { _password = npassword; }
void SetAnnounce(bool nannounce) { _announce = nannounce; }
- uint32 GetNumPlayers() const { return playersStore.size(); }
+ uint32 GetNumPlayers() const { return _playersStore.size(); }
uint8 GetFlags() const { return _flags; }
bool HasFlag(uint8 flag) const { return (_flags & flag) != 0; }
@@ -169,102 +180,102 @@ class Channel
void UnBan(Player const* player, std::string const& badname);
void Password(Player const* player, std::string const& pass);
void SetMode(Player const* player, std::string const& p2n, bool mod, bool set);
- void SetOwner(ObjectGuid guid, bool exclaim = true);
+ void SetOwner(ObjectGuid const& guid, bool exclaim = true);
void SetOwner(Player const* player, std::string const& name);
- void SendWhoOwner(ObjectGuid guid);
+ void SendWhoOwner(Player const* player);
void SetModerator(Player const* player, std::string const& newname) { SetMode(player, newname, true, true); }
void UnsetModerator(Player const* player, std::string const& newname) { SetMode(player, newname, true, false); }
void SetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, true); }
void UnsetMute(Player const* player, std::string const& newname) { SetMode(player, newname, false, false); }
void List(Player const* player);
void Announce(Player const* player);
- void Say(ObjectGuid guid, std::string const& what, uint32 lang);
+ void Say(ObjectGuid const& guid, std::string const& what, uint32 lang);
void Invite(Player const* player, std::string const& newp);
- void Voice(ObjectGuid guid1, ObjectGuid guid2);
- void DeVoice(ObjectGuid guid1, ObjectGuid guid2);
- void JoinNotify(ObjectGuid guid); // invisible notify
- void LeaveNotify(ObjectGuid guid); // invisible notify
+ void Voice(ObjectGuid const& guid1, ObjectGuid const& guid2);
+ void DeVoice(ObjectGuid const& guid1, ObjectGuid const& guid2);
+ void JoinNotify(Player const* player);
+ void LeaveNotify(Player const* player);
void SetOwnership(bool ownership) { _ownership = ownership; };
static void CleanOldChannelsInDB();
private:
// initial packet data (notify type and channel name)
- void MakeNotifyPacket(WorldPacket* data, uint8 notify_type);
+ void MakeNotifyPacket(WorldPackets::Channel::ChannelNotify& data, uint8 notifyType);
// type specific packet data
- void MakeJoined(WorldPacket* data, ObjectGuid guid); //+ 0x00
- void MakeLeft(WorldPacket* data, ObjectGuid guid); //+ 0x01
- void MakeYouJoined(WorldPacket* data); //+ 0x02
- void MakeYouLeft(WorldPacket* data); //+ 0x03
- void MakeWrongPassword(WorldPacket* data); //? 0x04
- void MakeNotMember(WorldPacket* data); //? 0x05
- void MakeNotModerator(WorldPacket* data); //? 0x06
- void MakePasswordChanged(WorldPacket* data, ObjectGuid guid); //+ 0x07
- void MakeOwnerChanged(WorldPacket* data, ObjectGuid guid); //? 0x08
- void MakePlayerNotFound(WorldPacket* data, std::string const& name); //+ 0x09
- void MakeNotOwner(WorldPacket* data); //? 0x0A
- void MakeChannelOwner(WorldPacket* data); //? 0x0B
- void MakeModeChange(WorldPacket* data, ObjectGuid guid, uint8 oldflags);//+ 0x0C
- void MakeAnnouncementsOn(WorldPacket* data, ObjectGuid guid); //+ 0x0D
- void MakeAnnouncementsOff(WorldPacket* data, ObjectGuid guid); //+ 0x0E
- void MakeMuted(WorldPacket* data); //? 0x11
- void MakePlayerKicked(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x12
- void MakeBanned(WorldPacket* data); //? 0x13
- void MakePlayerBanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x14
- void MakePlayerUnbanned(WorldPacket* data, ObjectGuid bad, ObjectGuid good);//? 0x15
- void MakePlayerNotBanned(WorldPacket* data, std::string const& name); //? 0x16
- void MakePlayerAlreadyMember(WorldPacket* data, ObjectGuid guid); //+ 0x17
- void MakeInvite(WorldPacket* data, ObjectGuid guid); //? 0x18
- void MakeInviteWrongFaction(WorldPacket* data); //? 0x19
- void MakeWrongFaction(WorldPacket* data); //? 0x1A
- void MakeInvalidName(WorldPacket* data); //? 0x1B
- void MakeNotModerated(WorldPacket* data); //? 0x1C
- void MakePlayerInvited(WorldPacket* data, std::string const& name); //+ 0x1D
- void MakePlayerInviteBanned(WorldPacket* data, std::string const& name);//? 0x1E
- void MakeThrottled(WorldPacket* data); //? 0x1F
- void MakeNotInArea(WorldPacket* data); //? 0x20
- void MakeNotInLfg(WorldPacket* data); //? 0x21
- void MakeVoiceOn(WorldPacket* data, ObjectGuid guid); //+ 0x22
- void MakeVoiceOff(WorldPacket* data, ObjectGuid guid); //+ 0x23
+ void MakeJoined(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x00
+ void MakeLeft(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x01
+ void MakeYouJoined(WorldPackets::Channel::ChannelNotify& data); //+ 0x02
+ void MakeYouLeft(WorldPackets::Channel::ChannelNotify& data); //+ 0x03
+ void MakeWrongPassword(WorldPackets::Channel::ChannelNotify& data); //? 0x04
+ void MakeNotMember(WorldPackets::Channel::ChannelNotify& data); //? 0x05
+ void MakeNotModerator(WorldPackets::Channel::ChannelNotify& data); //? 0x06
+ void MakePasswordChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x07
+ void MakeOwnerChanged(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //? 0x08
+ void MakePlayerNotFound(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //+ 0x09
+ void MakeNotOwner(WorldPackets::Channel::ChannelNotify& data); //? 0x0A
+ void MakeChannelOwner(WorldPackets::Channel::ChannelNotify& data); //? 0x0B
+ void MakeModeChange(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid, uint8 oldFlags, uint8 newFlags); //+ 0x0C
+ void MakeAnnouncementsOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x0D
+ void MakeAnnouncementsOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x0E
+ void MakeMuted(WorldPackets::Channel::ChannelNotify& data); //? 0x11
+ void MakePlayerKicked(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x12
+ void MakeBanned(WorldPackets::Channel::ChannelNotify& data); //? 0x13
+ void MakePlayerBanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x14
+ void MakePlayerUnbanned(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& bad, ObjectGuid const& good); //? 0x15
+ void MakePlayerNotBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //? 0x16
+ void MakePlayerAlreadyMember(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x17
+ void MakeInvite(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //? 0x18
+ void MakeInviteWrongFaction(WorldPackets::Channel::ChannelNotify& data); //? 0x19
+ void MakeWrongFaction(WorldPackets::Channel::ChannelNotify& data); //? 0x1A
+ void MakeInvalidName(WorldPackets::Channel::ChannelNotify& data); //? 0x1B
+ void MakeNotModerated(WorldPackets::Channel::ChannelNotify& data); //? 0x1C
+ void MakePlayerInvited(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //+ 0x1D
+ void MakePlayerInviteBanned(WorldPackets::Channel::ChannelNotify& data, std::string const& name); //? 0x1E
+ void MakeThrottled(WorldPackets::Channel::ChannelNotify& data); //? 0x1F
+ void MakeNotInArea(WorldPackets::Channel::ChannelNotify& data); //? 0x20
+ void MakeNotInLfg(WorldPackets::Channel::ChannelNotify& data); //? 0x21
+ void MakeVoiceOn(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x22
+ void MakeVoiceOff(WorldPackets::Channel::ChannelNotify& data, ObjectGuid const& guid); //+ 0x23
- void SendToAll(WorldPacket* data, ObjectGuid guid = ObjectGuid::Empty);
- void SendToAllButOne(WorldPacket* data, ObjectGuid who);
- void SendToOne(WorldPacket* data, ObjectGuid who);
+ void SendToAll(WorldPacket const* data, ObjectGuid const& guid = ObjectGuid::Empty);
+ void SendToAllButOne(WorldPacket const* data, ObjectGuid const& who);
+ void SendToOne(WorldPacket const* data, ObjectGuid const& who);
- bool IsOn(ObjectGuid who) const { return playersStore.find(who) != playersStore.end(); }
- bool IsBanned(ObjectGuid guid) const { return bannedStore.find(guid) != bannedStore.end(); }
+ bool IsOn(ObjectGuid const& who) const { return _playersStore.find(who) != _playersStore.end(); }
+ bool IsBanned(ObjectGuid const& guid) const { return _bannedStore.find(guid) != _bannedStore.end(); }
void UpdateChannelInDB() const;
void UpdateChannelUseageInDB() const;
- uint8 GetPlayerFlags(ObjectGuid guid) const
+ uint8 GetPlayerFlags(ObjectGuid const& guid) const
{
- PlayerContainer::const_iterator itr = playersStore.find(guid);
- return itr != playersStore.end() ? itr->second.flags : 0;
+ PlayerContainer::const_iterator itr = _playersStore.find(guid);
+ return itr != _playersStore.end() ? itr->second.GetFlags() : 0;
}
- void SetModerator(ObjectGuid guid, bool set)
+ void SetModerator(ObjectGuid const& guid, bool set)
{
- if (playersStore[guid].IsModerator() != set)
+ if (_playersStore[guid].IsModerator() != set)
{
- uint8 oldFlag = GetPlayerFlags(guid);
- playersStore[guid].SetModerator(set);
+ uint8 oldFlag = _playersStore[guid].GetFlags();
+ _playersStore[guid].SetModerator(set);
- WorldPacket data;
- MakeModeChange(&data, guid, oldFlag);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify data;
+ MakeModeChange(data, guid, oldFlag, _playersStore[guid].GetFlags());
+ SendToAll(data.Write());
}
}
- void SetMute(ObjectGuid guid, bool set)
+ void SetMute(ObjectGuid const& guid, bool set)
{
- if (playersStore[guid].IsMuted() != set)
+ if (_playersStore[guid].IsMuted() != set)
{
- uint8 oldFlag = GetPlayerFlags(guid);
- playersStore[guid].SetMuted(set);
+ uint8 oldFlag = _playersStore[guid].GetFlags();
+ _playersStore[guid].SetMuted(set);
- WorldPacket data;
- MakeModeChange(&data, guid, oldFlag);
- SendToAll(&data);
+ WorldPackets::Channel::ChannelNotify data;
+ MakeModeChange(data, guid, oldFlag, _playersStore[guid].GetFlags());
+ SendToAll(data.Write());
}
}
@@ -276,12 +287,12 @@ class Channel
bool _IsSaved;
uint8 _flags;
uint32 _channelId;
- uint32 _Team;
+ uint32 _team;
ObjectGuid _ownerGUID;
std::string _name;
std::string _password;
- PlayerContainer playersStore;
- BannedContainer bannedStore;
+ PlayerContainer _playersStore;
+ BannedContainer _bannedStore;
};
-#endif
+#endif
diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp
index a3a4ef69e63..097eea5bb09 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.cpp
+++ b/src/server/game/Chat/Channels/ChannelMgr.cpp
@@ -23,11 +23,11 @@
ChannelMgr::~ChannelMgr()
{
- for (ChannelMap::iterator itr = channels.begin(); itr != channels.end(); ++itr)
+ for (ChannelMap::iterator itr = _channels.begin(); itr != _channels.end(); ++itr)
delete itr->second;
}
-ChannelMgr* ChannelMgr::forTeam(uint32 team)
+ChannelMgr* ChannelMgr::ForTeam(uint32 team)
{
static ChannelMgr allianceChannelMgr;
static ChannelMgr hordeChannelMgr;
@@ -40,49 +40,43 @@ ChannelMgr* ChannelMgr::forTeam(uint32 team)
if (team == HORDE)
return &hordeChannelMgr;
- return NULL;
+ return nullptr;
}
Channel* ChannelMgr::GetJoinChannel(std::string const& name, uint32 channelId)
{
std::wstring wname;
if (!Utf8toWStr(name, wname))
- return NULL;
+ return nullptr;
wstrToLower(wname);
- ChannelMap::const_iterator i = channels.find(wname);
-
- if (i == channels.end())
+ ChannelMap::const_iterator i = _channels.find(wname);
+ if (i == _channels.end())
{
- Channel* nchan = new Channel(name, channelId, team);
- channels[wname] = nchan;
+ Channel* nchan = new Channel(name, channelId, _team);
+ _channels[wname] = nchan;
return nchan;
}
return i->second;
}
-Channel* ChannelMgr::GetChannel(std::string const& name, Player* player, bool pkt)
+Channel* ChannelMgr::GetChannel(std::string const& name, Player* player, bool notify /*= true*/)
{
std::wstring wname;
if (!Utf8toWStr(name, wname))
- return NULL;
+ return nullptr;
wstrToLower(wname);
- ChannelMap::const_iterator i = channels.find(wname);
-
- if (i == channels.end())
+ ChannelMap::const_iterator i = _channels.find(wname);
+ if (i == _channels.end())
{
- if (pkt)
- {
- WorldPacket data;
- MakeNotOnPacket(&data, name);
- player->GetSession()->SendPacket(&data);
- }
-
- return NULL;
+ if (notify)
+ SendNotOnChannelNotify(player, name);
+
+ return nullptr;
}
return i->second;
@@ -96,22 +90,23 @@ void ChannelMgr::LeftChannel(std::string const& name)
wstrToLower(wname);
- ChannelMap::const_iterator i = channels.find(wname);
-
- if (i == channels.end())
+ ChannelMap::const_iterator i = _channels.find(wname);
+ if (i == _channels.end())
return;
Channel* channel = i->second;
if (!channel->GetNumPlayers() && !channel->IsConstant())
{
- channels.erase(wname);
+ _channels.erase(i);
delete channel;
}
}
-void ChannelMgr::MakeNotOnPacket(WorldPacket* data, std::string const& name)
+void ChannelMgr::SendNotOnChannelNotify(Player const* player, std::string const& name)
{
- data->Initialize(SMSG_CHANNEL_NOTIFY, 1 + name.size());
- (*data) << uint8(5) << name;
+ WorldPackets::Channel::ChannelNotify notify;
+ notify.Type = CHAT_NOT_MEMBER_NOTICE;
+ notify._Channel = name;
+ player->SendDirectMessage(notify.Write());
}
diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h
index eee45ba5b97..9a8fdb10767 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.h
+++ b/src/server/game/Chat/Channels/ChannelMgr.h
@@ -21,11 +21,6 @@
#include "Common.h"
#include "Channel.h"
-#include <map>
-#include <string>
-
-#include "World.h"
-
#define MAX_CHANNEL_PASS_STR 31
class ChannelMgr
@@ -33,22 +28,22 @@ class ChannelMgr
typedef std::map<std::wstring, Channel*> ChannelMap;
protected:
- ChannelMgr() : team(0) { }
+ ChannelMgr() : _team(0) { }
~ChannelMgr();
public:
- static ChannelMgr* forTeam(uint32 team);
- void setTeam(uint32 newTeam) { team = newTeam; }
+ static ChannelMgr* ForTeam(uint32 team);
+ void SetTeam(uint32 newTeam) { _team = newTeam; }
- Channel* GetJoinChannel(std::string const& name, uint32 channel_id);
- Channel* GetChannel(std::string const& name, Player* p, bool pkt = true);
+ Channel* GetJoinChannel(std::string const& name, uint32 channelId);
+ Channel* GetChannel(std::string const& name, Player* player, bool notify = true);
void LeftChannel(std::string const& name);
private:
- ChannelMap channels;
- uint32 team;
+ ChannelMap _channels;
+ uint32 _team;
- void MakeNotOnPacket(WorldPacket* data, std::string const& name);
+ static void SendNotOnChannelNotify(Player const* player, std::string const& name);
};
#endif
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index ec3bc458066..cbb0e4683aa 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -35,6 +35,8 @@
#include "SpellMgr.h"
#include "ScriptMgr.h"
#include "ChatLink.h"
+#include "Guild.h"
+#include "Group.h"
bool ChatHandler::load_command_table = true;
@@ -202,7 +204,7 @@ bool ChatHandler::hasStringAbbr(const char* name, const char* part)
void ChatHandler::SendSysMessage(const char *str)
{
- WorldPacket data;
+ WorldPackets::Chat::Chat packet;
// need copy to prevent corruption by strtok call in LineFromMessage original string
char* buf = strdup(str);
@@ -210,8 +212,8 @@ void ChatHandler::SendSysMessage(const char *str)
while (char* line = LineFromMessage(pos))
{
- BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
- m_session->SendPacket(&data);
+ BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ m_session->SendPacket(packet.Write());
}
free(buf);
@@ -220,7 +222,7 @@ void ChatHandler::SendSysMessage(const char *str)
void ChatHandler::SendGlobalSysMessage(const char *str)
{
// Chat output
- WorldPacket data;
+ WorldPackets::Chat::Chat packet;
// need copy to prevent corruption by strtok call in LineFromMessage original string
char* buf = strdup(str);
@@ -228,8 +230,8 @@ void ChatHandler::SendGlobalSysMessage(const char *str)
while (char* line = LineFromMessage(pos))
{
- BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
- sWorld->SendGlobalMessage(&data);
+ BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ sWorld->SendGlobalMessage(packet.Write());
}
free(buf);
@@ -238,7 +240,7 @@ void ChatHandler::SendGlobalSysMessage(const char *str)
void ChatHandler::SendGlobalGMSysMessage(const char *str)
{
// Chat output
- WorldPacket data;
+ WorldPackets::Chat::Chat packet;
// need copy to prevent corruption by strtok call in LineFromMessage original string
char* buf = strdup(str);
@@ -246,8 +248,8 @@ void ChatHandler::SendGlobalGMSysMessage(const char *str)
while (char* line = LineFromMessage(pos))
{
- BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
- sWorld->SendGlobalGMMessage(&data);
+ BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ sWorld->SendGlobalGMMessage(packet.Write());
}
free(buf);
@@ -628,132 +630,56 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
return ShowHelpForSubCommands(table, "", cmd);
}
-size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag,
- std::string const& senderName /*= ""*/, std::string const& receiverName /*= ""*/,
- uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/,
- std::string const& addonPrefix /*= ""*/)
+void ChatHandler::BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message,
+ uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/)
{
- size_t receiverGUIDPos = 0;
- data.Initialize(!gmMessage ? SMSG_MESSAGECHAT : SMSG_GM_MESSAGECHAT);
- data << uint8(chatType);
- data << int32(language);
- data << senderGUID;
- data << uint32(0); // some flags
- switch (chatType)
- {
- case CHAT_MSG_MONSTER_SAY:
- case CHAT_MSG_MONSTER_PARTY:
- case CHAT_MSG_MONSTER_YELL:
- case CHAT_MSG_MONSTER_WHISPER:
- case CHAT_MSG_MONSTER_EMOTE:
- case CHAT_MSG_RAID_BOSS_EMOTE:
- case CHAT_MSG_RAID_BOSS_WHISPER:
- case CHAT_MSG_BATTLENET:
- data << uint32(senderName.length() + 1);
- data << senderName;
- receiverGUIDPos = data.wpos();
- data << receiverGUID;
- if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer() && !receiverGUID.IsPet())
- {
- data << uint32(receiverName.length() + 1);
- data << receiverName;
- }
-
- if (language == LANG_ADDON)
- data << addonPrefix;
- break;
- case CHAT_MSG_WHISPER_FOREIGN:
- data << uint32(senderName.length() + 1);
- data << senderName;
- receiverGUIDPos = data.wpos();
- data << receiverGUID;
- if (language == LANG_ADDON)
- data << addonPrefix;
- break;
- case CHAT_MSG_BG_SYSTEM_NEUTRAL:
- case CHAT_MSG_BG_SYSTEM_ALLIANCE:
- case CHAT_MSG_BG_SYSTEM_HORDE:
- receiverGUIDPos = data.wpos();
- data << receiverGUID;
- if (!receiverGUID.IsEmpty() && !receiverGUID.IsPlayer())
- {
- data << uint32(receiverName.length() + 1);
- data << receiverName;
- }
-
- if (language == LANG_ADDON)
- data << addonPrefix;
- break;
- case CHAT_MSG_ACHIEVEMENT:
- case CHAT_MSG_GUILD_ACHIEVEMENT:
- receiverGUIDPos = data.wpos();
- data << receiverGUID;
- if (language == LANG_ADDON)
- data << addonPrefix;
- break;
- default:
- if (gmMessage)
- {
- data << uint32(senderName.length() + 1);
- data << senderName;
- }
-
- if (chatType == CHAT_MSG_CHANNEL)
- {
- ASSERT(channelName.length() > 0);
- data << channelName;
- }
+ // Clear everything because same packet can be used multiple times
+ packet->Reset();
+ packet->SenderGUID.Clear();
+ packet->SenderAccountGUID.Clear();
+ packet->SenderGuildGUID.Clear();
+ packet->PartyGUID.Clear();
+ packet->TargetGUID.Clear();
+ packet->SenderName.clear();
+ packet->TargetName.clear();
+ packet->ChatFlags = CHAT_FLAG_NONE;
+
+ packet->SlashCmd = chatType;
+ packet->Language = language;
- receiverGUIDPos = data.wpos();
- data << receiverGUID;
-
- if (language == LANG_ADDON)
- data << addonPrefix;
- break;
- }
-
- data << uint32(message.length() + 1);
- data << message;
- data << uint8(chatTag);
-
- if (chatType == CHAT_MSG_ACHIEVEMENT || chatType == CHAT_MSG_GUILD_ACHIEVEMENT)
- data << uint32(achievementId);
- else if (chatType == CHAT_MSG_RAID_BOSS_WHISPER || chatType == CHAT_MSG_RAID_BOSS_EMOTE)
+ if (sender)
{
- data << float(0.0f); // Display time in middle of the screen (in seconds), defaults to 10 if not set (cannot be below 1)
- data << uint8(0); // Hide in chat frame (only shows in middle of the screen)
- }
+ packet->SenderGUID = sender->GetGUID();
- return receiverGUIDPos;
-}
+ if (Creature const* creatureSender = sender->ToCreature())
+ packet->SenderName = creatureSender->GetNameForLocaleIdx(locale);
-size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message,
- uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/)
-{
- ObjectGuid senderGUID;
- std::string senderName = "";
- uint8 chatTag = 0;
- bool gmMessage = false;
- ObjectGuid receiverGUID;
- std::string receiverName = "";
- if (sender)
- {
- senderGUID = sender->GetGUID();
- senderName = sender->GetNameForLocaleIdx(locale);
if (Player const* playerSender = sender->ToPlayer())
{
- chatTag = playerSender->GetChatTag();
- gmMessage = playerSender->GetSession()->HasPermission(rbac::RBAC_PERM_COMMAND_GM_CHAT);
+ packet->SenderAccountGUID = playerSender->GetSession()->GetAccountGUID();
+ packet->ChatFlags = playerSender->GetChatFlags();
+
+ if (Guild const* guild = playerSender->GetGuild())
+ packet->SenderGuildGUID = guild->GetGUID();
+
+ if (Group const* group = playerSender->GetGroup())
+ packet->PartyGUID = group->GetGUID();
}
}
if (receiver)
{
- receiverGUID = receiver->GetGUID();
- receiverName = receiver->GetNameForLocaleIdx(locale);
+ packet->TargetGUID = receiver->GetGUID();
+ if (Creature const* creatureReceiver = receiver->ToCreature())
+ packet->TargetName = creatureReceiver->GetNameForLocaleIdx(locale);
}
- return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName, addonPrefix);
+ packet->SenderVirtualAddress = GetVirtualRealmAddress();
+ packet->TargetVirtualAddress = GetVirtualRealmAddress();
+ packet->AchievementID = achievementId;
+ packet->Channel = channelName;
+ packet->Prefix = addonPrefix;
+ packet->ChatText = message;
}
Player* ChatHandler::getSelectedPlayer()
@@ -1000,7 +926,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
if (!idS)
return 0;
- uint32 id = (uint32)atol(idS);
+ uint32 id = atoul(idS);
switch (type)
{
@@ -1020,7 +946,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
return id;
case SPELL_LINK_GLYPH:
{
- uint32 glyph_prop_id = param1_str ? (uint32)atol(param1_str) : 0;
+ uint32 glyph_prop_id = param1_str ? atoul(param1_str) : 0;
GlyphPropertiesEntry const* glyphPropEntry = sGlyphPropertiesStore.LookupEntry(glyph_prop_id);
if (!glyphPropEntry)
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 98c3bc3efbb..5db48db0fbe 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -22,6 +22,7 @@
#include "SharedDefines.h"
#include "WorldSession.h"
#include "RBAC.h"
+#include "Packets/ChatPackets.h"
#include <vector>
@@ -53,14 +54,7 @@ class ChatHandler
explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) { }
virtual ~ChatHandler() { }
- // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
- static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag,
- std::string const& senderName = "", std::string const& receiverName = "",
- uint32 achievementId = 0, bool gmMessage = false, std::string const& channelName = "",
- std::string const& addonPrefix = "");
-
- // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
- static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = "");
+ static void BuildChatPacket(WorldPackets::Chat::Chat* packet, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE, std::string const& addonPrefix = "");
static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = NULL; return start; }
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 85510ab0545..cd1e3d5be95 100644
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -41,8 +41,8 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
threat *= threatEntry->pctMod;
// Energize is not affected by Mods
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
- if (threatSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE || threatSpell->Effects[i].ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE)
+ for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficulty()))
+ if (effect && (effect->Effect == SPELL_EFFECT_ENERGIZE || effect->ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE))
return threat;
if (Player* modOwner = hatedUnit->GetSpellModOwner())
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 6e4878ce4c5..654451af949 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -29,6 +29,79 @@
#include "SpellMgr.h"
#include "Spell.h"
+char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
+{
+ "None",
+ "Creature Loot",
+ "Disenchant Loot",
+ "Fishing Loot",
+ "GameObject Loot",
+ "Item Loot",
+ "Mail Loot",
+ "Milling Loot",
+ "Pickpocketing Loot",
+ "Prospecting Loot",
+ "Reference Loot",
+ "Skinning Loot",
+ "Spell Loot",
+ "Spell Impl. Target",
+ "Gossip Menu",
+ "Gossip Menu Option",
+ "Creature Vehicle",
+ "Spell Expl. Target",
+ "Spell Click Event",
+ "Quest Accept",
+ "Quest Show Mark",
+ "Vehicle Spell",
+ "SmartScript",
+ "Npc Vendor",
+ "Spell Proc",
+ "Phase Def"
+};
+
+ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[CONDITION_MAX] =
+{
+ { "None", false, false, false },
+ { "Aura", true, true, true },
+ { "Item Stored", true, true, true },
+ { "Item Equipped", true, false, false },
+ { "Zone", true, false, false },
+ { "Reputation", true, true, false },
+ { "Team", true, false, false },
+ { "Skill", true, true, false },
+ { "Quest Rewarded", true, false, false },
+ { "Quest Taken", true, false, false },
+ { "Drunken", true, false, false },
+ { "WorldState", true, true, false },
+ { "Active Event", true, false, false },
+ { "Instance Info", true, true, true },
+ { "Quest None", true, false, false },
+ { "Class", true, false, false },
+ { "Race", true, false, false },
+ { "Achievement", true, false, false },
+ { "Title", true, false, false },
+ { "SpawnMask", true, false, false },
+ { "Gender", true, false, false },
+ { "Unit State", true, false, false },
+ { "Map", true, false, false },
+ { "Area", true, false, false },
+ { "CreatureType", true, false, false },
+ { "Spell Known", true, false, false },
+ { "Phase", true, false, false },
+ { "Level", true, true, false },
+ { "Quest Completed", true, false, false },
+ { "Near Creature", true, true, false },
+ { "Near GameObject", true, true, false },
+ { "Object Entry or Guid", true, true, true },
+ { "Object TypeMask", true, false, false },
+ { "Relation", true, true, false },
+ { "Reaction", true, true, false },
+ { "Distance", true, true, true },
+ { "Alive", false, false, false },
+ { "Health Value", true, true, false },
+ { "Health Pct", true, true, false }
+};
+
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
bool Condition::Meets(ConditionSourceInfo& sourceInfo)
@@ -38,7 +111,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
// object not present, return false
if (!object)
{
- TC_LOG_DEBUG("condition", "Condition object not found for condition (Entry: %u Type: %u Group: %u)", SourceEntry, SourceType, SourceGroup);
+ TC_LOG_DEBUG("condition", "Condition object not found for %s", ToString().c_str());
return false;
}
bool condMeets = false;
@@ -540,6 +613,34 @@ uint32 Condition::GetMaxAvailableConditionTargets()
}
}
+std::string Condition::ToString(bool ext /*= false*/) const
+{
+ std::ostringstream ss;
+ ss << "[Condition ";
+ ss << "SourceType: " << SourceType;
+ if (SourceType < CONDITION_SOURCE_TYPE_MAX)
+ ss << " (" << ConditionMgr::StaticSourceTypeData[SourceType] << ")";
+ else
+ ss << " (Unknown)";
+ if (ConditionMgr::CanHaveSourceGroupSet(SourceType))
+ ss << ", SourceGroup: " << SourceGroup;
+ ss << ", SourceEntry: " << SourceEntry;
+ if (ConditionMgr::CanHaveSourceIdSet(SourceType))
+ ss << ", SourceId: " << SourceId;
+
+ if (ext)
+ {
+ ss << ", ConditionType: " << ConditionType;
+ if (ConditionType < CONDITION_MAX)
+ ss << " (" << ConditionMgr::StaticConditionTypeData[ConditionType].Name << ")";
+ else
+ ss << " (Unknown)";
+ }
+
+ ss << "]";
+ return ss.str();
+}
+
ConditionMgr::ConditionMgr() { }
ConditionMgr::~ConditionMgr()
@@ -602,7 +703,7 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
std::map<uint32, bool> ElseGroupStore;
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
- TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->ConditionType, (*i)->ConditionValue1);
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", (*i)->ToString().c_str(), (*i)->ConditionValue1);
if ((*i)->isLoaded())
{
//! Find ElseGroup in ElseGroupStore
@@ -623,8 +724,8 @@ bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo,
}
else
{
- TC_LOG_DEBUG("condition", "IsPlayerMeetToConditionList: Reference template -%u not found",
- (*i)->ReferenceId);//checked at loading, should never happen
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s Reference template -%u not found",
+ (*i)->ToString().c_str(), (*i)->ReferenceId); // checked at loading, should never happen
}
}
@@ -663,7 +764,7 @@ bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, Con
return IsObjectMeetToConditionList(sourceInfo, conditions);
}
-bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
+bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
{
return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE ||
@@ -687,7 +788,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
}
-bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const
+bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
{
return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
}
@@ -721,7 +822,7 @@ ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, u
if (i != (*itr).second.end())
{
cond = (*i).second;
- TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
+ TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId);
}
}
return cond;
@@ -753,7 +854,7 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int64 entryOrGuid, uint32
if (i != (*itr).second.end())
{
cond = (*i).second;
- TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid " SI64FMTD " event_id %u", entryOrGuid, eventId);
+ TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid " SI64FMTD " eventId %u", entryOrGuid, eventId);
}
}
return cond;
@@ -917,26 +1018,26 @@ void ConditionMgr::LoadConditions(bool isReload)
//Grouping is only allowed for some types (loot templates, gossip menus, gossip items)
if (cond->SourceGroup && !CanHaveSourceGroupSet(cond->SourceType))
{
- TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceGroup = %u!", uint32(cond->SourceType), cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceGroup = %u!", cond->ToString().c_str(), cond->SourceGroup);
delete cond;
continue;
}
if (cond->SourceId && !CanHaveSourceIdSet(cond->SourceType))
{
- TC_LOG_ERROR("sql.sql", "Condition type %u has not allowed value of SourceId = %u!", uint32(cond->SourceType), cond->SourceId);
+ TC_LOG_ERROR("sql.sql", "%s has not allowed value of SourceId = %u!", cond->ToString().c_str(), cond->SourceId);
delete cond;
continue;
}
if (cond->ErrorType && cond->SourceType != CONDITION_SOURCE_TYPE_SPELL)
{
- TC_LOG_ERROR("sql.sql", "Condition type %u entry %i can't have ErrorType (%u), set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorType);
+ TC_LOG_ERROR("sql.sql", "%s can't have ErrorType (%u), set to 0!", cond->ToString().c_str(), cond->ErrorType);
cond->ErrorType = 0;
}
if (cond->ErrorTextId && !cond->ErrorType)
{
- TC_LOG_ERROR("sql.sql", "Condition type %u entry %i has any ErrorType, ErrorTextId (%u) is set, set to 0!", uint32(cond->SourceType), cond->SourceEntry, cond->ErrorTextId);
+ TC_LOG_ERROR("sql.sql", "%s has any ErrorType, ErrorTextId (%u) is set, set to 0!", cond->ToString().c_str(), cond->ErrorTextId);
cond->ErrorTextId = 0;
}
@@ -1034,7 +1135,7 @@ void ConditionMgr::LoadConditions(bool isReload)
if (!valid)
{
- TC_LOG_ERROR("sql.sql", "Not handled grouped condition, SourceGroup %u", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s Not handled grouped condition.", cond->ToString().c_str());
delete cond;
}
else
@@ -1067,21 +1168,20 @@ void ConditionMgr::LoadConditions(bool isReload)
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
-
}
bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot)
{
if (!loot)
{
- TC_LOG_ERROR("sql.sql", "ConditionMgr: LootTemplate %u not found", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s LootTemplate %u not found.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
if (loot->addConditionItem(cond))
return true;
- TC_LOG_ERROR("sql.sql", "ConditionMgr: Item %u not found in LootTemplate %u", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s Item %u not found in LootTemplate %u.", cond->ToString().c_str(), cond->SourceEntry, cond->SourceGroup);
return false;
}
@@ -1101,7 +1201,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond)
}
}
- TC_LOG_ERROR("sql.sql", "addToGossipMenus: GossipMenu %u not found", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s GossipMenu %u not found.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
@@ -1120,7 +1220,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond)
}
}
- TC_LOG_ERROR("sql.sql", "addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->SourceGroup, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s GossipMenuId %u Item %u not found.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry);
return false;
}
@@ -1131,6 +1231,9 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
std::list<uint32> sharedMasks;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
+ SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, i);
+ if (!effect)
+ continue;
// check if effect is already a part of some shared mask
bool found = false;
for (std::list<uint32>::iterator itr = sharedMasks.begin(); itr != sharedMasks.end(); ++itr)
@@ -1146,10 +1249,13 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
// build new shared mask with found effect
uint32 sharedMask = (1<<i);
- ConditionList* cmp = spellInfo->Effects[i].ImplicitTargetConditions;
+ ConditionList* cmp = effect->ImplicitTargetConditions;
for (uint8 effIndex = i+1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
- if (spellInfo->Effects[effIndex].ImplicitTargetConditions == cmp)
+ SpellEffectInfo const* inner = spellInfo->GetEffect(DIFFICULTY_NONE, effIndex);
+ if (!inner)
+ continue;
+ if (inner->ImplicitTargetConditions == cmp)
sharedMask |= 1<<effIndex;
}
sharedMasks.push_back(sharedMask);
@@ -1168,8 +1274,12 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
if (firstEffIndex >= MAX_SPELL_EFFECTS)
return false;
+ SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, firstEffIndex);
+ if (!effect)
+ continue;
+
// get shared data
- ConditionList* sharedList = spellInfo->Effects[firstEffIndex].ImplicitTargetConditions;
+ ConditionList* sharedList = effect->ImplicitTargetConditions;
// there's already data entry for that sharedMask
if (sharedList)
@@ -1177,8 +1287,8 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
// we have overlapping masks in db
if (conditionEffMask != *itr)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
- "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup %u (spell effectMask) set - "
+ "effect masks are overlapping (all SourceGroup values having given bit set must be equal) - ignoring.", cond->ToString().c_str(), cond->SourceGroup);
return false;
}
}
@@ -1190,9 +1300,13 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
bool assigned = false;
for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i)
{
+ SpellEffectInfo const* eff = spellInfo->GetEffect(DIFFICULTY_NONE, firstEffIndex);
+ if (!eff)
+ continue;
+
if ((1<<i) & commonMask)
{
- spellInfo->Effects[i].ImplicitTargetConditions = sharedList;
+ const_cast<SpellEffectInfo*>(eff)->ImplicitTargetConditions = sharedList;
assigned = true;
}
}
@@ -1211,7 +1325,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Invalid ConditionSourceType %u in `condition` table, ignoring.", uint32(cond->SourceType));
+ TC_LOG_ERROR("sql.sql", "%s Invalid ConditionSourceType in `condition` table, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1221,7 +1335,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Creature.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `creature_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1229,7 +1343,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1238,7 +1352,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Disenchant.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `disenchant_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1246,7 +1360,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1255,7 +1369,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Fishing.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `fishing_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1263,7 +1377,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1272,7 +1386,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Gameobject.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1280,7 +1394,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1289,7 +1403,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Item.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1297,7 +1411,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1306,7 +1420,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Mail.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `mail_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1314,7 +1428,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1323,7 +1437,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Milling.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `milling_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1331,7 +1445,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1340,7 +1454,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Pickpocketing.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `pickpocketing_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1348,7 +1462,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1357,7 +1471,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Prospecting.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `prospecting_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1365,7 +1479,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1374,7 +1488,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Reference.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `reference_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1382,7 +1496,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1391,7 +1505,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Skinning.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `skinning_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1399,7 +1513,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1408,7 +1522,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!LootTemplates_Spell.HaveLootFor(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceGroup in `condition` table, does not exist in `spell_loot_template`, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1416,7 +1530,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceType, SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1426,13 +1540,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(cond->SourceEntry);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, SourceEntry does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
if ((cond->SourceGroup > MAX_EFFECT_MASK) || !cond->SourceGroup)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, has incorrect SourceGroup %u (spell effectMask) set, ignoring.", cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect SourceGroup (spell effectMask) set, ignoring.", cond->ToString().c_str());
return false;
}
@@ -1440,10 +1554,14 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (!((1<<i) & cond->SourceGroup))
+ if (!((1 << i) & cond->SourceGroup))
+ continue;
+
+ SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, i);
+ if (!effect)
continue;
- switch (spellInfo->Effects[i].TargetA.GetSelectionCategory())
+ switch (effect->TargetA.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_NEARBY:
case TARGET_SELECT_CATEGORY_CONE:
@@ -1453,7 +1571,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
break;
}
- switch (spellInfo->Effects[i].TargetB.GetSelectionCategory())
+ switch (effect->TargetB.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_NEARBY:
case TARGET_SELECT_CATEGORY_CONE:
@@ -1464,7 +1582,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
TC_LOG_ERROR("sql.sql", "SourceEntry %u SourceGroup %u in `condition` table - spell %u does not have implicit targets of types: _AREA_, _CONE_, _NEARBY_ for effect %u, SourceGroup needs correction, ignoring.", cond->SourceEntry, origGroup, cond->SourceEntry, uint32(i));
- cond->SourceGroup &= ~(1<<i);
+ cond->SourceGroup &= ~(1 << i);
}
// all effects were removed, no need to add the condition at all
if (!cond->SourceGroup)
@@ -1475,7 +1593,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1486,48 +1604,42 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(cond->SourceEntry);
if (!spellProto)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
}
case CONDITION_SOURCE_TYPE_QUEST_ACCEPT:
- if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
- {
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_ACCEPT specifies non-existing quest (%u), skipped", cond->SourceEntry);
- return false;
- }
- break;
case CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK:
if (!sObjectMgr->GetQuestTemplate(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK specifies non-existing quest (%u), skipped", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry specifies non-existing quest, skipped.", cond->ToString().c_str());
return false;
}
break;
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
case CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT:
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
if (!sSpellMgr->GetSpellInfo(cond->SourceEntry))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `spell.dbc`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1542,13 +1654,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `creature_template`, ignoring.", cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `creature_template`, ignoring.", cond->ToString().c_str());
return false;
}
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!itemTemplate)
{
- TC_LOG_ERROR("sql.sql", "SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in `item_template`, ignoring.", cond->ToString().c_str());
return false;
}
break;
@@ -1568,13 +1680,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX)
{
- TC_LOG_ERROR("sql.sql", "Invalid ConditionType %u at SourceEntry %u in `condition` table, ignoring.", uint32(cond->ConditionType), cond->SourceEntry);
+ TC_LOG_ERROR("sql.sql", "%s Invalid ConditionType in `condition` table, ignoring.", cond->ToString().c_str());
return false;
}
if (cond->ConditionTarget >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u, SourceGroup %u in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->SourceType, cond->SourceEntry, cond->SourceGroup);
+ TC_LOG_ERROR("sql.sql", "%s in `condition` table, has incorrect ConditionTarget set, ignoring.", cond->ToString(true).c_str());
return false;
}
@@ -1584,17 +1696,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Aura condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 > EFFECT_2)
{
- TC_LOG_ERROR("sql.sql", "Aura condition has non existing effect index (%u) (must be 0..2), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing effect index (%u) (must be 0..2), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Aura condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ITEM:
@@ -1602,13 +1712,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
if (!proto)
{
- TC_LOG_ERROR("sql.sql", "Item condition has non existing item (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (!cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "Item condition has 0 set for item count in value2 (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s Zero item count in ConditionValue2, skipped.", cond->ToString(true).c_str());
return false;
}
break;
@@ -1618,14 +1728,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(cond->ConditionValue1);
if (!proto)
{
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has non existing item (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Item (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ItemEquipped condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ZONEID:
@@ -1633,20 +1738,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
AreaTableEntry const* areaEntry = GetAreaEntryByAreaID(cond->ConditionValue1);
if (!areaEntry)
{
- TC_LOG_ERROR("sql.sql", "ZoneID condition has non existing area (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s Area (%u) does not exist, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (areaEntry->ParentAreaID != 0)
{
- TC_LOG_ERROR("sql.sql", "ZoneID condition requires to be in area (%u) which is a subzone but zone expected, skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s requires to be in area (%u) which is a subzone but zone expected, skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ZoneID condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_REPUTATION_RANK:
@@ -1654,25 +1754,18 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
FactionEntry const* factionEntry = sFactionStore.LookupEntry(cond->ConditionValue1);
if (!factionEntry)
{
- TC_LOG_ERROR("sql.sql", "Reputation condition has non existing faction (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing faction (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Reputation condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_TEAM:
{
if (cond->ConditionValue1 != ALLIANCE && cond->ConditionValue1 != HORDE)
{
- TC_LOG_ERROR("sql.sql", "Team condition specifies unknown team (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s specifies unknown team (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Team condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Team condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_SKILL:
@@ -1680,17 +1773,15 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(cond->ConditionValue1);
if (!pSkill)
{
- TC_LOG_ERROR("sql.sql", "Skill condition specifies non-existing skill (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s specifies non-existing skill (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 < 1 || cond->ConditionValue2 > sWorld->GetConfigMaxSkillValue())
{
- TC_LOG_ERROR("sql.sql", "Skill condition specifies skill (%u) with invalid value (%u), skipped", cond->ConditionValue1, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s specifies skill (%u) with invalid value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1, cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Skill condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_QUESTREWARDED:
@@ -1700,30 +1791,19 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!sObjectMgr->GetQuestTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Quest condition (Type: %u) points to non-existing quest (%u) for Source Entry %u. SourceGroup: %u, SourceTypeOrReferenceId: %u",
- cond->ConditionType, cond->ConditionValue1, cond->SourceEntry, cond->SourceGroup, cond->SourceType);
+ TC_LOG_ERROR("sql.sql", "%s points to non-existing quest (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2 > 1)
- TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Quest condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ACTIVE_EVENT:
{
GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
- if (cond->ConditionValue1 >=events.size() || !events[cond->ConditionValue1].isValid())
+ if (cond->ConditionValue1 >= events.size() || !events[cond->ConditionValue1].isValid())
{
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has non existing event id (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing event id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ActiveEvent condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_ACHIEVEMENT:
@@ -1731,56 +1811,36 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
AchievementEntry const* achievement = sAchievementMgr->GetAchievement(cond->ConditionValue1);
if (!achievement)
{
- TC_LOG_ERROR("sql.sql", "Achivement condition has non existing achivement id (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing achivement id (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Achivement condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_CLASS:
{
if (!(cond->ConditionValue1 & CLASSMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Class condition has non existing classmask (%u), skipped", cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
+ TC_LOG_ERROR("sql.sql", "%s has non existing classmask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Class condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Class condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_RACE:
{
if (!(cond->ConditionValue1 & RACEMASK_ALL_PLAYABLE))
{
- TC_LOG_ERROR("sql.sql", "Race condition has non existing racemask (%u), skipped", cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
+ TC_LOG_ERROR("sql.sql", "%s has non existing racemask (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Race condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Race condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_GENDER:
{
if (!Player::IsValidGender(uint8(cond->ConditionValue1)))
{
- TC_LOG_ERROR("sql.sql", "Gender condition has invalid gender (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid gender (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Gender condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_MAPID:
@@ -1788,77 +1848,54 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
MapEntry const* me = sMapStore.LookupEntry(cond->ConditionValue1);
if (!me)
{
- TC_LOG_ERROR("sql.sql", "Map condition has non existing map (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing map (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Map condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Map condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_SPELL:
{
if (!sSpellMgr->GetSpellInfo(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Spell condition has non existing spell (Id: %d), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing spell (Id: %d), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
-
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value2 (%u)!", cond->ConditionValue1, cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Spell condition has useless data (spell Id: %d) in value3 (%u)!", cond->ConditionValue1, cond->ConditionValue3);
break;
}
case CONDITION_LEVEL:
{
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "Level condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Level condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_DRUNKENSTATE:
{
if (cond->ConditionValue1 > DRUNKEN_SMASHED)
{
- TC_LOG_ERROR("sql.sql", "DrunkState condition has invalid state (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid state (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue2)
- {
- TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value2 (%u)!", cond->ConditionValue2);
- return false;
- }
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "DrunkState condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_NEAR_CREATURE:
{
if (!sObjectMgr->GetCreatureTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "NearCreature condition has non existing creature template entry (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "NearCreature condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_NEAR_GAMEOBJECT:
{
if (!sObjectMgr->GetGameObjectTemplate(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "NearGameObject condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString().c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "NearGameObject condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_OBJECT_ENTRY_GUID:
@@ -1868,7 +1905,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_UNIT:
if (cond->ConditionValue2 && !sObjectMgr->GetCreatureTemplate(cond->ConditionValue2))
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature template entry (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
@@ -1877,13 +1914,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match creature entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2);
return false;
}
}
else
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing creature guid (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has non existing creature guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
}
@@ -1891,7 +1928,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_GAMEOBJECT:
if (cond->ConditionValue2 && !sObjectMgr->GetGameObjectTemplate(cond->ConditionValue2))
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject template entry (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject template entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
if (cond->ConditionValue3)
@@ -1900,13 +1937,13 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue2 && goData->id != cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match gameobject entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has guid %u set but does not match gameobject entry (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3, cond->ConditionValue2);
return false;
}
}
else
{
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has non existing gameobject guid (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has non existing gameobject guid (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
}
@@ -1914,12 +1951,12 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
case TYPEID_PLAYER:
case TYPEID_CORPSE:
if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value2 (%u)!", cond->ConditionValue2);
+ LogUselessConditionValue(cond, 2, cond->ConditionValue2);
if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has useless data in value3 (%u)!", cond->ConditionValue3);
+ LogUselessConditionValue(cond, 3, cond->ConditionValue3);
break;
default:
- TC_LOG_ERROR("sql.sql", "ObjectEntryGuid condition has wrong typeid set (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has wrong typeid set (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -1928,51 +1965,45 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!cond->ConditionValue1 || (cond->ConditionValue1 & ~(TYPEMASK_UNIT | TYPEMASK_PLAYER | TYPEMASK_GAMEOBJECT | TYPEMASK_CORPSE)))
{
- TC_LOG_ERROR("sql.sql", "TypeMask condition has invalid typemask set (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid typemask set (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "TypeMask condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_RELATION_TO:
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 >= RELATION_MAX)
{
- TC_LOG_ERROR("sql.sql", "RelationTo condition has invalid ConditionValue2(RelationType) (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(RelationType) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "RelationTo condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_REACTION_TO:
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "ReactionTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "ReactionTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (!cond->ConditionValue2)
{
- TC_LOG_ERROR("sql.sql", "mConditionValue2 condition has invalid ConditionValue2(rankMask) (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue2(rankMask) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
break;
@@ -1981,83 +2012,60 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue1 >= cond->GetMaxAvailableConditionTargets())
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ConditionValue1(ConditionTarget selection) (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ConditionValue1(ConditionTarget selection) (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue1 == cond->ConditionTarget)
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has ConditionValue1(ConditionTarget selection) set to self (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has ConditionValue1(ConditionTarget selection) set to self (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue3 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "DistanceTo condition has invalid ComparisionType (%u), skipped", cond->ConditionValue3);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue3);
return false;
}
break;
}
- case CONDITION_ALIVE:
- {
- if (cond->ConditionValue1)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value1 (%u)!", cond->ConditionValue1);
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Alive condition has useless data in value3 (%u)!", cond->ConditionValue3);
- break;
- }
case CONDITION_HP_VAL:
{
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "HpVal condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "HpVal condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_HP_PCT:
{
if (cond->ConditionValue1 > 100)
{
- TC_LOG_ERROR("sql.sql", "HpPct condition has too big percent value (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has too big percent value (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
if (cond->ConditionValue2 >= COMP_TYPE_MAX)
{
- TC_LOG_ERROR("sql.sql", "HpPct condition has invalid ComparisionType (%u), skipped", cond->ConditionValue2);
+ TC_LOG_ERROR("sql.sql", "%s has invalid ComparisionType (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue2);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "HpPct condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
- case CONDITION_AREAID:
- case CONDITION_INSTANCE_INFO:
- break;
case CONDITION_WORLD_STATE:
{
if (!sWorld->getWorldState(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "World state condition has non existing world state in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing world state in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_PHASEID:
{
if (!sPhaseStore.LookupEntry(cond->ConditionValue1))
{
- TC_LOG_ERROR("sql.sql", "Phase condition has nonexistent phaseid in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has nonexistent phaseid in value1 (%u), skipped", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
- if (cond->ConditionValue2)
- TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value2 (%u)!", cond->ConditionValue2);
- if (cond->ConditionValue3)
- TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value3 (%u)!", cond->ConditionValue3);
break;
}
case CONDITION_TITLE:
@@ -2065,7 +2073,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(cond->ConditionValue1);
if (!titleEntry)
{
- TC_LOG_ERROR("sql.sql", "Title condition has non existing title in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing title in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2074,7 +2082,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionValue1 > SPAWNMASK_RAID_ALL)
{
- TC_LOG_ERROR("sql.sql", "SpawnMask condition has non existing SpawnMask in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing SpawnMask in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2083,7 +2091,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!(cond->ConditionValue1 & UNIT_STATE_ALL_STATE_SUPPORTED))
{
- TC_LOG_ERROR("sql.sql", "UnitState condition has non existing UnitState in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing UnitState in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
@@ -2092,17 +2100,34 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (!cond->ConditionValue1 || cond->ConditionValue1 > CREATURE_TYPE_GAS_CLOUD)
{
- TC_LOG_ERROR("sql.sql", "CreatureType condition has non existing CreatureType in value1 (%u), skipped", cond->ConditionValue1);
+ TC_LOG_ERROR("sql.sql", "%s has non existing CreatureType in value1 (%u), skipped.", cond->ToString(true).c_str(), cond->ConditionValue1);
return false;
}
break;
}
+ case CONDITION_INSTANCE_INFO:
+ case CONDITION_AREAID:
+ case CONDITION_ALIVE:
+ break;
default:
break;
}
+
+ if (cond->ConditionValue1 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue1)
+ LogUselessConditionValue(cond, 1, cond->ConditionValue1);
+ if (cond->ConditionValue2 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue2)
+ LogUselessConditionValue(cond, 2, cond->ConditionValue2);
+ if (cond->ConditionValue3 && !StaticConditionTypeData[cond->ConditionType].HasConditionValue3)
+ LogUselessConditionValue(cond, 3, cond->ConditionValue3);
+
return true;
}
+void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32 value)
+{
+ TC_LOG_ERROR("sql.sql", "%s has useless data in ConditionValue%u (%u)!", cond->ToString(true).c_str(), index, value);
+}
+
void ConditionMgr::Clean()
{
for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index e7f5b64716b..98bc1775e0d 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -23,6 +23,7 @@
#include "Errors.h"
#include <list>
#include <map>
+#include <string>
class Player;
class Unit;
@@ -210,6 +211,8 @@ struct Condition
uint32 GetSearcherTypeMaskForCondition();
bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; }
uint32 GetMaxAvailableConditionTargets();
+
+ std::string ToString(bool ext = false) const; /// For logging purpose
};
typedef std::list<Condition*> ConditionList;
@@ -229,7 +232,6 @@ class ConditionMgr
~ConditionMgr();
public:
-
static ConditionMgr* instance()
{
static ConditionMgr instance;
@@ -244,8 +246,8 @@ class ConditionMgr
bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
- bool CanHaveSourceGroupSet(ConditionSourceType sourceType) const;
- bool CanHaveSourceIdSet(ConditionSourceType sourceType) const;
+ static bool CanHaveSourceGroupSet(ConditionSourceType sourceType);
+ static bool CanHaveSourceIdSet(ConditionSourceType sourceType);
ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int64 entryOrGuid, uint32 eventId, uint32 sourceType);
@@ -253,6 +255,16 @@ class ConditionMgr
ConditionList const* GetConditionsForPhaseDefinition(uint32 zone, uint32 entry);
ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId);
+ struct ConditionTypeInfo
+ {
+ char const* Name;
+ bool HasConditionValue1;
+ bool HasConditionValue2;
+ bool HasConditionValue3;
+ };
+ static char const* StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
+ static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX];
+
private:
bool isSourceTypeValid(Condition* cond);
bool addToLootTemplate(Condition* cond, LootTemplate* loot);
@@ -261,6 +273,8 @@ class ConditionMgr
bool addToSpellImplicitTargetConditions(Condition* cond);
bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
+ static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value);
+
void Clean(); // free up resources
std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp
index a7cf8478704..65c5ec6873a 100644
--- a/src/server/game/Conditions/DisableMgr.cpp
+++ b/src/server/game/Conditions/DisableMgr.cpp
@@ -134,11 +134,11 @@ void LoadDisables()
break;
case MAP_INSTANCE:
case MAP_RAID:
- if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DUNGEON_DIFFICULTY_HEROIC))
+ if (flags & DUNGEON_STATUSFLAG_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_HEROIC))
flags -= DUNGEON_STATUSFLAG_HEROIC;
- if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_10MAN_HEROIC))
+ if (flags & RAID_STATUSFLAG_10MAN_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_10_HC))
flags -= RAID_STATUSFLAG_10MAN_HEROIC;
- if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, RAID_DIFFICULTY_25MAN_HEROIC))
+ if (flags & RAID_STATUSFLAG_25MAN_HEROIC && !GetMapDifficultyData(entry, DIFFICULTY_25_HC))
flags -= RAID_STATUSFLAG_25MAN_HEROIC;
if (!flags)
isFlagInvalid = true;
@@ -354,13 +354,13 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
GetDownscaledMapDifficultyData(entry, targetDifficulty);
switch (targetDifficulty)
{
- case DUNGEON_DIFFICULTY_NORMAL:
+ case DIFFICULTY_NORMAL:
return (disabledModes & DUNGEON_STATUSFLAG_NORMAL) != 0;
- case DUNGEON_DIFFICULTY_HEROIC:
+ case DIFFICULTY_HEROIC:
return (disabledModes & DUNGEON_STATUSFLAG_HEROIC) != 0;
- case RAID_DIFFICULTY_10MAN_HEROIC:
+ case DIFFICULTY_10_HC:
return (disabledModes & RAID_STATUSFLAG_10MAN_HEROIC) != 0;
- case RAID_DIFFICULTY_25MAN_HEROIC:
+ case DIFFICULTY_25_HC:
return (disabledModes & RAID_STATUSFLAG_25MAN_HEROIC) != 0;
}
}
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
index 7a29f7f5894..ae488a5f449 100644
--- a/src/server/game/DataStores/DB2Stores.cpp
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -39,6 +39,7 @@ DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore(Spell
DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore(SpellClassOptionsEntryfmt);
DB2Storage<SpellMiscEntry> sSpellMiscStore(SpellMiscEntryfmt);
DB2Storage<SpellPowerEntry> sSpellPowerStore(SpellPowerEntryfmt);
+SpellPowerBySpellIDMap sSpellPowerBySpellIDStore;
DB2Storage<SpellReagentsEntry> sSpellReagentsStore(SpellReagentsEntryfmt);
DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostEntryfmt);
DB2Storage<SpellTotemsEntry> sSpellTotemsStore(SpellTotemsEntryfmt);
@@ -52,6 +53,7 @@ TaxiMask sAllianceTaxiNodesMask;
TaxiMask sDeathKnightTaxiNodesMask;
TaxiPathSetBySource sTaxiPathSetBySource;
TaxiPathNodesByPath sTaxiPathNodesByPath;
+PhaseGroupContainer sPhasesByGroup;
typedef std::list<std::string> DB2StoreProblemList;
@@ -142,10 +144,19 @@ void LoadDB2Stores(std::string const& dataPath)
LoadDB2(availableDb2Locales, bad_db2_files, sTaxiNodesStore, db2Path, "TaxiNodes.db2");
LoadDB2(availableDb2Locales, bad_db2_files, sTaxiPathStore, db2Path, "TaxiPath.db2");
LoadDB2(availableDb2Locales, bad_db2_files, sTaxiPathNodeStore, db2Path, "TaxiPathNode.db2");
+
+ for (uint32 i = 0; i < sSpellPowerStore.GetNumRows(); ++i)
+ if (SpellPowerEntry const* power = sSpellPowerStore.LookupEntry(i))
+ sSpellPowerBySpellIDStore[power->SpellID] = power;
+
+ for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i)
+ if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i))
+ if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID))
+ sPhasesByGroup[group->PhaseGroupID].insert(phase->ID);
for (uint32 i = 0; i < sItemAppearanceStore.GetNumRows(); ++i)
if (ItemAppearanceEntry const* entry = sItemAppearanceStore.LookupEntry(i))
- sItemDisplayIDMap[entry->AppearanceID] = entry->DisplayID;
+ sItemDisplayIDMap[entry->FileDataID] = entry->DisplayID;
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
@@ -277,3 +288,8 @@ uint32 GetItemDisplayID(uint32 appearanceID)
return itr->second;
return 0;
}
+
+std::set<uint32> const& GetPhasesForGroup(uint32 group)
+{
+ return sPhasesByGroup[group];
+}
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
index 29fe93ce2b1..6521ea930a8 100644
--- a/src/server/game/DataStores/DB2Stores.h
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -39,6 +39,7 @@ extern DB2Storage<SpellCastingRequirementsEntry> sSpellCastingRequirementsStore;
extern DB2Storage<SpellClassOptionsEntry> sSpellClassOptionsStore;
extern DB2Storage<SpellMiscEntry> sSpellMiscStore;
extern DB2Storage<SpellPowerEntry> sSpellPowerStore;
+extern SpellPowerBySpellIDMap sSpellPowerBySpellIDStore;
extern DB2Storage<SpellReagentsEntry> sSpellReagentsStore;
extern DB2Storage<SpellRuneCostEntry> sSpellRuneCostStore;
extern DB2Storage<SpellTotemsEntry> sSpellTotemsStore;
@@ -59,4 +60,6 @@ DB2StorageBase const* GetDB2Storage(uint32 type);
uint32 GetItemDisplayID(uint32 appearanceID);
+std::set<uint32> const& GetPhasesForGroup(uint32 group);
+
#endif
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index de5436860a6..8e91ec8396f 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -21,6 +21,7 @@
#include "Common.h"
#include "DBCEnums.h"
#include "ItemPrototype.h"
+#include "Path.h"
// GCC has alternative #pragma pack(N) syntax and old gcc version does not support pack(push, N), also any gcc version does not support it at some platform
#if defined(__GNUC__)
@@ -60,15 +61,15 @@ struct ItemEntry
int32 Material; // 4
uint32 InventoryType; // 5
uint32 Sheath; // 6
- uint32 AppearanceID; // 7 (ItemAppearance.db2)
- //uint32 Unk; // 8
+ uint32 FileDataID; // 7
+ uint32 GroupSoundsID; // 8
};
struct ItemAppearanceEntry
{
uint32 ID; // 0 (reference to ItemModifiedAppearance.db2?)
uint32 DisplayID; // 1
- uint32 AppearanceID; // 2
+ uint32 FileDataID; // 2
};
struct ItemCurrencyCostEntry
@@ -94,7 +95,7 @@ struct ItemSparseEntry
{
uint32 ID; // 0
uint32 Quality; // 1
- uint32 Flags[3]; // 2-4
+ uint32 Flags[MAX_ITEM_PROTO_FLAGS]; // 2-4
float Unk1; // 5
float Unk2; // 6
uint32 BuyCount; // 7
@@ -153,77 +154,7 @@ struct ItemSparseEntry
float StatScalingFactor; // 98
uint32 CurrencySubstitutionID; // 99
uint32 CurrencySubstitutionCount; // 100
- //uint32 Unk3; // 101
-
- /*uint32 ID; // 0
- uint32 Quality; // 1
- uint32 Flags; // 2
- uint32 Flags2; // 3
- float Unk430_1;
- float Unk430_2;
- uint32 BuyCount;
- uint32 BuyPrice; // 4
- uint32 SellPrice; // 5
- uint32 InventoryType; // 6
- int32 AllowableClass; // 7
- int32 AllowableRace; // 8
- uint32 ItemLevel; // 9
- int32 RequiredLevel; // 10
- uint32 RequiredSkill; // 11
- uint32 RequiredSkillRank; // 12
- uint32 RequiredSpell; // 13
- uint32 RequiredHonorRank; // 14
- uint32 RequiredCityRank; // 15
- uint32 RequiredReputationFaction; // 16
- uint32 RequiredReputationRank; // 17
- uint32 MaxCount; // 18
- uint32 Stackable; // 19
- uint32 ContainerSlots; // 20
- int32 ItemStatType[MAX_ITEM_PROTO_STATS]; // 21 - 30
- uint32 ItemStatValue[MAX_ITEM_PROTO_STATS]; // 31 - 40
- int32 ItemStatUnk1[MAX_ITEM_PROTO_STATS]; // 41 - 50
- int32 ItemStatUnk2[MAX_ITEM_PROTO_STATS]; // 51 - 60
- uint32 ScalingStatDistribution; // 61
- uint32 DamageType; // 62
- uint32 Delay; // 63
- float RangedModRange; // 64
- int32 SpellId[MAX_ITEM_PROTO_SPELLS]; // 65 - 69
- int32 SpellTrigger[MAX_ITEM_PROTO_SPELLS]; // 70 - 74
- int32 SpellCharges[MAX_ITEM_PROTO_SPELLS]; // 75 - 79
- int32 SpellCooldown[MAX_ITEM_PROTO_SPELLS]; // 80 - 84
- int32 SpellCategory[MAX_ITEM_PROTO_SPELLS]; // 85 - 89
- int32 SpellCategoryCooldown[MAX_ITEM_PROTO_SPELLS]; // 90 - 94
- uint32 Bonding; // 95
- LocalizedString* Name; // 96
- LocalizedString* Name2; // 97
- LocalizedString* Name3; // 98
- LocalizedString* Name4; // 99
- LocalizedString* Description; // 100
- uint32 PageText; // 101
- uint32 LanguageID; // 102
- uint32 PageMaterial; // 103
- uint32 StartQuest; // 104
- uint32 LockID; // 105
- int32 Material; // 106
- uint32 Sheath; // 107
- uint32 RandomProperty; // 108
- uint32 RandomSuffix; // 109
- uint32 ItemSet; // 110
- uint32 Area; // 112
- uint32 Map; // 113
- uint32 BagFamily; // 114
- uint32 TotemCategory; // 115
- uint32 Color[MAX_ITEM_PROTO_SOCKETS]; // 116 - 118
- uint32 Content[MAX_ITEM_PROTO_SOCKETS]; // 119 - 121
- int32 SocketBonus; // 122
- uint32 GemProperties; // 123
- float ArmorDamageModifier; // 124
- uint32 Duration; // 125
- uint32 ItemLimitCategory; // 126
- uint32 HolidayId; // 127
- float StatScalingFactor; // 128
- int32 CurrencySubstitutionId; // 129
- int32 CurrencySubstitutionCount; // 130*/
+ uint32 ItemNameDescriptionID; // 101
};
#define MAX_ITEM_EXT_COST_ITEMS 5
@@ -232,13 +163,13 @@ struct ItemSparseEntry
struct ItemExtendedCostEntry
{
uint32 ID; // 0 extended-cost entry id
- //uint32 reqhonorpoints; // 1 required honor points
- //uint32 reqarenapoints; // 2 required arena points
+ uint32 RequiredHonorPoints; // 1 required honor points
+ uint32 RequiredArenaPoints; // 2 required arena points
uint32 RequiredArenaSlot; // 3 arena slot restrictions (min slot value)
uint32 RequiredItem[MAX_ITEM_EXT_COST_ITEMS]; // 4-8 required item id
uint32 RequiredItemCount[MAX_ITEM_EXT_COST_ITEMS]; // 9-13 required count of 1st item
uint32 RequiredPersonalArenaRating; // 14 required personal arena rating
- //uint32 ItemPurchaseGroup; // 15
+ uint32 ItemPurchaseGroup; // 15
uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES];// 16-20 required curency id
uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES];// 21-25 required curency count
uint32 RequiredFactionId;
@@ -423,6 +354,8 @@ struct TaxiPathNodeEntry
typedef std::map<uint32, uint32> ItemDisplayIDMap;
+typedef std::map<uint32, SpellPowerEntry const*> SpellPowerBySpellIDMap;
+
struct TaxiPathBySourceAndDestination
{
TaxiPathBySourceAndDestination() : ID(0), price(0) { }
@@ -448,4 +381,5 @@ typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
#define TaxiMaskSize 114
typedef uint8 TaxiMask[TaxiMaskSize];
-#endif \ No newline at end of file
+typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer;
+#endif
diff --git a/src/server/game/DataStores/DB2Utility.cpp b/src/server/game/DataStores/DB2Utility.cpp
index 37b7fb949db..a835547b640 100644
--- a/src/server/game/DataStores/DB2Utility.cpp
+++ b/src/server/game/DataStores/DB2Utility.cpp
@@ -42,15 +42,15 @@ void DB2Utilities::WriteItemDbReply(DB2Storage<ItemEntry> const& /*store*/, uint
buffer << uint32(proto->Class);
buffer << uint32(proto->SubClass);
buffer << int32(proto->SoundOverrideSubclass);
- buffer << uint32(proto->Material);
- buffer << uint32(proto->DisplayInfoID);
+ buffer << int32(proto->Material);
buffer << uint32(proto->InventoryType);
buffer << uint32(proto->Sheath);
+ buffer << uint32(proto->FileDataID);
+ buffer << uint32(proto->GroupSoundsID);
}
void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id, uint32 locale, ByteBuffer& buffer)
{
- /* TODO: 6.x update
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id);
ASSERT(proto);
@@ -58,10 +58,12 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s
buffer << uint32(proto->ItemId);
buffer << uint32(proto->Quality);
- buffer << uint32(proto->Flags);
- buffer << uint32(proto->Flags2);
- buffer << float(proto->Unk430_1);
- buffer << float(proto->Unk430_2);
+
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_FLAGS; ++i)
+ buffer << uint32(proto->Flags[i]);
+
+ buffer << float(proto->Unk1);
+ buffer << float(proto->Unk2);
buffer << uint32(proto->BuyCount);
buffer << int32(proto->BuyPrice);
buffer << uint32(proto->SellPrice);
@@ -97,25 +99,6 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s
buffer << uint32(proto->DamageType);
buffer << uint32(proto->Delay);
buffer << float(proto->RangedModRange);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << int32(proto->Spells[x].SpellId);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << uint32(proto->Spells[x].SpellTrigger);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << int32(proto->Spells[x].SpellCharges);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << int32(proto->Spells[x].SpellCooldown);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << uint32(proto->Spells[x].SpellCategory);
-
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
- buffer << int32(proto->Spells[x].SpellCategoryCooldown);
-
buffer << uint32(proto->Bonding);
// item name
@@ -145,8 +128,8 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s
buffer << uint32(proto->LockID);
buffer << int32(proto->Material);
buffer << uint32(proto->Sheath);
- buffer << int32(proto->RandomProperty);
- buffer << int32(proto->RandomSuffix);
+ buffer << uint32(proto->RandomProperty);
+ buffer << uint32(proto->RandomSuffix);
buffer << uint32(proto->ItemSet);
buffer << uint32(proto->Area);
@@ -157,9 +140,6 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s
for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
buffer << uint32(proto->Socket[x].Color);
- for (uint32 x = 0; x < MAX_ITEM_PROTO_SOCKETS; ++x)
- buffer << uint32(proto->Socket[x].Content);
-
buffer << uint32(proto->socketBonus);
buffer << uint32(proto->GemProperties);
buffer << float(proto->ArmorDamageModifier);
@@ -169,5 +149,5 @@ void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*s
buffer << float(proto->StatScalingFactor); // StatScalingFactor
buffer << uint32(proto->CurrencySubstitutionId);
buffer << uint32(proto->CurrencySubstitutionCount);
- */
+ buffer << uint32(proto->ItemNameDescriptionID);
}
diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h
index 5d2f374f2a7..f47efa43f89 100644
--- a/src/server/game/DataStores/DB2fmt.h
+++ b/src/server/game/DataStores/DB2fmt.h
@@ -19,11 +19,11 @@
#define TRINITY_DB2SFRM_H
char const HolidaysEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix";
-char const Itemfmt[]="niiiiiiix";
+char const Itemfmt[]="niiiiiiii";
char const ItemAppearanceEntryfmt[]="nii";
char const ItemCurrencyCostfmt[]="xn";
-char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiix";
-char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiiiiii";
+char const ItemSparsefmt[]="niiiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifisssssiiiiiiiiiiiiiiiiiiifiiifiii";
+char const ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
char const ItemEffectEntryfmt[]="niiiiiiii";
char const KeyChainfmt[]="nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
char const OverrideSpellDataEntryfmt[] = "niiiiiiiiiixx";
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index d4831127183..fa1ca29f4ef 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -51,11 +51,11 @@ enum LevelLimit
enum BattlegroundBracketId // bracketId for level ranges
{
BG_BRACKET_ID_FIRST = 0,
- BG_BRACKET_ID_LAST = 15
-};
+ BG_BRACKET_ID_LAST = 10,
-// must be max value in PvPDificulty slot+1
-#define MAX_BATTLEGROUND_BRACKETS 16
+ // must be max value in PvPDificulty slot + 1
+ MAX_BATTLEGROUND_BRACKETS
+};
enum AreaTeams
{
@@ -337,16 +337,26 @@ enum AreaFlags
enum Difficulty
{
- REGULAR_DIFFICULTY = 0,
-
- DUNGEON_DIFFICULTY_NORMAL = 0,
- DUNGEON_DIFFICULTY_HEROIC = 1,
- DUNGEON_DIFFICULTY_EPIC = 2,
-
- RAID_DIFFICULTY_10MAN_NORMAL = 0,
- RAID_DIFFICULTY_25MAN_NORMAL = 1,
- RAID_DIFFICULTY_10MAN_HEROIC = 2,
- RAID_DIFFICULTY_25MAN_HEROIC = 3
+ DIFFICULTY_NONE = 0,
+ DIFFICULTY_NORMAL = 1,
+ DIFFICULTY_HEROIC = 2,
+ DIFFICULTY_10_N = 3,
+ DIFFICULTY_25_N = 4,
+ DIFFICULTY_10_HC = 5,
+ DIFFICULTY_25_HC = 6,
+ DIFFICULTY_LFR = 7,
+ DIFFICULTY_CHALLENGE = 8,
+ DIFFICULTY_40 = 9,
+ DIFFICULTY_HC_SCENARIO = 11,
+ DIFFICULTY_N_SCENARIO = 12,
+ DIFFICULTY_NORMAL2 = 14,
+ DIFFICULTY_HEROIC2 = 15,
+ DIFFICULTY_MYTHIC = 16,
+ DIFFICULTY_LFR2 = 17,
+ DIFFICULTY_EVENT = 18,
+ DIFFICULTY_EVENT2 = 19,
+ DIFFICULTY_EVENT_SCENARIO = 20,
+ DIFFICULTY_MAX = 21,
};
#define RAID_DIFFICULTY_MASK_25MAN 1 // since 25man difficulties are 1 and 3, we can check them like that
@@ -357,18 +367,18 @@ enum Difficulty
enum SpawnMask
{
- SPAWNMASK_CONTINENT = (1 << REGULAR_DIFFICULTY), // any maps without spawn modes
+ SPAWNMASK_CONTINENT = (1 << DIFFICULTY_NONE), // any maps without spawn modes
- SPAWNMASK_DUNGEON_NORMAL = (1 << DUNGEON_DIFFICULTY_NORMAL),
- SPAWNMASK_DUNGEON_HEROIC = (1 << DUNGEON_DIFFICULTY_HEROIC),
+ SPAWNMASK_DUNGEON_NORMAL = (1 << DIFFICULTY_NORMAL),
+ SPAWNMASK_DUNGEON_HEROIC = (1 << DIFFICULTY_HEROIC),
SPAWNMASK_DUNGEON_ALL = (SPAWNMASK_DUNGEON_NORMAL | SPAWNMASK_DUNGEON_HEROIC),
- SPAWNMASK_RAID_10MAN_NORMAL = (1 << RAID_DIFFICULTY_10MAN_NORMAL),
- SPAWNMASK_RAID_25MAN_NORMAL = (1 << RAID_DIFFICULTY_25MAN_NORMAL),
+ SPAWNMASK_RAID_10MAN_NORMAL = (1 << DIFFICULTY_10_N),
+ SPAWNMASK_RAID_25MAN_NORMAL = (1 << DIFFICULTY_25_N),
SPAWNMASK_RAID_NORMAL_ALL = (SPAWNMASK_RAID_10MAN_NORMAL | SPAWNMASK_RAID_25MAN_NORMAL),
- SPAWNMASK_RAID_10MAN_HEROIC = (1 << RAID_DIFFICULTY_10MAN_HEROIC),
- SPAWNMASK_RAID_25MAN_HEROIC = (1 << RAID_DIFFICULTY_25MAN_HEROIC),
+ SPAWNMASK_RAID_10MAN_HEROIC = (1 << DIFFICULTY_10_HC),
+ SPAWNMASK_RAID_25MAN_HEROIC = (1 << DIFFICULTY_25_HC),
SPAWNMASK_RAID_HEROIC_ALL = (SPAWNMASK_RAID_10MAN_HEROIC | SPAWNMASK_RAID_25MAN_HEROIC),
SPAWNMASK_RAID_ALL = (SPAWNMASK_RAID_NORMAL_ALL | SPAWNMASK_RAID_HEROIC_ALL)
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 5defb7e527c..2af63e0b6bf 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -20,6 +20,7 @@
#include "Containers.h"
#include "Log.h"
#include "SharedDefines.h"
+#include "SpellInfo.h"
#include "SpellMgr.h"
#include "TransportMgr.h"
#include "DBCfmt.h"
@@ -101,25 +102,25 @@ DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);
DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);
DBCStorage <GameObjectDisplayInfoEntry> sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt);
+DBCStorage <GameTablesEntry> sGameTablesStore(GameTablesFmt);
DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt);
DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt);
DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt);
-DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
-DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
-DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
-DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
-DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt);
-DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt);
-DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt);
-DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt);
-DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
-//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
-DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt);
-DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
-DBCStorage <GtSpellScalingEntry> sGtSpellScalingStore(GtSpellScalingfmt);
-DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore(GtOCTBaseHPByClassfmt);
-DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore(GtOCTBaseMPByClassfmt);
+GameTable <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);
+GameTable <GtCombatRatingsEntry> sGtCombatRatingsStore(GtCombatRatingsfmt);
+GameTable <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);
+GameTable <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt);
+GameTable <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore(GtChanceToSpellCritBasefmt);
+GameTable <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore(GtChanceToSpellCritfmt);
+GameTable <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt);
+GameTable <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt);
+GameTable <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
+GameTable <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt);
+GameTable <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
+GameTable <GtSpellScalingEntry> sGtSpellScalingStore(GtSpellScalingfmt);
+GameTable <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore(GtOCTBaseHPByClassfmt);
+GameTable <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore(GtOCTBaseMPByClassfmt);
DBCStorage <GuildPerkSpellsEntry> sGuildPerkSpellsStore(GuildPerkSpellsfmt);
DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore(ImportPriceArmorfmt);
@@ -191,8 +192,13 @@ DBCStorage <SpecializationSpellsEntry> sSpecializationSpellsStore(Specialization
DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt);
DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt);
DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt);
+DBCStorage <SpellEffectScalingEntry> sSpellEffectScalingStore(SpellEffectScalingfmt);
+
SpellCategoryStore sSpellsByCategoryStore;
PetFamilySpellsStore sPetFamilySpellsStore;
+SpellsPerClassStore sSpellsPerClassStore;
+ClassBySkillIdStore sClassBySkillIdStore;
+SpellEffectScallingByEffectId sSpellEffectScallingByEffectId;
DBCStorage <SpellScalingEntry> sSpellScalingStore(SpellScalingEntryfmt);
@@ -216,6 +222,8 @@ DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentBySpellIDMap sTalentBySpellIDMap;
+SpecializationSpellsMap sSpecializationSpellsMap;
+SpecializationOverrideSpellsMap sSpecializationOverrideSpellMap;
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
DBCStorage <TransportAnimationEntry> sTransportAnimationStore(TransportAnimationfmt);
@@ -229,8 +237,6 @@ DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt)
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
DBCStorage <PhaseEntry> sPhaseStore(PhaseEntryfmt);
-PhaseGroupContainer sPhasesByGroup;
-
typedef std::list<std::string> StoreProblemList;
uint32 DBCFileCount = 0;
@@ -289,6 +295,51 @@ inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCSt
delete sql;
}
+template<class T>
+inline void LoadGameTable(StoreProblemList& errors, std::string const& tableName, GameTable<T>& storage, std::string const& dbcPath, std::string const& filename)
+{
+ // compatibility format and C++ structure sizes
+ ASSERT(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename));
+
+ ++DBCFileCount;
+ std::string dbcFilename = dbcPath + filename;
+
+ if (storage.Load(dbcFilename.c_str()))
+ {
+ bool found = false;
+ // Find table definition in GameTables.dbc
+ for (uint32 i = 0; i < sGameTablesStore.GetNumRows(); ++i)
+ {
+ GameTablesEntry const* gt = sGameTablesStore.LookupEntry(i);
+ if (!gt)
+ continue;
+
+ if (tableName == gt->Name)
+ {
+ found = true;
+ storage.SetGameTableEntry(gt);
+ break;
+ }
+ }
+
+ ASSERT(found, "Game table %s definition not found in GameTables.dbc", tableName.c_str());
+ }
+ else
+ {
+ // sort problematic dbc to (1) non compatible and (2) non-existed
+ if (FILE* f = fopen(dbcFilename.c_str(), "rb"))
+ {
+ std::ostringstream stream;
+ stream << dbcFilename << " exists, and has " << storage.GetFieldCount() << " field(s) (expected " << strlen(storage.GetFormat()) << "). Extracted file might be from wrong client version or a database-update has been forgotten.";
+ std::string buf = stream.str();
+ errors.push_back(buf);
+ fclose(f);
+ }
+ else
+ errors.push_back(dbcFilename);
+ }
+}
+
void LoadDBCStores(const std::string& dataPath)
{
uint32 oldMSTime = getMSTime();
@@ -398,24 +449,10 @@ void LoadDBCStores(const std::string& dataPath)
}
}
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGameTablesStore, dbcPath, "GameTables.dbc");//19243
LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc");//19116
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtNPCManaCostScalerStore, dbcPath, "gtNPCManaCostScaler.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");//15595
- //LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTHpPerStaminaStore, dbcPath, "gtOCTHpPerStamina.dbc");//15595
- //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtSpellScalingStore, dbcPath, "gtSpellScaling.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTBaseHPByClassStore, dbcPath, "gtOCTBaseHPByClass.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTBaseMPByClassStore, dbcPath, "gtOCTBaseMPByClass.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sGuildPerkSpellsStore, dbcPath, "GuildPerkSpells.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceArmorStore, dbcPath, "ImportPriceArmor.dbc"); // 19116
@@ -478,11 +515,6 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sPhaseStore, dbcPath, "Phase.dbc"); // 19116
- for (uint32 i = 0; i < sPhaseGroupStore.GetNumRows(); ++i)
- if (PhaseGroupEntry const* group = sPhaseGroupStore.LookupEntry(i))
- if (PhaseEntry const* phase = sPhaseStore.LookupEntry(group->PhaseID))
- sPhasesByGroup[group->PhaseGroupID].insert(phase->ID);
-
LoadDBC(availableDbcLocales, bad_dbc_files, sPowerDisplayStore, dbcPath, "PowerDisplay.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc");//19116
@@ -517,7 +549,10 @@ void LoadDBCStores(const std::string& dataPath)
SpecializationSpellsEntry const* specSpells = sSpecializationSpellsStore.LookupEntry(i);
if (!specSpells)
continue;
- sSpecializationSpellsBySpecStore[specSpells->SpecID].insert(specSpells);
+ sSpecializationSpellsBySpecStore[specSpells->SpecID].push_back(specSpells);
+
+ if (specSpells->OverridesSpellID)
+ sSpecializationOverrideSpellMap[specSpells->SpecID][specSpells->OverridesSpellID] = specSpells->SpellID;
}
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"/*, &CustomSpellEntryfmt, &CustomSpellEntryIndex*/);
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath, "SpellCategories.dbc");//15595
@@ -543,6 +578,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc");//19116
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEffectScalingStore, dbcPath, "SpellEffectScaling.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc");//19116
@@ -552,41 +588,67 @@ void LoadDBCStores(const std::string& dataPath)
//LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc");//15595
- // Must be done when sSkillLineAbilityStore, sSpellStore, sSpellLevelsStore and sCreatureFamilyStore are all loaded
- /* TODO: Requires spells attributes from SpellMisc.db2 is loaded after dbc
+ for (uint32 j = 0; j < sSpellEffectScalingStore.GetNumRows(); j++)
+ {
+ SpellEffectScalingEntry const* spellEffectScaling = sSpellEffectScalingStore.LookupEntry(j);
+ if (!spellEffectScaling)
+ continue;
+
+ sSpellEffectScallingByEffectId.insert(std::make_pair(spellEffectScaling->SpellEffectID, j));
+ }
+ std::map<std::string, uint32> classIdByName;
+ for (uint32 j = 0; j < sChrClassesStore.GetNumRows(); j++)
+ {
+ ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(j);
+ if (!classEntry)
+ continue;
+
+ classIdByName.insert(std::make_pair(std::string(classEntry->Name_lang), j));
+ }
+
+ for (uint32 j = 0; j < sSkillLineStore.GetNumRows(); j++)
+ {
+ SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(j);
+ if (!skillEntry)
+ continue;
+
+ if (skillEntry->CategoryID!= SKILL_CATEGORY_CLASS)
+ continue;
+
+ std::map<std::string, uint32> ::const_iterator iter = classIdByName.find(std::string(skillEntry->DisplayName_lang));
+ if (iter == classIdByName.end())
+ continue;
+
+ sClassBySkillIdStore.insert(std::make_pair(j, iter->second));
+ }
+
for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
{
- SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j);
- if (!skillLine)
+ SkillLineAbilityEntry const* skillAbility = sSkillLineAbilityStore.LookupEntry(j);
+ if (!skillAbility)
continue;
- SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->SpellID);
+ if (skillAbility->AquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillAbility->SpellID);
if (!spellInfo)
continue;
- SpellLevelsEntry const* levels = sSpellLevelsStore.LookupEntry(spellInfo->SpellLevelsID);
- if (spellInfo->SpellLevelsID && (!levels || levels->spellLevel))
+ SpellLevelsEntry const* spellLevels = sSpellLevelsStore.LookupEntry(spellInfo->LevelsID);
+ if (!spellLevels || !spellLevels->SpellLevel)
continue;
- if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
- {
- for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
- {
- CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
- if (!cFamily)
- continue;
+ uint32 classId = GetClassBySkillId(skillAbility->SkillLine);
- if (skillLine->SkillLine != cFamily->SkillLine[0] && skillLine->SkillLine != cFamily->SkillLine[1])
- continue;
+ if (!classId)
+ continue;
- if (skillLine->AquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
- continue;
+ if (sSpellsPerClassStore.find(classId) == sSpellsPerClassStore.end())
+ sSpellsPerClassStore.insert(make_pair(classId, std::list<SkillLineAbilityEntry const*>()));
- sPetFamilySpellsStore[i].insert(spellInfo->ID);
- }
- }
+ sSpellsPerClassStore[classId].push_back(skillAbility);
}
- */
LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc");//15595
@@ -664,6 +726,20 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); // 19116
+ LoadGameTable(bad_dbc_files, "BarberShopCostBase", sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc");//15595
+ LoadGameTable(bad_dbc_files, "CombatRatings", sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc");//15595
+ LoadGameTable(bad_dbc_files, "ChanceToMeleeCritBase", sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc");//15595
+ LoadGameTable(bad_dbc_files, "ChanceToMeleeCrit", sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");//15595
+ LoadGameTable(bad_dbc_files, "ChanceToSpellCritBase", sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");//15595
+ LoadGameTable(bad_dbc_files, "ChanceToSpellCrit", sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");//15595
+ LoadGameTable(bad_dbc_files, "NPCManaCostScaler", sGtNPCManaCostScalerStore, dbcPath, "gtNPCManaCostScaler.dbc");
+ LoadGameTable(bad_dbc_files, "OCTClassCombatRatingScalar", sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc");//15595
+ LoadGameTable(bad_dbc_files, "OCTHPPerStamina", sGtOCTHpPerStaminaStore, dbcPath, "gtOCTHpPerStamina.dbc");//15595
+ LoadGameTable(bad_dbc_files, "RegenMPPerSpt", sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");//15595
+ LoadGameTable(bad_dbc_files, "SpellScaling", sGtSpellScalingStore, dbcPath, "gtSpellScaling.dbc");//15595
+ LoadGameTable(bad_dbc_files, "OCTBaseHPByClass", sGtOCTBaseHPByClassStore, dbcPath, "gtOCTBaseHPByClass.dbc");//15595
+ LoadGameTable(bad_dbc_files, "OCTBaseMPByClass", sGtOCTBaseMPByClassStore, dbcPath, "gtOCTBaseMPByClass.dbc");//15595
+
// error checks
if (bad_dbc_files.size() >= DBCFileCount)
{
@@ -896,7 +972,7 @@ MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &di
MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(tmpDiff));
if (!mapDiff)
{
- if (tmpDiff > RAID_DIFFICULTY_25MAN_NORMAL) // heroic, downscale to normal
+ if (tmpDiff > DIFFICULTY_25_N) // heroic, downscale to normal
tmpDiff -= 2;
else
tmpDiff -= 1; // any non-normal mode for raids like tbc (only one mode)
@@ -1178,7 +1254,81 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u
return NULL;
}
-std::set<uint32> const& GetPhasesForGroup(uint32 group)
+uint32 GetClassBySkillId(uint32 skillId)
+{
+ ClassBySkillIdStore::const_iterator iter = sClassBySkillIdStore.find(skillId);
+ if (iter != sClassBySkillIdStore.end())
+ return iter->second;
+ return 0;
+}
+
+uint32 GetSkillIdByClass(uint32 classId)
+{
+ for (ClassBySkillIdStore::const_iterator iter = sClassBySkillIdStore.begin(); iter != sClassBySkillIdStore.end(); iter++)
+ if (iter->second == classId)
+ return iter->first;
+ return 0;
+}
+
+std::list<uint32> GetSpellsForLevels(uint32 classId, uint32 raceMask, uint32 specializationId, uint32 minLevel, uint32 maxLevel)
+{
+ std::list<uint32> spellList;
+
+ if (classId != 0)
+ {
+ SpellsPerClassStore::const_iterator classIter = sSpellsPerClassStore.find(classId);
+ if (classIter != sSpellsPerClassStore.end())
+ {
+ const std::list<SkillLineAbilityEntry const*>& learnSpellList = classIter->second;
+ for (std::list<SkillLineAbilityEntry const*>::const_iterator iter = learnSpellList.begin(); iter != learnSpellList.end(); iter++)
+ {
+ SkillLineAbilityEntry const* skillLine = *iter;
+ if (!skillLine)
+ continue;
+
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(skillLine->SpellID);
+ if (!spellInfo)
+ continue;
+
+ if (skillLine->RaceMask && !(skillLine->RaceMask & raceMask))
+ continue;
+
+ if (spellInfo->SpellLevel <= minLevel || spellInfo->SpellLevel > maxLevel)
+ continue;
+
+ spellList.push_back(spellInfo->Id);
+ }
+ }
+ }
+
+ if (!specializationId)
+ return spellList;
+
+ SpecializationSpellsBySpecStore::const_iterator specIter = sSpecializationSpellsBySpecStore.find(specializationId);
+ if (specIter != sSpecializationSpellsBySpecStore.end())
+ {
+ SpecializationSpellsBySpecEntry learnSpellList = specIter->second;
+ for (int i = 0; i < learnSpellList.size(); i++)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(learnSpellList[i]->SpellID);
+ if (!spellInfo)
+ {
+ TC_LOG_ERROR("spells", "GetSpellsForLevels: spell %u not found in spellstore", learnSpellList[i]->SpellID);
+ continue;
+ }
+ if (spellInfo->SpellLevel <= minLevel || spellInfo->SpellLevel > maxLevel)
+ continue;
+
+ spellList.push_back(spellInfo->Id);
+ }
+ }
+ return spellList;
+}
+
+uint32 GetTalentSpellCost(uint32 spellId)
{
- return sPhasesByGroup[group];
+ TalentBySpellIDMap::const_iterator itr = sTalentBySpellIDMap.find(spellId);
+ if (itr == sTalentBySpellIDMap.end())
+ return 0;
+ return 1;
}
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index e9a9b3c692f..20e8e1fc423 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -26,11 +26,14 @@
#include <list>
+typedef std::map<uint32, uint32> SpecializationOverrideSpellsList;
+typedef std::map<uint32, SpecializationOverrideSpellsList> SpecializationOverrideSpellsMap;
+
typedef std::list<uint32> SimpleFactionsList;
SimpleFactionsList const* GetFactionTeamList(uint32 faction);
char const* GetPetName(uint32 petfamily, uint32 dbclang);
-
+uint32 GetTalentSpellCost(uint32 spellId);
TalentEntry const* GetTalentBySpellID(uint32 spellID);
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
@@ -66,6 +69,9 @@ bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredT
void Zone2MapCoordinates(float &x, float &y, uint32 zone);
void Map2ZoneCoordinates(float &x, float &y, uint32 zone);
+uint32 GetClassBySkillId(uint32 skillId);
+uint32 GetSkillIdByClass(uint32 classId);
+std::list<uint32> GetSpellsForLevels(uint32 classId, uint32 raceMask, uint32 specializationId, uint32 minLevel, uint32 maxLevel);
typedef std::map<uint32/*pair32(map, diff)*/, MapDifficulty> MapDifficultyMap;
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
@@ -83,17 +89,47 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
uint32 GetDefaultMapLight(uint32 mapId);
-std::set<uint32> const& GetPhasesForGroup(uint32 group);
-
typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRaceClassInfoMap;
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
-typedef std::set<SpecializationSpellsEntry const*> SpecializationSpellsBySpecEntry;
+typedef std::vector<SpecializationSpellsEntry const*> SpecializationSpellsBySpecEntry;
typedef std::unordered_map<uint32, SpecializationSpellsBySpecEntry> SpecializationSpellsBySpecStore;
typedef ChrSpecializationEntry const* ChrSpecializationByIndexArray[MAX_CLASSES][MAX_SPECIALIZATIONS];
typedef std::unordered_map<uint32, TalentEntry const*> TalentBySpellIDMap;
+typedef std::map<uint32, std::vector<uint32> > SpecializationSpellsMap;
+extern SpecializationSpellsMap sSpecializationSpellsMap;
+extern SpecializationOverrideSpellsMap sSpecializationOverrideSpellMap;
+
+template<class T>
+class GameTable
+{
+public:
+ GameTable(char const* format) : _storage(format), _gtEntry(nullptr) { }
+
+ void SetGameTableEntry(GameTablesEntry const* gtEntry) { _gtEntry = gtEntry; }
+
+ T const* EvaluateTable(uint32 row, uint32 column) const
+ {
+ ASSERT(row < _gtEntry->NumRows);
+ ASSERT(column < _gtEntry->NumColumns);
+
+ return _storage.LookupEntry(_gtEntry->NumRows * column + row);
+ }
+
+ char const* GetFormat() const { return _storage.GetFormat(); }
+ uint32 GetFieldCount() const { return _storage.GetFieldCount(); }
+ bool Load(char const* fileName) { return _storage.Load(fileName, nullptr); }
+
+ uint32 GetTableRowCount() const { return _gtEntry->NumRows; }
+ uint32 GetTableColumnCount() const { return _gtEntry->NumColumns; }
+
+private:
+ DBCStorage<T> _storage;
+ GameTablesEntry const* _gtEntry;
+};
+
extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
@@ -134,20 +170,19 @@ extern DBCStorage <GemPropertiesEntry> sGemPropertiesStore;
extern DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore;
extern DBCStorage <GlyphSlotEntry> sGlyphSlotStore;
-extern DBCStorage <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
-extern DBCStorage <GtCombatRatingsEntry> sGtCombatRatingsStore;
-extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
-extern DBCStorage <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
-extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
-extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
-extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
-extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
-//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
-extern DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore;
-extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
-extern DBCStorage <GtSpellScalingEntry> sGtSpellScalingStore;
-extern DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore;
-extern DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore;
+extern GameTable <GtBarberShopCostBaseEntry> sGtBarberShopCostBaseStore;
+extern GameTable <GtCombatRatingsEntry> sGtCombatRatingsStore;
+extern GameTable <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;
+extern GameTable <GtChanceToMeleeCritEntry> sGtChanceToMeleeCritStore;
+extern GameTable <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
+extern GameTable <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
+extern GameTable <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
+extern GameTable <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
+extern GameTable <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore;
+extern GameTable <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
+extern GameTable <GtSpellScalingEntry> sGtSpellScalingStore;
+extern GameTable <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore;
+extern GameTable <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore;
extern DBCStorage <GuildPerkSpellsEntry> sGuildPerkSpellsStore;
extern DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore;
extern DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore;
@@ -200,6 +235,7 @@ extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
+extern SpellEffectScallingByEffectId sSpellEffectScallingByEffectId;
extern DBCStorage <SpecializationSpellsEntry> sSpecializationSpellsStore;
extern SpecializationSpellsBySpecStore sSpecializationSpellsBySpecStore;
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
@@ -215,6 +251,7 @@ extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
extern DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore;
extern DBCStorage <SpellEntry> sSpellStore;
+extern DBCStorage <SpellEffectScalingEntry> sSpellEffectScalingStore;
extern DBCStorage <SpellAuraOptionsEntry> sSpellAuraOptionsStore;
extern DBCStorage <SpellCategoriesEntry> sSpellCategoriesStore;
extern DBCStorage <SpellCooldownsEntry> sSpellCooldownsStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 3bf632001b0..2f16ce9a0e5 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -647,7 +647,7 @@ struct BarberShopStyleEntry
struct BattlemasterListEntry
{
uint32 ID; // 0
- uint32 MapID[16]; // 1-16 mapid
+ int32 MapID[16]; // 1-16 mapid
uint32 InstanceType; // 17 map type (3 - BG, 4 - arena)
//uint32 GroupsAllowed; // 18 (0 or 1)
char* Name_lang; // 19
@@ -812,7 +812,7 @@ struct CreatureDisplayInfoEntry
//uint32 ObjectEffectPackageID; // 16
//uint32 AnimReplacementSetID; // 17
//uint32 Flags; // 18
- //uint32 Gender; // 19
+ int32 Gender; // 19
//uint32 StateSpellVisualKitID; // 20
};
@@ -1102,6 +1102,14 @@ struct GameObjectDisplayInfoEntry
//float OverrideNameScale; // 20
};
+struct GameTablesEntry
+{
+ //uint32 Index; // 0 - not a real field, not counted for columns
+ char const* Name; // 1
+ uint32 NumRows; // 2
+ uint32 NumColumns; // 3
+};
+
struct GemPropertiesEntry
{
uint32 ID; // 0
@@ -1128,11 +1136,6 @@ struct GlyphSlotEntry
//uint32 Tooltip; // 2
};
-// All Gt* DBC store data for 100 levels, some by 100 per class/race
-#define GT_MAX_LEVEL 100
-// gtOCTClassCombatRatingScalar.dbc stores data for 32 ratings, look at MAX_COMBAT_RATING for real used amount
-#define GT_MAX_RATING 32
-
struct GtBarberShopCostBaseEntry
{
//uint32 level;
@@ -1364,7 +1367,7 @@ struct ItemRandomPropertiesEntry
{
uint32 ID; // 0
//char* Name; // 1
- uint32 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; // 2-6
+ uint32 Enchantment[MAX_ITEM_RANDOM_PROPERTIES]; // 2-6
char* Name_lang; // 7
};
@@ -1800,8 +1803,18 @@ struct SpellEffectEntry
float BonusCoefficientFromAP; // 30
};
-#define MAX_SPELL_EFFECTS 3
-#define MAX_EFFECT_MASK 7
+#define MAX_SPELL_EFFECTS 32
+#define MAX_EFFECT_MASK 0xFFFFFFFF
+
+// SpellEffectScaling.dbc
+struct SpellEffectScalingEntry
+{
+ uint32 ID; // 0
+ float Coefficient; // 1
+ float Variance; // 2
+ float ResourceCoefficient; // 3
+ uint32 SpellEffectID; // 4
+};
// SpellAuraOptions.dbc
struct SpellAuraOptionsEntry
@@ -1865,6 +1878,9 @@ typedef std::set<uint32> SpellCategorySet;
typedef std::map<uint32, SpellCategorySet > SpellCategoryStore;
typedef std::set<uint32> PetFamilySpellsSet;
typedef std::map<uint32, PetFamilySpellsSet > PetFamilySpellsStore;
+typedef std::unordered_map<uint32, std::list<SkillLineAbilityEntry const*> > SpellsPerClassStore;
+typedef std::unordered_map<uint32, uint32> ClassBySkillIdStore;
+typedef std::unordered_map<uint32, uint32> SpellEffectScallingByEffectId;
struct SpellCastTimesEntry
{
@@ -2371,6 +2387,4 @@ struct MapDifficulty
};
typedef std::map<uint32, uint32> TalentSpellPosMap;
-
-typedef std::unordered_map<uint32, std::set<uint32>> PhaseGroupContainer;
#endif
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index 867e64ef92e..c92d3babb25 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -43,7 +43,7 @@ char const ChrRacesEntryfmt[] = "niixiixxxxxxiisxxxxxxxxxxxxxxxxxxxxxxxxx";
char const ChrClassesXPowerTypesfmt[] = "nii";
char const ChrSpecializationEntryfmt[] = "nxiiiiiiiiixxxii";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
-char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxxxxxx";
+char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxxxxix";
char const CreatureDisplayInfoExtrafmt[] = "dixxxxxxxxxxxxxxxxxxxx";
char const CreatureFamilyfmt[] = "nfifiiiiixsx";
char const CreatureModelDatafmt[] = "nixxxxxxxxxxxxxffxxxxxxxxxxxxxxxxx";
@@ -59,6 +59,7 @@ char const EmotesTextEntryfmt[] = "nxixxxxxxxxxxxxxxxx";
char const FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixsxixx";
char const FactionTemplateEntryfmt[] = "niiiiiiiiiiiii";
char const GameObjectDisplayInfofmt[] = "nixxxxxxxxxxffffffxxx";
+char const GameTablesFmt[] = "dsii";
char const GemPropertiesEntryfmt[] = "nixxii";
char const GlyphPropertiesfmt[] = "niiix";
char const GlyphSlotfmt[] = "nix";
@@ -129,12 +130,13 @@ char const SpellCastTimefmt[] = "nixx";
char const SpellCategoriesEntryfmt[] = "diiiiiiiix";
char const SpellCategoryfmt[] = "nixxxx";
char const SpellDurationfmt[] = "niii";
-char const SpellEffectEntryfmt[] = "niifiiiffiiiiiifiifiiiiifiiiiif";
+char const SpellEffectEntryfmt[] = "iiifiiiffiiiiiifiifiiiiifiiiiif";
const std::string CustomSpellEffectEntryfmt = "ppppppppppppppappppppppppp";
const std::string CustomSpellEffectEntryIndex = "Id";
char const SpellEntryfmt[] = "nsxxxiiiiiiiiiiiiiiiiiii";
const std::string CustomSpellEntryfmt = "ppppppppppppppapaaaaaaaaapaaaaaapapppaapppaaapa";
const std::string CustomSpellEntryIndex = "Id";
+char const SpellEffectScalingfmt[] = "nfffi";
char const SpellFocusObjectfmt[] = "nx";
char const SpellItemEnchantmentfmt[] = "niiiiiiiiiixiiiiiiiiiiifff";
char const SpellItemEnchantmentConditionfmt[] = "nbbbbbiiiiibbbbbbbbbbiiiiibbbbb";
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 863324f278c..7099d38d428 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -1406,7 +1406,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId)
}
// Update achievements
- if (dungeon->difficulty == DUNGEON_DIFFICULTY_HEROIC)
+ if (dungeon->difficulty == DIFFICULTY_HEROIC)
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS, 1);
LfgReward const* reward = GetRandomDungeonReward(rDungeonId, player->getLevel());
@@ -1594,7 +1594,7 @@ LfgLockMap const LFGMgr::GetLockedDungeons(ObjectGuid guid)
lockStatus = LFG_LOCKSTATUS_INSUFFICIENT_EXPANSION;
else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player))
lockStatus = LFG_LOCKSTATUS_RAID_LOCKED;
- else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
+ else if (dungeon->difficulty > DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
lockStatus = LFG_LOCKSTATUS_RAID_LOCKED;
else if (dungeon->minlevel > level)
lockStatus = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index dea8d996c53..4fbd60202c3 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -268,7 +268,7 @@ struct LfgPlayerBoot
struct LFGDungeonData
{
LFGDungeonData(): id(0), name(""), map(0), type(0), expansion(0), group(0), minlevel(0),
- maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
+ maxlevel(0), difficulty(DIFFICULTY_NONE), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f),
requiredItemLevel(0)
{ }
LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->Name_lang), map(dbc->MapID),
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 7fb3822c888..7dbb87bcbf3 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -51,6 +51,7 @@
#include "WaypointMovementGenerator.h"
#include "World.h"
#include "WorldPacket.h"
+#include "CombatPackets.h"
#include "Transport.h"
@@ -283,7 +284,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
}
// for instances heroic to normal, other cases attempt to retrieve previous difficulty
- if (diff >= RAID_DIFFICULTY_10MAN_HEROIC && GetMap()->IsRaid())
+ if (diff >= DIFFICULTY_10_HC && GetMap()->IsRaid())
diff -= 2; // to normal raid difficulty cases
else
--diff;
@@ -297,10 +298,10 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
m_creatureInfo = cinfo; // map mode related always
// equal to player Race field, but creature does not have race
- SetByteValue(UNIT_FIELD_BYTES_0, 0, 0);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, 0);
// known valid are: CLASS_WARRIOR, CLASS_PALADIN, CLASS_ROGUE, CLASS_MAGE
- SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(cinfo->unit_class));
// Cancel load if no model defined
if (!(cinfo->GetFirstValidModelId()))
@@ -319,7 +320,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/)
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
// Load creature equipment
if (!data || data->equipmentId == 0)
@@ -804,7 +805,7 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 /*phaseMask*
{
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
LastUsedScriptID = GetCreatureTemplate()->ScriptID;
@@ -1559,7 +1560,7 @@ void Creature::Respawn(bool force)
{
SetDisplayId(displayID);
SetNativeDisplayId(displayID);
- SetByteValue(UNIT_FIELD_BYTES_0, 2, minfo->gender);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
GetMotionMaster()->InitDefault();
@@ -1619,11 +1620,11 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const
// This check must be done instead of 'if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Mechanic - 1)))' for not break
// the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data.
bool immunedToAllEffects = true;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (!spellInfo->Effects[i].IsEffect())
+ if (!effect || !effect->IsEffect())
continue;
- if (!IsImmunedToSpellEffect(spellInfo, i))
+ if (!IsImmunedToSpellEffect(spellInfo, effect->EffectIndex))
{
immunedToAllEffects = false;
break;
@@ -1637,10 +1638,13 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo) const
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
{
- if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (spellInfo->Effects[index].Mechanic - 1)))
+ SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty());
+ if (!effect)
+ return true;
+ if (GetCreatureTemplate()->MechanicImmuneMask & (1 << (effect->Mechanic - 1)))
return true;
- if (GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && spellInfo->Effects[index].Effect == SPELL_EFFECT_HEAL)
+ if (GetCreatureTemplate()->type == CREATURE_TYPE_MECHANICAL && effect->Effect == SPELL_EFFECT_HEAL)
return true;
return Unit::IsImmunedToSpellEffect(spellInfo, index);
@@ -1680,13 +1684,13 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
}
bool bcontinue = true;
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; j++)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if ((spellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE) ||
- (spellInfo->Effects[j].Effect == SPELL_EFFECT_INSTAKILL) ||
- (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) ||
- (spellInfo->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH)
- )
+ if (effect && ((effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE) ||
+ (effect->Effect == SPELL_EFFECT_INSTAKILL) ||
+ (effect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE) ||
+ (effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
+ ))
{
bcontinue = false;
break;
@@ -1728,9 +1732,9 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim)
}
bool bcontinue = true;
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; j++)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if ((spellInfo->Effects[j].Effect == SPELL_EFFECT_HEAL))
+ if (effect && (effect->Effect == SPELL_EFFECT_HEAL))
{
bcontinue = false;
break;
@@ -1826,12 +1830,12 @@ Player* Creature::SelectNearestPlayer(float distance) const
void Creature::SendAIReaction(AiReaction reactionType)
{
- WorldPacket data(SMSG_AI_REACTION, 12);
+ WorldPackets::Combat::AIReaction packet;
- data << GetGUID();
- data << uint32(reactionType);
+ packet.UnitGUID = GetGUID();
+ packet.Reaction = reactionType;
- ((WorldObject*)this)->SendMessageToSet(&data, true);
+ SendMessageToSet(packet.Write(), true);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_AI_REACTION, type %u.", reactionType);
}
@@ -2212,12 +2216,7 @@ void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs
continue;
uint32 unSpellId = m_spells[i];
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
- if (!spellInfo)
- {
- ASSERT(spellInfo);
- continue;
- }
+ SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(unSpellId);
// Not send cooldown for this spells
if (spellInfo->IsCooldownStartedOnEvent())
@@ -2573,7 +2572,7 @@ void Creature::SetDisplayId(uint32 modelId)
}
}
-void Creature::SetTarget(ObjectGuid guid)
+void Creature::SetTarget(ObjectGuid const& guid)
{
if (!_focusSpell)
SetGuidValue(UNIT_FIELD_TARGET, guid);
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 9acde98a7a8..e9212b50933 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -88,9 +88,9 @@ struct CreatureTemplate
std::string SubName;
std::string IconName;
uint32 GossipMenuId;
- uint8 minlevel;
- uint8 maxlevel;
- uint32 expansion;
+ int16 minlevel;
+ int16 maxlevel;
+ int32 expansion;
uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb
uint32 faction;
uint32 npcflag;
@@ -287,8 +287,8 @@ struct CreatureModelInfo
{
float bounding_radius;
float combat_reach;
- uint8 gender;
- uint32 modelid_other_gender;
+ int8 gender;
+ uint32 displayId_other_gender;
};
// Benchmarked: Faster than std::map (insert/find)
@@ -392,11 +392,13 @@ struct VendorItemCount
typedef std::list<VendorItemCount> VendorItemCounts;
+#define MAX_TRAINERSPELL_ABILITY_REQS 3
+
struct TrainerSpell
{
TrainerSpell() : SpellID(0), MoneyCost(0), ReqSkillLine(0), ReqSkillRank(0), ReqLevel(0)
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (uint8 i = 0; i < MAX_TRAINERSPELL_ABILITY_REQS; ++i)
ReqAbility[i] = 0;
}
@@ -405,7 +407,7 @@ struct TrainerSpell
uint32 ReqSkillLine;
uint32 ReqSkillRank;
uint32 ReqLevel;
- uint32 ReqAbility[3];
+ uint32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS];
// helpers
bool IsCastable() const { return ReqAbility[0] != SpellID; }
@@ -674,7 +676,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
bool m_isTempWorldObject; //true when possessed
// Handling caster facing during spellcast
- void SetTarget(ObjectGuid guid) override;
+ void SetTarget(ObjectGuid const& guid) override;
void FocusTarget(Spell const* focusSpell, WorldObject const* target);
void ReleaseFocus(Spell const* focusSpell);
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 4d14ede70fe..2b07683d335 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -23,6 +23,8 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "Formulas.h"
+#include "QuestPackets.h"
+#include "NPCPackets.h"
GossipMenu::GossipMenu()
{
@@ -192,44 +194,45 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
{
_gossipMenu.SetSenderGUID(objectGUID);
- WorldPacket data(SMSG_GOSSIP_MESSAGE, 100); // guess size
- data << objectGUID;
- data << uint32(_gossipMenu.GetMenuId()); // new 2.4.0
- data << uint32(titleTextId);
- data << uint32(_gossipMenu.GetMenuItemCount()); // max count 0x10
+ WorldPackets::NPC::GossipMessage packet;
+ packet.GossipGUID = objectGUID;
+ packet.TextID = titleTextId;
+ packet.GossipOptions.resize(_gossipMenu.GetMenuItems().size());
+ uint32 count = 0;
for (GossipMenuItemContainer::const_iterator itr = _gossipMenu.GetMenuItems().begin(); itr != _gossipMenu.GetMenuItems().end(); ++itr)
{
+ WorldPackets::NPC::ClientGossipOptions& opt = packet.GossipOptions[count];
GossipMenuItem const& item = itr->second;
- data << uint32(itr->first);
- data << uint8(item.MenuItemIcon);
- data << uint8(item.IsCoded); // makes pop up box password
- data << uint32(item.BoxMoney); // money required to open menu, 2.0.3
- data << item.Message; // text for gossip item
- data << item.BoxMessage; // accept text (related to money) pop up box, 2.0.3
+ opt.ClientOption = itr->first;
+ opt.OptionNPC = item.MenuItemIcon;
+ opt.OptionFlags = item.IsCoded; // makes pop up box password
+ opt.OptionCost = item.BoxMoney; // money required to open menu, 2.0.3
+ opt.Text = item.Message; // text for gossip item
+ opt.Confirm = item.BoxMessage; // accept text (related to money) pop up box, 2.0.3
+ ++count;
}
- size_t count_pos = data.wpos();
- data << uint32(0); // max count 0x20
- uint32 count = 0;
-
// Store this instead of checking the Singleton every loop iteration
bool questLevelInTitle = sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS);
+ packet.GossipText.resize(_questMenu.GetMenuItemCount());
+ count = 0;
for (uint8 i = 0; i < _questMenu.GetMenuItemCount(); ++i)
{
QuestMenuItem const& item = _questMenu.GetItem(i);
uint32 questID = item.QuestId;
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questID))
{
- ++count;
- data << uint32(questID);
- data << uint32(item.QuestIcon);
- data << int32(quest->GetQuestLevel());
- data << uint32(quest->GetFlags()); // 3.3.3 quest flags
- data << uint8(0); // 3.3.3 changes icon: blue question or yellow exclamation
- std::string title = quest->GetTitle();
+ WorldPackets::NPC::ClientGossipText& text = packet.GossipText[count];
+ text.QuestID = questID;
+ text.QuestType = item.QuestIcon;
+ text.QuestLevel = quest->GetQuestLevel();
+ text.QuestFlags[0] = quest->GetFlags();
+ text.QuestFlags[1] = 0;
+ text.Repeatable = quest->IsRepeatable();
+ std::string title = quest->GetTitle();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID))
@@ -238,12 +241,15 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID)
if (questLevelInTitle)
AddQuestLevelToTitle(title, quest->GetQuestLevel());
- data << title; // max 0x200
+ text.QuestTitle = title;
+ ++count;
}
}
- data.put<uint8>(count_pos, count);
- _session->SendPacket(&data);
+ // Shrink to the real size
+ packet.GossipText.resize(count);
+
+ _session->SendPacket(packet.Write());
}
void PlayerMenu::SendCloseGossip()
@@ -373,11 +379,11 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string
void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, ObjectGuid npcGUID) const
{
- WorldPacket data(SMSG_QUESTGIVER_STATUS, 8 + 4);
- data << npcGUID;
- data << uint32(questStatus);
+ WorldPackets::Quest::QuestGiverStatus packet;
+ packet.QuestGiver.Guid = npcGUID;
+ packet.QuestGiver.Status = questStatus;
- _session->SendPacket(&data);
+ _session->SendPacket(packet.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC=%s, status=%u", npcGUID.ToString().c_str(), questStatus);
}
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 2b13c859255..382bf45052b 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -1809,9 +1809,9 @@ void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /*= true
return;
bool self = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)
+ if (effect && effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
{
self = true;
break;
@@ -2150,7 +2150,7 @@ void GameObject::SetTransportState(GOState state, uint32 stopFrame /*= 0*/)
}
else
{
- ASSERT(state < GO_STATE_TRANSPORT_STOPPED + MAX_GO_STATE_TRANSPORT_STOP_FRAMES);
+ ASSERT(state < GOState(GO_STATE_TRANSPORT_STOPPED + MAX_GO_STATE_TRANSPORT_STOP_FRAMES));
ASSERT(stopFrame < m_goValue.Transport.StopFrames->size());
m_goValue.Transport.PathProgress = getMSTime() + m_goValue.Transport.StopFrames->at(stopFrame);
SetGoState(GOState(GO_STATE_TRANSPORT_STOPPED + stopFrame));
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
index f5813ae0781..ea9e24dff94 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp
@@ -127,36 +127,42 @@ uint32 GenerateEnchSuffixFactor(uint32 item_id)
if (!itemProto->RandomSuffix)
return 0;
- RandomPropertiesPointsEntry const* randomProperty = sRandomPropertiesPointsStore.LookupEntry(itemProto->ItemLevel);
- if (!randomProperty)
- return 0;
+ return GetRandomPropertyPoints(itemProto->ItemLevel, itemProto->Quality, itemProto->InventoryType, itemProto->SubClass);
+}
+
+uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subClass)
+{
+ uint32 propIndex;
- uint32 suffixFactor;
- switch (itemProto->InventoryType)
+ switch (inventoryType)
{
- // Items of that type don`t have points
- case INVTYPE_NON_EQUIP:
- case INVTYPE_BAG:
- case INVTYPE_TABARD:
- case INVTYPE_AMMO:
- case INVTYPE_QUIVER:
- case INVTYPE_RELIC:
- return 0;
- // Select point coefficient
case INVTYPE_HEAD:
case INVTYPE_BODY:
case INVTYPE_CHEST:
case INVTYPE_LEGS:
+ case INVTYPE_RANGED:
case INVTYPE_2HWEAPON:
case INVTYPE_ROBE:
- suffixFactor = 0;
+ case INVTYPE_THROWN:
+ propIndex = 0;
+ break;
+ case INVTYPE_RANGEDRIGHT:
+ if (subClass == ITEM_SUBCLASS_WEAPON_WAND)
+ propIndex = 3;
+ else
+ propIndex = 0;
+ break;
+ case INVTYPE_WEAPON:
+ case INVTYPE_WEAPONMAINHAND:
+ case INVTYPE_WEAPONOFFHAND:
+ propIndex = 3;
break;
case INVTYPE_SHOULDERS:
case INVTYPE_WAIST:
case INVTYPE_FEET:
case INVTYPE_HANDS:
case INVTYPE_TRINKET:
- suffixFactor = 1;
+ propIndex = 1;
break;
case INVTYPE_NECK:
case INVTYPE_WRISTS:
@@ -164,36 +170,29 @@ uint32 GenerateEnchSuffixFactor(uint32 item_id)
case INVTYPE_SHIELD:
case INVTYPE_CLOAK:
case INVTYPE_HOLDABLE:
- suffixFactor = 2;
- break;
- case INVTYPE_WEAPON:
- case INVTYPE_WEAPONMAINHAND:
- case INVTYPE_WEAPONOFFHAND:
- suffixFactor = 3;
- break;
- case INVTYPE_RANGED:
- case INVTYPE_THROWN:
- case INVTYPE_RANGEDRIGHT:
- suffixFactor = 4;
+ propIndex = 2;
break;
+ case INVTYPE_RELIC:
+ propIndex = 4;
default:
return 0;
}
- // Select rare/epic modifier
- switch (itemProto->Quality)
+
+ RandomPropertiesPointsEntry const* randPropPointsEntry = sRandomPropertiesPointsStore.LookupEntry(itemLevel);
+ if (!randPropPointsEntry)
+ return 0;
+
+ switch (quality)
{
case ITEM_QUALITY_UNCOMMON:
- return randomProperty->UncommonPropertiesPoints[suffixFactor];
+ return randPropPointsEntry->UncommonPropertiesPoints[propIndex];
case ITEM_QUALITY_RARE:
- return randomProperty->RarePropertiesPoints[suffixFactor];
+ case ITEM_QUALITY_HEIRLOOM:
+ return randPropPointsEntry->RarePropertiesPoints[propIndex];
case ITEM_QUALITY_EPIC:
- return randomProperty->EpicPropertiesPoints[suffixFactor];
case ITEM_QUALITY_LEGENDARY:
- case ITEM_QUALITY_ARTIFACT:
- return 0; // not have random properties
- default:
- break;
+ return randPropPointsEntry->EpicPropertiesPoints[propIndex];
}
+
return 0;
}
-
diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.h b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
index a263ec0dae4..73d3d97bb0b 100644
--- a/src/server/game/Entities/Item/ItemEnchantmentMgr.h
+++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.h
@@ -24,5 +24,6 @@
void LoadRandomEnchantmentsTable();
uint32 GetItemEnchantMod(int32 entry);
uint32 GenerateEnchSuffixFactor(uint32 item_id);
+uint32 GetRandomPropertyPoints(uint32 itemLevel, uint32 quality, uint32 inventoryType, uint32 subclass);
#endif
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index e28e8a21678..3846f7dd642 100644
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -598,7 +598,7 @@ struct ItemEffect
{
uint32 SpellID;
uint32 Trigger;
- uint32 Charges;
+ int32 Charges;
int32 Cooldown;
uint32 Category;
int32 CategoryCooldown;
@@ -611,6 +611,7 @@ struct ItemEffect
#pragma pack(pop)
#endif
+#define MAX_ITEM_PROTO_FLAGS 3
#define MAX_ITEM_PROTO_DAMAGES 2 // changed in 3.1.0
#define MAX_ITEM_PROTO_SOCKETS 3
#define MAX_ITEM_PROTO_STATS 10
@@ -623,8 +624,10 @@ struct ItemTemplate
int32 SoundOverrideSubclass; // < 0: id from ItemSubClass.dbc, used to override weapon sound from actual SubClass
std::string Name1;
uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc
+ uint32 FileDataID;
+ uint32 GroupSoundsID;
uint32 Quality;
- uint32 Flags[3];
+ uint32 Flags[MAX_ITEM_PROTO_FLAGS];
float Unk1;
float Unk2;
uint32 BuyCount;
@@ -678,6 +681,7 @@ struct ItemTemplate
float StatScalingFactor;
uint32 CurrencySubstitutionId; // May be used instead of a currency
uint32 CurrencySubstitutionCount;
+ uint32 ItemNameDescriptionID;
// extra fields, not part of db2 files
float DamageMin;
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index e482e0a449d..40a8ed046fb 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -943,7 +943,14 @@ uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const
case TYPEID_AREATRIGGER:
flags = AreaTriggerUpdateFieldFlags;
break;
+ case TYPEID_SCENEOBJECT:
+ flags = SceneObjectUpdateFieldFlags;
+ break;
+ case TYPEID_CONVERSATION:
+ flags = ConversationUpdateFieldFlags;
+ break;
case TYPEID_OBJECT:
+ ASSERT(false);
break;
}
@@ -981,6 +988,9 @@ uint32 Object::GetDynamicUpdateFieldData(Player const* target, uint32*& flags) c
visibleFlag |= UF_FLAG_PARTY_MEMBER;
break;
}
+ case TYPEID_CONVERSATION:
+ flags = ConversationDynamicUpdateFieldFlags;
+ break;
default:
flags = nullptr;
break;
@@ -1001,7 +1011,7 @@ void Object::_LoadIntoDataField(std::string const& data, uint32 startOffset, uin
for (uint32 index = 0; index < count; ++index)
{
- m_uint32Values[startOffset + index] = atol(tokens[index]);
+ m_uint32Values[startOffset + index] = atoul(tokens[index]);
_changesMask.SetBit(startOffset + index);
}
}
@@ -2359,19 +2369,19 @@ void Object::ForceValuesUpdateAtIndex(uint32 i)
}
}
-void WorldObject::SendMessageToSet(WorldPacket* data, bool self)
+void WorldObject::SendMessageToSet(WorldPacket const* data, bool self)
{
if (IsInWorld())
SendMessageToSetInRange(data, GetVisibilityRange(), self);
}
-void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/)
+void WorldObject::SendMessageToSetInRange(WorldPacket const* data, float dist, bool /*self*/)
{
Trinity::MessageDistDeliverer notifier(this, data, dist);
VisitNearbyWorldObject(dist, notifier);
}
-void WorldObject::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
+void WorldObject::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr)
{
Trinity::MessageDistDeliverer notifier(this, data, GetVisibilityRange(), false, skipped_rcvr);
VisitNearbyWorldObject(GetVisibilityRange(), notifier);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index bae3a8b07c1..d2dd0108d20 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -661,9 +661,9 @@ class WorldObject : public Object, public WorldLocation
virtual void CleanupsBeforeDelete(bool finalCleanup = true); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units
- virtual void SendMessageToSet(WorldPacket* data, bool self);
- virtual void SendMessageToSetInRange(WorldPacket* data, float dist, bool self);
- virtual void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr);
+ virtual void SendMessageToSet(WorldPacket const* data, bool self);
+ virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self);
+ virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr);
virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; }
diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp
index f59c82d44f5..327b83ba6d4 100644
--- a/src/server/game/Entities/Object/ObjectGuid.cpp
+++ b/src/server/game/Entities/Object/ObjectGuid.cpp
@@ -231,13 +231,13 @@ ObjectGuid const ObjectGuid::Empty = ObjectGuid();
ObjectGuid const ObjectGuid::TradeItem = ObjectGuid::Create<HighGuid::Uniq>(uint64(10));
template<HighGuid type>
-ObjectGuid ObjectGuid::Create(LowType counter)
+ObjectGuid ObjectGuid::Create(LowType /*counter*/)
{
static_assert(type == HighGuid::Count, "This guid type cannot be constructed using Create(LowType counter).");
}
template<HighGuid type>
-ObjectGuid ObjectGuid::Create(uint16 mapId, uint32 entry, LowType counter)
+ObjectGuid ObjectGuid::Create(uint16 /*mapId*/, uint32 /*entry*/, LowType /*counter*/)
{
static_assert(type == HighGuid::Count, "This guid type cannot be constructed using Create(uint16 mapId, uint32 entry, LowType counter).");
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp
index 74f6b62e398..c6a9a0b1132 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp
@@ -45,7 +45,7 @@ void UpdateData::AddUpdateBlock(const ByteBuffer &block)
bool UpdateData::BuildPacket(WorldPacket* packet)
{
ASSERT(packet->empty()); // shouldn't happen
- packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos(), CONNECTION_TYPE_INSTANCE);
+ packet->Initialize(SMSG_UPDATE_OBJECT, 2 + 4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
*packet << uint32(m_blockCount);
*packet << uint16(m_map);
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 52045f46472..bc08e8b1baf 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -214,18 +214,15 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
{
case SUMMON_PET:
petlevel = owner->getLevel();
-
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x800); // class = mage
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
- // this enables popup window (pet dismiss, cancel)
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_MAGE);
+ SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet dismiss, cancel)
break;
case HUNTER_PET:
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); // class = warrior, gender = none, power = focus
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_WARRIOR);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, GENDER_NONE);
SetSheath(SHEATH_STATE_MELEE);
SetByteFlag(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_CAN_BE_ABANDONED : UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
-
- SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
- // this enables popup window (pet abandon, cancel)
+ SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel)
setPowerType(POWER_FOCUS);
break;
default:
@@ -782,7 +779,9 @@ bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phas
if (cinfo->type == CREATURE_TYPE_BEAST)
{
- SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_WARRIOR);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, GENDER_NONE);
+ SetUInt32Value(UNIT_FIELD_DISPLAY_POWER, POWER_FOCUS);
SetSheath(SHEATH_STATE_MELEE);
SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED | UNIT_CAN_BE_ABANDONED);
}
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index ae8f0191137..a3a6c0d21a1 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -28,7 +28,6 @@
#include "BattlegroundMgr.h"
#include "BattlegroundScore.h"
#include "CellImpl.h"
-#include "Channel.h"
#include "ChannelMgr.h"
#include "CharacterDatabaseCleaner.h"
#include "CharacterPackets.h"
@@ -40,6 +39,7 @@
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "DisableMgr.h"
+#include "EquipmentSetPackets.h"
#include "Formulas.h"
#include "GameEventMgr.h"
#include "GameObjectAI.h"
@@ -87,6 +87,9 @@
#include "WorldSession.h"
#include "WorldStatePackets.h"
#include "MiscPackets.h"
+#include "ChatPackets.h"
+#include "MovementPackets.h"
+#include "ItemPackets.h"
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
@@ -169,7 +172,7 @@ void PlayerTaxi::LoadTaxiMask(std::string const &data)
for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index)
{
// load and set bits only for existing taxi nodes
- m_taximask[index] = sTaxiNodesMask[index] & uint32(atol(*iter));
+ m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter);
}
}
@@ -196,7 +199,7 @@ bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint3
for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter)
{
- uint32 node = uint32(atol(*iter));
+ uint32 node = atoul(*iter);
AddTaxiDestination(node);
}
@@ -785,9 +788,9 @@ Player::Player(WorldSession* session): Unit(true)
m_HomebindTimer = 0;
m_InstanceValid = true;
- m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL;
- m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
- m_raidMapDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
+ m_dungeonDifficulty = DIFFICULTY_NORMAL;
+ m_raidDifficulty = DIFFICULTY_10_N;
+ m_raidMapDifficulty = DIFFICULTY_10_N;
m_lastPotionId = 0;
_talentMgr = new PlayerTalentInfo();
@@ -982,9 +985,10 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac
return false;
}
- uint32 RaceClassGender = (createInfo->Race) | (createInfo->Class << 8) | (createInfo->Sex << 16);
-
- SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, createInfo->Race);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, createInfo->Class);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, createInfo->Sex);
+ SetUInt32Value(UNIT_FIELD_DISPLAY_POWER, powertype);
InitDisplayIds();
if (sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || sWorld->getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP)
{
@@ -1930,18 +1934,18 @@ void Player::ToggleDND()
ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND);
}
-uint8 Player::GetChatTag() const
+uint8 Player::GetChatFlags() const
{
- uint8 tag = CHAT_TAG_NONE;
+ uint8 tag = CHAT_FLAG_NONE;
if (isGMChat())
- tag |= CHAT_TAG_GM;
+ tag |= CHAT_FLAG_GM;
if (isDND())
- tag |= CHAT_TAG_DND;
+ tag |= CHAT_FLAG_DND;
if (isAFK())
- tag |= CHAT_TAG_AFK;
+ tag |= CHAT_FLAG_AFK;
if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER))
- tag |= CHAT_TAG_DEV;
+ tag |= CHAT_FLAG_DEV;
return tag;
}
@@ -2133,18 +2137,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (!GetSession()->PlayerLogout())
{
// send transfer packets
- WorldPacket data(SMSG_TRANSFER_PENDING, 4 + 4 + 4);
- data.WriteBit(0); // unknown
+ WorldPackets::Movement::TransferPending transferPending;
+ transferPending.MapID = mapid;
if (Transport* transport = GetTransport())
{
- data.WriteBit(1); // has transport
- data << GetMapId() << transport->GetEntry();
+ transferPending.Ship.HasValue = true;
+ transferPending.Ship.Value.ID = transport->GetEntry();
+ transferPending.Ship.Value.OriginMapID = GetMapId();
}
- else
- data.WriteBit(0); // has transport
- data << uint32(mapid);
- GetSession()->SendPacket(&data);
+ GetSession()->SendPacket(transferPending.Write());
}
// remove from old map now
@@ -2158,14 +2160,12 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (!GetSession()->PlayerLogout())
{
- WorldPacket data(SMSG_NEW_WORLD, 4 + 4 + 4 + 4 + 4);
- data << float(m_teleport_dest.GetPositionX());
- data << float(m_teleport_dest.GetOrientation());
- data << float(m_teleport_dest.GetPositionZ());
- data << uint32(mapid);
- data << float(m_teleport_dest.GetPositionY());
+ WorldPackets::Movement::NewWorld packet;
+ packet.MapID = mapid;
+ packet.Pos = m_teleport_dest;
+ packet.Reason = NEW_WORLD_NORMAL;
- GetSession()->SendPacket(&data);
+ SendDirectMessage(packet.Write());
SendSavedInstances();
}
@@ -2985,11 +2985,39 @@ void Player::GiveLevel(uint8 level)
SetByteFlag(PLAYER_FIELD_BYTES, 1, 0x01);
}
+ std::list<uint32> learnList = GetSpellsForLevels(getClass(), getRaceMask(), GetTalentSpec(GetActiveTalentGroup()), oldLevel, level);
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
+ {
+ if (!HasSpell(*iter))
+ LearnSpell(*iter, true);
+ }
+
sScriptMgr->OnPlayerLevelChanged(this, oldLevel);
}
void Player::InitTalentForLevel()
{
+ uint8 level = getLevel();
+ // talents base at level diff (talents = level - 9 but some can be used already)
+ if (level < 15)
+ {
+ // Remove all talent points
+ if (GetUsedTalentCount() > 0) // Free any used talents
+ {
+ ResetTalents(true);
+ }
+ }
+ else
+ {
+ if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || GetTalentGroupsCount() == 0)
+ {
+ SetTalentGroupsCount(1);
+ SetActiveTalentGroup(0);
+ }
+ }
+
+ SetUInt32Value(PLAYER_FIELD_MAX_TALENT_TIERS, CalculateTalentsPoints());
+
if (!GetSession()->PlayerLoading())
SendTalentsInfoData(); // update at client
}
@@ -3164,9 +3192,10 @@ void Player::InitStatsForLevel(bool reapplyMods)
void Player::SendKnownSpells()
{
- WorldPackets::Spell::SendKnownSpells knownSpells;
+ WorldPackets::Spells::SendKnownSpells knownSpells;
knownSpells.InitialLogin = false; /// @todo
+ knownSpells.KnownSpells.reserve(m_spells.size());
for (PlayerSpellMap::value_type const& spell : m_spells)
{
if (spell.second->state == PLAYERSPELL_REMOVED)
@@ -3266,7 +3295,7 @@ void DeleteSpellFromAllPlayers(uint32 spellId)
}
}
-bool Player::AddTalent(uint32 talentId, uint8 spec)
+bool Player::AddTalent(uint32 talentId, uint8 spec, bool learning)
{
TalentEntry const* talentEntry = sTalentStore.LookupEntry(talentId);
@@ -3308,15 +3337,28 @@ bool Player::AddTalent(uint32 talentId, uint8 spec)
return false;
}
- TalentGroupInfo* talentGroupInfo = GetTalentGroupInfo(spec);
+ PlayerTalentMap::iterator itr = GetTalentMap(spec)->find(talentId);
+ if (itr == GetTalentMap(spec)->end())
+ {
+ //if (GetTalentBySpellID(talentEntry->SpellID))
+ {
+ PlayerSpellState state = learning ? PLAYERSPELL_NEW : PLAYERSPELL_UNCHANGED;
+ PlayerTalent* newtalent = new PlayerTalent();
- // Check if player already has this talent
- if (talentGroupInfo->HasTalent(talentId))
- return false;
+ newtalent->state = state;
+ newtalent->spec = spec;
- talentGroupInfo->Talents[talentEntry->TierID] = talentId;
+ (*GetTalentMap(spec))[talentId] = newtalent;
- return true;
+ return true;
+ }
+ //else
+ // TC_LOG_ERROR("spells", "Player::addTalent: Talent %u not found in talent store.", talentId);
+ }
+ else
+ itr->second->state = PLAYERSPELL_UNCHANGED;
+
+ return false;
}
bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, bool fromSkill /*= false*/)
@@ -3420,9 +3462,9 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
SendSupercededSpell(spellId, next_active_spell_id);
else
{
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint32(spellId);
- GetSession()->SendPacket(&data);
+ WorldPackets::Spells::SendRemovedSpell removedSpells;
+ removedSpells.Spells.push_back(spellId);
+ GetSession()->SendPacket(removedSpells.Write());
}
}
@@ -3528,9 +3570,11 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
return false;
}
+ uint32 talentCost = GetTalentSpellCost(spellId);
+
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
- if (!loading && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
+ if (!loading && talentCost > 0 && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
{
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
CastSpell(this, spellId, true);
@@ -3547,6 +3591,9 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
return false;
}
+ // update used talent points count
+ SetUsedTalentCount(GetUsedTalentCount() + talentCost);
+
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
{
@@ -3554,38 +3601,62 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
SetFreePrimaryProfessions(freeProfs-1);
}
+ // add dependent skills
+ uint16 maxskill = GetMaxSkillValueForLevel();
+
+ SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId);
+
SkillLineAbilityMapBounds skill_bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellId);
- // add dependent skills if this spell is not learned from adding skill already
- if (!fromSkill)
+ if (spellLearnSkill)
{
- if (SpellLearnSkillNode const* spellLearnSkill = sSpellMgr->GetSpellLearnSkill(spellId))
- {
- uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill);
- uint32 skill_max_value = GetPureMaxSkillValue(spellLearnSkill->skill);
+ uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill);
+ uint32 skill_max_value = GetPureMaxSkillValue(spellLearnSkill->skill);
- if (skill_value < spellLearnSkill->value)
- skill_value = spellLearnSkill->value;
+ if (skill_value < spellLearnSkill->value)
+ skill_value = spellLearnSkill->value;
- uint32 new_skill_max_value = spellLearnSkill->maxvalue == 0 ? GetMaxSkillValueForLevel() : spellLearnSkill->maxvalue;
+ uint32 new_skill_max_value = spellLearnSkill->maxvalue == 0 ? maxskill : spellLearnSkill->maxvalue;
- if (skill_max_value < new_skill_max_value)
- skill_max_value = new_skill_max_value;
+ if (skill_max_value < new_skill_max_value)
+ skill_max_value = new_skill_max_value;
- SetSkill(spellLearnSkill->skill, spellLearnSkill->step, skill_value, skill_max_value);
- }
- else
+ SetSkill(spellLearnSkill->skill, spellLearnSkill->step, skill_value, skill_max_value);
+ }
+ else
+ {
+ // not ranked skills
+ for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx)
{
- // not ranked skills
- for (SkillLineAbilityMap::const_iterator _spell_idx = skill_bounds.first; _spell_idx != skill_bounds.second; ++_spell_idx)
- {
- SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->SkillLine);
- if (!pSkill)
- continue;
+ SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->SkillLine);
+ if (!pSkill)
+ continue;
+
+ if (HasSkill(pSkill->ID))
+ continue;
- ///@todo: confirm if rogues start with lockpicking skill at level 1 but only receive the spell to use it at level 16
- if ((_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN && !HasSkill(pSkill->ID)) || (pSkill->ID == SKILL_LOCKPICKING && _spell_idx->second->TrivialSkillLineRankHigh == 0))
- LearnDefaultSkill(pSkill->ID, 0);
+ SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(pSkill->ID, getRace(), getClass());
+ if (!rcEntry)
+ continue;
+
+ if (_spell_idx->second->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN ||
+ // lockpicking/runeforging special case, not have SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN
+ ((pSkill->ID == SKILL_LOCKPICKING || pSkill->ID == SKILL_RUNEFORGING) && (_spell_idx->second->TrivialSkillLineRankHigh == 0 || _spell_idx->second->TrivialSkillLineRankHigh == 1)))
+ {
+ switch (GetSkillRangeType(rcEntry))
+ {
+ case SKILL_RANGE_LANGUAGE:
+ SetSkill(pSkill->ID, GetSkillStep(pSkill->ID), 300, 300);
+ break;
+ case SKILL_RANGE_LEVEL:
+ SetSkill(pSkill->ID, GetSkillStep(pSkill->ID), 1, GetMaxSkillValueForLevel());
+ break;
+ case SKILL_RANGE_MONO:
+ SetSkill(pSkill->ID, GetSkillStep(pSkill->ID), 1, 1);
+ break;
+ default:
+ break;
+ }
}
}
}
@@ -3664,6 +3735,7 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const
bool Player::IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const
{
+
if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetActiveTalentSpec()))
return spellInfo->Id == chrSpec->MasterySpellID[0] || spellInfo->Id == chrSpec->MasterySpellID[1];
@@ -3682,10 +3754,9 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, bool fromSkill /*= fals
// prevent duplicated entires in spell book, also not send if not in world (loading)
if (learning && IsInWorld())
{
- WorldPacket data(SMSG_LEARNED_SPELL, 8);
- data << uint32(spell_id);
- data << uint32(0);
- GetSession()->SendPacket(&data);
+ WorldPackets::Spells::LearnedSpells packet;
+ packet.SpellID.push_back(spell_id);
+ GetSession()->SendPacket(packet.Write());
}
// learn all disabled higher ranks and required spells (recursive)
@@ -3848,18 +3919,11 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
if (spell_id == 46917 && m_canTitanGrip)
SetCanTitanGrip(false);
+
if (m_canDualWield)
{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
- if (spellInfo->IsPassive())
- {
- for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
- if (spellInfo->Effects[i].Effect == SPELL_EFFECT_DUAL_WIELD)
- {
- SetCanDualWield(false);
- break;
- }
- }
+ if (spellInfo && spellInfo->IsPassive() && spellInfo->HasEffect(SPELL_EFFECT_DUAL_WIELD))
+ SetCanDualWield(false);
}
if (sWorld->getBoolConfig(CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN))
@@ -3868,9 +3932,9 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
// remove from spell book if not replaced by lesser rank
if (!prev_activate)
{
- WorldPacket data(SMSG_REMOVED_SPELL, 4);
- data << uint32(spell_id);
- GetSession()->SendPacket(&data);
+ WorldPackets::Spells::SendRemovedSpell removedSpells;
+ removedSpells.Spells.push_back(spell_id);
+ GetSession()->SendPacket(removedSpells.Write());
}
}
@@ -4055,9 +4119,12 @@ uint32 Player::GetNextResetTalentsCost() const
}
}
-bool Player::ResetTalents(bool no_cost)
+bool Player::ResetTalents(bool noCost, bool resetTalents, bool resetSpecialization)
{
- sScriptMgr->OnPlayerTalentsReset(this, no_cost);
+ if (!resetTalents && !resetSpecialization)
+ return false;
+
+ sScriptMgr->OnPlayerTalentsReset(this, noCost);
// not need after this call
if (HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
@@ -4065,7 +4132,7 @@ bool Player::ResetTalents(bool no_cost)
uint32 cost = 0;
- if (!no_cost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST))
+ if (!noCost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST))
{
cost = GetNextResetTalentsCost();
@@ -4078,66 +4145,54 @@ bool Player::ResetTalents(bool no_cost)
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- uint8 group = GetActiveTalentGroup();
- uint32 specID = GetActiveTalentSpec();
-
- for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
+ if (resetTalents)
{
- TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
+ for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
+ {
+ TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
- if (!talentInfo)
- continue;
+ if (!talentInfo)
+ continue;
- // unlearn only talents for character class
- // some spell learned by one class as normal spells or know at creation but another class learn it as talent,
- // to prevent unexpected lost normal learned spell skip another class talents
- if (getClass() != talentInfo->ClassID)
- continue;
+ // unlearn only talents for character class
+ // some spell learned by one class as normal spells or know at creation but another class learn it as talent,
+ // to prevent unexpected lost normal learned spell skip another class talents
+ if (talentInfo->ClassID != getClass())
+ continue;
- const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
+ SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
+ if (!spellEntry)
+ continue;
- if (!_spellEntry)
- continue;
+ RemoveSpell(spellEntry->Id, false);
- RemoveSpell(talentInfo->SpellID, true);
+ // search for spells that the talent teaches and unlearn them, 6.x remove?
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ if (effect && effect->TriggerSpell > 0 && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
+ RemoveSpell(effect->TriggerSpell, true);
- // search for spells that the talent teaches and unlearn them
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
- RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true);
+ GetTalentMap(GetActiveTalentGroup())->erase(talentId);
+ }
}
- // Remove all specialization specific spells and give default ones which were overriden
- auto specSpells = sSpecializationSpellsBySpecStore.find(specID);
- if (specSpells != sSpecializationSpellsBySpecStore.end())
+ if (resetSpecialization)
{
- for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
+ std::list<uint32> learnList = GetSpellsForLevels(0, getRaceMask(), GetTalentSpec(GetActiveTalentGroup()), 0, getLevel());
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
{
- SpecializationSpellsEntry const* specSpell = *it;
- if (HasSpell(specSpell->SpellID)) {
- RemoveSpell(specSpell->SpellID, true);
- if (specSpell->OverridesSpellID)
- LearnSpell(specSpell->OverridesSpellID, false);
- }
+ if (HasSpell(*iter))
+ RemoveSpell(*iter, true);
}
+ SetTalentSpec(GetActiveTalentGroup(), 0);
+ SetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID, 0);
}
- // Unlearn masteries
- if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(specID))
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (uint32 mastery = chrSpec->MasterySpellID[i])
- RemoveAurasDueToSpell(mastery);
-
- // Reset talents store
- GetTalentGroupInfo(group)->Reset();
- SetTalentSpec(group, 0);
-
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveTalents(trans);
_SaveSpells(trans);
CharacterDatabase.CommitTransaction(trans);
- if (!no_cost)
+ if (!noCost)
{
ModifyMoney(-(int64)cost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost);
@@ -4158,6 +4213,35 @@ bool Player::ResetTalents(bool no_cost)
return true;
}
+bool Player::RemoveTalent(uint32 talentId)
+{
+ TalentEntry const* talent = sTalentStore.LookupEntry(talentId);
+ if (!talent)
+ return false;
+
+ uint32 spellId = talent->SpellID;
+
+ SpellInfo const* unlearnSpellProto = sSpellMgr->GetSpellInfo(spellId);
+
+ RemoveSpell(spellId, false);
+
+ // 6.x remove?
+ for (SpellEffectInfo const* effect : unlearnSpellProto->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ if (effect && effect->TriggerSpell > 0 && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
+ RemoveSpell(effect->TriggerSpell, false);
+
+ GetTalentMap(GetActiveTalentSpec())->erase(talentId);
+
+ // Needs to be executed orthewise the talents will be screwedsx
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ _SaveTalents(trans);
+ _SaveSpells(trans);
+ CharacterDatabase.CommitTransaction(trans);
+
+ SendTalentsInfoData();
+ return true;
+}
+
Mail* Player::GetMail(uint32 id)
{
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -4224,7 +4308,8 @@ bool Player::HasSpell(uint32 spell) const
bool Player::HasTalent(uint32 talentId, uint8 group)
{
- return GetTalentGroupInfo(group)->HasTalent(talentId);
+ PlayerTalentMap::const_iterator itr = GetTalentMap(group)->find(talentId);
+ return (itr != GetTalentMap(group)->end());
}
bool Player::HasActiveSpell(uint32 spell) const
@@ -4872,7 +4957,7 @@ void Player::CreateCorpse()
// prevent existence 2 corpse for player
SpawnCorpseBones();
- uint32 _uf, _pb, _pb2, _cfb1, _cfb2;
+ uint32 _pb, _pb2, _cfb1, _cfb2;
Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE);
SetPvPDeath(false);
@@ -4883,18 +4968,16 @@ void Player::CreateCorpse()
return;
}
- _uf = GetUInt32Value(UNIT_FIELD_BYTES_0);
_pb = GetUInt32Value(PLAYER_BYTES);
_pb2 = GetUInt32Value(PLAYER_BYTES_2);
- uint8 race = (uint8)(_uf);
uint8 skin = (uint8)(_pb);
uint8 face = (uint8)(_pb >> 8);
uint8 hairstyle = (uint8)(_pb >> 16);
uint8 haircolor = (uint8)(_pb >> 24);
uint8 facialhair = (uint8)(_pb2);
- _cfb1 = ((0x00) | (race << 8) | (getGender() << 16) | (skin << 24));
+ _cfb1 = ((0x00) | (getRace() << 8) | (getGender() << 16) | (skin << 24));
_cfb2 = ((face) | (hairstyle << 8) | (haircolor << 16) | (facialhair << 24));
corpse->SetUInt32Value(CORPSE_FIELD_BYTES_1, _cfb1);
@@ -5225,8 +5308,8 @@ void Player::CleanupChannels()
{
Channel* ch = *m_channels.begin();
m_channels.erase(m_channels.begin()); // remove from player's channel list
- ch->LeaveChannel(this, false); // not send to client, not remove from player's channel list
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam()))
+ ch->LeaveChannel(this, false); // not send to client, not remove from player's channel list
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetTeam()))
cMgr->LeftChannel(ch->GetName()); // deleted channel if empty
}
TC_LOG_DEBUG("chat.system", "Player %s: channels cleaned up!", GetName().c_str());
@@ -5241,12 +5324,10 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (!current_zone)
return;
- ChannelMgr* cMgr = ChannelMgr::forTeam(GetTeam());
+ ChannelMgr* cMgr = ChannelMgr::ForTeam(GetTeam());
if (!cMgr)
return;
- std::string current_zone_name = current_zone->ZoneName;
-
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
{
if (ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(i))
@@ -5279,7 +5360,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (channel->Flags & CHANNEL_DBC_FLAG_CITY_ONLY)
currentNameExt = sObjectMgr->GetTrinityStringForDBCLocale(LANG_CHANNEL_CITY);
else
- currentNameExt = current_zone_name.c_str();
+ currentNameExt = current_zone->ZoneName;
snprintf(new_channel_name_buf, 100, channel->Name_lang, currentNameExt);
@@ -5385,11 +5466,11 @@ float Player::GetMeleeCritFromAgility()
uint8 level = getLevel();
uint32 pclass = getClass();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
+ if (level >= sGtChanceToMeleeCritStore.GetTableRowCount())
+ level = sGtChanceToMeleeCritStore.GetTableRowCount() - 1;
- GtChanceToMeleeCritBaseEntry const* critBase = sGtChanceToMeleeCritBaseStore.LookupEntry(pclass-1);
- GtChanceToMeleeCritEntry const* critRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
+ GtChanceToMeleeCritBaseEntry const* critBase = sGtChanceToMeleeCritBaseStore.EvaluateTable(pclass - 1, 0);
+ GtChanceToMeleeCritEntry const* critRatio = sGtChanceToMeleeCritStore.EvaluateTable(level - 1, pclass - 1);
if (critBase == NULL || critRatio == NULL)
return 0.0f;
@@ -5433,11 +5514,11 @@ void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing)
uint8 level = getLevel();
uint32 pclass = getClass();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
+ if (level >= sGtChanceToMeleeCritStore.GetTableRowCount())
+ level = sGtChanceToMeleeCritStore.GetTableRowCount() - 1;
// Dodge per agility is proportional to crit per agility, which is available from DBC files
- GtChanceToMeleeCritEntry const* dodgeRatio = sGtChanceToMeleeCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
+ GtChanceToMeleeCritEntry const* dodgeRatio = sGtChanceToMeleeCritStore.EvaluateTable(level - 1, pclass - 1);
if (dodgeRatio == NULL || pclass > MAX_CLASSES)
return;
@@ -5455,11 +5536,11 @@ float Player::GetSpellCritFromIntellect()
uint8 level = getLevel();
uint32 pclass = getClass();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
+ if (level >= sGtChanceToSpellCritStore.GetTableRowCount())
+ level = sGtChanceToSpellCritStore.GetTableRowCount() - 1;
- GtChanceToSpellCritBaseEntry const* critBase = sGtChanceToSpellCritBaseStore.LookupEntry(pclass - 1);
- GtChanceToSpellCritEntry const* critRatio = sGtChanceToSpellCritStore.LookupEntry((pclass - 1) * GT_MAX_LEVEL + level - 1);
+ GtChanceToSpellCritBaseEntry const* critBase = sGtChanceToSpellCritBaseStore.EvaluateTable(pclass - 1, 0);
+ GtChanceToSpellCritEntry const* critRatio = sGtChanceToSpellCritStore.EvaluateTable(level - 1, pclass - 1);
if (critBase == NULL || critRatio == NULL)
return 0.0f;
@@ -5471,12 +5552,12 @@ float Player::GetRatingMultiplier(CombatRating cr) const
{
uint8 level = getLevel();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
+ if (level >= sGtCombatRatingsStore.GetTableRowCount())
+ level = sGtCombatRatingsStore.GetTableRowCount() - 1;
- GtCombatRatingsEntry const* Rating = sGtCombatRatingsStore.LookupEntry(cr*GT_MAX_LEVEL+level-1);
+ GtCombatRatingsEntry const* Rating = sGtCombatRatingsStore.EvaluateTable(level - 1, cr);
// gtOCTClassCombatRatingScalarStore.dbc starts with 1, CombatRating with zero, so cr+1
- GtOCTClassCombatRatingScalarEntry const* classRating = sGtOCTClassCombatRatingScalarStore.LookupEntry((getClass()-1)*GT_MAX_RATING+cr+1);
+ GtOCTClassCombatRatingScalarEntry const* classRating = sGtOCTClassCombatRatingScalarStore.EvaluateTable(cr + 1, getClass() - 1);
if (!Rating || !classRating)
return 1.0f; // By default use minimum coefficient (not must be called)
@@ -5510,11 +5591,10 @@ float Player::OCTRegenMPPerSpirit()
uint8 level = getLevel();
uint32 pclass = getClass();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
+ if (level >= sGtRegenMPPerSptStore.GetTableRowCount())
+ level = sGtRegenMPPerSptStore.GetTableRowCount() - 1;
-// GtOCTRegenMPEntry const* baseRatio = sGtOCTRegenMPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- GtRegenMPPerSptEntry const* moreRatio = sGtRegenMPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
+ GtRegenMPPerSptEntry const* moreRatio = sGtRegenMPPerSptStore.EvaluateTable(level - 1, pclass - 1);
if (moreRatio == NULL)
return 0.0f;
@@ -6203,20 +6283,20 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const
void Player::SendActionButtons(uint32 state) const
{
- WorldPackets::Spell::UpdateActionButtons packet;
+ WorldPackets::Spells::UpdateActionButtons packet;
for (uint8 button = 0; button < MAX_ACTION_BUTTONS; ++button)
{
ActionButtonList::const_iterator itr = m_actionButtons.find(button);
if (itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED)
- packet.ActionButtons[button] = uint32(itr->second.packedData);
+ packet.ActionButtons[button] = uint64(itr->second.packedData);
else
packet.ActionButtons[button] = 0;
}
packet.Reason = state;
- GetSession()->SendPacket(packet.Write());
+ SendDirectMessage(packet.Write());
TC_LOG_INFO("network", "Action Buttons for '%s' group '%u' Sent", GetGUID().ToString().c_str(), GetActiveTalentGroup());
}
@@ -6346,7 +6426,7 @@ void Player::SaveRecallPosition()
m_recallO = GetOrientation();
}
-void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self)
+void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self)
{
if (self)
GetSession()->SendPacket(data);
@@ -6355,7 +6435,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self)
VisitNearbyWorldObject(dist, notifier);
}
-void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only)
+void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only)
{
if (self)
GetSession()->SendPacket(data);
@@ -6364,7 +6444,7 @@ void Player::SendMessageToSetInRange(WorldPacket* data, float dist, bool self, b
VisitNearbyWorldObject(dist, notifier);
}
-void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
+void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr)
{
if (skipped_rcvr != this)
GetSession()->SendPacket(data);
@@ -6375,7 +6455,7 @@ void Player::SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr)
VisitNearbyWorldObject(GetVisibilityRange(), notifier);
}
-void Player::SendDirectMessage(WorldPacket const* data)
+void Player::SendDirectMessage(WorldPacket const* data) const
{
m_session->SendPacket(data);
}
@@ -8263,7 +8343,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
}
// not allow proc extra attack spell at extra attack
- if (m_extraAttacks && spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (m_extraAttacks && spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return;
float chance = (float)spellInfo->ProcChance;
@@ -9494,6 +9574,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
data << uint32(4131) << uint32(0); // 10 WORLDSTATE_ALGALON_DESPAWN_TIMER
}
break;
+ // Halls of Refection
+ case 4820:
+ if (instance && mapid == 668)
+ instance->FillInitialWorldStates(data);
+ else
+ {
+ data << uint32(4884) << uint32(0); // 9 WORLD_STATE_HOR_WAVES_ENABLED
+ data << uint32(4882) << uint32(0); // 10 WORLD_STATE_HOR_WAVE_COUNT
+ }
+ break;
// Zul Aman
case 3805:
if (instance && mapid == 568)
@@ -9528,20 +9618,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
// Wintergrasp
case 4197:
if (bf && bf->GetTypeId() == BATTLEFIELD_WG)
- {
bf->FillInitialWorldStates(data);
- break;
- }
- // Halls of Refection
- case 4820:
- if (instance && mapid == 668)
- instance->FillInitialWorldStates(data);
- else
- {
- data << uint32(4884) << uint32(0); // 9 WORLD_STATE_HOR_WAVES_ENABLED
- data << uint32(4882) << uint32(0); // 10 WORLD_STATE_HOR_WAVE_COUNT
- }
- break;
// No break here, intended.
default:
data << uint32(0x914) << uint32(0x0); // 7
@@ -15127,7 +15204,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
if (quest->GetRewSpellCast() > 0)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpellCast());
- if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM))
+ if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM))
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpellCast(), true);
@@ -15138,7 +15215,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else if (quest->GetRewSpell() > 0)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(quest->GetRewSpell());
- if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(SPELL_EFFECT_CREATE_ITEM))
+ if (questGiver->isType(TYPEMASK_UNIT) && !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_LEARN_SPELL) && !spellInfo->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_CREATE_ITEM))
{
if (Creature* creature = GetMap()->GetCreature(questGiver->GetGUID()))
creature->CastSpell(this, quest->GetRewSpell(), true);
@@ -16744,28 +16821,26 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result)
if (!result)
return;
- uint32 count = 0;
do
{
Field* fields = result->Fetch();
- EquipmentSet eqSet;
+ EquipmentSetInfo eqSet;
- eqSet.Guid = fields[0].GetUInt64();
- uint8 index = fields[1].GetUInt8();
- eqSet.Name = fields[2].GetString();
- eqSet.IconName = fields[3].GetString();
- eqSet.IgnoreMask = fields[4].GetUInt32();
- eqSet.state = EQUIPMENT_SET_UNCHANGED;
+ eqSet.Data.Guid = fields[0].GetUInt64();
+ eqSet.Data.SetID = fields[1].GetUInt8();
+ eqSet.Data.SetName = fields[2].GetString();
+ eqSet.Data.SetIcon = fields[3].GetString();
+ eqSet.Data.IgnoreMask = fields[4].GetUInt32();
+ eqSet.State = EQUIPMENT_SET_UNCHANGED;
for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
- eqSet.Items[i] = fields[5 + i].GetUInt64();
-
- m_EquipmentSets[index] = eqSet;
+ if (ObjectGuid::LowType guid = fields[5 + i].GetUInt64())
+ eqSet.Data.Pieces[i] = ObjectGuid::Create<HighGuid::Item>(guid);
- ++count;
+ if (eqSet.Data.SetID >= MAX_EQUIPMENT_SET_INDEX) // client limit
+ continue;
- if (count >= MAX_EQUIPMENT_SET_INDEX) // client limit
- break;
+ _equipmentSets[eqSet.Data.SetID] = eqSet;
}
while (result->NextRow());
}
@@ -16830,6 +16905,17 @@ void Player::SetHomebind(WorldLocation const& loc, uint32 areaId)
CharacterDatabase.Execute(stmt);
}
+void Player::SendBindPointUpdate()
+{
+ WorldPackets::Misc::BindPointUpdate packet;
+ packet.BindPosition.x = m_homebindX;
+ packet.BindPosition.y = m_homebindY;
+ packet.BindPosition.z = m_homebindZ;
+ packet.BindMapID = m_homebindMapId;
+ packet.BindAreaID = m_homebindAreaId;
+ SendDirectMessage(packet.Write());
+}
+
uint32 Player::GetUInt32ValueFromArray(Tokenizer const& data, uint16 index)
{
if (index >= data.size())
@@ -16919,12 +17005,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
return false;
}
- // overwrite some data fields
- uint32 bytes0 = 0;
- bytes0 |= fields[3].GetUInt8(); // race
- bytes0 |= fields[4].GetUInt8() << 8; // class
- bytes0 |= gender << 16; // gender
- SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE, fields[3].GetUInt8());
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, fields[4].GetUInt8());
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender);
// check if race/class combination is valid
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
@@ -16996,10 +17079,10 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F;
if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY)
- dungeonDiff = DUNGEON_DIFFICULTY_NORMAL;
+ dungeonDiff = DIFFICULTY_NORMAL;
uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F;
if (raidDiff >= MAX_RAID_DIFFICULTY)
- raidDiff = RAID_DIFFICULTY_10MAN_NORMAL;
+ raidDiff = DIFFICULTY_10_N;
SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup
SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup
@@ -17390,13 +17473,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
if (i >= talentSpecs.size())
break;
- uint32 talentSpec = atol(talentSpecs[i]);
- if (sChrSpecializationStore.LookupEntry(talentSpec))
- SetTalentSpec(i, talentSpec);
- else
- SetAtLoginFlag(AT_LOGIN_RESET_TALENTS);
+ uint32 talentSpec = atoul(talentSpecs[i]);
+ if (talentSpec)
+ {
+ if (sChrSpecializationStore.LookupEntry(talentSpec))
+ SetTalentSpec(i, talentSpec);
+ else
+ SetAtLoginFlag(AT_LOGIN_RESET_TALENTS);
+ }
}
+ SetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID, GetActiveTalentSpec());
+
_LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
_LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS));
@@ -17810,7 +17898,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
Field* fields = result->Fetch();
if (Item* item = _LoadItem(trans, zoneId, timeDiff, fields))
{
- ObjectGuid bagGuid = ObjectGuid::Create<HighGuid::Item>(fields[11].GetUInt64());
+ ObjectGuid bagGuid = fields[11].GetUInt64() ? ObjectGuid::Create<HighGuid::Item>(fields[11].GetUInt64()) : ObjectGuid::Empty;
uint8 slot = fields[12].GetUInt8();
uint8 err = EQUIP_ERR_OK;
@@ -18462,6 +18550,13 @@ void Player::_LoadSpells(PreparedQueryResult result)
AddSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool(), true);
while (result->NextRow());
}
+
+ std::list<uint32> learnList = GetSpellsForLevels(getClass(), getRaceMask(), GetActiveTalentSpec(), 0, getLevel());
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
+ {
+ if (!HasSpell(*iter))
+ LearnSpell(*iter, true);
+ }
}
void Player::_LoadGroup(PreparedQueryResult result)
@@ -18710,7 +18805,7 @@ void Player::SendRaidInfo()
if (itr->second.perm)
{
InstanceSave* save = itr->second.save;
- bool isHeroic = save->GetDifficulty() == RAID_DIFFICULTY_10MAN_HEROIC || save->GetDifficulty() == RAID_DIFFICULTY_25MAN_HEROIC;
+ bool isHeroic = save->GetDifficulty() == DIFFICULTY_10_HC || save->GetDifficulty() == DIFFICULTY_25_HC;
uint32 completedEncounters = 0;
if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId()))
if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript())
@@ -20173,7 +20268,7 @@ void Player::ResetInstances(uint8 method, bool isRaid)
if (method == INSTANCE_RESET_ALL)
{
// the "reset all instances" method can only reset normal maps
- if (entry->IsRaid() || diff == DUNGEON_DIFFICULTY_HEROIC)
+ if (entry->IsRaid() || diff == DIFFICULTY_HEROIC)
{
++itr;
continue;
@@ -20416,9 +20511,9 @@ void Player::Say(std::string const& text, Language language, WorldObject const*
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SAY, language, this, this, _text);
+ SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
}
void Player::Yell(std::string const& text, Language language, WorldObject const* /*= nullptr*/)
@@ -20426,9 +20521,9 @@ void Player::Yell(std::string const& text, Language language, WorldObject const*
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_YELL, language, this, this, _text);
+ SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true);
}
void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/, bool /*= false*/)
@@ -20436,9 +20531,9 @@ void Player::TextEmote(std::string const& text, WorldObject const* /*= nullptr*/
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
- SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT));
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
+ SendMessageToSetInRange(packet.Write(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT));
}
void Player::WhisperAddon(std::string const& text, const std::string& prefix, Player* receiver)
@@ -20449,9 +20544,9 @@ void Player::WhisperAddon(std::string const& text, const std::string& prefix, Pl
if (!receiver->GetSession()->IsAddonRegistered(prefix))
return;
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix);
- receiver->GetSession()->SendPacket(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, LANG_ADDON, this, this, text, 0, "", DEFAULT_LOCALE, prefix);
+ receiver->SendDirectMessage(packet.Write());
}
void Player::Whisper(std::string const& text, Language language, Player* target, bool /*= false*/)
@@ -20466,16 +20561,16 @@ void Player::Whisper(std::string const& text, Language language, Player* target,
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text);
- target->GetSession()->SendPacket(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER, Language(language), this, this, _text);
+ target->SendDirectMessage(packet.Write());
// rest stuff shouldn't happen in case of addon message
if (isAddonMessage)
return;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text);
- GetSession()->SendPacket(&data);
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text);
+ SendDirectMessage(packet.Write());
if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster())
{
@@ -20791,15 +20886,18 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
TC_LOG_DEBUG("spells", "Player::AddSpellMod %d", mod->spellId);
OpcodeServer opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
+ WorldPackets::Spells::SetSpellModifier packet(opcode);
+
int i = 0;
- flag96 _mask;
- uint32 modTypeCount = 0; // count of mods per one mod->op
- WorldPacket data(opcode);
- data << uint32(1); // count of different mod->op's in packet
- size_t writePos = data.wpos();
- data << uint32(modTypeCount);
- data << uint8(mod->op);
- for (int eff = 0; eff < 96; ++eff)
+ flag128 _mask;
+
+ /// @todo Implement sending of bulk modifiers instead of single
+ packet.Modifiers.resize(1);
+ WorldPackets::Spells::SpellModifier& spellMod = packet.Modifiers[0];
+
+ spellMod.ModIndex = mod->op;
+
+ for (int eff = 0; eff < 128; ++eff)
{
if (eff != 0 && (eff % 32) == 0)
_mask[i++] = 0;
@@ -20807,19 +20905,24 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
_mask[i] = uint32(1) << (eff - (32 * i));
if (mod->mask & _mask)
{
- int32 val = 0;
+ WorldPackets::Spells::SpellModifierData modData;
+
for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr)
if ((*itr)->type == mod->type && (*itr)->mask & _mask)
- val += (*itr)->value;
- val += apply ? mod->value : -(mod->value);
+ modData.ModifierValue += (*itr)->value;
+
+ modData.ModifierValue += apply ? mod->value : -(mod->value);
+ if (mod->type == SPELLMOD_PCT)
+ modData.ModifierValue = 1.0f + (modData.ModifierValue * 0.01f);
- data << uint8(eff);
- data << float(val);
- ++modTypeCount;
+ modData.ClassIndex = eff;
+
+ spellMod.ModifierData.push_back(modData);
}
}
- data.put<uint32>(writePos, modTypeCount);
- SendDirectMessage(&data);
+
+ SendDirectMessage(packet.Write());
+
if (apply)
m_spellMods[mod->op].push_back(mod);
else
@@ -20965,9 +21068,10 @@ void Player::SetSpellModTakingSpell(Spell* spell, bool apply)
// send Proficiency
void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
{
- WorldPacket data(SMSG_SET_PROFICIENCY, 1 + 4);
- data << uint8(itemClass) << uint32(itemSubclassMask);
- GetSession()->SendPacket(&data);
+ WorldPackets::Item::SetProficiency packet;
+ packet.ProficiencyMask = itemSubclassMask;
+ packet.ProficiencyClass = itemClass;
+ SendDirectMessage(packet.Write());
}
void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type)
@@ -21371,12 +21475,7 @@ void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
if (itr->second->state == PLAYERSPELL_REMOVED)
continue;
uint32 unSpellId = itr->first;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
- if (!spellInfo)
- {
- ASSERT(spellInfo);
- continue;
- }
+ SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(unSpellId);
// Not send cooldown for this spells
if (spellInfo->IsCooldownStartedOnEvent())
@@ -22781,6 +22880,10 @@ template void Player::UpdateVisibilityOf(AreaTrigger* target, UpdateData& data
void Player::UpdateObjectVisibility(bool forced)
{
+ // Prevent updating visibility if player is not in world (example: LoadFromDB sets drunkstate which updates invisibility while player is not in map)
+ if (!IsInWorld())
+ return;
+
if (!forced)
AddToNotify(NOTIFY_VISIBILITY_CHANGED);
else
@@ -22970,67 +23073,67 @@ void Player::SendInitialPacketsBeforeAddToMap()
/// Pass 'this' as argument because we're not stored in ObjectAccessor yet
GetSocial()->SendSocialList(this);
- // guild bank list wtf?
-
+ /// SMSG_SPELL_CATEGORY_COOLDOWN
GetSession()->SendSpellCategoryCooldowns();
- // Homebind
- WorldPacket data(SMSG_BINDPOINTUPDATE, 5*4);
- data << m_homebindX << m_homebindY << m_homebindZ;
- data << (uint32) m_homebindMapId;
- data << (uint32) m_homebindAreaId;
- GetSession()->SendPacket(&data);
+ /// SMSG_BINDPOINTUPDATE
+ SendBindPointUpdate();
// SMSG_SET_PROFICIENCY
// SMSG_SET_PCT_SPELL_MODIFIER
// SMSG_SET_FLAT_SPELL_MODIFIER
- // SMSG_UPDATE_AURA_DURATION
+ /// SMSG_TALENTS_INFO
SendTalentsInfoData();
-
- data.Initialize(SMSG_WORLD_SERVER_INFO, 1 + 1 + 4 + 4);
- data.WriteBit(0); // HasRestrictedLevel
- data.WriteBit(0); // HasRestrictedMoney
- data.WriteBit(0); // IneligibleForLoot
- data.FlushBits();
- //if (IneligibleForLoot)
- // data << uint32(0); // EncounterMask
-
- data << uint8(0); // IsOnTournamentRealm
- //if (HasRestrictedMoney)
- // data << uint32(100000); // RestrictedMoney (starter accounts)
- //if (HasRestrictedLevel)
- // data << uint32(20); // RestrictedLevel (starter accounts)
-
- data << uint32(sWorld->GetNextWeeklyQuestsResetTime() - WEEK); // LastWeeklyReset (not instance reset)
- data << uint32(GetMap()->GetDifficulty());
- GetSession()->SendPacket(&data);
-
+ /// SMSG_INITIAL_SPELLS
SendKnownSpells();
- WorldPackets::Spell::SendUnlearnSpells packet;
- GetSession()->SendPacket(packet.Write());
+ /// SMSG_SEND_UNLEARN_SPELLS
+ SendDirectMessage(WorldPackets::Spells::SendUnlearnSpells().Write());
+ /// @todo: SMSG_SEND_SPELL_HISTORY
+ /// @todo: SMSG_SEND_SPELL_CHARGES
+
+ /// SMSG_ACTION_BUTTONS
SendInitialActionButtons();
- m_reputationMgr->SendInitialReputations();
- m_achievementMgr->SendAllAchievementData(this);
+ /// SMSG_INITIALIZE_FACTIONS
+ m_reputationMgr->SendInitialReputations();
+ /// SMSG_SET_FORCED_REACTIONS
+ m_reputationMgr->SendForceReactions();
+ /// SMSG_INIT_CURRENCY
+ SendCurrencies();
+ /// SMSG_EQUIPMENT_SET_LIST
SendEquipmentSetList();
- data.Initialize(SMSG_LOGIN_SETTIMESPEED, 4 + 4 + 4);
- data.AppendPackedTime(sWorld->GetGameTime());
- data << float(0.01666667f); // game speed
- data << uint32(0); // added in 3.1.2
- GetSession()->SendPacket(&data);
+ m_achievementMgr->SendAllAchievementData(this);
- GetReputationMgr().SendForceReactions(); // SMSG_SET_FORCED_REACTIONS
+ /// SMSG_LOGIN_SETTIMESPEED
+ static float const TimeSpeed = 0.01666667f;
+ WorldPackets::Misc::LoginSetTimeSpeed loginSetTimeSpeed;
+ loginSetTimeSpeed.NewSpeed = TimeSpeed;
+ loginSetTimeSpeed.GameTime = sWorld->GetGameTime();
+ loginSetTimeSpeed.ServerTime = sWorld->GetGameTime();
+ loginSetTimeSpeed.GameTimeHolidayOffset = 0; /// @todo
+ loginSetTimeSpeed.ServerTimeHolidayOffset = 0; /// @todo
+ SendDirectMessage(loginSetTimeSpeed.Write());
+
+ /// SMSG_WORLD_SERVER_INFO
+ WorldPackets::Misc::WorldServerInfo worldServerInfo;
+ worldServerInfo.IneligibleForLootMask.Clear(); /// @todo
+ worldServerInfo.WeeklyReset = sWorld->GetNextWeeklyQuestsResetTime() - WEEK;
+ worldServerInfo.InstanceGroupSize.Clear(); /// @todo
+ worldServerInfo.IsTournamentRealm = 0; /// @todo
+ worldServerInfo.RestrictedAccountMaxLevel.Clear(); /// @todo
+ worldServerInfo.RestrictedAccountMaxMoney.Clear(); /// @todo
+ worldServerInfo.DifficultyID = GetMap()->GetDifficulty();
+ SendDirectMessage(worldServerInfo.Write());
// SMSG_TALENTS_INFO x 2 for pet (unspent points and talents in separate packets...)
// SMSG_PET_GUIDS
// SMSG_UPDATE_WORLD_STATE
// SMSG_POWER_UPDATE
- SendCurrencies();
SetMover(this);
}
@@ -23105,11 +23208,11 @@ void Player::SendUpdateToOutOfRangeGroupMembers()
void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 arg)
{
- WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);
- data << uint32(mapid);
- data << uint8(reason); // transfer abort reason
- data << uint8(arg);
- GetSession()->SendPacket(&data);
+ WorldPackets::Movement::TransferAborted transferAborted;
+ transferAborted.MapID = mapid;
+ transferAborted.Arg = arg;
+ transferAborted.TransfertAbort = reason;
+ GetSession()->SendPacket(transferAborted.Write());
}
void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time)
@@ -23256,7 +23359,6 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
if (!rcInfo)
return;
- TC_LOG_DEBUG("entities.player.loading", "PLAYER (Class: %u Race: %u): Adding initial skill, id = %u", uint32(getClass()), uint32(getRace()), skillId);
switch (GetSkillRangeType(rcInfo))
{
case SKILL_RANGE_LANGUAGE:
@@ -23302,6 +23404,7 @@ void Player::LearnDefaultSkill(uint32 skillId, uint16 rank)
}
}
+
void Player::LearnQuestRewardedSpells(Quest const* quest)
{
int32 spell_id = quest->GetRewSpellCast();
@@ -23324,9 +23427,9 @@ void Player::LearnQuestRewardedSpells(Quest const* quest)
// check learned spells state
bool found = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL && !HasSpell(spellInfo->Effects[i].TriggerSpell))
+ if (effect && effect->Effect == SPELL_EFFECT_LEARN_SPELL && !HasSpell(effect->TriggerSpell))
{
found = true;
break;
@@ -23337,8 +23440,12 @@ void Player::LearnQuestRewardedSpells(Quest const* quest)
if (!found)
return;
+ SpellEffectInfo const* effect = spellInfo->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (!effect)
+ return;
+
// prevent learn non first rank unknown profession and second specialization for same profession)
- uint32 learned_0 = spellInfo->Effects[0].TriggerSpell;
+ uint32 learned_0 = effect->TriggerSpell;
if (sSpellMgr->GetSpellRank(learned_0) > 1 && !HasSpell(learned_0))
{
SpellInfo const* learnedInfo = sSpellMgr->GetSpellInfo(learned_0);
@@ -23354,8 +23461,15 @@ void Player::LearnQuestRewardedSpells(Quest const* quest)
{
uint32 profSpell = itr2->second;
+ SpellEffectInfo const* effect0 = learnedInfo->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (!effect0)
+ continue;
+ SpellEffectInfo const* effect1 = learnedInfo->GetEffect(DIFFICULTY_NONE, EFFECT_1);
+ if (!effect1)
+ continue;
+
// specialization
- if (learnedInfo->Effects[0].Effect == SPELL_EFFECT_TRADE_SKILL && learnedInfo->Effects[1].Effect == 0 && profSpell)
+ if (effect0->Effect == SPELL_EFFECT_TRADE_SKILL && effect1->Effect == 0 && profSpell)
{
// search other specialization for same prof
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
@@ -23367,8 +23481,16 @@ void Player::LearnQuestRewardedSpells(Quest const* quest)
if (!itrInfo)
return;
+
+ SpellEffectInfo const* itrEffect0 = itrInfo->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (!itrEffect0)
+ continue;
+ SpellEffectInfo const* itrEffect1 = itrInfo->GetEffect(DIFFICULTY_NONE, EFFECT_1);
+ if (!itrEffect1)
+ continue;
+
// compare only specializations
- if (itrInfo->Effects[0].Effect != SPELL_EFFECT_TRADE_SKILL || itrInfo->Effects[1].Effect != 0)
+ if (itrEffect0->Effect != SPELL_EFFECT_TRADE_SKILL || itrEffect1->Effect != 0)
continue;
// compare same chain spells
@@ -23405,7 +23527,8 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
if (!ability || ability->SkillLine != skillId)
continue;
- if (!sSpellMgr->GetSpellInfo(ability->SpellID))
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(ability->SpellID);
+ if (!spellInfo)
continue;
if (ability->AquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE && ability->AquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
@@ -23419,6 +23542,10 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue)
if (ability->ClassMask && !(ability->ClassMask & classMask))
continue;
+ // check level, skip class spells if not high enough
+ if (getLevel() < spellInfo->SpellLevel)
+ continue;
+
// need unlearn spell
if (skillValue < ability->MinSkillLineRank && ability->AquireMethod == SKILL_LINE_ABILITY_LEARNED_ON_SKILL_VALUE)
RemoveSpell(ability->SpellID);
@@ -23447,17 +23574,18 @@ void Player::SendAurasForTarget(Unit* target)
if (target->HasAuraType(SPELL_AURA_HOVER))
target->SetHover(true, true);
- WorldPacket data(SMSG_AURA_UPDATE_ALL);
- data << target->GetPackGUID();
-
Unit::VisibleAuraMap const* visibleAuras = target->GetVisibleAuras();
+
+ WorldPackets::Spells::SendAuraUpdate update;
+ update.Init(true, GetGUID(), visibleAuras->size());
+
for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
{
AuraApplication * auraApp = itr->second;
- auraApp->BuildUpdatePacket(data, false);
+ update.BuildUpdatePacket(auraApp, false, getLevel()); // TODO 6.x should be caster's level
}
- GetSession()->SendPacket(&data);
+ GetSession()->SendPacket(const_cast<WorldPacket*>(update.Write()));
}
void Player::SetDailyQuestStatus(uint32 quest_id)
@@ -24676,8 +24804,8 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
{
uint8 level = getLevel();
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL; // max level in this dbc
+ if (level >= sGtBarberShopCostBaseStore.GetTableRowCount())
+ level = sGtBarberShopCostBaseStore.GetTableRowCount() - 1;
uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2);
uint8 haircolor = GetByteValue(PLAYER_BYTES, 3);
@@ -24687,7 +24815,7 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
if ((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair) && (!newSkin || (newSkin->Data == skincolor)))
return 0;
- GtBarberShopCostBaseEntry const* bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1);
+ GtBarberShopCostBaseEntry const* bsc = sGtBarberShopCostBaseStore.EvaluateTable(level - 1, 0);
if (!bsc) // shouldn't happen
return 0xFFFFFFFF;
@@ -25416,37 +25544,36 @@ void Player::CompletedAchievement(AchievementEntry const* entry)
bool Player::LearnTalent(uint32 talentId)
{
- uint8 group = GetActiveTalentGroup();
-
- // check if talent specialization is learnt
- if (!GetTalentSpec(group))
- return false;
-
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
if (!talentInfo)
return false;
+ uint32 maxTalentTier = GetUInt32Value(PLAYER_FIELD_MAX_TALENT_TIERS);
+
// prevent learn talent for different class (cheating)
- if (getClass() != talentInfo->ClassID)
+ if (talentInfo->ClassID != getClass())
return false;
- // Check player level
- // TODO: fix level requirements for deathknights
- uint8 levelReq = std::min(15*talentInfo->TierID + 15, sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
- if (getLevel() < levelReq)
+ // check if we have enough talent points
+ if (talentInfo->TierID > maxTalentTier)
return false;
- // Check if such tier talent hasn't been picked already
- TalentGroupInfo* talentGroupInfo = GetTalentGroupInfo(group);
- if (talentGroupInfo->Talents[talentInfo->TierID])
- return false;
+ // Check if player doesnt have any spell in selected collumn
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++)
+ {
+ if (TalentEntry const* talent = sTalentStore.LookupEntry(i))
+ {
+ if (talentInfo->TierID == talent->TierID && HasSpell(talent->SpellID))
+ return false;
+ }
+ }
// spell not set in talent.dbc
uint32 spellid = talentInfo->SpellID;
if (spellid == 0)
{
- TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u spell id = 0", talentId);
+ TC_LOG_ERROR("entities.player", "Talent.dbc has no spellInfo for talent: %u (spell id = 0)", talentId);
return false;
}
@@ -25454,54 +25581,64 @@ bool Player::LearnTalent(uint32 talentId)
if (HasSpell(spellid))
return false;
- // Check talent spec
- if (talentInfo->SpecID != GetTalentSpec(group))
+ if (!AddTalent(talentId, GetActiveTalentGroup(), true))
return false;
- // learn! (other talent ranks will unlearned at learning)
LearnSpell(spellid, false);
- AddTalent(talentId, group);
- TC_LOG_INFO("misc", "TalentID: %u Spell: %u Group: %u\n", talentId, spellid, group);
+ TC_LOG_INFO("misc", "TalentID: %u Spell: %u Group: %u\n", talentId, spellid, GetActiveTalentGroup());
return true;
}
void Player::LearnTalentSpecialization(uint32 talentSpec)
{
+ if (GetActiveTalentSpec())
+ return;
+
SetTalentSpec(GetActiveTalentGroup(), talentSpec);
- // Replace default spells by specialization spells
- auto specSpells = sSpecializationSpellsBySpecStore.find(talentSpec);
- if (specSpells != sSpecializationSpellsBySpecStore.end())
+ SetUInt32Value(PLAYER_FIELD_CURRENT_SPEC_ID, talentSpec);
+
+ PlayerTalentMap* talents = GetTalentMap(GetActiveTalentGroup());
+
+ for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
{
- for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
- {
- SpecializationSpellsEntry const* specSpell = *it;
+ TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
- // Unlearn spell if it is replaced by new specialization
- if (specSpell->OverridesSpellID)
- RemoveSpell(specSpell->OverridesSpellID, true);
+ if (!talentInfo || talentInfo->ClassID != getClass() || talentInfo->SpecID != talentSpec)
+ continue;
- // Learn new spell
- if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(specSpell->SpellID))
- if (spellInfo->BaseLevel <= getLevel())
- LearnSpell(specSpell->SpellID, false);
+ for (PlayerTalentMap::iterator itr = talents->begin(); itr != talents->end();)
+ {
+ TalentEntry const* talent = sTalentStore.LookupEntry(itr->first);
+ if (!talent || talent->TierID != talentInfo->TierID)
+ {
+ ++itr;
+ continue;
+ }
+ RemoveSpell(talent->SpellID, false);
+ itr = talents->erase(itr);
+
+ TC_LOG_DEBUG("spells", "Player %s unlearning talent id: %u tier: %u due to specialization change", GetName().c_str(), talent->ID, talent->TierID);
}
}
- if (CanUseMastery())
+ SendTalentsInfoData();
+
+ std::list<uint32> learnList = GetSpellsForLevels(0, getRaceMask(), GetActiveTalentSpec(), 0, getLevel());
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
{
- ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(talentSpec);
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(chrSpec->MasterySpellID[i]))
- if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell))
- CastSpell(this, masterySpell->Id, true);
+ if (!HasSpell(*iter))
+ LearnSpell(*iter, true);
}
-
+
+ SaveToDB();
+
SendTalentsInfoData();
}
+
void Player::AddKnownCurrency(uint32 itemId)
{
if (CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId))
@@ -25586,28 +25723,44 @@ void Player::SendTalentsInfoData()
for (uint8 i = 0; i < groupsCount; ++i)
{
- TalentGroupInfo* groupInfo = GetTalentGroupInfo(i);
WorldPackets::Talent::TalentGroupInfo groupInfoPkt;
- groupInfoPkt.SpecID = groupInfo->SpecID;
+ groupInfoPkt.SpecID = GetTalentSpec(i);
- groupInfoPkt.TalentIDs.reserve(MAX_TALENT_TIERS);
- for (uint32 x = 0; x < MAX_TALENT_TIERS; ++x)
+ groupInfoPkt.TalentIDs.reserve(GetTalentMap(i)->size());
+
+ for (PlayerTalentMap::const_iterator itr = GetTalentMap(i)->begin(); itr != GetTalentMap(i)->end(); ++itr)
{
- // Do not send empty talents
- if (!groupInfo->Talents[x])
- break;
+ TalentEntry const* talentInfo = sTalentStore.LookupEntry(itr->first);
+ if (!talentInfo)
+ {
+ TC_LOG_ERROR("entities.player", "Player %s has unknown talent id: %u", GetName().c_str(), itr->first);
+ continue;
+ }
+
+ if (talentInfo->ClassID != getClass())
+ continue;
+
+ SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
+ if (!spellEntry)
+ {
+ TC_LOG_ERROR("entities.player", "Player %s has unknown talent spell: %u", GetName().c_str(), talentInfo->SpellID);
+ continue;
+ }
- groupInfoPkt.TalentIDs.push_back(groupInfo->Talents[x]);
+ if (!HasTalent(itr->first, i))
+ continue;
+
+ groupInfoPkt.TalentIDs.push_back(uint16(itr->first));
}
for (uint32 x = 0; x < MAX_GLYPH_SLOT_INDEX; ++x)
- groupInfoPkt.GlyphIDs[x] = groupInfo->Glyphs[x];
+ groupInfoPkt.GlyphIDs[x] = uint16(GetGlyph(i, x));
packet.Info.TalentGroups.push_back(groupInfoPkt);
}
- GetSession()->SendPacket(packet.Write());
+ SendDirectMessage(packet.Write());
}
void Player::BuildEnchantmentsInfoData(WorldPacket* data)
@@ -25655,122 +25808,100 @@ void Player::BuildEnchantmentsInfoData(WorldPacket* data)
void Player::SendEquipmentSetList()
{
- ObjectGuid ignoredItemGuid;
- ignoredItemGuid.SetRawValue(0, 1);
- uint32 count = 0;
- WorldPacket data(SMSG_EQUIPMENT_SET_LIST, 4);
- size_t count_pos = data.wpos();
- data << uint32(count); // count placeholder
- for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
+ WorldPackets::EquipmentSet::LoadEquipmentSet data;
+
+ for (EquipmentSetContainer::value_type const& eqSet : _equipmentSets)
{
- if (itr->second.state == EQUIPMENT_SET_DELETED)
+ if (eqSet.second.State == EQUIPMENT_SET_DELETED)
continue;
- data.AppendPackedUInt64(itr->second.Guid);
- data << uint32(itr->first);
- data << itr->second.Name;
- data << itr->second.IconName;
- for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
- {
- // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HIGHGUID_ITEM
- if (itr->second.IgnoreMask & (1 << i))
- data << ignoredItemGuid;
- else
- data << ObjectGuid::Create<HighGuid::Item>(itr->second.Items[i]);
- }
- ++count; // client have limit but it checked at loading and set
+ data.SetData.push_back(&eqSet.second.Data);
}
- data.put<uint32>(count_pos, count);
- GetSession()->SendPacket(&data);
+
+ SendDirectMessage(data.Write());
}
-void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
+void Player::SetEquipmentSet(EquipmentSetInfo::EquipmentSetData&& newEqSet)
{
- if (eqset.Guid != 0)
+ if (newEqSet.Guid != 0)
{
- bool found = false;
-
- for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
- {
- if ((itr->second.Guid == eqset.Guid) && (itr->first == index))
- {
- found = true;
- break;
- }
- }
-
- if (!found) // something wrong...
+ // something wrong...
+ EquipmentSetContainer::const_iterator itr = _equipmentSets.find(newEqSet.SetID);
+ if (itr == _equipmentSets.end() || itr->second.Data.Guid != newEqSet.Guid)
{
- TC_LOG_ERROR("entities.player", "Player %s tried to save equipment set " UI64FMTD " (index %u), but that equipment set not found!", GetName().c_str(), eqset.Guid, index);
+ TC_LOG_ERROR("entities.player", "Player %s tried to save equipment set " UI64FMTD " (index: %u), but that equipment set not found!", GetName().c_str(), newEqSet.Guid, newEqSet.SetID);
return;
}
}
- EquipmentSet& eqslot = m_EquipmentSets[index];
+ EquipmentSetInfo& eqSlot = _equipmentSets[newEqSet.SetID];
- EquipmentSetUpdateState old_state = eqslot.state;
+ EquipmentSetUpdateState oldState = eqSlot.State;
- eqslot = eqset;
+ eqSlot.Data = newEqSet;
- if (eqset.Guid == 0)
+ if (eqSlot.Data.Guid == 0)
{
- eqslot.Guid = sObjectMgr->GenerateEquipmentSetGuid();
+ eqSlot.Data.Guid = sObjectMgr->GenerateEquipmentSetGuid();
- WorldPacket data(SMSG_EQUIPMENT_SET_SAVED, 4 + 1);
- data << uint32(index);
- data.AppendPackedUInt64(eqslot.Guid);
- GetSession()->SendPacket(&data);
+ WorldPackets::EquipmentSet::EquipmentSetID data;
+ data.GUID = eqSlot.Data.Guid;
+ data.SetID = eqSlot.Data.SetID;
+ SendDirectMessage(data.Write());
}
- eqslot.state = old_state == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED;
+ eqSlot.State = oldState == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED;
}
void Player::_SaveEquipmentSets(SQLTransaction& trans)
{
- for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();)
+ for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();)
{
- uint32 index = itr->first;
- EquipmentSet& eqset = itr->second;
- PreparedStatement* stmt = NULL;
+ EquipmentSetInfo& eqSet = itr->second;
+ PreparedStatement* stmt = nullptr;
uint8 j = 0;
- switch (eqset.state)
+ switch (eqSet.State)
{
case EQUIPMENT_SET_UNCHANGED:
++itr;
break; // nothing do
case EQUIPMENT_SET_CHANGED:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_EQUIP_SET);
- stmt->setString(j++, eqset.Name.c_str());
- stmt->setString(j++, eqset.IconName.c_str());
- stmt->setUInt32(j++, eqset.IgnoreMask);
- for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i)
- stmt->setUInt64(j++, eqset.Items[i]);
+ stmt->setString(j++, eqSet.Data.SetName);
+ stmt->setString(j++, eqSet.Data.SetIcon);
+ stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
+
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter());
+
stmt->setUInt64(j++, GetGUID().GetCounter());
- stmt->setUInt64(j++, eqset.Guid);
- stmt->setUInt32(j, index);
+ stmt->setUInt64(j++, eqSet.Data.Guid);
+ stmt->setUInt32(j, eqSet.Data.SetID);
trans->Append(stmt);
- eqset.state = EQUIPMENT_SET_UNCHANGED;
+ eqSet.State = EQUIPMENT_SET_UNCHANGED;
++itr;
break;
case EQUIPMENT_SET_NEW:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_EQUIP_SET);
stmt->setUInt64(j++, GetGUID().GetCounter());
- stmt->setUInt64(j++, eqset.Guid);
- stmt->setUInt32(j++, index);
- stmt->setString(j++, eqset.Name.c_str());
- stmt->setString(j++, eqset.IconName.c_str());
- stmt->setUInt32(j++, eqset.IgnoreMask);
- for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i)
- stmt->setUInt64(j++, eqset.Items[i]);
+ stmt->setUInt64(j++, eqSet.Data.Guid);
+ stmt->setUInt32(j++, eqSet.Data.SetID);
+ stmt->setString(j++, eqSet.Data.SetName);
+ stmt->setString(j++, eqSet.Data.SetIcon);
+ stmt->setUInt32(j++, eqSet.Data.IgnoreMask);
+
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ stmt->setUInt64(j++, eqSet.Data.Pieces[i].GetCounter());
+
trans->Append(stmt);
- eqset.state = EQUIPMENT_SET_UNCHANGED;
+ eqSet.State = EQUIPMENT_SET_UNCHANGED;
++itr;
break;
case EQUIPMENT_SET_DELETED:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EQUIP_SET);
- stmt->setUInt64(0, eqset.Guid);
+ stmt->setUInt64(0, eqSet.Data.Guid);
trans->Append(stmt);
- m_EquipmentSets.erase(itr++);
+ itr = _equipmentSets.erase(itr);
break;
}
}
@@ -25799,16 +25930,17 @@ void Player::_SaveBGData(SQLTransaction& trans)
void Player::DeleteEquipmentSet(uint64 setGuid)
{
- for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr)
+ for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();)
{
- if (itr->second.Guid == setGuid)
+ if (itr->second.Data.Guid == setGuid)
{
- if (itr->second.state == EQUIPMENT_SET_NEW)
- m_EquipmentSets.erase(itr);
+ if (itr->second.State == EQUIPMENT_SET_NEW)
+ itr = _equipmentSets.erase(itr);
else
- itr->second.state = EQUIPMENT_SET_DELETED;
+ itr->second.State = EQUIPMENT_SET_DELETED;
break;
}
+ ++itr;
}
}
@@ -25935,7 +26067,7 @@ void Player::_LoadTalents(PreparedQueryResult result)
if (result)
{
do
- AddTalent((*result)[0].GetUInt32(), (*result)[1].GetUInt8());
+ AddTalent((*result)[0].GetUInt32(), (*result)[1].GetUInt8(), false);
while (result->NextRow());
}
}
@@ -25948,17 +26080,12 @@ void Player::_SaveTalents(SQLTransaction& trans)
for (uint8 group = 0; group < MAX_TALENT_GROUPS; ++group)
{
- TalentGroupInfo* talentGroupInfo = GetTalentGroupInfo(group);
-
- for (uint32 tier = 0; tier < MAX_TALENT_TIERS; ++tier)
+ for (PlayerTalentMap::iterator itr = GetTalentMap(group)->begin(); itr != GetTalentMap(group)->end(); ++itr)
{
- if (!talentGroupInfo->Talents[tier])
- continue;
-
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_TALENT);
stmt->setUInt64(0, GetGUID().GetCounter());
- stmt->setUInt32(1, talentGroupInfo->Talents[tier]);
- stmt->setUInt8(2, group);
+ stmt->setUInt32(1, itr->first);
+ stmt->setUInt8(2, itr->second->spec);
trans->Append(stmt);
}
}
@@ -26057,30 +26184,27 @@ void Player::ActivateTalentGroup(uint8 group)
if (getClass() != talentInfo->ClassID)
continue;
+ SpellInfo const* spellEntry = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
+ if (!spellEntry)
+ continue;
+
RemoveSpell(talentInfo->SpellID, true);
+
+ // search for spells that the talent teaches and unlearn them
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ if (effect && effect->TriggerSpell > 0 && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
+ RemoveSpell(effect->TriggerSpell, true);
}
// Unlearn specialization specific spells
- auto specSpells = sSpecializationSpellsBySpecStore.find(GetActiveTalentSpec());
- if (specSpells != sSpecializationSpellsBySpecStore.end())
+ std::list<uint32> learnList = GetSpellsForLevels(0, getRaceMask(), GetActiveTalentSpec(), 0, getLevel());
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
{
- for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
- {
- SpecializationSpellsEntry const* specSpell = *it;
- if (HasSpell(specSpell->SpellID)) {
- RemoveSpell(specSpell->SpellID, true);
- LearnSpell(specSpell->OverridesSpellID, false);
- }
- }
+ if (HasSpell(*iter))
+ RemoveSpell(*iter, true);
}
- // Unlearn mastery spells
- ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetActiveTalentSpec());
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (chrSpec->MasterySpellID[i])
- RemoveSpell(chrSpec->MasterySpellID[i], true);
-
- // set glyphs
+ // remove glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
// remove secondary glyph
if (uint32 oldglyph = GetGlyph(GetActiveTalentGroup(), slot))
@@ -26090,6 +26214,15 @@ void Player::ActivateTalentGroup(uint8 group)
// Activate new group
SetActiveTalentGroup(group);
+ uint32 spentTalents = 0;
+
+ learnList = GetSpellsForLevels(getClass(), getRaceMask(), GetActiveTalentSpec(), 0, getLevel());
+ for (std::list<uint32>::const_iterator iter = learnList.begin(); iter != learnList.end(); iter++)
+ {
+ if (!HasSpell(*iter))
+ LearnSpell(*iter, true);
+ }
+
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
{
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
@@ -26101,31 +26234,12 @@ void Player::ActivateTalentGroup(uint8 group)
if (getClass() != talentInfo->ClassID)
continue;
- LearnSpell(talentInfo->SpellID, false);
- }
+ ++spentTalents;
- // Replace default spells with specialization specific spells
- auto newSpecSpells = sSpecializationSpellsBySpecStore.find(GetActiveTalentSpec());
- if (newSpecSpells != sSpecializationSpellsBySpecStore.end())
- {
- for (auto it = newSpecSpells->second.begin(); it != newSpecSpells->second.end(); ++it)
- {
- SpecializationSpellsEntry const* specSpell = *it;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(specSpell->SpellID);
- if (getLevel() >= spellInfo->BaseLevel) {
- if (specSpell->OverridesSpellID)
- RemoveSpell(specSpell->OverridesSpellID, true);
- LearnSpell(specSpell->SpellID, false);
- }
- }
+ if (HasTalent(talentInfo->SpellID, group))
+ LearnSpell(talentInfo->SpellID, false);
}
- if (CanUseMastery())
- if (ChrSpecializationEntry const* newChrSpec = sChrSpecializationStore.LookupEntry(GetActiveTalentSpec()))
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (newChrSpec->MasterySpellID[i])
- LearnSpell(newChrSpec->MasterySpellID[i], false);
-
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
{
@@ -26139,6 +26253,7 @@ void Player::ActivateTalentGroup(uint8 group)
SetGlyph(slot, glyph);
}
+ SetUsedTalentCount(spentTalents);
InitTalentForLevel();
{
@@ -26158,7 +26273,9 @@ void Player::ActivateTalentGroup(uint8 group)
SetPower(pw, 0);
if (!sChrSpecializationStore.LookupEntry(GetActiveTalentSpec()))
+ {
ResetTalents(true);
+ }
}
void Player::ResetTimeSync()
@@ -26174,7 +26291,7 @@ void Player::SendTimeSync()
WorldPackets::Misc::TimeSyncRequest packet;
packet.SequenceIndex = m_timeSyncQueue.back();
- GetSession()->SendPacket(packet.Write());
+ SendDirectMessage(packet.Write());
// Schedule next sync in 10 sec
m_timeSyncTimer = 10000;
@@ -26742,7 +26859,13 @@ std::string Player::GetCoordsMapAreaAndZoneString()
Guild* Player::GetGuild()
{
ObjectGuid::LowType guildId = GetGuildId();
- return guildId ? sGuildMgr->GetGuildById(guildId) : NULL;
+ return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr;
+}
+
+Guild const* Player::GetGuild() const
+{
+ ObjectGuid::LowType guildId = GetGuildId();
+ return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr;
}
Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration)
@@ -26812,7 +26935,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
case SUMMON_PET:
// this enables pet details window (Shift+P)
pet->GetCharmInfo()->SetPetNumber(pet_number, true);
- pet->SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
+ pet->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, CLASS_MAGE);
pet->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
pet->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
pet->SetFullHealth();
@@ -27192,3 +27315,9 @@ void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell)
data << uint32(newSpell) << uint32(oldSpell);
GetSession()->SendPacket(&data);
}
+
+uint32 Player::CalculateTalentsPoints() const
+{
+ // 1 talent point for every 15 levels
+ return getLevel() >= 100 ? 7 : uint32(floor(getLevel() / 15.f));
+}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1dd993e5b5f..6b9e925e28d 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -116,6 +116,12 @@ struct PlayerSpell
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
};
+struct PlayerTalent
+{
+ PlayerSpellState state : 8;
+ uint8 spec : 8;
+};
+
extern uint32 const MasterySpells[MAX_CLASSES];
enum TalentSpecialization // talent tabs
@@ -184,6 +190,7 @@ struct PlayerCurrency
uint32 weekCount;
};
+typedef std::unordered_map<uint32, PlayerTalent*> PlayerTalentMap;
typedef std::unordered_map<uint32, PlayerSpell*> PlayerSpellMap;
typedef std::list<SpellModifier*> SpellModList;
typedef std::unordered_map<uint32, PlayerCurrency> PlayerCurrenciesMap;
@@ -329,7 +336,7 @@ enum ReputationSource
};
#define ACTION_BUTTON_ACTION(X) (uint64(X) & 0x00000000FFFFFFFF)
-#define ACTION_BUTTON_TYPE(X) ((uint64(X) & 0xFFFFFFFF00000000) >> 32)
+#define ACTION_BUTTON_TYPE(X) ((uint64(X) & 0xFFFFFFFF00000000) >> 56)
#define MAX_ACTION_BUTTON_ACTION_VALUE (0xFFFFFFFF)
struct ActionButton
@@ -344,7 +351,7 @@ struct ActionButton
uint32 GetAction() const { return ACTION_BUTTON_ACTION(packedData); }
void SetActionAndType(uint32 action, ActionButtonType type)
{
- uint64 newData = uint64(action) | (uint64(type) << 32);
+ uint64 newData = uint64(action) | (uint64(type) << 56);
if (newData != packedData || uState == ACTIONBUTTON_DELETED)
{
packedData = newData;
@@ -747,24 +754,26 @@ enum EquipmentSetUpdateState
EQUIPMENT_SET_DELETED = 3
};
-struct EquipmentSet
+struct EquipmentSetInfo
{
- EquipmentSet() : Guid(0), IgnoreMask(0), state(EQUIPMENT_SET_NEW)
+ /// Data sent in EquipmentSet related packets
+ struct EquipmentSetData
{
- memset(Items, 0, sizeof(Items));
- }
+ uint64 Guid = 0; ///< Set Identifier
+ uint32 SetID = 0; ///< Index
+ uint32 IgnoreMask = 0; ///< Mask of EquipmentSlot
+ std::string SetName;
+ std::string SetIcon;
+ ObjectGuid Pieces[EQUIPMENT_SLOT_END];
+ } Data;
- uint64 Guid;
- std::string Name;
- std::string IconName;
- uint32 IgnoreMask;
- ObjectGuid::LowType Items[EQUIPMENT_SLOT_END];
- EquipmentSetUpdateState state;
+ /// Server-side data
+ EquipmentSetUpdateState State = EQUIPMENT_SET_NEW;
};
#define MAX_EQUIPMENT_SET_INDEX 10 // client limit
-typedef std::map<uint32, EquipmentSet> EquipmentSets;
+typedef std::map<uint32, EquipmentSetInfo> EquipmentSetContainer;
struct ItemPosCount
{
@@ -785,24 +794,45 @@ enum TradeSlots
enum TransferAbortReason
{
- TRANSFER_ABORT_NONE = 0x00,
- TRANSFER_ABORT_ERROR = 0x01,
- TRANSFER_ABORT_MAX_PLAYERS = 0x02, // Transfer Aborted: instance is full
- TRANSFER_ABORT_NOT_FOUND = 0x03, // Transfer Aborted: instance not found
- TRANSFER_ABORT_TOO_MANY_INSTANCES = 0x04, // You have entered too many instances recently.
- TRANSFER_ABORT_ZONE_IN_COMBAT = 0x06, // Unable to zone in while an encounter is in progress.
- TRANSFER_ABORT_INSUF_EXPAN_LVL = 0x07, // You must have <TBC, WotLK> expansion installed to access this area.
- TRANSFER_ABORT_DIFFICULTY = 0x08, // <Normal, Heroic, Epic> difficulty mode is not available for %s.
- TRANSFER_ABORT_UNIQUE_MESSAGE = 0x09, // Until you've escaped TLK's grasp, you cannot leave this place!
- TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x0A, // Additional instances cannot be launched, please try again later.
- TRANSFER_ABORT_NEED_GROUP = 0x0B, // 3.1
- TRANSFER_ABORT_NOT_FOUND1 = 0x0C, // 3.1
- TRANSFER_ABORT_NOT_FOUND2 = 0x0D, // 3.1
- TRANSFER_ABORT_NOT_FOUND3 = 0x0E, // 3.2
- TRANSFER_ABORT_REALM_ONLY = 0x0F, // All players on party must be from the same realm.
- TRANSFER_ABORT_MAP_NOT_ALLOWED = 0x10, // Map can't be entered at this time.
- TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 0x12, // 4.2.2
- TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 0x13 // 4.2.2
+ TRANSFER_ABORT_NONE = 0,
+ TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 1, // Additional instances cannot be launched, please try again later.
+ TRANSFER_ABORT_DIFFICULTY = 3, // <Normal, Heroic, Epic> difficulty mode is not available for %s.
+ TRANSFER_ABORT_INSUF_EXPAN_LVL = 8, // You must have <TBC, WotLK> expansion installed to access this area.
+ TRANSFER_ABORT_NOT_FOUND = 10, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_TOO_MANY_INSTANCES = 11, // You have entered too many instances recently.
+ TRANSFER_ABORT_MAX_PLAYERS = 12, // Transfer Aborted: instance is full
+ TRANSFER_ABORT_XREALM_ZONE_DOWN = 14, // Transfer Aborted: cross-realm zone is down
+ TRANSFER_ABORT_NOT_FOUND_2 = 15, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_DIFFICULTY_NOT_FOUND = 16, // client writes to console "Unable to resolve requested difficultyID %u to actual difficulty for map %d"
+ TRANSFER_ABORT_NOT_FOUND_3 = 17, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_NOT_FOUND_4 = 18, // Transfer Aborted: instance not found
+ TRANSFER_ABORT_ZONE_IN_COMBAT = 19, // Unable to zone in while an encounter is in progress.
+ TRANSFER_ABORT_ALREADY_COMPLETED_ENCOUNTER = 20, // You are ineligible to participate in at least one encounter in this instance because you are already locked to an instance in which it has been defeated.
+ TRANSFER_ABORT_LOCKED_TO_DIFFERENT_INSTANCE = 24, // You are already locked to %s
+ TRANSFER_ABORT_REALM_ONLY = 25, // All players in the party must be from the same realm to enter %s.
+ TRANSFER_ABORT_MAP_NOT_ALLOWED = 27, // Map cannot be entered at this time.
+ TRANSFER_ABORT_SOLO_PLAYER_SWITCH_DIFFICULTY = 28, // This instance is already in progress. You may only switch difficulties from inside the instance.
+ TRANSFER_ABORT_NEED_GROUP = 29, // Transfer Aborted: you must be in a raid group to enter this instance
+ TRANSFER_ABORT_UNIQUE_MESSAGE = 30, // Until you've escaped TLK's grasp, you cannot leave this place!
+ TRANSFER_ABORT_ERROR = 31,
+ /*
+ // Unknown values - not used by the client to display any error
+ TRANSFER_ABORT_MANY_REALM_INSTANCES
+ TRANSFER_ABORT_AREA_NOT_ZONED
+ TRANSFER_ABORT_TIMEOUT
+ TRANSFER_ABORT_SHUTTING_DOWN
+ TRANSFER_ABORT_PLAYER_CONDITION
+ TRANSFER_ABORT_BUSY
+ TRANSFER_ABORT_DISCONNECTED
+ TRANSFER_ABORT_LOGGING_OUT
+ TRANSFER_ABORT_NEED_SERVER
+ */
+};
+
+enum NewWorldReason
+{
+ NEW_WORLD_NORMAL = 16, // Normal map change
+ NEW_WORLD_SEAMLESS = 21, // Teleport to another map without a loading screen, used for outdoor scenarios
};
enum InstanceResetWarningType
@@ -858,18 +888,6 @@ enum EnviromentalDamage
DAMAGE_FALL_TO_VOID = 6 // custom case for fall without durability loss
};
-enum PlayerChatTag
-{
- CHAT_TAG_NONE = 0x00,
- CHAT_TAG_AFK = 0x01,
- CHAT_TAG_DND = 0x02,
- CHAT_TAG_GM = 0x04,
- CHAT_TAG_COM = 0x08, // Commentator
- CHAT_TAG_DEV = 0x10,
- CHAT_TAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper
- CHAT_TAG_MOBILE = 0x40
-};
-
enum PlayedTimeIndex
{
PLAYED_TIME_TOTAL = 0,
@@ -1212,48 +1230,36 @@ private:
bool _isPvP;
};
-struct TalentGroupInfo
+struct PlayerTalentInfo
{
- uint32 Talents[MAX_TALENT_TIERS];
- uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
- uint32 SpecID;
-
- bool HasTalent(uint32 talentId)
+ PlayerTalentInfo() : UsedTalentCount(0), ResetTalentsCost(0), ResetTalentsTime(0), ActiveGroup(0), GroupsCount(1)
{
- for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i)
- if (Talents[i] == talentId)
- return true;
- return false;
- }
-
- uint32 TalentCount()
- {
- for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i)
- if (!Talents[i])
- return i;
- return MAX_TALENT_TIERS;
- }
-
- void Reset()
- {
- for (uint32 i = 0; i < MAX_TALENT_TIERS; ++i)
- Talents[i] = 0;
+ for (uint8 i = 0; i < MAX_TALENT_GROUPS; ++i)
+ {
+ GroupInfo[i].Talents = new PlayerTalentMap();
+ memset(GroupInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
+ GroupInfo[i].TalentTree = 0;
+ }
}
-};
-struct PlayerTalentInfo
-{
- PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), ActiveGroup(0), GroupsCount(1)
+ ~PlayerTalentInfo()
{
for (uint8 i = 0; i < MAX_TALENT_GROUPS; ++i)
{
- memset(GroupInfo[i].Talents, 0, sizeof(uint32)*MAX_TALENT_TIERS);
- memset(GroupInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
- GroupInfo[i].SpecID = 0;
+ for (PlayerTalentMap::const_iterator itr = GroupInfo[i].Talents->begin(); itr != GroupInfo[i].Talents->end(); ++itr)
+ delete itr->second;
+ delete GroupInfo[i].Talents;
}
}
- TalentGroupInfo GroupInfo[MAX_TALENT_GROUPS];
+ struct TalentGroupInfo
+ {
+ PlayerTalentMap* Talents;
+ uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
+ uint32 TalentTree;
+ } GroupInfo[MAX_TALENT_GROUPS];
+
+ uint32 UsedTalentCount;
uint32 ResetTalentsCost;
time_t ResetTalentsTime;
uint8 ActiveGroup;
@@ -1314,7 +1320,7 @@ class Player : public Unit, public GridObject<Player>
void ToggleDND();
bool isAFK() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_AFK); }
bool isDND() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DND); }
- uint8 GetChatTag() const;
+ uint8 GetChatFlags() const;
std::string autoReplyMsg;
uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair, BarberShopStyleEntry const* newSkin=NULL);
@@ -1747,8 +1753,8 @@ class Player : public Unit, public GridObject<Player>
Unit* GetSelectedUnit() const;
Player* GetSelectedPlayer() const;
- void SetTarget(ObjectGuid /*guid*/) override { } /// Used for serverside target changes, does not apply to players
- void SetSelection(ObjectGuid guid) { SetGuidValue(UNIT_FIELD_TARGET, guid); }
+ void SetTarget(ObjectGuid const& /*guid*/) override { } /// Used for serverside target changes, does not apply to players
+ void SetSelection(ObjectGuid const& guid) { SetGuidValue(UNIT_FIELD_TARGET, guid); }
uint8 GetComboPoints() const { return m_comboPoints; }
ObjectGuid GetComboTarget() const { return m_comboTarget; }
@@ -1822,25 +1828,35 @@ class Player : public Unit, public GridObject<Player>
std::string GetGuildName();
// Talents
+ uint32 GetUsedTalentCount() const { return _talentMgr->UsedTalentCount; }
+ void SetUsedTalentCount(uint32 talents) { _talentMgr->UsedTalentCount = talents; }
uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; }
void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; }
uint32 GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; }
void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; }
- uint8 GetActiveTalentGroup() const { return _talentMgr->ActiveGroup; }
- void SetActiveTalentGroup(uint8 group){ _talentMgr->ActiveGroup = group; }
+
uint8 GetTalentGroupsCount() const { return _talentMgr->GroupsCount; }
void SetTalentGroupsCount(uint8 count) { _talentMgr->GroupsCount = count; }
- uint32 GetTalentSpec(uint8 group) const { return _talentMgr->GroupInfo[group].SpecID; }
- void SetTalentSpec(uint8 group, uint32 talentSpec) const { _talentMgr->GroupInfo[group].SpecID = talentSpec; }
- uint32 GetActiveTalentSpec() const { return _talentMgr->GroupInfo[_talentMgr->ActiveGroup].SpecID; }
+ uint8 GetActiveTalentGroup() const { return _talentMgr->ActiveGroup; }
+ void SetActiveTalentGroup(uint8 group){ _talentMgr->ActiveGroup = group; }
+
+ uint32 GetTalentSpec(uint8 group) const { return _talentMgr->GroupInfo[group].TalentTree; }
+ void SetTalentSpec(uint8 group, uint32 talentSpec) const { _talentMgr->GroupInfo[group].TalentTree = talentSpec; }
+ uint32 GetActiveTalentSpec() const { return _talentMgr->GroupInfo[_talentMgr->ActiveGroup].TalentTree; }
+
+
+ bool ResetTalents(bool noCost = false, bool resetTalents = true, bool resetSpecialization = true);
+ bool RemoveTalent(uint32 talentId);
- bool ResetTalents(bool no_cost = false);
uint32 GetNextResetTalentsCost() const;
void InitTalentForLevel();
void SendTalentsInfoData();
bool LearnTalent(uint32 talentId);
- bool AddTalent(uint32 talentId, uint8 spec);
+ bool AddTalent(uint32 talentId, uint8 spec, bool learning);
bool HasTalent(uint32 talentId, uint8 spec);
+ uint32 CalculateTalentsPoints() const;
+
+
void LearnTalentSpecialization(uint32 talentSpec);
// Dual Spec
@@ -1854,7 +1870,8 @@ class Player : public Unit, public GridObject<Player>
void SetGlyph(uint8 slot, uint32 glyph);
uint32 GetGlyph(uint8 group, uint8 slot) const { return _talentMgr->GroupInfo[group].Glyphs[slot]; }
- TalentGroupInfo* GetTalentGroupInfo(uint8 group) { return &_talentMgr->GroupInfo[group]; }
+ PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->GroupInfo[spec].Talents; }
+ PlayerTalentMap* GetTalentMap(uint8 spec) { return _talentMgr->GroupInfo[spec].Talents; }
ActionButtonList const& GetActionButtons() const { return m_actionButtons; }
uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); }
@@ -1968,6 +1985,7 @@ class Player : public Unit, public GridObject<Player>
void SetGuildIdInvited(ObjectGuid::LowType GuildId) { m_GuildIdInvited = GuildId; }
ObjectGuid::LowType GetGuildId() const { return GetUInt64Value(OBJECT_FIELD_DATA); /* return only lower part */ }
Guild* GetGuild();
+ Guild const* GetGuild() const;
static ObjectGuid::LowType GetGuildIdFromDB(ObjectGuid guid);
static uint8 GetRankFromDB(ObjectGuid guid);
ObjectGuid::LowType GetGuildIdInvited() { return m_GuildIdInvited; }
@@ -2089,10 +2107,10 @@ class Player : public Unit, public GridObject<Player>
bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); }
void UpdateUnderwaterState(Map* m, float x, float y, float z) override;
- void SendMessageToSet(WorldPacket* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet
- void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange
- void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only);
- void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) override;
+ void SendMessageToSet(WorldPacket const* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); };// overwrite Object::SendMessageToSet
+ void SendMessageToSetInRange(WorldPacket const* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange
+ void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only);
+ void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) override;
Corpse* GetCorpse() const;
void SpawnCorpseBones();
@@ -2240,12 +2258,12 @@ class Player : public Unit, public GridObject<Player>
void CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 procVictim, uint32 procEx, Item* item, ItemTemplate const* proto);
void SendEquipmentSetList();
- void SetEquipmentSet(uint32 index, EquipmentSet eqset);
+ void SetEquipmentSet(EquipmentSetInfo::EquipmentSetData&& newEqSet);
void DeleteEquipmentSet(uint64 setGuid);
void SendInitWorldStates(uint32 zone, uint32 area);
void SendUpdateWorldState(uint32 variable, uint32 value, bool hidden = false);
- void SendDirectMessage(WorldPacket const* data);
+ void SendDirectMessage(WorldPacket const* data) const;
void SendBGWeekendWorldStates();
void SendBattlefieldWorldStates();
@@ -2379,6 +2397,7 @@ class Player : public Unit, public GridObject<Player>
void SaveRecallPosition();
void SetHomebind(WorldLocation const& loc, uint32 areaId);
+ void SendBindPointUpdate();
// Homebind coordinates
uint32 m_homebindMapId;
@@ -2852,7 +2871,7 @@ class Player : public Unit, public GridObject<Player>
DeclinedName *m_declinedname;
Runes *m_runes;
- EquipmentSets m_EquipmentSets;
+ EquipmentSetContainer _equipmentSets;
bool CanAlwaysSee(WorldObject const* obj) const override;
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 54956e591b4..d6aeb5dee9c 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -145,9 +145,10 @@ bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) con
/// @todo possibly all negative auras immune?
if (GetEntry() == 5925)
return false;
-
- switch (spellInfo->Effects[index].ApplyAuraName)
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), index))
{
+ switch (effect->ApplyAuraName)
+ {
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_MOD_FEAR:
@@ -155,7 +156,10 @@ bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) con
return true;
default:
break;
+ }
}
+ else
+ return true;
return Creature::IsImmunedToSpellEffect(spellInfo, index);
}
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index ea15daed587..5761fac56e2 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -258,7 +258,7 @@ float Player::GetHealthBonusFromStamina()
{
// Taken from PaperDollFrame.lua - 4.3.4.15595
float ratio = 10.0f;
- if (gtOCTHpPerStaminaEntry const* hpBase = sGtOCTHpPerStaminaStore.LookupEntry((getClass() - 1) * GT_MAX_LEVEL + getLevel() - 1))
+ if (gtOCTHpPerStaminaEntry const* hpBase = sGtOCTHpPerStaminaStore.EvaluateTable(getLevel() - 1, 0))
ratio = hpBase->ratio;
float stamina = GetStat(STAT_STAMINA);
@@ -537,16 +537,16 @@ void Player::UpdateMastery()
if (Aura* aura = GetAura(chrSpec->MasterySpellID[i]))
{
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : aura->GetSpellEffectInfos())
{
- if (!aura->HasEffect(j))
+ if (!effect)
continue;
- float mult = aura->GetSpellInfo()->Effects[j].BonusCoefficient;
+ float mult = effect->BonusCoefficient;
if (G3D::fuzzyEq(mult, 0.0f))
continue;
- aura->GetEffect(j)->ChangeAmount(int32(value * aura->GetSpellInfo()->Effects[j].BonusCoefficient));
+ aura->GetEffect(effect->EffectIndex)->ChangeAmount(int32(value * effect->BonusCoefficient));
}
}
}
@@ -989,8 +989,9 @@ bool Guardian::UpdateStats(Stats stat)
AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0);
if (aurEff)
{
- SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value
- AddPct(mod, spellInfo->Effects[EFFECT_1].CalcValue(owner)); // Ravenous Dead edits the original scale
+ SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), EFFECT_1))
+ AddPct(mod, effect->CalcValue(owner)); // Ravenous Dead edits the original scale
}
// Glyph of the Ghoul
aurEff = owner->GetAuraEffect(58686, 0);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 89ded594990..be26299f6fd 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -62,6 +62,10 @@
#include "WorldPacket.h"
#include "MovementStructures.h"
#include "WorldSession.h"
+#include "ChatPackets.h"
+#include "MovementPackets.h"
+#include "CombatPackets.h"
+#include "CombatLogPackets.h"
#include <cmath>
@@ -935,23 +939,6 @@ void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castI
CastSpell(targets, spellInfo, NULL, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
}
-// Obsolete func need remove, here only for comotability vs another patches
-uint32 Unit::SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage)
-{
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellID);
- if (!spellInfo)
- return 0;
- SpellNonMeleeDamage damageInfo(this, victim, spellInfo->Id, spellInfo->SchoolMask);
- damage = SpellDamageBonusDone(victim, spellInfo, damage, SPELL_DIRECT_DAMAGE);
- damage = victim->SpellDamageBonusTaken(this, spellInfo, damage, SPELL_DIRECT_DAMAGE);
-
- CalculateSpellDamageTaken(&damageInfo, damage, spellInfo);
- DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
- SendSpellNonMeleeDamageLog(&damageInfo);
- DealSpellDamage(&damageInfo, true);
- return damageInfo.damage;
-}
-
void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType, bool crit)
{
if (damage < 0)
@@ -1383,8 +1370,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
if (Unit* caster = (*dmgShieldItr)->GetCaster())
{
- damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
- damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
+ damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetSpellEffectInfo());
+ damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetSpellEffectInfo());
}
// No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that
@@ -1409,10 +1396,10 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
void Unit::HandleEmoteCommand(uint32 anim_id)
{
- WorldPacket data(SMSG_EMOTE, 4 + 8);
- data << uint32(anim_id);
- data << GetGUID();
- SendMessageToSet(&data, true);
+ WorldPackets::Chat::Emote packet;
+ packet.Guid = GetGUID();
+ packet.EmoteID = anim_id;
+ SendMessageToSet(packet.Write(), true);
}
bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo, uint8 effIndex)
@@ -1427,10 +1414,10 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s
return false;
// bleeding effects are not reduced by armor
- if (effIndex != MAX_SPELL_EFFECTS)
+ if (SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), effIndex))
{
- if (spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
- spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
+ if (effect->ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE ||
+ effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
if (spellInfo->GetEffectMechanicMask(effIndex) & (1<<MECHANIC_BLEED))
return false;
}
@@ -1696,7 +1683,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
int32 manaReduction = currentAbsorb;
// lower absorb amount by talents
- if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].CalcValueMultiplier(absorbAurEff->GetCaster()))
+ if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster()))
manaReduction = int32(float(manaReduction) * manaMultiplier);
int32 manaTaken = -victim->ModifyPower(POWER_MANA, -manaReduction);
@@ -2108,24 +2095,24 @@ float Unit::CalculateLevelPenalty(SpellInfo const* spellProto) const
void Unit::SendMeleeAttackStart(Unit* victim)
{
- WorldPacket data(SMSG_ATTACKSTART, 8 + 8);
- data << GetGUID();
- data << victim->GetGUID();
- SendMessageToSet(&data, true);
+ WorldPackets::Combat::AttackStart packet;
+ packet.Attacker = GetGUID();
+ packet.Victim = victim->GetGUID();
+ SendMessageToSet(packet.Write(), true);
TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTART");
}
void Unit::SendMeleeAttackStop(Unit* victim)
{
- WorldPacket data(SMSG_ATTACKSTOP, (8+8+4));
- data << GetPackGUID();
+ WorldPackets::Combat::SAttackStop packet;
+ packet.Attacker = GetGUID();
if (victim)
- data << victim->GetPackGUID();
- else
- data << uint8(0);
+ {
+ packet.Victim = victim->GetGUID();
+ packet.Dead = victim->isDead();
+ }
- data << uint32(0); //! Can also take the value 0x01, which seems related to updating rotation
- SendMessageToSet(&data, true);
+ SendMessageToSet(packet.Write(), true);
TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP");
if (victim)
@@ -2166,12 +2153,12 @@ int32 Unit::GetMechanicResistChance(SpellInfo const* spellInfo) const
return 0;
int32 resistMech = 0;
- for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (!spellInfo->Effects[eff].IsEffect())
+ if (!effect || !effect->IsEffect())
break;
- int32 effectMech = spellInfo->GetEffectMechanic(eff);
+ int32 effectMech = spellInfo->GetEffectMechanic(effect->EffectIndex, GetMap()->GetDifficulty());
if (effectMech)
{
int32 temp = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effectMech);
@@ -2226,7 +2213,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
// Get effects mechanic and chance
for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
{
- int32 effect_mech = spellInfo->GetEffectMechanic(eff);
+ int32 effect_mech = spellInfo->GetEffectMechanic(eff, GetMap()->GetDifficulty());
if (effect_mech)
{
int32 temp = victim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MECHANIC_RESISTANCE, effect_mech);
@@ -2990,7 +2977,7 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
+Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= 0*/)
{
ASSERT(!casterGUID.IsEmpty() || caster);
@@ -3016,18 +3003,22 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8
return NULL;
// update basepoints with new values - effect amount will be recalculated in ModStackAmount
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : foundAura->GetSpellEffectInfos())
{
- if (!foundAura->HasEffect(i))
+ if (!effect)
+ continue;
+
+ AuraEffect const* eff = foundAura->GetEffect(effect->EffectIndex);
+ if (!eff)
continue;
int bp;
if (baseAmount)
- bp = *(baseAmount + i);
+ bp = *(baseAmount + effect->EffectIndex);
else
- bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
+ bp = effect->BasePoints;
- int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
+ int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(effect->EffectIndex)->m_baseAmount)); // todo 6.x review GetBaseAmount and GetCastItemGUID in this case
*oldBP = bp;
}
@@ -3087,7 +3078,7 @@ void Unit::_AddAura(UnitAura* aura, Unit* caster)
// creates aura application instance and registers it in lists
// aura application effects are handled separately to prevent aura list corruption
-AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask)
+AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask)
{
// can't apply aura on unit which is going to be deleted - to not create a memory leak
ASSERT(!m_cleanupDone);
@@ -3116,7 +3107,7 @@ AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask)
AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
}
- if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
+ if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty()))
m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
aura->_ApplyForTarget(this, caster, aurApp);
@@ -3137,7 +3128,7 @@ void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex)
// handles effects of aura application
// should be done after registering aura in lists
-void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
+void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask)
{
Aura* aura = aurApp->GetBase();
@@ -3147,7 +3138,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask)
return;
// Update target aura state flag
- if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
+ if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty()))
ModifyAuraState(aState, true);
if (aurApp->GetRemoveMode())
@@ -3202,7 +3193,7 @@ void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMo
}
bool auraStateFound = false;
- AuraStateType auraState = aura->GetSpellInfo()->GetAuraState();
+ AuraStateType auraState = aura->GetSpellInfo()->GetAuraState(GetMap()->GetDifficulty());
if (auraState)
{
bool canBreak = false;
@@ -3278,12 +3269,12 @@ void Unit::_RemoveNoStackAurasDueToAura(Aura* aura)
SpellInfo const* spellProto = aura->GetSpellInfo();
// passive spell special case (only non stackable with ranks)
- if (spellProto->IsPassiveStackableWithRanks())
+ if (spellProto->IsPassiveStackableWithRanks(GetMap()->GetDifficulty()))
return;
if (!IsHighestExclusiveAura(aura))
{
- if (!aura->GetSpellInfo()->IsAffectingArea())
+ if (!aura->GetSpellInfo()->IsAffectingArea(GetMap()->GetDifficulty()))
{
Unit* caster = aura->GetCaster();
if (caster && caster->GetTypeId() == TYPEID_PLAYER)
@@ -3343,7 +3334,7 @@ void Unit::RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode)
i = m_ownedAuras.begin();
}
-void Unit::RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID, uint8 reqEffMask, AuraRemoveMode removeMode)
+void Unit::RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode)
{
for (AuraMap::iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId);)
if (((itr->second->GetEffectMask() & reqEffMask) == reqEffMask) && (!casterGUID || itr->second->GetCasterGUID() == casterGUID))
@@ -3377,7 +3368,7 @@ void Unit::RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode)
ASSERT(false);
}
-Aura* Unit::GetOwnedAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, Aura* except) const
+Aura* Unit::GetOwnedAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask, Aura* except) const
{
AuraMapBounds range = m_ownedAuras.equal_range(spellId);
for (AuraMap::const_iterator itr = range.first; itr != range.second; ++itr)
@@ -3406,7 +3397,7 @@ void Unit::RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode)
aura->Remove(mode);
}
-void Unit::RemoveAura(uint32 spellId, ObjectGuid caster, uint8 reqEffMask, AuraRemoveMode removeMode)
+void Unit::RemoveAura(uint32 spellId, ObjectGuid caster, uint32 reqEffMask, AuraRemoveMode removeMode)
{
AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
@@ -3466,7 +3457,7 @@ void Unit::RemoveAura(Aura* aura, AuraRemoveMode mode)
RemoveAura(aurApp, mode);
}
-void Unit::RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID, uint8 reqEffMask, AuraRemoveMode removeMode)
+void Unit::RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode)
{
for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
@@ -3875,7 +3866,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type)
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
Aura const* aura = iter->second->GetBase();
- if (aura->GetSpellInfo()->HasAura(type))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type))
++iter;
else
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3884,7 +3875,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type)
for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
Aura* aura = iter->second;
- if (aura->GetSpellInfo()->HasAura(type))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type))
++iter;
else
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3896,7 +3887,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type1, AuraType type2)
for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
Aura const* aura = iter->second->GetBase();
- if (aura->GetSpellInfo()->HasAura(type1) || aura->GetSpellInfo()->HasAura(type2))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type2))
++iter;
else
_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -3905,7 +3896,7 @@ void Unit::RemoveAllAurasExceptType(AuraType type1, AuraType type2)
for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
Aura* aura = iter->second;
- if (aura->GetSpellInfo()->HasAura(type1) || aura->GetSpellInfo()->HasAura(type2))
+ if (aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type1) || aura->GetSpellInfo()->HasAura(GetMap()->GetDifficulty(), type2))
++iter;
else
RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
@@ -4005,7 +3996,7 @@ AuraEffect* Unit::GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8
return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);
}
-AuraApplication * Unit::GetAuraApplication(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, AuraApplication * except) const
+AuraApplication * Unit::GetAuraApplication(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask, AuraApplication * except) const
{
AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
for (; range.first != range.second; ++range.first)
@@ -4024,13 +4015,13 @@ AuraApplication * Unit::GetAuraApplication(uint32 spellId, ObjectGuid casterGUID
return NULL;
}
-Aura* Unit::GetAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask) const
+Aura* Unit::GetAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask) const
{
AuraApplication * aurApp = GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask);
return aurApp ? aurApp->GetBase() : NULL;
}
-AuraApplication * Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, AuraApplication* except) const
+AuraApplication * Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask, AuraApplication* except) const
{
uint32 rankSpell = sSpellMgr->GetFirstSpellInChain(spellId);
while (rankSpell)
@@ -4042,7 +4033,7 @@ AuraApplication * Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGu
return NULL;
}
-Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask) const
+Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask) const
{
AuraApplication * aurApp = GetAuraApplicationOfRankedSpell(spellId, casterGUID, itemCasterGUID, reqEffMask);
return aurApp ? aurApp->GetBase() : NULL;
@@ -4117,7 +4108,7 @@ uint32 Unit::GetAuraCount(uint32 spellId) const
return count;
}
-bool Unit::HasAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask) const
+bool Unit::HasAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint32 reqEffMask) const
{
if (GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask))
return true;
@@ -4196,9 +4187,9 @@ bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
if (spellInfo->Mechanic && (mechanicMask & (1 << spellInfo->Mechanic)))
return true;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (iter->second->HasEffect(i) && spellInfo->Effects[i].Effect && spellInfo->Effects[i].Mechanic)
- if (mechanicMask & (1 << spellInfo->Effects[i].Mechanic))
+ for (SpellEffectInfo const* effect : iter->second->GetBase()->GetSpellEffectInfos())
+ if (effect && effect->Effect && effect->Mechanic)
+ if (mechanicMask & (1 << effect->Mechanic))
return true;
}
@@ -4721,22 +4712,20 @@ void Unit::RemoveAllGameObjects()
void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage* log)
{
- WorldPacket data(SMSG_SPELLNONMELEEDAMAGELOG, (16+4+4+4+1+4+4+1+1+4+4+1)); // we guess size
- data << log->target->GetPackGUID();
- data << log->attacker->GetPackGUID();
- data << uint32(log->SpellID);
- data << uint32(log->damage); // damage amount
+ WorldPackets::CombatLog::SpellNonMeleeDamageLog packet;
+ packet.Me = log->target->GetGUID();
+ packet.CasterGUID = log->attacker->GetGUID();
+ packet.SpellID = log->SpellID;
+ packet.Damage = log->damage;
int32 overkill = log->damage - log->target->GetHealth();
- data << uint32(overkill > 0 ? overkill : 0); // overkill
- data << uint8 (log->schoolMask); // damage school
- data << uint32(log->absorb); // AbsorbedDamage
- data << uint32(log->resist); // resist
- data << uint8 (log->physicalLog); // if 1, then client show spell name (example: %s's ranged shot hit %s for %u school or %s suffers %u school damage from %s's spell_name
- data << uint8 (log->unused); // unused
- data << uint32(log->blocked); // blocked
- data << uint32(log->HitInfo);
- data << uint8 (0); // flag to use extend data
- SendMessageToSet(&data, true);
+ packet.Overkill = (overkill > 0 ? overkill : 0);
+ packet.SchoolMask = log->schoolMask;
+ packet.ShieldBlock = log->blocked;
+ packet.Resisted = log->resist;
+ packet.Absorbed = log->absorb;
+ packet.Periodic = false;
+ packet.Flags = log->HitInfo;
+ SendMessageToSet(packet.Write(), true);
}
void Unit::SendSpellNonMeleeDamageLog(Unit* target, uint32 SpellID, uint32 Damage, SpellSchoolMask damageSchoolMask, uint32 AbsorbedDamage, uint32 Resist, bool PhysicalDamage, uint32 Blocked, bool CriticalHit)
@@ -4848,67 +4837,26 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
{
TC_LOG_DEBUG("entities.unit", "WORLD: Sending SMSG_ATTACKERSTATEUPDATE");
- uint32 count = 1;
- size_t maxsize = 4+5+5+4+4+1+4+4+4+4+4+1+4+4+4+4+4*12;
- WorldPacket data(SMSG_ATTACKERSTATEUPDATE, maxsize); // we guess size
- data << uint32(damageInfo->HitInfo);
- data << damageInfo->attacker->GetPackGUID();
- data << damageInfo->target->GetPackGUID();
- data << uint32(damageInfo->damage); // Full damage
+ WorldPackets::Combat::AttackerStateUpdate packet;
+ packet.HitInfo = damageInfo->HitInfo;
+ packet.AttackerGUID = damageInfo->attacker->GetGUID();
+ packet.VictimGUID = damageInfo->target->GetGUID();
+ packet.Damage = damageInfo->damage;
int32 overkill = damageInfo->damage - damageInfo->target->GetHealth();
- data << uint32(overkill < 0 ? 0 : overkill); // Overkill
- data << uint8(count); // Sub damage count
+ packet.OverDamage = (overkill < 0 ? -1 : overkill);
- for (uint32 i = 0; i < count; ++i)
- {
- data << uint32(damageInfo->damageSchoolMask); // School of sub damage
- data << float(damageInfo->damage); // sub damage
- data << uint32(damageInfo->damage); // Sub Damage
- }
+ WorldPackets::Combat::SubDamage& subDmg = packet.SubDmg.Value;
+ subDmg.SchoolMask = damageInfo->damageSchoolMask; // School of sub damage
+ subDmg.FDamage = damageInfo->damage; // sub damage
+ subDmg.Damage = damageInfo->damage; // Sub Damage
+ subDmg.Absorbed = damageInfo->absorb;
+ subDmg.Resisted = damageInfo->resist;
+ packet.SubDmg.HasValue = true;
- if (damageInfo->HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB))
- {
- for (uint32 i = 0; i < count; ++i)
- data << uint32(damageInfo->absorb); // Absorb
- }
+ packet.VictimState = damageInfo->TargetState;
+ packet.BlockAmount = damageInfo->blocked_amount;
- if (damageInfo->HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST))
- {
- for (uint32 i = 0; i < count; ++i)
- data << uint32(damageInfo->resist); // Resist
- }
-
- data << uint8(damageInfo->TargetState);
- data << uint32(0); // Unknown attackerstate
- data << uint32(0); // Melee spellid
-
- if (damageInfo->HitInfo & HITINFO_BLOCK)
- data << uint32(damageInfo->blocked_amount);
-
- if (damageInfo->HitInfo & HITINFO_RAGE_GAIN)
- data << uint32(0);
-
- //! Probably used for debugging purposes, as it is not known to appear on retail servers
- if (damageInfo->HitInfo & HITINFO_UNK1)
- {
- data << uint32(0);
- data << float(0);
- data << float(0);
- data << float(0);
- data << float(0);
- data << float(0);
- data << float(0);
- data << float(0);
- data << float(0);
- for (uint8 i = 0; i < 2; ++i)
- {
- data << float(0);
- data << float(0);
- }
- data << uint32(0);
- }
-
- SendMessageToSet(&data, true);
+ SendMessageToSet(packet.Write(), true);
}
void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType*/, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount)
@@ -4926,133 +4874,6 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit* target, uint8 /*SwingType
SendAttackStateUpdate(&dmgInfo);
}
-bool Unit::HandleAuraProcOnPowerAmount(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 /*procEx*/, uint32 cooldown)
-{
- // Get triggered aura spell info
- SpellInfo const* auraSpellInfo = triggeredByAura->GetSpellInfo();
-
- // Get effect index used for the proc
- uint32 effIndex = triggeredByAura->GetEffIndex();
-
- // Power amount required to proc the spell
- int32 powerAmountRequired = triggeredByAura->GetAmount();
- // Power type required to proc
- Powers powerRequired = Powers(auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].MiscValue);
-
- // Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
-
- Unit* target = NULL;
- int32 basepoints0 = 0;
-
- Item* castItem = !triggeredByAura->GetBase()->GetCastItemGUID().IsEmpty() && GetTypeId() == TYPEID_PLAYER
- ? ToPlayer()->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
-
- /* Try handle unknown trigger spells or with invalid power amount or misc value
- if (sSpellMgr->GetSpellInfo(trigger_spell_id) == NULL || powerAmountRequired == NULL || powerRequired >= MAX_POWER)
- {
- switch (auraSpellInfo->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- {
- break;
- }
- }
- }*/
-
- // All ok. Check current trigger spell
- SpellInfo const* triggerEntry = sSpellMgr->GetSpellInfo(trigger_spell_id);
- if (triggerEntry == NULL)
- {
- // Not cast unknown spell
- // TC_LOG_ERROR("Unit::HandleAuraProcOnPowerAmount: Spell %u have 0 in EffectTriggered[%d], not handled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex());
- return false;
- }
-
- // not allow proc extra attack spell at extra attack
- if (m_extraAttacks && triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
- return false;
-
- if (!powerRequired || !powerAmountRequired)
- {
- TC_LOG_ERROR("spells", "Unit::HandleAuraProcOnPowerAmount: Spell %u have 0 powerAmountRequired in EffectAmount[%d] or 0 powerRequired in EffectMiscValue, not handled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex());
- return false;
- }
-
- if (GetPower(powerRequired) != powerAmountRequired)
- return false;
-
- // Custom requirements (not listed in procEx) Warning! damage dealing after this
- // Custom triggered spells
- switch (auraSpellInfo->SpellFamilyName)
- {
- case SPELLFAMILY_DRUID:
- {
- // Eclipse Mastery Driver Passive
- if (auraSpellInfo->Id == 79577)
- {
- uint32 solarEclipseMarker = 67483;
- uint32 lunarEclipseMarker = 67484;
-
- switch (effIndex)
- {
- case 0:
- {
- if (HasAura(trigger_spell_id))
- return false;
-
- // Do not proc if proc spell isnt starfire and starsurge
- if (procSpell->Id != 2912 && procSpell->Id != 78674)
- return false;
-
- if (HasAura(solarEclipseMarker))
- {
- RemoveAurasDueToSpell(solarEclipseMarker);
- CastSpell(this, lunarEclipseMarker, true);
- }
- break;
- }
- case 1:
- {
- if (HasAura(trigger_spell_id))
- return false;
-
- // Do not proc if proc spell isnt wrath and starsurge
- if (procSpell->Id != 5176 && procSpell->Id != 78674)
- return false;
-
- if (HasAura(lunarEclipseMarker))
- {
- RemoveAurasDueToSpell(lunarEclipseMarker);
- CastSpell(this, solarEclipseMarker, true);
- }
-
- break;
- }
- }
- }
- break;
- }
- }
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(trigger_spell_id))
- return false;
-
- // try detect target manually if not set
- if (target == NULL)
- target = !(procFlag & (PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS | PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS)) && triggerEntry && triggerEntry->IsPositive() ? this : victim;
-
- if (basepoints0)
- CastCustomSpell(target, trigger_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- else
- CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown);
-
- return true;
-}
-
//victim may be NULL
bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
@@ -5616,18 +5437,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 28810;
break;
}
- // Priest T10 Healer 2P Bonus
- case 70770:
- // Flash Heal
- if (procSpell->SpellFamilyFlags[0] & 0x800)
- {
- triggered_spell_id = 70772;
- SpellInfo const* blessHealing = sSpellMgr->GetSpellInfo(triggered_spell_id);
- if (!blessHealing)
- return false;
- basepoints0 = int32(CalculatePct(damage, triggerAmount) / (blessHealing->GetMaxDuration() / blessHealing->Effects[0].ApplyAuraPeriod));
- }
- break;
+ break;
}
break;
}
@@ -5745,7 +5555,10 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
+ SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (!effect)
+ return false;
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
// Add remaining ticks to damage done
basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
}
@@ -6129,7 +5942,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
+ if (SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0))
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
}
break;
}
@@ -6143,9 +5957,12 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
SpellInfo const* triggeredSpell = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!triggeredSpell)
return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / triggeredSpell->Effects[0].ApplyAuraPeriod);
- // Add remaining ticks to healing done
- basepoints0 += GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_HEAL);
+ if (SpellEffectInfo const* effect = triggeredSpell->GetEffect(DIFFICULTY_NONE, EFFECT_0))
+ {
+ basepoints0 = CalculatePct(int32(damage), triggerAmount) / (triggeredSpell->GetMaxDuration() / effect->ApplyAuraPeriod);
+ // Add remaining ticks to healing done
+ basepoints0 += GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_HEAL);
+ }
}
break;
}
@@ -6187,53 +6004,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 63685;
break;
}
- // Flametongue Weapon (Passive)
- if (dummySpell->SpellFamilyFlags[0] & 0x200000)
- {
- if (GetTypeId() != TYPEID_PLAYER || !victim || !victim->IsAlive() || !castItem || !castItem->IsEquipped())
- return false;
-
- WeaponAttackType attType = WeaponAttackType(Player::GetAttackBySlot(castItem->GetSlot()));
- if ((attType != BASE_ATTACK && attType != OFF_ATTACK)
- || (attType == BASE_ATTACK && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
- || (attType == OFF_ATTACK && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK))
- return false;
-
- float fire_onhit = float(CalculatePct(dummySpell->Effects[EFFECT_0]. CalcValue(), 1.0f));
-
- float add_spellpower = (float)(SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_FIRE)
- + victim->SpellBaseDamageBonusTaken(SPELL_SCHOOL_MASK_FIRE));
-
- // 1.3speed = 5%, 2.6speed = 10%, 4.0 speed = 15%, so, 1.0speed = 3.84%
- ApplyPct(add_spellpower, 3.84f);
-
- // Enchant on Off-Hand and ready?
- if (castItem->GetSlot() == EQUIPMENT_SLOT_OFFHAND && procFlag & PROC_FLAG_DONE_OFFHAND_ATTACK)
- {
- float BaseWeaponSpeed = GetAttackTime(OFF_ATTACK) / 1000.0f;
-
- // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
- basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
- triggered_spell_id = 10444;
- }
-
- // Enchant on Main-Hand and ready?
- else if (castItem->GetSlot() == EQUIPMENT_SLOT_MAINHAND && procFlag & PROC_FLAG_DONE_MAINHAND_ATTACK)
- {
- float BaseWeaponSpeed = GetAttackTime(BASE_ATTACK) / 1000.0f;
-
- // Value1: add the tooltip damage by swingspeed + Value2: add spelldmg by swingspeed
- basepoints0 = int32((fire_onhit * BaseWeaponSpeed) + (add_spellpower * BaseWeaponSpeed));
- triggered_spell_id = 10444;
- }
-
- // If not ready, we should return, shouldn't we?!
- else
- return false;
-
- CastCustomSpell(victim, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- return true;
- }
// Static Shock
if (dummySpell->SpellIconID == 3059)
{
@@ -6255,15 +6025,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
case SPELLFAMILY_DEATHKNIGHT:
{
- // Blood-Caked Blade
- if (dummySpell->SpellIconID == 138)
- {
- if (!target || !target->IsAlive())
- return false;
-
- triggered_spell_id = dummySpell->Effects[effIndex].TriggerSpell;
- break;
- }
// Dancing Rune Weapon
if (dummySpell->Id == 49028)
{
@@ -6289,24 +6050,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
else
return false;
}
- // Unholy Blight
- if (dummySpell->Id == 49194)
- {
- triggered_spell_id = 50536;
- SpellInfo const* unholyBlight = sSpellMgr->GetSpellInfo(triggered_spell_id);
- if (!unholyBlight)
- return false;
-
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
-
- //Glyph of Unholy Blight
- if (AuraEffect* glyph=GetAuraEffect(63332, 0))
- AddPct(basepoints0, glyph->GetAmount());
-
- basepoints0 = basepoints0 / (unholyBlight->GetMaxDuration() / unholyBlight->Effects[0].ApplyAuraPeriod);
- basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
- break;
- }
// Threat of Thassarian
if (dummySpell->SpellIconID == 2023)
{
@@ -6347,26 +6090,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
case SPELLFAMILY_PET:
{
- switch (dummySpell->SpellIconID)
- {
- // Guard Dog
- case 201:
- {
- if (!victim)
- return false;
-
- triggered_spell_id = 54445;
- target = this;
- float addThreat = float(CalculatePct(procSpell->Effects[0].CalcValue(this), triggerAmount));
- victim->AddThreat(this, addThreat);
- break;
- }
- // Silverback
- case 1582:
- triggered_spell_id = dummySpell->Id == 62765 ? 62801 : 62800;
- target = this;
- break;
- }
break;
}
default:
@@ -6375,7 +6098,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// if not handled by custom case, get triggered spell from dummySpell proto
if (!triggered_spell_id)
- triggered_spell_id = dummySpell->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
+ triggered_spell_id = triggeredByAura->GetSpellEffectInfo()->TriggerSpell;
// processed charge only counting case
if (!triggered_spell_id)
@@ -6405,10 +6128,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return true;
}
- /*
- */
-
-
// Used in case when access to whole aura is needed
// All procs should be handled like this...
bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown, bool * handled)
@@ -6459,9 +6178,12 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Swift Hand of Justice
case 59906:
{
- int32 bp0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_0]. CalcValue());
- CastCustomSpell(this, 59913, &bp0, NULL, NULL, true);
- *handled = true;
+ if (SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo(EFFECT_0))
+ {
+ int32 bp0 = CalculatePct(GetMaxHealth(), effect->CalcValue());
+ CastCustomSpell(this, 59913, &bp0, NULL, NULL, true);
+ *handled = true;
+ }
break;
}
}
@@ -6476,49 +6198,10 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
CastSpell(victim, 68055, true);
return true;
}
- // Glyph of Divinity
- else if (dummySpell->Id == 54939)
- {
- if (!procSpell)
- return false;
- *handled = true;
- // Check if we are the target and prevent mana gain
- if (victim && triggeredByAura->GetCasterGUID() == victim->GetGUID())
- return false;
- // Lookup base amount mana restore
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
- {
- if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
- {
- // value multiplied by 2 because you should get twice amount
- int32 mana = procSpell->Effects[i].CalcValue() * 2;
- CastCustomSpell(this, 54986, 0, &mana, NULL, true);
- }
- }
- return true;
- }
break;
}
case SPELLFAMILY_MAGE:
{
- switch (dummySpell->Id)
- {
- // Empowered Fire
- case 31656:
- case 31657:
- case 31658:
- {
- *handled = true;
-
- SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(67545);
- if (!spInfo)
- return false;
-
- int32 bp0 = int32(CalculatePct(GetCreateMana(), spInfo->Effects[0].CalcValue()));
- CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(EFFECT_0), GetGUID());
- return true;
- }
- }
break;
}
case SPELLFAMILY_DEATHKNIGHT:
@@ -6603,8 +6286,11 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Item - Warrior T10 Protection 4P Bonus
case 70844:
{
- int32 basepoints0 = CalculatePct(GetMaxHealth(), dummySpell->Effects[EFFECT_1]. CalcValue());
- CastCustomSpell(this, 70845, &basepoints0, NULL, NULL, true);
+ if (SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo(EFFECT_1))
+ {
+ int32 basepoints0 = CalculatePct(GetMaxHealth(), effect->CalcValue());
+ CastCustomSpell(this, 70845, &basepoints0, NULL, NULL, true);
+ }
break;
}
// Recklessness
@@ -6635,7 +6321,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
int32 triggerAmount = triggeredByAura->GetAmount();
// Set trigger spell id, target, custom basepoints
- uint32 trigger_spell_id = auraSpellInfo->Effects[triggeredByAura->GetEffIndex()].TriggerSpell;
+ uint32 trigger_spell_id = triggeredByAura->GetSpellEffectInfo()->TriggerSpell;
Unit* target = NULL;
int32 basepoints0 = 0;
@@ -6655,11 +6341,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
case SPELLFAMILY_GENERIC:
switch (auraSpellInfo->Id)
{
- case 43820: // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)
- // Pct value stored in dummy
- basepoints0 = victim->GetCreateHealth() * auraSpellInfo->Effects[1].CalcValue() / 100;
- target = victim;
- break;
case 57345: // Darkmoon Card: Greatness
{
float stat = 0.0f;
@@ -6760,19 +6441,9 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
case SPELLFAMILY_HUNTER:
{
- if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots
+ /*if (auraSpellInfo->SpellIconID == 3247) // Piercing Shots
{
- switch (auraSpellInfo->Id)
- {
- case 53234: // Rank 1
- case 53237: // Rank 2
- case 53238: // Rank 3
- trigger_spell_id = 63468;
- break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u miss posibly Piercing Shots", auraSpellInfo->Id);
- return false;
- }
+ trigger_spell_id = 63468; // 6.x missing from dbc but it is in the tooltip
SpellInfo const* TriggerPS = sSpellMgr->GetSpellInfo(trigger_spell_id);
if (!TriggerPS)
return false;
@@ -6780,7 +6451,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
basepoints0 = CalculatePct(int32(damage), triggerAmount) / (TriggerPS->GetMaxDuration() / TriggerPS->Effects[0].ApplyAuraPeriod);
basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), trigger_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
break;
- }
+ }*/
// Item - Hunter T9 4P Bonus
if (auraSpellInfo->Id == 67151)
{
@@ -6903,7 +6574,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
// not allow proc extra attack spell at extra attack
- if (m_extraAttacks && triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (m_extraAttacks && triggerEntry->HasEffect(GetMap()->GetDifficulty(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
return false;
// Custom requirements (not listed in procEx) Warning! damage dealing after this
@@ -6983,10 +6654,9 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
break;
}
// Decimation
- case 63156:
- case 63158:
+ case 108869:
// Can proc only if target has hp below 25%
- if (!victim || !victim->HealthBelowPct(auraSpellInfo->Effects[EFFECT_1].CalcValue()))
+ if (!victim || !victim->HealthBelowPct(triggeredByAura->GetSpellEffectInfo()->CalcValue()))
return false;
break;
// Deathbringer Saurfang - Blood Beast's Blood Link
@@ -7120,7 +6790,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
// extra attack should hit same target
- if (triggerEntry->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (triggerEntry->HasEffect(GetMap()->GetDifficulty(), SPELL_EFFECT_ADD_EXTRA_ATTACKS))
target = victim;
// try detect target manually if not set
@@ -7204,7 +6874,7 @@ void Unit::setPowerType(Powers new_powertype)
if (getPowerType() == new_powertype)
return;
- SetByteValue(UNIT_FIELD_BYTES_0, 3, new_powertype);
+ SetUInt32Value(UNIT_FIELD_DISPLAY_POWER, new_powertype);
if (GetTypeId() == TYPEID_PLAYER)
{
@@ -7961,14 +7631,14 @@ void Unit::SetMinion(Minion *minion, bool apply)
else if (minion->IsTotem())
{
// All summoned by totem minions must disappear when it is removed.
- if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
- for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if (spInfo->Effects[i].Effect != SPELL_EFFECT_SUMMON)
- continue;
+ if (SpellInfo const* spInfo = sSpellMgr->GetSpellInfo(minion->ToTotem()->GetSpell()))
+ for (SpellEffectInfo const* effect : spInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ {
+ if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
+ continue;
- RemoveAllMinionsByEntry(spInfo->Effects[i].MiscValue);
- }
+ RemoveAllMinionsByEntry(effect->MiscValue);
+ }
}
if (GetTypeId() == TYPEID_PLAYER)
@@ -8419,7 +8089,7 @@ void Unit::EnergizeBySpell(Unit* victim, uint32 spellId, int32 damage, Powers po
victim->getHostileRefManager().threatAssist(this, float(damage) * 0.5f, spellInfo);
}
-uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) const
+uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack) const
{
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
return pdamage;
@@ -8431,7 +8101,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// For totems get damage bonus from owner
if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTotem())
if (Unit* owner = GetOwner())
- return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype);
+ return owner->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effect, stack);
float ApCoeffMod = 1.0f;
int32 DoneTotal = 0;
@@ -8462,32 +8132,11 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
}
// Custom scripted damage
- switch (spellProto->SpellFamilyName)
+ /*switch (spellProto->SpellFamilyName)
{
case SPELLFAMILY_DEATHKNIGHT:
- // Impurity (dummy effect)
- if (GetTypeId() == TYPEID_PLAYER)
- {
- PlayerSpellMap playerSpells = ToPlayer()->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = playerSpells.begin(); itr != playerSpells.end(); ++itr)
- {
- if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
- continue;
- switch (itr->first)
- {
- case 49220:
- case 49633:
- case 49635:
- case 49636:
- case 49638:
- if (SpellInfo const* proto = sSpellMgr->GetSpellInfo(itr->first))
- AddPct(ApCoeffMod, proto->Effects[0].CalcValue());
- break;
- }
- }
- }
break;
- }
+ }*/
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
@@ -8497,39 +8146,18 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
DoneAdvertisedBenefit += ((Guardian*)this)->GetBonusDamage();
// Check for table values
- float coeff = 0;
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- if (bonus)
+ float coeff = effect->BonusCoefficient;
+ if (effect->BonusCoefficientFromAP > 0)
{
- if (damagetype == DOT)
- {
- coeff = bonus->dot_damage;
- if (bonus->ap_dot_bonus > 0)
- {
- WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
- float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
- APbonus += GetTotalAttackPowerValue(attType);
- DoneTotal += int32(bonus->ap_dot_bonus * stack * ApCoeffMod * APbonus);
- }
- }
- else
- {
- coeff = bonus->direct_damage;
- if (bonus->ap_bonus > 0)
- {
- WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
- float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
- APbonus += GetTotalAttackPowerValue(attType);
- DoneTotal += int32(bonus->ap_bonus * stack * ApCoeffMod * APbonus);
- }
- }
+ WeaponAttackType attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
+ float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
+ APbonus += GetTotalAttackPowerValue(attType);
+ DoneTotal += int32(effect->BonusCoefficientFromAP * stack * ApCoeffMod * APbonus);
}
+
// Default calculation
if (DoneAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
-
float factorMod = CalculateLevelPenalty(spellProto) * stack;
if (Player* modOwner = GetSpellModOwner())
@@ -8627,6 +8255,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage
// Health at 25% or less (25% stored at effect 2 of the spell)
if (victim->HealthBelowPct(CalculateSpellDamage(this, (*i)->GetSpellInfo(), EFFECT_2)))
AddPct(DoneTotalMod, (*i)->GetAmount());
+ break;
}
case 6916: // Death's Embrace heal effect
case 6925:
@@ -8741,7 +8370,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage
return DoneTotalMod;
}
-uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack) const
+uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack) const
{
if (!spellProto || damagetype == DIRECT_DAMAGE)
return pdamage;
@@ -8792,17 +8421,11 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
int32 TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto->GetSchoolMask());
// Check for table values
- float coeff = 0;
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- if (bonus)
- coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
+ float coeff = effect->BonusCoefficient;
// Default calculation
if (TakenAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack);
-
float factorMod = CalculateLevelPenalty(spellProto) * stack;
// level penalty still applied on Taken bonus - is it blizzlike?
if (Player* modOwner = GetSpellModOwner())
@@ -9130,12 +8753,12 @@ uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* /*spellProto*/, uint32 d
return damage;
}
-uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) const
+uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack) const
{
// For totems get healing bonus from owner (statue isn't totem in fact)
if (GetTypeId() == TYPEID_UNIT && IsTotem())
if (Unit* owner = GetOwner())
- return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, stack);
+ return owner->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, effect, stack);
// No bonus healing for potion spells
if (spellProto->SpellFamilyName == SPELLFAMILY_POTION)
@@ -9191,27 +8814,14 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask());
// Check for table values
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- float coeff = 0;
+ float coeff = effect->BonusCoefficient;
float factorMod = 1.0f;
- if (bonus)
+ if (effect->BonusCoefficientFromAP > 0.0f)
{
- if (damagetype == DOT)
- {
- coeff = bonus->dot_damage;
- if (bonus->ap_dot_bonus > 0)
- DoneTotal += int32(bonus->ap_dot_bonus * stack * GetTotalAttackPowerValue(
- (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
- }
- else
- {
- coeff = bonus->direct_damage;
- if (bonus->ap_bonus > 0)
- DoneTotal += int32(bonus->ap_bonus * stack * GetTotalAttackPowerValue(
- (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass !=SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
- }
+ DoneTotal += int32(effect->BonusCoefficientFromAP * stack * GetTotalAttackPowerValue(
+ (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
}
- else
+ else if (coeff <= 0.0f)
{
// No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
@@ -9221,9 +8831,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
// Default calculation
if (DoneAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
-
factorMod *= CalculateLevelPenalty(spellProto) * stack;
if (Player* modOwner = GetSpellModOwner())
@@ -9236,9 +8843,11 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- switch (spellProto->Effects[i].ApplyAuraName)
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// Bonus healing does not apply to these spells
case SPELL_AURA_PERIODIC_LEECH:
@@ -9246,7 +8855,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
break;
}
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
+ if (effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
DoneTotal = 0;
}
@@ -9331,7 +8940,7 @@ float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
return DoneTotalMod;
}
-uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack) const
+uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType /*damagetype*/, SpellEffectInfo const* effect, uint32 stack) const
{
float TakenTotalMod = 1.0f;
@@ -9364,12 +8973,9 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
}
// Check for table values
- SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
- float coeff = 0;
+ float coeff = effect->BonusCoefficient;
float factorMod = 1.0f;
- if (bonus)
- coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
- else
+ if (coeff <= 0.0f)
{
// No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
@@ -9382,9 +8988,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
// Default calculation
if (TakenAdvertisedBenefit)
{
- if (!bonus || coeff < 0)
- coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
-
factorMod *= CalculateLevelPenalty(spellProto) * int32(stack);
if (Player* modOwner = GetSpellModOwner())
{
@@ -9401,17 +9004,19 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- switch (spellProto->Effects[i].ApplyAuraName)
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// Bonus healing does not apply to these spells
- case SPELL_AURA_PERIODIC_LEECH:
- case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
- TakenTotal = 0;
- break;
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
+ TakenTotal = 0;
+ break;
}
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
+ if (effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
TakenTotal = 0;
}
@@ -9444,7 +9049,7 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
{
// stat used dependent from misc value (stat index)
- Stats usedStat = Stats((*i)->GetSpellInfo()->Effects[(*i)->GetEffIndex()].MiscValue);
+ Stats usedStat = Stats((*i)->GetSpellEffectInfo()->MiscValue);
advertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount()));
}
@@ -9542,13 +9147,13 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const
}
bool immuneToAllEffects = true;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
// State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately
- if (!spellInfo->Effects[i].IsEffect())
+ if (!effect || !effect->IsEffect())
continue;
- if (!IsImmunedToSpellEffect(spellInfo, i))
+ if (!IsImmunedToSpellEffect(spellInfo, effect->EffectIndex))
{
immuneToAllEffects = false;
break;
@@ -9576,20 +9181,24 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo) const
bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const
{
- if (!spellInfo || !spellInfo->Effects[index].IsEffect())
+ if (!spellInfo)
+ return false;
+
+ SpellEffectInfo const* effect = spellInfo->GetEffect(GetMap()->GetDifficulty(), index);
+ if (!effect || !effect->IsEffect())
return false;
if (spellInfo->Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY)
return false;
// If m_immuneToEffect type contain this effect type, IMMUNE effect.
- uint32 effect = spellInfo->Effects[index].Effect;
+ uint32 eff = effect->Effect;
SpellImmuneList const& effectList = m_spellImmune[IMMUNITY_EFFECT];
for (SpellImmuneList::const_iterator itr = effectList.begin(); itr != effectList.end(); ++itr)
- if (itr->type == effect)
+ if (itr->type == eff)
return true;
- if (uint32 mechanic = spellInfo->Effects[index].Mechanic)
+ if (uint32 mechanic = effect->Mechanic)
{
SpellImmuneList const& mechanicList = m_spellImmune[IMMUNITY_MECHANIC];
for (SpellImmuneList::const_iterator itr = mechanicList.begin(); itr != mechanicList.end(); ++itr)
@@ -9597,7 +9206,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) cons
return true;
}
- if (uint32 aura = spellInfo->Effects[index].ApplyAuraName)
+ if (uint32 aura = effect->ApplyAuraName)
{
SpellImmuneList const& list = m_spellImmune[IMMUNITY_STATE];
for (SpellImmuneList::const_iterator itr = list.begin(); itr != list.end(); ++itr)
@@ -9663,8 +9272,8 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
{
bool normalized = false;
if (spellProto)
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ if (effect && effect->Effect == SPELL_EFFECT_NORMALIZED_WEAPON_DMG)
{
normalized = true;
break;
@@ -10269,7 +9878,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
return false;
// can't attack invisible (ignore stealth for aoe spells) also if the area being looked at is from a spell use the dynamic object created instead of the casting unit.
- if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea())))
+ if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && (obj ? !obj->CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty())) : !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty()))))
return false;
// can't attack dead
@@ -10390,7 +9999,7 @@ bool Unit::_IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) co
return false;
// can't assist invisible
- if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea()))
+ if ((!bySpell || !(bySpell->AttributesEx6 & SPELL_ATTR6_CAN_TARGET_INVISIBLE)) && !CanSeeOrDetect(target, bySpell && bySpell->IsAffectingArea(GetMap()->GetDifficulty())))
return false;
// can't assist dead
@@ -10768,6 +10377,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
propagateSpeedChange();
+ // Spline packets are for creatures and move_update are for players
static OpcodeServer const moveTypeToOpcode[MAX_MOVE_TYPE][3] =
{
{SMSG_SPLINE_MOVE_SET_WALK_SPEED, SMSG_MOVE_SET_WALK_SPEED, SMSG_MOVE_UPDATE_WALK_SPEED },
@@ -10792,11 +10402,28 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
}
- static MovementStatusElements const speedVal = MSEExtraFloat;
- Movement::ExtraMovementStatusElement extra(&speedVal);
- extra.Data.floatData = GetSpeed(mtype);
+ if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Send notification to self
+ WorldPackets::Movement::MoveSetSpeed selfpacket(moveTypeToOpcode[mtype][1]);
+ selfpacket.MoverGUID = GetGUID();
+ selfpacket.SequenceIndex = m_movementCounter++;
+ selfpacket.Speed = rate;
+ ToPlayer()->GetSession()->SendPacket(selfpacket.Write());
- Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send();
+ // Send notification to other players
+ WorldPackets::Movement::MoveUpdateSpeed packet(moveTypeToOpcode[mtype][2]);
+ packet.movementInfo = &m_movementInfo;
+ packet.Speed = rate;
+ SendMessageToSet(packet.Write(), false);
+ }
+ else
+ {
+ WorldPackets::Movement::MoveSplineSetSpeed packet(moveTypeToOpcode[mtype][0]);
+ packet.MoverGUID = GetGUID();
+ packet.Speed = rate;
+ SendMessageToSet(packet.Write(), true);
+ }
}
void Unit::setDeathState(DeathState s)
@@ -11138,9 +10765,13 @@ float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index
}
// function uses real base points (typically value - 1)
-int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints) const
+int32 Unit::CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints /*= nullptr*/, float* variance /*= nullptr*/) const
{
- return spellProto->Effects[effect_index].CalcValue(this, basePoints, target);
+ SpellEffectInfo const* effect = spellProto->GetEffect(GetMap()->GetDifficulty(), effect_index);
+ if (variance)
+ *variance = 0.0f;
+
+ return effect ? effect->CalcValue(this, basePoints, target, variance) : 0;
}
int32 Unit::CalcSpellDuration(SpellInfo const* spellProto)
@@ -11228,7 +10859,8 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in
sSpellMgr->IsSpellMemberOfSpellGroup(spellProto->Id, SPELL_GROUP_ELIXIR_BATTLE) ||
sSpellMgr->IsSpellMemberOfSpellGroup(spellProto->Id, SPELL_GROUP_ELIXIR_GUARDIAN)))
{
- if (target->HasAura(53042) && target->HasSpell(spellProto->Effects[0].TriggerSpell))
+ SpellEffectInfo const* effect = spellProto->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (target->HasAura(53042) && effect && target->HasSpell(effect->TriggerSpell))
duration *= 2;
}
}
@@ -12236,7 +11868,7 @@ void CharmInfo::LoadPetActionBar(const std::string& data)
// use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion
ActiveStates type = ActiveStates(atol(*iter));
++iter;
- uint32 action = uint32(atol(*iter));
+ uint32 action = atoul(*iter);
PetActionBar[index].SetActionAndType(action, type);
@@ -12476,10 +12108,17 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo();
// only auras that has triggered spell should proc from fully absorbed damage
- if (procExtra & PROC_EX_ABSORB && isVictim)
- if (damage || spellProto->Effects[EFFECT_0].TriggerSpell || spellProto->Effects[EFFECT_1].TriggerSpell || spellProto->Effects[EFFECT_2].TriggerSpell)
- active = true;
-
+ if (procExtra & PROC_EX_ABSORB && isVictim && damage)
+ {
+ for (SpellEffectInfo const* effect : itr->second->GetBase()->GetSpellEffectInfos())
+ {
+ if (effect && effect->TriggerSpell)
+ {
+ active = true;
+ break;
+ }
+ }
+ }
if (!IsTriggeredAtSpellProcEvent(target, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent))
continue;
@@ -12497,11 +12136,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
bool triggered = !(spellProto->AttributesEx3 & SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED) ?
(procExtra & PROC_EX_INTERNAL_TRIGGERED && !(procFlag & PROC_FLAG_DONE_TRAP_ACTIVATION)) : false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect const* aurEff : itr->second->GetBase()->GetAuraEffects())
{
- if (itr->second->HasEffect(i))
+ if (aurEff)
{
- AuraEffect* aurEff = itr->second->GetBase()->GetEffect(i);
// Skip this auras
if (isNonTriggerAura[aurEff->GetAuraType()])
continue;
@@ -12510,7 +12148,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
continue;
// Some spells must always trigger
if (!triggered || isAlwaysTriggeredAura[aurEff->GetAuraType()])
- triggerData.effMask |= 1<<i;
+ triggerData.effMask |= 1 << aurEff->GetEffIndex();
}
}
if (triggerData.effMask)
@@ -12611,9 +12249,8 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
case SPELL_AURA_PROC_ON_POWER_AMOUNT:
{
- TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell id %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
- if (HandleAuraProcOnPowerAmount(target, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
- takeCharges = true;
+ triggeredByAura->HandleProcTriggerSpellOnPowerAmountAuraProc(aurApp, eventInfo);
+ takeCharges = true;
break;
}
case SPELL_AURA_OBS_MOD_POWER:
@@ -12892,10 +12529,10 @@ void Unit::SendPetAIReaction(ObjectGuid guid)
if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
return;
- WorldPacket data(SMSG_AI_REACTION, 8 + 4);
- data << guid;
- data << uint32(AI_REACTION_HOSTILE);
- owner->ToPlayer()->GetSession()->SendPacket(&data);
+ WorldPackets::Combat::AIReaction packet;
+ packet.UnitGUID = guid;
+ packet.Reaction = AI_REACTION_HOSTILE;
+ owner->ToPlayer()->SendDirectMessage(packet.Write());
}
///----------End of Pet responses methods----------
@@ -13153,9 +12790,11 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
bool DirectDamage = false;
bool AreaEffect = false;
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- switch (spellProto->Effects[i].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
case SPELL_EFFECT_POWER_DRAIN:
@@ -13166,7 +12805,7 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
DirectDamage = true;
break;
case SPELL_EFFECT_APPLY_AURA:
- switch (spellProto->Effects[i].ApplyAuraName)
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
@@ -13183,7 +12822,7 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
break;
}
- if (spellProto->Effects[i].IsTargetingArea())
+ if (effect->IsTargetingArea())
AreaEffect = true;
}
@@ -13210,10 +12849,12 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
CastingTime /= 2;
// 50% for damage and healing spells for leech spells from damage bonus and 0% from healing
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (spellProto->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH ||
- (spellProto->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && spellProto->Effects[j].ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
+ if (!effect)
+ continue;
+ if (effect->Effect == SPELL_EFFECT_HEALTH_LEECH ||
+ (effect->Effect == SPELL_EFFECT_APPLY_AURA && effect->ApplyAuraName == SPELL_AURA_PERIODIC_LEECH))
{
CastingTime /= 2;
break;
@@ -13276,7 +12917,7 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect
if (!spellInfo->IsChanneled() && DotDuration > 0)
DotFactor = DotDuration / 15000.0f;
- if (uint32 DotTicks = spellInfo->GetMaxTicks())
+ if (uint32 DotTicks = spellInfo->GetMaxTicks(GetMap()->GetDifficulty()))
DotFactor /= DotTicks;
}
@@ -13550,7 +13191,8 @@ bool Unit::HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura)
{
if (Unit* caster = triggeredByAura->GetCaster())
{
- float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster);
+ SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo();
+ float radius = effect->CalcRadius(caster);
if (Unit* target = GetNextRandomRaidMemberOrPet(radius))
{
@@ -13602,7 +13244,8 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
{
if (Unit* caster = triggeredByAura->GetCaster())
{
- float radius = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcRadius(caster);
+ SpellEffectInfo const* effect = triggeredByAura->GetSpellEffectInfo();
+ float radius = effect->CalcRadius(caster);
if (Unit* target= GetNextRandomRaidMemberOrPet(radius))
{
CastSpell(target, spellProto, true, NULL, triggeredByAura, caster_guid);
@@ -14302,7 +13945,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
// to prevent client crash
- SetByteValue(UNIT_FIELD_BYTES_0, 1, (uint8)CLASS_MAGE);
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, (uint8)CLASS_MAGE);
// just to enable stat window
if (GetCharmInfo())
@@ -14404,7 +14047,7 @@ void Unit::RemoveCharmedBy(Unit* charmer)
CreatureTemplate const* cinfo = ToCreature()->GetCreatureTemplate();
if (cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
- SetByteValue(UNIT_FIELD_BYTES_0, 1, uint8(cinfo->unit_class));
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(cinfo->unit_class));
if (GetCharmInfo())
GetCharmInfo()->SetPetNumber(0, true);
else
@@ -14621,7 +14264,7 @@ Aura* Unit::AddAura(uint32 spellId, Unit* target)
return AddAura(spellInfo, MAX_EFFECT_MASK, target);
}
-Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target)
+Aura* Unit::AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target)
{
if (!spellInfo)
return NULL;
@@ -15374,9 +15017,12 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
uint8 i = 0;
bool valid = false;
- while (i < MAX_SPELL_EFFECTS && !valid)
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
{
- if (spellEntry->Effects[i].ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
+ if (!effect)
+ continue;
+
+ if (effect->ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE)
{
valid = true;
break;
@@ -15395,8 +15041,9 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else // This can happen during Player::_LoadAuras
{
int32 bp0[MAX_SPELL_EFFECTS];
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
- bp0[j] = spellEntry->Effects[j].BasePoints;
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ if (effect)
+ bp0[effect->EffectIndex] = effect->BasePoints;
bp0[i] = seatId;
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, NULL, origCasterGUID);
@@ -15822,64 +15469,24 @@ void Unit::SendTeleportPacket(Position& pos)
if (GetTypeId() == TYPEID_UNIT)
Relocate(&pos); // Relocate the unit to its new position in order to build the packets correctly.
- ObjectGuid guid = GetGUID();
- ObjectGuid transGuid = GetTransGUID();
-
- WorldPacket data(SMSG_MOVE_UPDATE_TELEPORT, 38);
- WriteMovementInfo(data);
+ WorldPackets::Movement::MoveUpdateTeleport packet;
+ packet.movementInfo = &m_movementInfo;
if (GetTypeId() == TYPEID_PLAYER)
{
- WorldPacket data2(MSG_MOVE_TELEPORT, 38);
- data2.WriteBit(guid[6]);
- data2.WriteBit(guid[0]);
- data2.WriteBit(guid[3]);
- data2.WriteBit(guid[2]);
- data2.WriteBit(0); // unknown
- data2.WriteBit(!transGuid.IsEmpty());
- data2.WriteBit(guid[1]);
- if (!transGuid.IsEmpty())
- {
- data2.WriteBit(transGuid[1]);
- data2.WriteBit(transGuid[3]);
- data2.WriteBit(transGuid[2]);
- data2.WriteBit(transGuid[5]);
- data2.WriteBit(transGuid[0]);
- data2.WriteBit(transGuid[7]);
- data2.WriteBit(transGuid[6]);
- data2.WriteBit(transGuid[4]);
- }
- data2.WriteBit(guid[4]);
- data2.WriteBit(guid[7]);
- data2.WriteBit(guid[5]);
- data2.FlushBits();
+ WorldPackets::Movement::MoveTeleport selfPacket;
+ selfPacket.MoverGUID = GetGUID();
+
+ ObjectGuid transGuid = GetTransGUID();
if (!transGuid.IsEmpty())
- {
- data2.WriteByteSeq(transGuid[6]);
- data2.WriteByteSeq(transGuid[5]);
- data2.WriteByteSeq(transGuid[1]);
- data2.WriteByteSeq(transGuid[7]);
- data2.WriteByteSeq(transGuid[0]);
- data2.WriteByteSeq(transGuid[2]);
- data2.WriteByteSeq(transGuid[4]);
- data2.WriteByteSeq(transGuid[3]);
- }
-
- data2 << uint32(0); // counter
- data2.WriteByteSeq(guid[1]);
- data2.WriteByteSeq(guid[2]);
- data2.WriteByteSeq(guid[3]);
- data2.WriteByteSeq(guid[5]);
- data2 << float(GetPositionX());
- data2.WriteByteSeq(guid[4]);
- data2 << float(GetOrientation());
- data2.WriteByteSeq(guid[7]);
- data2 << float(GetPositionZMinusOffset());
- data2.WriteByteSeq(guid[0]);
- data2.WriteByteSeq(guid[6]);
- data2 << float(GetPositionY());
- ToPlayer()->SendDirectMessage(&data2); // Send the MSG_MOVE_TELEPORT packet to self.
+ selfPacket.TransportGUID.Set(transGuid);
+
+ selfPacket.Pos.Relocate(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
+ selfPacket.Facing = GetOrientation();
+ selfPacket.SequenceIndex = m_movementCounter++;
+
+ ToPlayer()->SendDirectMessage(selfPacket.Write());
}
// Relocate the player/creature to its old position, so we can broadcast to nearby players correctly
@@ -15889,7 +15496,7 @@ void Unit::SendTeleportPacket(Position& pos)
Relocate(&oldPos);
// Broadcast the packet to everyone except self.
- SendMessageToSet(&data, false);
+ SendMessageToSet(packet.Write(), false);
}
bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)
@@ -15953,19 +15560,19 @@ void Unit::SendThreatListUpdate()
{
if (!getThreatManager().isThreatListEmpty())
{
- uint32 count = getThreatManager().getThreatList().size();
-
TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message");
- WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8);
- data << GetPackGUID();
- data << uint32(count);
+ WorldPackets::Combat::ThreatUpdate packet;
+ packet.UnitGUID = GetGUID();
ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList();
+ packet.ThreatList.reserve(tlist.size());
for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{
- data << (*itr)->getUnitGuid().WriteAsPacked();
- data << uint32((*itr)->getThreat() * 100);
+ WorldPackets::Combat::ThreatInfo info;
+ info.UnitGUID = (*itr)->getUnitGuid();
+ info.Threat = (*itr)->getThreat() * 100;
+ packet.ThreatList.push_back(info);
}
- SendMessageToSet(&data, false);
+ SendMessageToSet(packet.Write(), false);
}
}
@@ -15973,20 +15580,20 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference)
{
if (!getThreatManager().isThreatListEmpty())
{
- uint32 count = getThreatManager().getThreatList().size();
-
TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_HIGHEST_THREAT_UPDATE Message");
- WorldPacket data(SMSG_HIGHEST_THREAT_UPDATE, 8 + 8 + count * 8);
- data << GetPackGUID();
- data << pHostileReference->getUnitGuid().WriteAsPacked();
- data << uint32(count);
+ WorldPackets::Combat::HighestThreatUpdate packet;
+ packet.UnitGUID = GetGUID();
+ packet.HighestThreatGUID = pHostileReference->getUnitGuid();
ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList();
+ packet.ThreatList.reserve(tlist.size());
for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr)
{
- data << (*itr)->getUnitGuid().WriteAsPacked();
- data << uint32((*itr)->getThreat());
+ WorldPackets::Combat::ThreatInfo info;
+ info.UnitGUID = (*itr)->getUnitGuid();
+ info.Threat = int32((*itr)->getThreat());
+ packet.ThreatList.push_back(info);
}
- SendMessageToSet(&data, false);
+ SendMessageToSet(packet.Write(), false);
}
}
@@ -16001,10 +15608,10 @@ void Unit::SendClearThreatListOpcode()
void Unit::SendRemoveFromThreatListOpcode(HostileReference* pHostileReference)
{
TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_REMOVE Message");
- WorldPacket data(SMSG_THREAT_REMOVE, 8 + 8);
- data << GetPackGUID();
- data << pHostileReference->getUnitGuid().WriteAsPacked();
- SendMessageToSet(&data, false);
+ WorldPackets::Combat::ThreatRemove packet;
+ packet.UnitGUID = GetGUID();
+ packet.AboutGUID = pHostileReference->getUnitGuid();
+ SendMessageToSet(packet.Write(), false);
}
// baseRage means damage taken when attacker = false
@@ -16282,10 +15889,27 @@ bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
}
}
- if (disable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
+ static OpcodeServer const gravityOpcodeTable[2][2] =
+ {
+ {SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE },
+ {SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE }
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(gravityOpcodeTable[disable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(gravityOpcodeTable[disable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
return true;
}
@@ -16316,10 +15940,11 @@ bool Unit::SetSwim(bool enable)
else
RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
- if (enable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, static_cast<OpcodeServer>(NULL_OPCODE)).Send();
- else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, static_cast<OpcodeServer>(NULL_OPCODE)).Send();
+ static OpcodeServer const swimOpcodeTable[2] = {SMSG_SPLINE_MOVE_STOP_SWIM, SMSG_SPLINE_MOVE_START_SWIM};
+
+ WorldPackets::Movement::MoveSplineSetFlag packet(swimOpcodeTable[enable]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
return true;
}
@@ -16342,10 +15967,27 @@ bool Unit::SetCanFly(bool enable)
SetFall(true);
}
- if (enable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
+ static OpcodeServer const flyOpcodeTable[2][2] =
+ {
+ {SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY },
+ {SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY }
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(flyOpcodeTable[enable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(flyOpcodeTable[enable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
return true;
}
@@ -16363,10 +16005,27 @@ bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
}
- if (enable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WATER_WALK, SMSG_MOVE_WATER_WALK).Send();
+ static OpcodeServer const waterWalkingOpcodeTable[2][2] =
+ {
+ {SMSG_SPLINE_MOVE_SET_LAND_WALK, SMSG_MOVE_LAND_WALK },
+ {SMSG_SPLINE_MOVE_SET_WATER_WALK, SMSG_MOVE_WATER_WALK}
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(waterWalkingOpcodeTable[enable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_LAND_WALK, SMSG_MOVE_LAND_WALK).Send();
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(waterWalkingOpcodeTable[enable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
return true;
}
@@ -16384,10 +16043,27 @@ bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
}
- if (enable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FEATHER_FALL, SMSG_MOVE_FEATHER_FALL).Send();
+ static OpcodeServer const featherFallOpcodeTable[2][2] =
+ {
+ {SMSG_SPLINE_MOVE_SET_NORMAL_FALL, SMSG_MOVE_NORMAL_FALL },
+ {SMSG_SPLINE_MOVE_SET_FEATHER_FALL, SMSG_MOVE_FEATHER_FALL }
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(featherFallOpcodeTable[enable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_NORMAL_FALL, SMSG_MOVE_NORMAL_FALL).Send();
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(featherFallOpcodeTable[enable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
return true;
}
@@ -16420,10 +16096,27 @@ bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
}
}
- if (enable)
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
+ static OpcodeServer const hoverOpcodeTable[2][2] =
+ {
+ {SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER },
+ {SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER }
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(hoverOpcodeTable[enable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
else
- Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(hoverOpcodeTable[enable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
return true;
}
@@ -16557,9 +16250,9 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
// this also applies for transform auras
if (SpellInfo const* transform = sSpellMgr->GetSpellInfo(getTransForm()))
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (transform->Effects[i].IsAura(SPELL_AURA_TRANSFORM))
- if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(transform->Effects[i].MiscValue))
+ for (SpellEffectInfo const* effect : transform->GetEffectsForDifficulty(GetMap()->GetDifficulty()))
+ if (effect && effect->IsAura(SPELL_AURA_TRANSFORM))
+ if (CreatureTemplate const* transformInfo = sObjectMgr->GetCreatureTemplate(effect->MiscValue))
{
cinfo = transformInfo;
break;
@@ -16693,43 +16386,42 @@ int32 Unit::GetHighestExclusiveSameEffectSpellGroupValue(AuraEffect const* aurEf
bool Unit::IsHighestExclusiveAura(Aura const* aura, bool removeOtherAuraApplications /*= false*/)
{
- for (uint32 i = 0 ; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* aurEff : aura->GetAuraEffects())
{
- if (AuraEffect const* aurEff = aura->GetEffect(i))
+ if (!aurEff)
+ continue;
+ AuraType const auraType = AuraType(aurEff->GetSpellEffectInfo()->ApplyAuraName);
+ AuraEffectList const& auras = GetAuraEffectsByType(auraType);
+ for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end();)
{
- AuraType const auraType = AuraType(aura->GetSpellInfo()->Effects[i].ApplyAuraName);
- AuraEffectList const& auras = GetAuraEffectsByType(auraType);
- for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end();)
+ AuraEffect const* existingAurEff = (*itr);
+ ++itr;
+
+ if (sSpellMgr->CheckSpellGroupStackRules(aura->GetSpellInfo(), existingAurEff->GetSpellInfo())
+ == SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST)
{
- AuraEffect const* existingAurEff = (*itr);
- ++itr;
+ int32 diff = abs(aurEff->GetAmount()) - abs(existingAurEff->GetAmount());
+ if (!diff)
+ diff = int32(aura->GetEffectMask()) - int32(existingAurEff->GetBase()->GetEffectMask());
- if (sSpellMgr->CheckSpellGroupStackRules(aura->GetSpellInfo(), existingAurEff->GetSpellInfo())
- == SPELL_GROUP_STACK_RULE_EXCLUSIVE_HIGHEST)
+ if (diff > 0)
{
- int32 diff = abs(aurEff->GetAmount()) - abs(existingAurEff->GetAmount());
- if (!diff)
- diff = int32(aura->GetEffectMask()) - int32(existingAurEff->GetBase()->GetEffectMask());
-
- if (diff > 0)
+ Aura const* base = existingAurEff->GetBase();
+ // no removing of area auras from the original owner, as that completely cancels them
+ if (removeOtherAuraApplications && (!base->IsArea() || base->GetOwner() != this))
{
- Aura const* base = existingAurEff->GetBase();
- // no removing of area auras from the original owner, as that completely cancels them
- if (removeOtherAuraApplications && (!base->IsArea() || base->GetOwner() != this))
+ if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID()))
{
- if (AuraApplication* aurApp = existingAurEff->GetBase()->GetApplicationOfTarget(GetGUID()))
- {
- bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType);
- uint32 removedAuras = m_removedAurasCount;
- RemoveAura(aurApp);
- if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
- itr = auras.begin();
- }
+ bool hasMoreThanOneEffect = base->HasMoreThanOneEffectForType(auraType, GetMap()->GetDifficulty());
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aurApp);
+ if (hasMoreThanOneEffect || m_removedAurasCount > removedAuras + 1)
+ itr = auras.begin();
}
}
- else if (diff < 0)
- return false;
}
+ else if (diff < 0)
+ return false;
}
}
}
@@ -16766,9 +16458,9 @@ void Unit::Whisper(std::string const& text, Language language, Player* target, b
return;
LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex();
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale);
- target->SendDirectMessage(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale);
+ target->SendDirectMessage(packet.Write());
}
void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target)
@@ -16813,7 +16505,7 @@ void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/
}
LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex();
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale);
- target->SendDirectMessage(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale);
+ target->SendDirectMessage(packet.Write());
}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index b28d26af2c9..2b9b4d932ad 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -123,6 +123,36 @@ enum SpellValueMod
SPELLVALUE_BASE_POINT0,
SPELLVALUE_BASE_POINT1,
SPELLVALUE_BASE_POINT2,
+ SPELLVALUE_BASE_POINT3,
+ SPELLVALUE_BASE_POINT4,
+ SPELLVALUE_BASE_POINT5,
+ SPELLVALUE_BASE_POINT6,
+ SPELLVALUE_BASE_POINT7,
+ SPELLVALUE_BASE_POINT8,
+ SPELLVALUE_BASE_POINT9,
+ SPELLVALUE_BASE_POINT10,
+ SPELLVALUE_BASE_POINT11,
+ SPELLVALUE_BASE_POINT12,
+ SPELLVALUE_BASE_POINT13,
+ SPELLVALUE_BASE_POINT14,
+ SPELLVALUE_BASE_POINT15,
+ SPELLVALUE_BASE_POINT16,
+ SPELLVALUE_BASE_POINT17,
+ SPELLVALUE_BASE_POINT18,
+ SPELLVALUE_BASE_POINT19,
+ SPELLVALUE_BASE_POINT20,
+ SPELLVALUE_BASE_POINT21,
+ SPELLVALUE_BASE_POINT22,
+ SPELLVALUE_BASE_POINT23,
+ SPELLVALUE_BASE_POINT24,
+ SPELLVALUE_BASE_POINT25,
+ SPELLVALUE_BASE_POINT26,
+ SPELLVALUE_BASE_POINT27,
+ SPELLVALUE_BASE_POINT28,
+ SPELLVALUE_BASE_POINT29,
+ SPELLVALUE_BASE_POINT30,
+ SPELLVALUE_BASE_POINT31,
+ SPELLVALUE_BASE_POINT_END,
SPELLVALUE_RADIUS_MOD,
SPELLVALUE_MAX_TARGETS,
SPELLVALUE_AURA_STACK
@@ -191,6 +221,13 @@ enum UnitStandFlags
UNIT_STAND_FLAGS_ALL = 0xFF
};
+enum UnitBytes0Offsets
+{
+ UNIT_BYTES_0_OFFSET_RACE = 0,
+ UNIT_BYTES_0_OFFSET_CLASS = 1,
+ UNIT_BYTES_0_OFFSET_GENDER = 3,
+};
+
// byte flags value (UNIT_FIELD_BYTES_1, 3)
enum UnitBytes1_Flags
{
@@ -309,7 +346,7 @@ enum HitInfo
HITINFO_CRITICALHIT = 0x00000200, // critical hit
// 0x00000400
// 0x00000800
- // 0x00001000
+ HITINFO_UNK12 = 0x00001000,
HITINFO_BLOCK = 0x00002000, // blocked damage
// 0x00004000 // Hides worldtext for 0 damage
// 0x00008000 // Related to blood visual
@@ -340,6 +377,7 @@ class AuraEffect;
class Creature;
class Spell;
class SpellInfo;
+class SpellEffectInfo;
class DynamicObject;
class GameObject;
class Item;
@@ -1373,11 +1411,11 @@ class Unit : public WorldObject
uint8 getLevel() const { return uint8(GetUInt32Value(UNIT_FIELD_LEVEL)); }
uint8 getLevelForTarget(WorldObject const* /*target*/) const override { return getLevel(); }
void SetLevel(uint8 lvl);
- uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, 0); }
+ uint8 getRace() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_RACE); }
uint32 getRaceMask() const { return 1 << (getRace()-1); }
- uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, 1); }
+ uint8 getClass() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS); }
uint32 getClassMask() const { return 1 << (getClass()-1); }
- uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, 2); }
+ uint8 getGender() const { return GetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER); }
float GetStat(Stats stat) const { return float(GetUInt32Value(UNIT_FIELD_STAT+stat)); }
void SetStat(Stats stat, int32 val) { SetStatInt32Value(UNIT_FIELD_STAT+stat, val); }
@@ -1406,7 +1444,7 @@ class Unit : public WorldObject
int32 ModifyHealth(int32 val);
int32 GetHealthGain(int32 dVal);
- Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
+ Powers getPowerType() const { return Powers(GetUInt32Value(UNIT_FIELD_DISPLAY_POWER)); }
void setPowerType(Powers power);
int32 GetPower(Powers power) const;
int32 GetMinPower(Powers power) const { return power == POWER_ECLIPSE ? -100 : 0; }
@@ -1583,7 +1621,6 @@ class Unit : public WorldObject
int32 HealBySpell(Unit* victim, SpellInfo const* spellInfo, uint32 addHealth, bool critical = false);
void SendEnergizeSpellLog(Unit* victim, uint32 spellID, int32 damage, Powers powertype);
void EnergizeBySpell(Unit* victim, uint32 SpellID, int32 Damage, Powers powertype);
- uint32 SpellNonMeleeDamageLog(Unit* victim, uint32 spellID, uint32 damage);
void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid::Empty);
void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid::Empty);
@@ -1597,7 +1634,7 @@ class Unit : public WorldObject
void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid::Empty);
void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, ObjectGuid originalCaster = ObjectGuid::Empty);
Aura* AddAura(uint32 spellId, Unit* target);
- Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
+ Aura* AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
void SendPlaySpellVisualKit(uint32 id, uint32 unkParam);
void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown);
@@ -1730,11 +1767,11 @@ class Unit : public WorldObject
bool InitTamedPet(Pet* pet, uint8 level, uint32 spell_id);
// aura apply/remove helpers - you should better not use these
- Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
+ Aura* _TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
void _AddAura(UnitAura* aura, Unit* caster);
- AuraApplication * _CreateAuraApplication(Aura* aura, uint8 effMask);
+ AuraApplication * _CreateAuraApplication(Aura* aura, uint32 effMask);
void _ApplyAuraEffect(Aura* aura, uint8 effIndex);
- void _ApplyAura(AuraApplication * aurApp, uint8 effMask);
+ void _ApplyAura(AuraApplication * aurApp, uint32 effMask);
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
void _RemoveNoStackAuraApplicationsDueToAura(Aura* aura);
@@ -1747,21 +1784,21 @@ class Unit : public WorldObject
AuraMap const& GetOwnedAuras() const { return m_ownedAuras; }
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
- void RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
- Aura* GetOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, Aura* except = NULL) const;
+ Aura* GetOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, Aura* except = NULL) const;
// m_appliedAuras container management
AuraApplicationMap & GetAppliedAuras() { return m_appliedAuras; }
AuraApplicationMap const& GetAppliedAuras() const { return m_appliedAuras; }
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
- void RemoveAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(Aura* aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
- void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit* stealer);
@@ -1796,17 +1833,17 @@ class Unit : public WorldObject
AuraEffect* GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID = ObjectGuid::Empty) const;
AuraEffect* GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const;
- AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = NULL) const;
- Aura* GetAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const;
+ AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraApplication * except = NULL) const;
+ Aura* GetAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0) const;
- AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = NULL) const;
- Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const;
+ AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraApplication * except = NULL) const;
+ Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0) const;
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList);
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster = ObjectGuid::Empty) const;
uint32 GetAuraCount(uint32 spellId) const;
- bool HasAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const;
+ bool HasAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0) const;
bool HasAuraType(AuraType auraType) const;
bool HasAuraTypeWithCaster(AuraType auratype, ObjectGuid caster) const;
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const;
@@ -1994,14 +2031,14 @@ class Unit : public WorldObject
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const;
- uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
+ uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack = 1) const;
float SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const;
- uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack = 1) const;
+ uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack = 1) const;
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const;
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
- uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
+ uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack = 1) const;
float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
- uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;
+ uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, SpellEffectInfo const* effect, uint32 stack = 1) const;
uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL);
uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = NULL);
@@ -2028,7 +2065,7 @@ class Unit : public WorldObject
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index) const; // redefined in Creature
- static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
+ bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
uint32 CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK);
uint32 CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const;
void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL);
@@ -2040,7 +2077,7 @@ class Unit : public WorldObject
void SetSpeed(UnitMoveType mtype, float rate, bool forced = false);
float ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const;
- int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = NULL) const;
+ int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr, float* variance = nullptr) const;
int32 CalcSpellDuration(SpellInfo const* spellProto);
int32 ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask);
void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL);
@@ -2164,7 +2201,7 @@ class Unit : public WorldObject
TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; }
ObjectGuid GetTarget() const { return GetGuidValue(UNIT_FIELD_TARGET); }
- virtual void SetTarget(ObjectGuid /*guid*/) = 0;
+ virtual void SetTarget(ObjectGuid const& /*guid*/) = 0;
// Movement info
Movement::MoveSpline * movespline;
@@ -2265,7 +2302,6 @@ class Unit : public WorldObject
void DisableSpline();
private:
bool IsTriggeredAtSpellProcEvent(Unit* victim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const* & spellProcEvent);
- bool HandleAuraProcOnPowerAmount(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled);
bool HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 90a40aa7990..4da985c7bb6 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -155,6 +155,16 @@ bool normalizePlayerName(std::string& name)
return true;
}
+// Extracts player and realm names delimited by -
+ExtendedPlayerName ExtractExtendedPlayerName(std::string& name)
+{
+ size_t pos = name.find('-');
+ if (pos != std::string::npos)
+ return ExtendedPlayerName(name.substr(0, pos), name.substr(pos+1));
+ else
+ return ExtendedPlayerName(name, "");
+}
+
LanguageDesc lang_description[LANGUAGES_COUNT] =
{
{ LANG_ADDON, 0, 0 },
@@ -472,8 +482,8 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.SubName = fields[12].GetString();
creatureTemplate.IconName = fields[13].GetString();
creatureTemplate.GossipMenuId = fields[14].GetUInt32();
- creatureTemplate.minlevel = fields[15].GetUInt8();
- creatureTemplate.maxlevel = fields[16].GetUInt8();
+ creatureTemplate.minlevel = fields[15].GetInt16();
+ creatureTemplate.maxlevel = fields[16].GetInt16();
creatureTemplate.expansion = uint32(fields[17].GetInt16());
creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16());
creatureTemplate.faction = uint32(fields[19].GetUInt16());
@@ -574,17 +584,17 @@ void ObjectMgr::LoadCreatureTemplateAddons()
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
+ SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr));
if (!AdditionalSpellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has wrong spell %lu defined in `auras` field in `creature_template_addon`.", entry, atoul(*itr));
continue;
}
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
+ if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, uint32(atol(*itr)));
- creatureAddon.auras[i++] = uint32(atol(*itr));
+ creatureAddon.auras[i++] = atoul(*itr);
}
if (creatureAddon.mount)
@@ -664,18 +674,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
cInfo->Entry, cInfo->expansion, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->expansion);
}
- if (cInfo->minlevel > difficultyInfo->minlevel)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, minlevel %u) has lower `minlevel` in difficulty %u mode (Entry: %u, minlevel %u).",
- cInfo->Entry, cInfo->minlevel, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->minlevel);
- }
-
- if (cInfo->maxlevel > difficultyInfo->maxlevel)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, maxlevel %u) has lower `maxlevel` in difficulty %u mode (Entry: %u, maxlevel %u).",
- cInfo->Entry, cInfo->maxlevel, diff + 1, cInfo->DifficultyEntry[diff], difficultyInfo->maxlevel);
- }
-
if (cInfo->faction != difficultyInfo->faction)
{
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, faction %u) has different `faction` in difficulty %u mode (Entry: %u, faction %u).",
@@ -973,6 +971,27 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
const_cast<CreatureTemplate*>(cInfo)->flags_extra &= CREATURE_FLAG_EXTRA_DB_ALLOWED;
}
+ // -1 is used in the client for auto-updating the levels
+ // having their expansion set to it to the latest one
+ if (cInfo->expansion == -1)
+ {
+ const_cast<CreatureTemplate*>(cInfo)->minlevel = (MAX_LEVEL + cInfo->minlevel);
+ const_cast<CreatureTemplate*>(cInfo)->maxlevel = (MAX_LEVEL + cInfo->maxlevel);
+ const_cast<CreatureTemplate*>(cInfo)->expansion = EXPANSION_WARLORDS_OF_DRAENOR;
+ }
+
+ if (cInfo->minlevel < 1 || cInfo->minlevel > STRONG_MAX_LEVEL)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (ID: %u): MinLevel %i is not within [1, 255], value has been set to 1.", cInfo->Entry, cInfo->minlevel);
+ const_cast<CreatureTemplate*>(cInfo)->minlevel = 1;
+ }
+
+ if (cInfo->maxlevel < 1 || cInfo->maxlevel > STRONG_MAX_LEVEL)
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (ID: %u): MaxLevel %i is not within [1, 255], value has been set to 1.", cInfo->Entry, cInfo->maxlevel);
+ const_cast<CreatureTemplate*>(cInfo)->maxlevel = 1;
+ }
+
const_cast<CreatureTemplate*>(cInfo)->ModDamage *= Creature::_GetDamageMod(cInfo->rank);
}
@@ -1022,17 +1041,18 @@ void ObjectMgr::LoadCreatureAddons()
creatureAddon.auras.resize(tokens.size());
for (Tokenizer::const_iterator itr = tokens.begin(); itr != tokens.end(); ++itr)
{
- SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(uint32(atol(*itr)));
+ SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(atoul(*itr));
if (!AdditionalSpellInfo)
{
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has wrong spell %lu defined in `auras` field in `creature_addon`.", guid, atoul(*itr));
continue;
}
- if (AdditionalSpellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+ if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %lu defined in `auras` field in `creature_addon`.", guid, uint32(atol(*itr)));
+
- creatureAddon.auras[i++] = uint32(atol(*itr));
+ creatureAddon.auras[i++] = atoul(*itr);
}
if (creatureAddon.mount)
@@ -1222,15 +1242,15 @@ CreatureModelInfo const* ObjectMgr::GetCreatureModelRandomGender(uint32* display
return NULL;
// If a model for another gender exists, 50% chance to use it
- if (modelInfo->modelid_other_gender != 0 && urand(0, 1) == 0)
+ if (modelInfo->displayId_other_gender != 0 && urand(0, 1) == 0)
{
- CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->modelid_other_gender);
+ CreatureModelInfo const* minfo_tmp = GetCreatureModelInfo(modelInfo->displayId_other_gender);
if (!minfo_tmp)
- TC_LOG_ERROR("sql.sql", "Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", *displayID, modelInfo->modelid_other_gender);
+ TC_LOG_ERROR("sql.sql", "Model (Entry: %u) has modelid_other_gender %u not found in table `creature_model_info`. ", *displayID, modelInfo->displayId_other_gender);
else
{
- // Model ID changed
- *displayID = modelInfo->modelid_other_gender;
+ // DisplayID changed
+ *displayID = modelInfo->displayId_other_gender;
return minfo_tmp;
}
}
@@ -1242,7 +1262,7 @@ void ObjectMgr::LoadCreatureModelInfo()
{
uint32 oldMSTime = getMSTime();
- QueryResult result = WorldDatabase.Query("SELECT modelid, bounding_radius, combat_reach, gender, modelid_other_gender FROM creature_model_info");
+ QueryResult result = WorldDatabase.Query("SELECT DisplayID, BoundingRadius, CombatReach, DisplayID_Other_Gender FROM creature_model_info");
if (!result)
{
@@ -1257,30 +1277,36 @@ void ObjectMgr::LoadCreatureModelInfo()
{
Field* fields = result->Fetch();
- uint32 modelId = fields[0].GetUInt32();
+ uint32 displayId = fields[0].GetUInt32();
+
+ CreatureDisplayInfoEntry const* creatureDisplay = sCreatureDisplayInfoStore.LookupEntry(displayId);
+ if (!creatureDisplay)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has a non-existent DisplayID (ID: %u). Skipped.", displayId);
+ continue;
+ }
- CreatureModelInfo& modelInfo = _creatureModelStore[modelId];
+ CreatureModelInfo& modelInfo = _creatureModelStore[displayId];
- modelInfo.bounding_radius = fields[1].GetFloat();
- modelInfo.combat_reach = fields[2].GetFloat();
- modelInfo.gender = fields[3].GetUInt8();
- modelInfo.modelid_other_gender = fields[4].GetUInt32();
+ modelInfo.bounding_radius = fields[1].GetFloat();
+ modelInfo.combat_reach = fields[2].GetFloat();
+ modelInfo.displayId_other_gender = fields[3].GetUInt32();
+ modelInfo.gender = creatureDisplay->Gender;
// Checks
- if (!sCreatureDisplayInfoStore.LookupEntry(modelId))
- TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has model for nonexistent display id (%u).", modelId);
-
- if (modelInfo.gender > GENDER_NONE)
+ // to remove when the purpose of GENDER_UNKNOWN is known
+ if (modelInfo.gender == GENDER_UNKNOWN)
{
- TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has wrong gender (%u) for display id (%u).", uint32(modelInfo.gender), modelId);
+ // We don't need more errors
+ //TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has an unimplemented Gender (ID: %i) being used by DisplayID (ID: %u). Gender set to GENDER_MALE.", modelInfo.gender, modelId);
modelInfo.gender = GENDER_MALE;
}
- if (modelInfo.modelid_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.modelid_other_gender))
+ if (modelInfo.displayId_other_gender && !sCreatureDisplayInfoStore.LookupEntry(modelInfo.displayId_other_gender))
{
- TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has nonexistent alt.gender model (%u) for existed display id (%u).", modelInfo.modelid_other_gender, modelId);
- modelInfo.modelid_other_gender = 0;
+ TC_LOG_ERROR("sql.sql", "Table `creature_model_info` has a non-existent DisplayID_Other_Gender (ID: %u) being used by DisplayID (ID: %u).", modelInfo.displayId_other_gender, displayId);
+ modelInfo.displayId_other_gender = 0;
}
if (modelInfo.combat_reach < 0.1f)
@@ -2301,8 +2327,7 @@ void FillItemDamageFields(float* minDamage, float* maxDamage, float* dps, uint32
return;
}
- if (!store)
- return;
+ ASSERT(store);
ItemDamageEntry const* damageInfo = store->LookupEntry(itemLevel);
if (!damageInfo)
@@ -2492,7 +2517,9 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.SubClass = db2Data->SubClass;
itemTemplate.SoundOverrideSubclass = db2Data->SoundOverrideSubclass;
itemTemplate.Name1 = sparse->Name->Str[sWorld->GetDefaultDbcLocale()];
- itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->AppearanceID);
+ itemTemplate.DisplayInfoID = GetItemDisplayID(db2Data->FileDataID);
+ itemTemplate.FileDataID = db2Data->FileDataID;
+ itemTemplate.GroupSoundsID = db2Data->GroupSoundsID;
itemTemplate.Quality = sparse->Quality;
memcpy(itemTemplate.Flags, sparse->Flags, sizeof(itemTemplate.Flags));
itemTemplate.Unk1 = sparse->Unk1;
@@ -2571,6 +2598,7 @@ void ObjectMgr::LoadItemTemplates()
itemTemplate.StatScalingFactor = sparse->StatScalingFactor;
itemTemplate.CurrencySubstitutionId = sparse->CurrencySubstitutionID;
itemTemplate.CurrencySubstitutionCount = sparse->CurrencySubstitutionCount;
+ itemTemplate.ItemNameDescriptionID = sparse->ItemNameDescriptionID;
itemTemplate.ScriptId = 0;
itemTemplate.FoodType = 0;
itemTemplate.MinMoneyLoot = 0;
@@ -2590,7 +2618,7 @@ void ObjectMgr::LoadItemTemplates()
continue;
ItemTemplate& itemTemplate = itemItr->second;
-
+
ItemEffect effect;
effect.SpellID = effectEntry->SpellID;
effect.Trigger = effectEntry->Trigger;
@@ -3250,7 +3278,6 @@ void ObjectMgr::LoadPlayerInfo()
}
}
-
// Load playercreate skills
TC_LOG_INFO("server.loading", "Loading Player Create Skill Data...");
{
@@ -3325,8 +3352,8 @@ void ObjectMgr::LoadPlayerInfo()
}
}
- // Load playercreate spells
- TC_LOG_INFO("server.loading", "Loading Player Create Spell Data...");
+ // Load playercreate custom spells
+ TC_LOG_INFO("server.loading", "Loading Player Create Custom Spell Data...");
{
uint32 oldMSTime = getMSTime();
@@ -3334,7 +3361,7 @@ void ObjectMgr::LoadPlayerInfo()
if (!result)
{
- TC_LOG_ERROR("server.loading", ">> Loaded 0 player create spells. DB table `playercreateinfo_spell_custom` is empty.");
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 player create custom spells. DB table `playercreateinfo_spell_custom` is empty.");
}
else
{
@@ -3665,8 +3692,8 @@ void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& base
if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
- GtOCTBaseHPByClassEntry const* hp = sGtOCTBaseHPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1);
- GtOCTBaseMPByClassEntry const* mp = sGtOCTBaseMPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1);
+ GtOCTBaseHPByClassEntry const* hp = sGtOCTBaseHPByClassStore.EvaluateTable(level - 1, class_ - 1);
+ GtOCTBaseMPByClassEntry const* mp = sGtOCTBaseMPByClassStore.EvaluateTable(level - 1, class_ - 1);
if (!hp || !mp)
{
@@ -4501,12 +4528,12 @@ void ObjectMgr::LoadQuests()
if (!spellInfo)
continue;
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[j].Effect != SPELL_EFFECT_QUEST_COMPLETE)
+ if (!effect || effect->Effect != SPELL_EFFECT_QUEST_COMPLETE)
continue;
- uint32 quest_id = spellInfo->Effects[j].MiscValue;
+ uint32 quest_id = effect->MiscValue;
Quest const* quest = GetQuestTemplate(quest_id);
@@ -4911,7 +4938,8 @@ void ObjectMgr::LoadSpellScripts()
uint8 i = (uint8)((uint32(itr->first) >> 24) & 0x000000FF);
//check for correct spellEffect
- if (!spellInfo->Effects[i].Effect || (spellInfo->Effects[i].Effect != SPELL_EFFECT_SCRIPT_EFFECT && spellInfo->Effects[i].Effect != SPELL_EFFECT_DUMMY))
+ SpellEffectInfo const* effect = spellInfo->GetEffect(i);
+ if (effect && (!effect->Effect || (effect->Effect != SPELL_EFFECT_SCRIPT_EFFECT && effect->Effect != SPELL_EFFECT_DUMMY)))
TC_LOG_ERROR("sql.sql", "Table `spell_scripts` - spell %u effect %u is not SPELL_EFFECT_SCRIPT_EFFECT or SPELL_EFFECT_DUMMY", spellId, i);
}
}
@@ -4930,10 +4958,10 @@ void ObjectMgr::LoadEventScripts()
// Load all possible script entries from spells
for (uint32 i = 1; i < sSpellMgr->GetSpellInfoStoreSize(); ++i)
if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(i))
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
- if (spell->Effects[j].Effect == SPELL_EFFECT_SEND_EVENT)
- if (spell->Effects[j].MiscValue)
- evt_scripts.insert(spell->Effects[j].MiscValue);
+ for (SpellEffectInfo const* effect : spell->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ if (effect && effect->Effect == SPELL_EFFECT_SEND_EVENT)
+ if (effect->MiscValue)
+ evt_scripts.insert(effect->MiscValue);
for (size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx)
{
@@ -5687,35 +5715,32 @@ void ObjectMgr::LoadAreaTriggerScripts()
uint32 oldMSTime = getMSTime();
_areaTriggerScriptStore.clear(); // need for reload case
- QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
+ QueryResult result = WorldDatabase.Query("SELECT entry, ScriptName FROM areatrigger_scripts");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 areatrigger scripts. DB table `areatrigger_scripts` is empty.");
return;
}
- uint32 count = 0;
-
do
{
- ++count;
-
Field* fields = result->Fetch();
- uint32 Trigger_ID = fields[0].GetUInt32();
- const char *scriptName = fields[1].GetCString();
+ uint32 triggerId = fields[0].GetUInt32();
+ char const* scriptName = fields[1].GetCString();
- AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID);
+ AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(triggerId);
if (!atEntry)
{
- TC_LOG_ERROR("sql.sql", "Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.", Trigger_ID);
+ TC_LOG_ERROR("sql.sql", "AreaTrigger (ID: %u) does not exist in `AreaTrigger.dbc`.", triggerId);
continue;
}
- _areaTriggerScriptStore[Trigger_ID] = GetScriptId(scriptName);
- } while (result->NextRow());
+ _areaTriggerScriptStore[triggerId] = GetScriptId(scriptName);
+ }
+ while (result->NextRow());
- TC_LOG_INFO("server.loading", ">> Loaded %u areatrigger scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " areatrigger scripts in %u ms", _areaTriggerScriptStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 team)
@@ -8114,25 +8139,25 @@ void ObjectMgr::AddSpellToTrainer(uint32 ID, uint32 SpellID, uint32 MoneyCost, u
// calculate learned spell for profession case when stored cast-spell
trainerSpell.ReqAbility[0] = SpellID;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellinfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellinfo->Effects[i].Effect != SPELL_EFFECT_LEARN_SPELL)
+ if (!effect || effect->Effect != SPELL_EFFECT_LEARN_SPELL)
continue;
if (trainerSpell.ReqAbility[0] == SpellID)
trainerSpell.ReqAbility[0] = 0;
// player must be able to cast spell on himself
- if (spellinfo->Effects[i].TargetA.GetTarget() != 0 && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_TARGET_ALLY
- && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_TARGET_ANY && spellinfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() != 0 && effect->TargetA.GetTarget() != TARGET_UNIT_TARGET_ALLY
+ && effect->TargetA.GetTarget() != TARGET_UNIT_TARGET_ANY && effect->TargetA.GetTarget() != TARGET_UNIT_CASTER)
{
TC_LOG_ERROR("sql.sql", "Table `npc_trainer` has spell %u for trainer entry %u with learn effect which has incorrect target type, ignoring learn effect!", SpellID, ID);
continue;
}
- trainerSpell.ReqAbility[i] = spellinfo->Effects[i].TriggerSpell;
+ trainerSpell.ReqAbility[effect->EffectIndex] = effect->TriggerSpell;
- if (trainerSpell.ReqAbility[i])
+ if (trainerSpell.ReqAbility[effect->EffectIndex])
{
- SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(trainerSpell.ReqAbility[i]);
+ SpellInfo const* learnedSpellInfo = sSpellMgr->GetSpellInfo(trainerSpell.ReqAbility[effect->EffectIndex]);
if (learnedSpellInfo && learnedSpellInfo->IsProfession())
data.trainerType = 2;
}
@@ -8529,31 +8554,32 @@ void ObjectMgr::LoadScriptNames()
{
uint32 oldMSTime = getMSTime();
- _scriptNamesStore.push_back("");
+ _scriptNamesStore.emplace_back("");
+
QueryResult result = WorldDatabase.Query(
- "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
- "UNION "
- "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
+ "SELECT DISTINCT(ScriptName) FROM achievement_criteria_data WHERE ScriptName <> '' AND type = 11 "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM battleground_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM spell_script_names WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM transports WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM game_weather WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM conditions WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(ScriptName) FROM outdoorpvp_template WHERE ScriptName <> '' "
+ "UNION "
+ "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''");
if (!result)
{
@@ -8561,20 +8587,23 @@ void ObjectMgr::LoadScriptNames()
return;
}
- uint32 count = 1;
-
do
{
- _scriptNamesStore.push_back((*result)[0].GetString());
- ++count;
+ _scriptNamesStore.emplace_back((*result)[0].GetCString());
}
while (result->NextRow());
std::sort(_scriptNamesStore.begin(), _scriptNamesStore.end());
- TC_LOG_INFO("server.loading", ">> Loaded %d Script Names in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+
+#ifdef SCRIPTS
+ for (size_t i = 1; i < _scriptNamesStore.size(); ++i)
+ UnusedScriptNames.push_back(_scriptNamesStore[i]);
+#endif
+
+ TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " ScriptNames in %u ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
-uint32 ObjectMgr::GetScriptId(const char *name)
+uint32 ObjectMgr::GetScriptId(char const* name)
{
// use binary search to find the script name in the sorted vector
// assume "" is the first element
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index bb392caeffb..14f845dcd1b 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -677,6 +677,15 @@ SkillRangeType GetSkillRangeType(SkillRaceClassInfoEntry const* rcEntry);
bool normalizePlayerName(std::string& name);
+struct ExtendedPlayerName
+{
+ ExtendedPlayerName(std::string const& name, std::string const& realm) : Name(name), Realm(realm) {}
+ std::string Name;
+ std::string Realm;
+};
+
+ExtendedPlayerName ExtractExtendedPlayerName(std::string& name);
+
struct LanguageDesc
{
Language lang_id;
@@ -1277,9 +1286,8 @@ class ObjectMgr
bool IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
void LoadScriptNames();
- ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; }
- const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
- uint32 GetScriptId(const char *name);
+ char const* GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
+ uint32 GetScriptId(char const* name);
SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
{
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index ae3bef5a8df..b693d2e13ac 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -33,6 +33,7 @@
#include "CreatureAI.h"
#include "Spell.h"
#include "WorldSession.h"
+#include "Packets/ChatPackets.h"
class Player;
//class Map;
@@ -125,11 +126,11 @@ namespace Trinity
struct MessageDistDeliverer
{
WorldObject* i_source;
- WorldPacket* i_message;
+ WorldPacket const* i_message;
float i_distSq;
uint32 team;
Player const* skipped_receiver;
- MessageDistDeliverer(WorldObject* src, WorldPacket* msg, float dist, bool own_team_only = false, Player const* skipped = NULL)
+ MessageDistDeliverer(WorldObject* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = NULL)
: i_source(src), i_message(msg), i_distSq(dist * dist)
, team(0)
, skipped_receiver(skipped)
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index c4e4b6f21ae..9c4a2a5a2d1 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -54,7 +54,7 @@ Loot* Roll::getLoot()
}
Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL),
-m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL),
+m_dungeonDifficulty(DIFFICULTY_NORMAL), m_raidDifficulty(DIFFICULTY_10_N),
m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(),
m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0)
{
@@ -111,8 +111,8 @@ bool Group::Create(Player* leader)
m_looterGuid = leaderGuid;
m_masterLooterGuid.Clear();
- m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL;
- m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
+ m_dungeonDifficulty = DIFFICULTY_NORMAL;
+ m_raidDifficulty = DIFFICULTY_10_N;
if (!isBGGroup() && !isBFGroup())
{
@@ -182,13 +182,13 @@ void Group::LoadGroupFromDB(Field* fields)
uint32 diff = fields[13].GetUInt8();
if (diff >= MAX_DUNGEON_DIFFICULTY)
- m_dungeonDifficulty = DUNGEON_DIFFICULTY_NORMAL;
+ m_dungeonDifficulty = DIFFICULTY_NORMAL;
else
m_dungeonDifficulty = Difficulty(diff);
uint32 r_diff = fields[14].GetUInt8();
if (r_diff >= MAX_RAID_DIFFICULTY)
- m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
+ m_raidDifficulty = DIFFICULTY_10_N;
else
m_raidDifficulty = Difficulty(r_diff);
@@ -1623,7 +1623,7 @@ void Group::UpdatePlayerOutOfRange(Player* player)
}
}
-void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/)
+void Group::BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignore /*= ObjectGuid::Empty*/)
{
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1638,7 +1638,7 @@ void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string&
}
}
-void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer)
+void Group::BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group, ObjectGuid ignoredPlayer)
{
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -1651,7 +1651,7 @@ void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int
}
}
-void Group::BroadcastReadyCheck(WorldPacket* packet)
+void Group::BroadcastReadyCheck(WorldPacket const* packet)
{
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -2008,7 +2008,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo)
if (method == INSTANCE_RESET_ALL)
{
// the "reset all instances" method can only reset normal maps
- if (entry->IsRaid() || diff == DUNGEON_DIFFICULTY_HEROIC)
+ if (entry->IsRaid() || diff == DIFFICULTY_HEROIC)
{
++itr;
continue;
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 0bdfbf24a71..6216b7323b0 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -288,9 +288,9 @@ class Group
worker(itr->GetSource());
}
- void BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty);
- void BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty);
- void BroadcastReadyCheck(WorldPacket* packet);
+ void BroadcastPacket(WorldPacket const* packet, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignoredPlayer = ObjectGuid::Empty);
+ void BroadcastAddonMessagePacket(WorldPacket const* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, ObjectGuid ignore = ObjectGuid::Empty);
+ void BroadcastReadyCheck(WorldPacket const* packet);
void OfflineReadyCheck();
/*********************************************************/
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index 4fb361209c1..0b703d4bcb2 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -30,6 +30,7 @@
#include "ScriptMgr.h"
#include "SocialMgr.h"
#include "Opcodes.h"
+#include "ChatPackets.h"
#define MAX_GUILD_BANK_TAB_TEXT_LEN 500
#define EMBLEM_PRICE 10 * GOLD
@@ -1481,23 +1482,23 @@ void Guild::SendQueryResponse(WorldSession* session)
response.GuildGuid = GetGUID();
response.Info.HasValue = true;
- response.Info.value.GuildGUID = GetGUID();
- response.Info.value.VirtualRealmAddress = GetVirtualRealmAddress();
+ response.Info.Value.GuildGUID = GetGUID();
+ response.Info.Value.VirtualRealmAddress = GetVirtualRealmAddress();
- response.Info.value.EmblemStyle = m_emblemInfo.GetStyle();
- response.Info.value.EmblemColor = m_emblemInfo.GetColor();
- response.Info.value.BorderStyle = m_emblemInfo.GetBorderStyle();
- response.Info.value.BorderColor = m_emblemInfo.GetBorderColor();
- response.Info.value.BackgroundColor = m_emblemInfo.GetBackgroundColor();
+ response.Info.Value.EmblemStyle = m_emblemInfo.GetStyle();
+ response.Info.Value.EmblemColor = m_emblemInfo.GetColor();
+ response.Info.Value.BorderStyle = m_emblemInfo.GetBorderStyle();
+ response.Info.Value.BorderColor = m_emblemInfo.GetBorderColor();
+ response.Info.Value.BackgroundColor = m_emblemInfo.GetBackgroundColor();
for (uint8 i = 0; i < _GetRanksSize(); ++i)
{
WorldPackets::Guild::QueryGuildInfoResponse::GuildInfo::GuildInfoRank info
(m_ranks[i].GetId(), i, m_ranks[i].GetName());
- response.Info.value.Ranks.insert(info);
+ response.Info.Value.Ranks.insert(info);
}
- response.Info.value.GuildName = m_name;
+ response.Info.Value.GuildName = m_name;
session->SendPacket(response.Write());
TC_LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str());
@@ -2593,13 +2594,14 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin
{
if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK))
{
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, Language(language), session->GetPlayer(), NULL, msg);
+ WorldPacket const* data = packet.Write();
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (Player* player = itr->second->FindConnectedPlayer())
if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
!player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID()))
- player->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(data);
}
}
@@ -2607,14 +2609,15 @@ void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::
{
if (session && session->GetPlayer() && _HasRankRight(session->GetPlayer(), officerOnly ? GR_RIGHT_OFFCHATSPEAK : GR_RIGHT_GCHATSPEAK))
{
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, officerOnly ? CHAT_MSG_OFFICER : CHAT_MSG_GUILD, LANG_ADDON, session->GetPlayer(), NULL, msg, 0, "", DEFAULT_LOCALE, prefix);
+ WorldPacket const* data = packet.Write();
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if (Player* player = itr->second->FindPlayer())
if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) &&
!player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID()) &&
player->GetSession()->IsAddonRegistered(prefix))
- player->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(data);
}
}
diff --git a/src/server/game/Guilds/GuildFinderMgr.cpp b/src/server/game/Guilds/GuildFinderMgr.cpp
index 67a00d3dff8..40e2bc1613e 100644
--- a/src/server/game/Guilds/GuildFinderMgr.cpp
+++ b/src/server/game/Guilds/GuildFinderMgr.cpp
@@ -129,11 +129,11 @@ void GuildFinderMgr::AddMembershipRequest(ObjectGuid const& guildGuid, Membershi
// Notify the applicant his submittion has been added
if (Player* player = ObjectAccessor::FindPlayer(request.GetPlayerGUID()))
- SendMembershipRequestListUpdate(*player);
+ SendMembershipRequestListUpdate(player);
// Notify the guild master and officers the list changed
if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
- SendApplicantListUpdate(*guild);
+ SendApplicantListUpdate(guild);
}
void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(ObjectGuid const& playerId)
@@ -159,7 +159,7 @@ void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(ObjectGuid const& pla
// Notify the guild master and officers the list changed
if (Guild* guild = sGuildMgr->GetGuildByGuid(itr->first))
- SendApplicantListUpdate(*guild);
+ SendApplicantListUpdate(guild);
}
}
@@ -182,15 +182,15 @@ void GuildFinderMgr::RemoveMembershipRequest(ObjectGuid const& playerId, ObjectG
CharacterDatabase.CommitTransaction(trans);
- _membershipRequests[guildId].erase(itr);
-
// Notify the applicant his submittion has been removed
if (Player* player = ObjectAccessor::FindPlayer(itr->GetPlayerGUID()))
- SendMembershipRequestListUpdate(*player);
+ SendMembershipRequestListUpdate(player);
// Notify the guild master and officers the list changed
if (Guild* guild = sGuildMgr->GetGuildByGuid(guildId))
- SendApplicantListUpdate(*guild);
+ SendApplicantListUpdate(guild);
+
+ _membershipRequests[guildId].erase(itr);
}
std::list<MembershipRequest> GuildFinderMgr::GetAllMembershipRequestsForPlayer(ObjectGuid const& playerGuid)
@@ -302,7 +302,7 @@ void GuildFinderMgr::DeleteGuild(ObjectGuid const& guildId)
// Notify the applicant his submition has been removed
if (Player* player = ObjectAccessor::FindPlayer(itr->GetPlayerGUID()))
- SendMembershipRequestListUpdate(*player);
+ SendMembershipRequestListUpdate(player);
++itr;
}
@@ -312,19 +312,19 @@ void GuildFinderMgr::DeleteGuild(ObjectGuid const& guildId)
// Notify the guild master the list changed (even if he's not a GM any more, not sure if needed)
if (Guild* guild = sGuildMgr->GetGuildByGuid(guildId))
- SendApplicantListUpdate(*guild);
+ SendApplicantListUpdate(guild);
}
-void GuildFinderMgr::SendApplicantListUpdate(Guild& guild)
+void GuildFinderMgr::SendApplicantListUpdate(Guild* guild)
{
WorldPacket data(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, 0);
- if (Player* player = ObjectAccessor::FindPlayer(guild.GetLeaderGUID()))
+ if (Player* player = ObjectAccessor::FindPlayer(guild->GetLeaderGUID()))
player->SendDirectMessage(&data);
- guild.BroadcastPacketToRank(&data, GR_OFFICER);
+ guild->BroadcastPacketToRank(&data, GR_OFFICER);
}
-void GuildFinderMgr::SendMembershipRequestListUpdate(Player& player)
+void GuildFinderMgr::SendMembershipRequestListUpdate(Player* player)
{
WorldPacket data(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, 0);
- player.SendDirectMessage(&data);
+ player->SendDirectMessage(&data);
}
diff --git a/src/server/game/Guilds/GuildFinderMgr.h b/src/server/game/Guilds/GuildFinderMgr.h
index 45228957b55..763d9285b31 100644
--- a/src/server/game/Guilds/GuildFinderMgr.h
+++ b/src/server/game/Guilds/GuildFinderMgr.h
@@ -262,8 +262,8 @@ class GuildFinderMgr
/// Counts the amount of pending membership requests, given the player's db guid.
uint8 CountRequestsFromPlayer(ObjectGuid const& playerId);
- void SendApplicantListUpdate(Guild& guild);
- void SendMembershipRequestListUpdate(Player& player);
+ static void SendApplicantListUpdate(Guild* guild);
+ static void SendMembershipRequestListUpdate(Player* player);
static GuildFinderMgr* instance()
{
diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp
index c9e1e6508b9..d8b8f4fe018 100644
--- a/src/server/game/Handlers/AuthHandler.cpp
+++ b/src/server/game/Handlers/AuthHandler.cpp
@@ -27,20 +27,20 @@ void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
response.SuccessInfo.HasValue = code == AUTH_OK;
response.Result = code;
response.WaitInfo.HasValue = queued;
- response.WaitInfo.value.WaitCount = queuePos;
+ response.WaitInfo.Value.WaitCount = queuePos;
if (code == AUTH_OK)
{
- response.SuccessInfo.value.AccountExpansionLevel = Expansion();
- response.SuccessInfo.value.ActiveExpansionLevel = Expansion();
- response.SuccessInfo.value.VirtualRealmAddress = GetVirtualRealmAddress();
+ response.SuccessInfo.Value.AccountExpansionLevel = Expansion();
+ response.SuccessInfo.Value.ActiveExpansionLevel = Expansion();
+ response.SuccessInfo.Value.VirtualRealmAddress = GetVirtualRealmAddress();
std::string realmName = sObjectMgr->GetRealmName(realmHandle.Index);
// Send current home realm. Also there is no need to send it later in realm queries.
- response.SuccessInfo.value.VirtualRealms.emplace_back(GetVirtualRealmAddress(), true, false, realmName, realmName);
+ response.SuccessInfo.Value.VirtualRealms.emplace_back(GetVirtualRealmAddress(), true, false, realmName, realmName);
- response.SuccessInfo.value.AvailableClasses = &sObjectMgr->GetClassExpansionRequirements();
- response.SuccessInfo.value.AvailableRaces = &sObjectMgr->GetRaceExpansionRequirements();
+ response.SuccessInfo.Value.AvailableClasses = &sObjectMgr->GetClassExpansionRequirements();
+ response.SuccessInfo.Value.AvailableRaces = &sObjectMgr->GetRaceExpansionRequirements();
}
SendPacket(response.Write());
@@ -60,7 +60,7 @@ void WorldSession::SendAuthWaitQue(uint32 position)
{
response.WaitInfo.HasValue = true;
response.SuccessInfo.HasValue = false;
- response.WaitInfo.value.WaitCount = position;
+ response.WaitInfo.Value.WaitCount = position;
response.Result = AUTH_WAIT_QUEUE;
}
diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp
index 649e5ff171f..14928e1efdc 100644
--- a/src/server/game/Handlers/BattlefieldHandler.cpp
+++ b/src/server/game/Handlers/BattlefieldHandler.cpp
@@ -27,7 +27,7 @@
#include "BattlefieldMgr.h"
/**
- * @fn void WorldSession::SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 acceptTime)
+ * @fn void WorldSession::SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint32 acceptTime)
*
* @brief This send to player windows for invite player to join the war.
*
@@ -62,7 +62,7 @@ void WorldSession::SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint3
}
/**
- * @fn void WorldSession::SendBfInvitePlayerToQueue(uint64 guid)
+ * @fn void WorldSession::SendBfInvitePlayerToQueue(ObjectGuid guid)
*
* @brief This send invitation to player to join the queue.
*
@@ -103,7 +103,7 @@ void WorldSession::SendBfInvitePlayerToQueue(ObjectGuid guid)
}
/**
- * @fn void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 zoneId, bool canQueue, bool full)
+ * @fn void WorldSession::SendBfQueueInviteResponse(ObjectGuid guid, uint32 zoneId, bool canQueue, bool full)
*
* @brief This send packet for inform player that he join queue.
*
@@ -157,7 +157,7 @@ void WorldSession::SendBfQueueInviteResponse(ObjectGuid guid, uint32 zoneId, boo
}
/**
- * @fn void WorldSession::SendBfEntered(uint64 guid)
+ * @fn void WorldSession::SendBfEntered(ObjectGuid guid)
*
* @brief This is call when player accept to join war.
*
@@ -196,7 +196,7 @@ void WorldSession::SendBfEntered(ObjectGuid guid)
}
/**
- * @fn void WorldSession::SendBfLeaveMessage(uint64 guid, BFLeaveReason reason)
+ * @fn void WorldSession::SendBfLeaveMessage(ObjectGuid guid, BFLeaveReason reason)
*
* @brief This is call when player leave battlefield zone.
*
diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp
index 5826415a201..c6cd5337c5b 100644
--- a/src/server/game/Handlers/ChannelHandler.cpp
+++ b/src/server/game/Handlers/ChannelHandler.cpp
@@ -18,31 +18,20 @@
#include "ObjectMgr.h" // for normalizePlayerName
#include "ChannelMgr.h"
+#include "ChannelPackets.h"
#include "Player.h"
#include "WorldSession.h"
#include <cctype>
-void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
+void WorldSession::HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet)
{
- uint32 channelId;
- uint32 channelLength, passLength;
- std::string channelName, password;
+ TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL %s ChatChannelId: %u, CreateVoiceSession: %u, Internal: %u, ChannelName: %s, Password: %s",
+ GetPlayerInfo().c_str(), packet.ChatChannelId, packet.CreateVoiceSession, packet.Internal, packet.ChannelName.c_str(), packet.Password.c_str());
- recvPacket >> channelId;
- uint8 unknown1 = recvPacket.ReadBit(); // unknowns
- uint8 unknown2 = recvPacket.ReadBit();
- channelLength = recvPacket.ReadBits(8);
- passLength = recvPacket.ReadBits(8);
- channelName = recvPacket.ReadString(channelLength);
- password = recvPacket.ReadString(passLength);
-
- TC_LOG_DEBUG("chat.system", "CMSG_JOIN_CHANNEL %s Channel: %u, unk1: %u, unk2: %u, channel: %s, password: %s",
- GetPlayerInfo().c_str(), channelId, unknown1, unknown2, channelName.c_str(), password.c_str());
-
- if (channelId)
+ if (packet.ChatChannelId)
{
- ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(channelId);
+ ChatChannelsEntry const* channel = sChatChannelsStore.LookupEntry(packet.ChatChannelId);
if (!channel)
return;
@@ -51,53 +40,43 @@ void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
return;
}
- if (channelName.empty())
+ if (packet.ChannelName.empty())
return;
- if (isdigit(channelName[0]))
+ if (isdigit(packet.ChannelName[0]))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
{
- cMgr->setTeam(GetPlayer()->GetTeam());
- if (Channel* channel = cMgr->GetJoinChannel(channelName, channelId))
- channel->JoinChannel(GetPlayer(), password);
+ cMgr->SetTeam(GetPlayer()->GetTeam());
+ if (Channel* channel = cMgr->GetJoinChannel(packet.ChannelName, packet.ChatChannelId))
+ channel->JoinChannel(GetPlayer(), packet.Password);
}
}
-void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
+void WorldSession::HandleLeaveChannel(WorldPackets::Channel::LeaveChannel& packet)
{
- uint32 unk;
- std::string channelName;
- recvPacket >> unk; // channel id?
- uint32 length = recvPacket.ReadBits(8);
- channelName = recvPacket.ReadString(length);
+ TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s ChannelName: %s, ZoneChannelID: %u",
+ GetPlayerInfo().c_str(), packet.ChannelName.c_str(), packet.ZoneChannelID);
- TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s Channel: %s, unk1: %u",
- GetPlayerInfo().c_str(), channelName.c_str(), unk);
-
- if (channelName.empty())
+ if (packet.ChannelName.empty())
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
{
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
+ if (Channel* channel = cMgr->GetChannel(packet.ChannelName, GetPlayer()))
channel->LeaveChannel(GetPlayer(), true);
- cMgr->LeftChannel(channelName);
+ cMgr->LeftChannel(packet.ChannelName);
}
}
-void WorldSession::HandleChannelList(WorldPacket& recvPacket)
+void WorldSession::HandleChannelList(WorldPackets::Channel::ChannelListRequest& packet)
{
- uint32 length = recvPacket.ReadBits(8);
- std::string channelName = recvPacket.ReadString(length);
-
- TC_LOG_DEBUG("chat.system", "%s %s Channel: %s",
- recvPacket.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST ? "CMSG_CHANNEL_DISPLAY_LIST" : "CMSG_CHANNEL_LIST",
- GetPlayerInfo().c_str(), channelName.c_str());
+ TC_LOG_DEBUG("chat.system", "%s %s ChannelName: %s",
+ GetOpcodeNameForLogging(packet.GetOpcode()).c_str(), GetPlayerInfo().c_str(), packet.ChannelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
- if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
+ if (Channel* channel = cMgr->GetChannel(packet.ChannelName, GetPlayer()))
channel->List(GetPlayer());
}
@@ -115,7 +94,7 @@ void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
if (password.length() > MAX_CHANNEL_PASS_STR)
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->Password(GetPlayer(), password);
}
@@ -134,7 +113,7 @@ void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->SetOwner(GetPlayer(), targetName);
}
@@ -147,9 +126,9 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
- channel->SendWhoOwner(GetPlayer()->GetGUID());
+ channel->SendWhoOwner(GetPlayer());
}
void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
@@ -166,7 +145,7 @@ void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->SetModerator(GetPlayer(), targetName);
}
@@ -185,7 +164,7 @@ void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->UnsetModerator(GetPlayer(), targetName);
}
@@ -204,7 +183,7 @@ void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->SetMute(GetPlayer(), targetName);
}
@@ -223,7 +202,7 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->UnsetMute(GetPlayer(), targetName);
}
@@ -242,7 +221,7 @@ void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->Invite(GetPlayer(), targetName);
}
@@ -261,7 +240,7 @@ void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->Kick(GetPlayer(), targetName);
}
@@ -283,7 +262,7 @@ void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->Ban(GetPlayer(), targetName);
}
@@ -302,7 +281,7 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
if (!normalizePlayerName(targetName))
return;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->UnBan(GetPlayer(), targetName);
}
@@ -315,17 +294,11 @@ void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
channel->Announce(GetPlayer());
}
-void WorldSession::HandleChannelDisplayListQuery(WorldPacket &recvPacket)
-{
- // this should be OK because the 2 function _were_ the same
- HandleChannelList(recvPacket);
-}
-
void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
{
std::string channelName;
@@ -334,7 +307,7 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
TC_LOG_DEBUG("chat.system", "CMSG_GET_CHANNEL_MEMBER_COUNT %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(GetPlayer()->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(GetPlayer()->GetTeam()))
{
if (Channel* channel = cMgr->GetChannel(channelName, GetPlayer()))
{
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index a2e6f4b0340..de7d44bdc69 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -29,6 +29,7 @@
#include "ClientConfigPackets.h"
#include "Common.h"
#include "DatabaseEnv.h"
+#include "EquipmentSetPackets.h"
#include "Group.h"
#include "Guild.h"
#include "GuildFinderMgr.h"
@@ -36,6 +37,7 @@
#include "Language.h"
#include "LFGMgr.h"
#include "Log.h"
+#include "MiscPackets.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
@@ -835,6 +837,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
return;
}
+ SendTutorialsData();
+
pCurrChar->GetMotionMaster()->Initialize();
pCurrChar->SendDungeonDifficulty(false);
@@ -857,6 +861,16 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
/// Send FeatureSystemStatus
{
WorldPackets::System::FeatureSystemStatus features;
+
+ /// START OF DUMMY VALUES
+ features.ComplaintStatus = 2;
+ features.ScrollOfResurrectionRequestsRemaining = 1;
+ features.ScrollOfResurrectionMaxRequestsPerDay = 1;
+ features.CfgRealmID = 2;
+ features.CfgRealmRecID = 0;
+ features.VoiceEnabled = true;
+ /// END OF DUMMY VALUES
+
features.CharUndeleteEnabled = sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_ENABLED);
features.BpayStoreEnabled = sWorld->getBoolConfig(CONFIG_FEATURE_SYSTEM_BPAY_STORE_ENABLED);
@@ -1096,32 +1110,35 @@ void WorldSession::HandleSetFactionCheat(WorldPacket& /*recvData*/)
GetPlayer()->GetReputationMgr().SendStates();
}
-void WorldSession::HandleTutorialFlag(WorldPacket& recvData)
-{
- uint32 data;
- recvData >> data;
-
- uint8 index = uint8(data / 32);
- if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
- return;
-
- uint32 value = (data % 32);
-
- uint32 flag = GetTutorialInt(index);
- flag |= (1 << value);
- SetTutorialInt(index, flag);
-}
-
-void WorldSession::HandleTutorialClear(WorldPacket& /*recvData*/)
-{
- for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
- SetTutorialInt(i, 0xFFFFFFFF);
-}
-
-void WorldSession::HandleTutorialReset(WorldPacket& /*recvData*/)
+void WorldSession::HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet)
{
- for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
- SetTutorialInt(i, 0x00000000);
+ switch (packet.Action)
+ {
+ case TUTORIAL_ACTION_UPDATE:
+ {
+ uint8 index = uint8(packet.TutorialBit >> 5);
+ if (index >= MAX_ACCOUNT_TUTORIAL_VALUES)
+ {
+ TC_LOG_ERROR("network", "CMSG_TUTORIAL_FLAG received bad TutorialBit %u.", packet.TutorialBit);
+ return;
+ }
+ uint32 flag = GetTutorialInt(index);
+ flag |= (1 << (packet.TutorialBit & 0x1F));
+ SetTutorialInt(index, flag);
+ break;
+ }
+ case TUTORIAL_ACTION_CLEAR:
+ for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
+ SetTutorialInt(i, 0xFFFFFFFF);
+ break;
+ case TUTORIAL_ACTION_RESET:
+ for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
+ SetTutorialInt(i, 0x00000000);
+ break;
+ default:
+ TC_LOG_ERROR("network", "CMSG_TUTORIAL_FLAG received unknown TutorialAction %u.", packet.Action);
+ return;
+ }
}
void WorldSession::HandleSetWatchedFactionOpcode(WorldPacket& recvData)
@@ -1525,59 +1542,36 @@ void WorldSession::HandleCharCustomizeCallback(PreparedQueryResult result, World
GetAccountId(), GetRemoteAddress().c_str(), oldName.c_str(), customizeInfo->CharGUID.ToString().c_str(), customizeInfo->CharName.c_str());
}
-void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData)
+void WorldSession::HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipmentSet& packet)
{
TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
- uint64 setGuid;
- recvData.ReadPackedUInt64(setGuid);
-
- uint32 index;
- recvData >> index;
- if (index >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
+ if (packet.Set.SetID >= MAX_EQUIPMENT_SET_INDEX) // client set slots amount
return;
- std::string name;
- recvData >> name;
-
- std::string iconName;
- recvData >> iconName;
-
- EquipmentSet eqSet;
-
- eqSet.Guid = setGuid;
- eqSet.Name = name;
- eqSet.IconName = iconName;
- eqSet.state = EQUIPMENT_SET_NEW;
-
- ObjectGuid ignoredItemGuid;
- ignoredItemGuid.SetRawValue(0, 1);
-
- for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
{
- ObjectGuid itemGuid;
- recvData >> itemGuid.ReadAsPacked();
-
- // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set)
- if (itemGuid == ignoredItemGuid)
+ if (!(packet.Set.IgnoreMask & (1 << i)))
{
- // ignored slots saved as bit mask because we have no free special values for Items[i]
- eqSet.IgnoreMask |= 1 << i;
- continue;
- }
-
- Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
+ ObjectGuid const& itemGuid = packet.Set.Pieces[i];
- if (!item && !itemGuid.IsEmpty()) // cheating check 1
- return;
+ Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (item && item->GetGUID() != itemGuid) // cheating check 2
- return;
+ /// cheating check 1 (item equipped but sent empty guid)
+ if (!item && !itemGuid.IsEmpty())
+ return;
- eqSet.Items[i] = itemGuid.GetCounter();
+ /// cheating check 2 (sent guid does not match equipped item)
+ if (item && item->GetGUID() != itemGuid)
+ return;
+ }
+ else
+ packet.Set.Pieces[i].Clear();
}
- _player->SetEquipmentSet(index, eqSet);
+ packet.Set.IgnoreMask &= 0x7FFFF; /// clear invalid bits (i > EQUIPMENT_SLOT_END)
+
+ _player->SetEquipmentSet(std::move(packet.Set));
}
void WorldSession::HandleEquipmentSetDelete(WorldPacket& recvData)
@@ -1799,7 +1793,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (factionChangeInfo->SkinID.HasValue)
{
playerBytes &= ~uint32(0xFF);
- playerBytes |= factionChangeInfo->SkinID.value;
+ playerBytes |= factionChangeInfo->SkinID.Value;
}
else
factionChangeInfo->SkinID.Set(uint8(playerBytes & 0xFF));
@@ -1807,7 +1801,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (factionChangeInfo->FaceID.HasValue)
{
playerBytes &= ~(uint32(0xFF) << 8);
- playerBytes |= uint32(factionChangeInfo->FaceID.value) << 8;
+ playerBytes |= uint32(factionChangeInfo->FaceID.Value) << 8;
}
else
factionChangeInfo->FaceID.Set(uint8((playerBytes2 >> 8) & 0xFF));
@@ -1815,7 +1809,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (factionChangeInfo->HairStyleID.HasValue)
{
playerBytes &= ~(uint32(0xFF) << 16);
- playerBytes |= uint32(factionChangeInfo->HairStyleID.value) << 16;
+ playerBytes |= uint32(factionChangeInfo->HairStyleID.Value) << 16;
}
else
factionChangeInfo->HairStyleID.Set(uint8((playerBytes2 >> 16) & 0xFF));
@@ -1823,7 +1817,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (factionChangeInfo->HairColorID.HasValue)
{
playerBytes &= ~(uint32(0xFF) << 24);
- playerBytes |= uint32(factionChangeInfo->HairColorID.value) << 24;
+ playerBytes |= uint32(factionChangeInfo->HairColorID.Value) << 24;
}
else
factionChangeInfo->HairColorID.Set(uint8((playerBytes2 >> 24) & 0xFF));
@@ -1831,7 +1825,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
if (factionChangeInfo->FacialHairStyleID.HasValue)
{
playerBytes2 &= ~0xFF;
- playerBytes2 |= factionChangeInfo->FacialHairStyleID.value;
+ playerBytes2 |= factionChangeInfo->FacialHairStyleID.Value;
}
else
factionChangeInfo->FacialHairStyleID.Set(uint8(playerBytes2 & 0xFF));
@@ -2181,7 +2175,7 @@ void WorldSession::HandleCharRaceOrFactionChangeCallback(PreparedQueryResult res
}
for (uint32 index = 0; index < ktcount; ++index)
- knownTitles[index] = atol(tokens[index]);
+ knownTitles[index] = atoul(tokens[index]);
for (std::map<uint32, uint32>::const_iterator it = sObjectMgr->FactionChangeTitles.begin(); it != sObjectMgr->FactionChangeTitles.end(); ++it)
{
@@ -2526,14 +2520,14 @@ void WorldSession::SendCharFactionChange(ResponseCodes result, WorldPackets::Cha
if (result == RESPONSE_SUCCESS)
{
packet.Display.HasValue = true;
- packet.Display.value.Name = factionChangeInfo->Name;
- packet.Display.value.SexID = factionChangeInfo->SexID;
- packet.Display.value.SkinID = factionChangeInfo->SkinID.value;
- packet.Display.value.HairColorID = factionChangeInfo->HairColorID.value;
- packet.Display.value.HairStyleID = factionChangeInfo->HairStyleID.value;
- packet.Display.value.FacialHairStyleID = factionChangeInfo->FacialHairStyleID.value;
- packet.Display.value.FaceID = factionChangeInfo->FaceID.value;
- packet.Display.value.RaceID = factionChangeInfo->RaceID;
+ packet.Display.Value.Name = factionChangeInfo->Name;
+ packet.Display.Value.SexID = factionChangeInfo->SexID;
+ packet.Display.Value.SkinID = factionChangeInfo->SkinID.Value;
+ packet.Display.Value.HairColorID = factionChangeInfo->HairColorID.Value;
+ packet.Display.Value.HairStyleID = factionChangeInfo->HairStyleID.Value;
+ packet.Display.Value.FacialHairStyleID = factionChangeInfo->FacialHairStyleID.Value;
+ packet.Display.Value.FaceID = factionChangeInfo->FaceID.Value;
+ packet.Display.Value.RaceID = factionChangeInfo->RaceID;
}
SendPacket(packet.Write());
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index a2fc248bb61..81248519994 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -39,261 +39,165 @@
#include "Util.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
+#include "ChatPackets.h"
-void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
+void WorldSession::HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet)
{
- uint32 type = 0;
- uint32 lang;
+ ChatMsg type;
- switch (recvData.GetOpcode())
+ switch (packet.GetOpcode())
{
- /*
case CMSG_MESSAGECHAT_SAY:
type = CHAT_MSG_SAY;
break;
case CMSG_MESSAGECHAT_YELL:
type = CHAT_MSG_YELL;
break;
- case CMSG_MESSAGECHAT_CHANNEL:
- type = CHAT_MSG_CHANNEL;
- break;
- case CMSG_MESSAGECHAT_WHISPER:
- type = CHAT_MSG_WHISPER;
- break;
case CMSG_MESSAGECHAT_GUILD:
type = CHAT_MSG_GUILD;
break;
case CMSG_MESSAGECHAT_OFFICER:
type = CHAT_MSG_OFFICER;
break;
- case CMSG_MESSAGECHAT_AFK:
- type = CHAT_MSG_AFK;
- break;
- case CMSG_MESSAGECHAT_DND:
- type = CHAT_MSG_DND;
- break;
- case CMSG_MESSAGECHAT_EMOTE:
- type = CHAT_MSG_EMOTE;
- break;
case CMSG_MESSAGECHAT_PARTY:
type = CHAT_MSG_PARTY;
break;
case CMSG_MESSAGECHAT_RAID:
type = CHAT_MSG_RAID;
break;
- case CMSG_MESSAGECHAT_BATTLEGROUND:
- type = CHAT_MSG_BATTLEGROUND;
- break;
case CMSG_MESSAGECHAT_RAID_WARNING:
type = CHAT_MSG_RAID_WARNING;
break;
- */
default:
- TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", recvData.GetOpcode());
- recvData.hexlike();
+ TC_LOG_ERROR("network", "HandleMessagechatOpcode : Unknown chat opcode (%u)", packet.GetOpcode());
return;
}
- if (type >= MAX_CHAT_MSG_TYPE)
- {
- TC_LOG_ERROR("network", "CHAT: Wrong message type received: %u", type);
- recvData.rfinish();
- return;
- }
+ HandleChatMessage(type, packet.Language, packet.Text);
+}
+
+void WorldSession::HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet)
+{
+ HandleChatMessage(CHAT_MSG_WHISPER, packet.Language, packet.Text, packet.Target);
+}
+void WorldSession::HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet)
+{
+ HandleChatMessage(CHAT_MSG_CHANNEL, packet.Language, packet.Text, packet.Target);
+}
+
+void WorldSession::HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet)
+{
+ HandleChatMessage(CHAT_MSG_EMOTE, LANG_UNIVERSAL, packet.Text);
+}
+
+void WorldSession::HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target /*= ""*/)
+{
Player* sender = GetPlayer();
- //TC_LOG_DEBUG("misc", "CHAT: packet received. type %u, lang %u", type, lang);
+ if (lang == LANG_UNIVERSAL && type != CHAT_MSG_EMOTE)
+ {
+ TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
+ SendNotification(LANG_UNKNOWN_LANGUAGE);
+ return;
+ }
- // no language sent with emote packet.
- if (type != CHAT_MSG_EMOTE && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
+ // prevent talking at unknown language (cheating)
+ LanguageDesc const* langDesc = GetLanguageDescByID(lang);
+ if (!langDesc)
{
- recvData >> lang;
+ SendNotification(LANG_UNKNOWN_LANGUAGE);
+ return;
+ }
- if (lang == LANG_UNIVERSAL)
+ if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
+ {
+ // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
+ Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
+ bool foundAura = false;
+ for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
{
- TC_LOG_ERROR("network", "CMSG_MESSAGECHAT: Possible hacking-attempt: %s tried to send a message in universal language", GetPlayerInfo().c_str());
- SendNotification(LANG_UNKNOWN_LANGUAGE);
- recvData.rfinish();
- return;
+ if ((*i)->GetMiscValue() == int32(lang))
+ {
+ foundAura = true;
+ break;
+ }
}
-
- // prevent talking at unknown language (cheating)
- LanguageDesc const* langDesc = GetLanguageDescByID(lang);
- if (!langDesc)
+ if (!foundAura)
{
- SendNotification(LANG_UNKNOWN_LANGUAGE);
- recvData.rfinish();
+ SendNotification(LANG_NOT_LEARNED_LANGUAGE);
return;
}
+ }
- if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
- {
- // also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
- Unit::AuraEffectList const& langAuras = sender->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
- bool foundAura = false;
- for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
- {
- if ((*i)->GetMiscValue() == int32(lang))
- {
- foundAura = true;
- break;
- }
- }
- if (!foundAura)
- {
- SendNotification(LANG_NOT_LEARNED_LANGUAGE);
- recvData.rfinish();
- return;
- }
- }
-
- if (lang == LANG_ADDON)
+ // send in universal language if player in .gm on mode (ignore spell effects)
+ if (sender->IsGameMaster())
+ lang = LANG_UNIVERSAL;
+ else
+ {
+ // send in universal language in two side iteration allowed mode
+ if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
+ lang = LANG_UNIVERSAL;
+ else
{
- // LANG_ADDON is only valid for the following message types
switch (type)
{
case CHAT_MSG_PARTY:
case CHAT_MSG_RAID:
+ case CHAT_MSG_RAID_WARNING:
+ // allow two side chat at group channel if two side group allowed
+ if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
+ lang = LANG_UNIVERSAL;
+ break;
case CHAT_MSG_GUILD:
- case CHAT_MSG_BATTLEGROUND:
- case CHAT_MSG_WHISPER:
- // check if addon messages are disabled
- if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
- {
- recvData.rfinish();
- return;
- }
+ case CHAT_MSG_OFFICER:
+ // allow two side chat at guild channel if two side guild allowed
+ if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
+ lang = LANG_UNIVERSAL;
break;
default:
- TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid language/message type combination",
- GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().ToString().c_str());
-
- recvData.rfinish();
- return;
+ break;
}
}
- // LANG_ADDON should not be changed nor be affected by flood control
- else
- {
- // send in universal language if player in .gm on mode (ignore spell effects)
- if (sender->IsGameMaster())
- lang = LANG_UNIVERSAL;
- else
- {
- // send in universal language in two side iteration allowed mode
- if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
- lang = LANG_UNIVERSAL;
- else
- {
- switch (type)
- {
- case CHAT_MSG_PARTY:
- case CHAT_MSG_PARTY_LEADER:
- case CHAT_MSG_RAID:
- case CHAT_MSG_RAID_LEADER:
- case CHAT_MSG_RAID_WARNING:
- // allow two side chat at group channel if two side group allowed
- if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP))
- lang = LANG_UNIVERSAL;
- break;
- case CHAT_MSG_GUILD:
- case CHAT_MSG_OFFICER:
- // allow two side chat at guild channel if two side guild allowed
- if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD))
- lang = LANG_UNIVERSAL;
- break;
- }
- }
-
- // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
- Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
- if (!ModLangAuras.empty())
- lang = ModLangAuras.front()->GetMiscValue();
- }
- if (!sender->CanSpeak())
- {
- std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
- SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
- recvData.rfinish(); // Prevent warnings
- return;
- }
- }
+ // but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
+ Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
+ if (!ModLangAuras.empty())
+ lang = ModLangAuras.front()->GetMiscValue();
}
- else
- lang = LANG_UNIVERSAL;
- if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
+ if (!sender->CanSpeak())
{
- SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
- recvData.rfinish();
+ std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
+ SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
return;
}
- uint32 textLength = 0;
- uint32 receiverLength = 0;
- std::string to, channel, msg;
- bool ignoreChecks = false;
- switch (type)
+ if (sender->HasAura(GM_SILENCE_AURA) && type != CHAT_MSG_WHISPER)
{
- case CHAT_MSG_SAY:
- case CHAT_MSG_EMOTE:
- case CHAT_MSG_YELL:
- case CHAT_MSG_PARTY:
- case CHAT_MSG_GUILD:
- case CHAT_MSG_OFFICER:
- case CHAT_MSG_RAID:
- case CHAT_MSG_RAID_WARNING:
- case CHAT_MSG_BATTLEGROUND:
- textLength = recvData.ReadBits(9);
- msg = recvData.ReadString(textLength);
- break;
- case CHAT_MSG_WHISPER:
- receiverLength = recvData.ReadBits(10);
- textLength = recvData.ReadBits(9);
- to = recvData.ReadString(receiverLength);
- msg = recvData.ReadString(textLength);
- break;
- case CHAT_MSG_CHANNEL:
- receiverLength = recvData.ReadBits(10);
- textLength = recvData.ReadBits(9);
- msg = recvData.ReadString(textLength);
- channel = recvData.ReadString(receiverLength);
- break;
- case CHAT_MSG_AFK:
- case CHAT_MSG_DND:
- textLength = recvData.ReadBits(9);
- msg = recvData.ReadString(textLength);
- ignoreChecks = true;
- break;
+ SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
+ return;
}
- if (!ignoreChecks)
- {
- if (msg.empty())
- return;
+ if (msg.empty())
+ return;
- if (ChatHandler(this).ParseCommands(msg.c_str()))
- return;
+ if (ChatHandler(this).ParseCommands(msg.c_str()))
+ return;
- if (lang != LANG_ADDON)
- {
- // Strip invisible characters for non-addon messages
- if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
- stripLineInvisibleChars(msg);
+ // Strip invisible characters for non-addon messages
+ if (sWorld->getBoolConfig(CONFIG_CHAT_FAKE_MESSAGE_PREVENTING))
+ stripLineInvisibleChars(msg);
- if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str()))
- {
- TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
- GetPlayer()->GetGUID().ToString().c_str(), msg.c_str());
+ if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str()))
+ {
+ TC_LOG_ERROR("network", "Player %s (%s) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(),
+ GetPlayer()->GetGUID().ToString().c_str(), msg.c_str());
- if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
- KickPlayer();
+ if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
+ KickPlayer();
- return;
- }
- }
+ return;
}
switch (type)
@@ -322,16 +226,19 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
case CHAT_MSG_WHISPER:
{
- if (!normalizePlayerName(to))
+ /// @todo implement cross realm whispers (someday)
+ ExtendedPlayerName extName = ExtractExtendedPlayerName(target);
+
+ if (!normalizePlayerName(extName.Name))
{
- SendPlayerNotFoundNotice(to);
+ SendPlayerNotFoundNotice(target);
break;
}
- Player* receiver = ObjectAccessor::FindConnectedPlayerByName(to);
+ Player* receiver = ObjectAccessor::FindConnectedPlayerByName(extName.Name);
if (!receiver || (lang != LANG_ADDON && !receiver->isAcceptWhispers() && receiver->GetSession()->HasPermission(rbac::RBAC_PERM_CAN_FILTER_WHISPERS) && !receiver->IsInWhisperWhiteList(sender->GetGUID())))
{
- SendPlayerNotFoundNotice(to);
+ SendPlayerNotFoundNotice(target);
return;
}
if (!sender->IsGameMaster() && sender->getLevel() < sWorld->getIntConfig(CONFIG_CHAT_WHISPER_LEVEL_REQ) && !receiver->IsInWhisperWhiteList(sender->GetGUID()))
@@ -362,7 +269,6 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
break;
}
case CHAT_MSG_PARTY:
- case CHAT_MSG_PARTY_LEADER:
{
// if player is in battleground, he cannot say to battleground members by /p
Group* group = GetPlayer()->GetOriginalGroup();
@@ -378,9 +284,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID()));
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg);
+ group->BroadcastPacket(packet.Write(), false, group->GetMemberGroup(GetPlayer()->GetGUID()));
break;
}
case CHAT_MSG_GUILD:
@@ -410,25 +316,19 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
break;
}
case CHAT_MSG_RAID:
- case CHAT_MSG_RAID_LEADER:
{
- // if player is in battleground, he cannot say to battleground members by /ra
Group* group = GetPlayer()->GetOriginalGroup();
if (!group)
- {
- group = GetPlayer()->GetGroup();
- if (!group || group->isBGGroup() || !group->isRaidGroup())
- return;
- }
+ return;
if (group->IsLeader(GetPlayer()->GetGUID()))
type = CHAT_MSG_RAID_LEADER;
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, ChatMsg(type), Language(lang), sender, NULL, msg);
+ group->BroadcastPacket(packet.Write(), false);
break;
}
case CHAT_MSG_RAID_WARNING:
@@ -439,28 +339,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
- WorldPacket data;
+ WorldPackets::Chat::Chat packet;
//in battleground, raid warning is sent only to players in battleground - code is ok
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false);
- break;
- }
- case CHAT_MSG_BATTLEGROUND:
- case CHAT_MSG_BATTLEGROUND_LEADER:
- {
- // battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
- Group* group = GetPlayer()->GetGroup();
- if (!group || !group->isBGGroup())
- return;
-
- if (group->IsLeader(GetPlayer()->GetGUID()))
- type = CHAT_MSG_BATTLEGROUND_LEADER;
-
- sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
-
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false);
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg);
+ group->BroadcastPacket(packet.Write(), false);
break;
}
case CHAT_MSG_CHANNEL:
@@ -474,9 +356,9 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
}
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(sender->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(sender->GetTeam()))
{
- if (Channel* chn = cMgr->GetChannel(channel, sender))
+ if (Channel* chn = cMgr->GetChannel(target, sender))
{
sScriptMgr->OnPlayerChat(sender, type, lang, msg, chn);
chn->Say(sender->GetGUID(), msg.c_str(), lang);
@@ -484,70 +366,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
break;
}
- case CHAT_MSG_AFK:
- {
- if (!sender->IsInCombat())
- {
- if (sender ->isAFK()) // Already AFK
- {
- if (msg.empty())
- sender->ToggleAFK(); // Remove AFK
- else
- sender->autoReplyMsg = msg; // Update message
- }
- else // New AFK mode
- {
- sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : msg;
-
- if (sender->isDND())
- sender->ToggleDND();
-
- sender->ToggleAFK();
- }
-
- sScriptMgr->OnPlayerChat(sender, type, lang, msg);
- }
- break;
- }
- case CHAT_MSG_DND:
- {
- if (sender->isDND()) // Already DND
- {
- if (msg.empty())
- sender->ToggleDND(); // Remove DND
- else
- sender->autoReplyMsg = msg; // Update message
- }
- else // New DND mode
- {
- sender->autoReplyMsg = msg.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : msg;
-
- if (sender->isAFK())
- sender->ToggleAFK();
-
- sender->ToggleDND();
- }
-
- sScriptMgr->OnPlayerChat(sender, type, lang, msg);
- break;
- }
default:
TC_LOG_ERROR("network", "CHAT: unknown message type %u, lang: %u", type, lang);
break;
}
}
-void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
+void WorldSession::HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet)
{
- Player* sender = GetPlayer();
ChatMsg type;
- switch (recvData.GetOpcode())
+ switch (packet.GetOpcode())
{
- /*
- case CMSG_MESSAGECHAT_ADDON_BATTLEGROUND:
- type = CHAT_MSG_BATTLEGROUND;
- break;
case CMSG_MESSAGECHAT_ADDON_GUILD:
type = CHAT_MSG_GUILD;
break;
@@ -560,95 +390,50 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
case CMSG_MESSAGECHAT_ADDON_RAID:
type = CHAT_MSG_RAID;
break;
- case CMSG_MESSAGECHAT_ADDON_WHISPER:
- type = CHAT_MSG_WHISPER;
- break;
- */
default:
- TC_LOG_ERROR("network", "HandleAddonMessagechatOpcode: Unknown addon chat opcode (%u)", recvData.GetOpcode());
- recvData.hexlike();
+ TC_LOG_ERROR("network", "HandleChatAddonMessageOpcode: Unknown addon chat opcode (%u)", packet.GetOpcode());
return;
}
- std::string message;
- std::string prefix;
- std::string targetName;
+ HandleChatAddonMessage(type, packet.Prefix, packet.Text);
+}
- switch (type)
- {
- case CHAT_MSG_WHISPER:
- {
- uint32 msgLen = recvData.ReadBits(9);
- uint32 prefixLen = recvData.ReadBits(5);
- uint32 targetLen = recvData.ReadBits(10);
- message = recvData.ReadString(msgLen);
- prefix = recvData.ReadString(prefixLen);
- targetName = recvData.ReadString(targetLen);
- break;
- }
- case CHAT_MSG_PARTY:
- case CHAT_MSG_RAID:
- case CHAT_MSG_OFFICER:
- {
- uint32 prefixLen = recvData.ReadBits(5);
- uint32 msgLen = recvData.ReadBits(9);
- prefix = recvData.ReadString(prefixLen);
- message = recvData.ReadString(msgLen);
- break;
- }
- case CHAT_MSG_GUILD:
- case CHAT_MSG_BATTLEGROUND:
- {
- uint32 msgLen = recvData.ReadBits(9);
- uint32 prefixLen = recvData.ReadBits(5);
- message = recvData.ReadString(msgLen);
- prefix = recvData.ReadString(prefixLen);
- break;
- }
- default:
- break;
- }
+void WorldSession::HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet)
+{
+ HandleChatAddonMessage(CHAT_MSG_WHISPER, packet.Prefix, packet.Text, packet.Target);
+}
+
+void WorldSession::HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target /*= ""*/)
+{
+ Player* sender = GetPlayer();
if (prefix.empty() || prefix.length() > 16)
return;
// Disabled addon channel?
if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
- {
- recvData.rfinish();
return;
- }
switch (type)
{
- case CHAT_MSG_BATTLEGROUND:
- {
- Group* group = sender->GetGroup();
- if (!group || !group->isBGGroup())
- return;
-
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix);
- group->BroadcastAddonMessagePacket(&data, prefix, false);
- break;
- }
case CHAT_MSG_GUILD:
case CHAT_MSG_OFFICER:
{
if (sender->GetGuildId())
if (Guild* guild = sGuildMgr->GetGuildById(sender->GetGuildId()))
- guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, message, prefix);
+ guild->BroadcastAddonToGuild(this, type == CHAT_MSG_OFFICER, text, prefix);
break;
}
case CHAT_MSG_WHISPER:
{
- if (!normalizePlayerName(targetName))
+ if (!normalizePlayerName(target))
break;
- Player* receiver = sObjectAccessor->FindPlayerByName(targetName);
+
+ Player* receiver = sObjectAccessor->FindPlayerByName(target);
if (!receiver)
break;
- sender->WhisperAddon(message, prefix, receiver);
+ sender->WhisperAddon(text, prefix, receiver);
break;
}
// Messages sent to "RAID" while in a party will get delivered to "PARTY"
@@ -657,12 +442,12 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
{
Group* group = sender->GetGroup();
- if (!group || group->isBGGroup())
+ if (!group)
break;
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix);
- group->BroadcastAddonMessagePacket(&data, prefix, true, -1, sender->GetGUID());
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, type, LANG_ADDON, sender, NULL, text, 0U, "", DEFAULT_LOCALE, prefix);
+ group->BroadcastAddonMessagePacket(packet.Write(), prefix, true, -1, sender->GetGUID());
break;
}
default:
@@ -673,6 +458,72 @@ void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
}
}
+void WorldSession::HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet)
+{
+ Player* sender = GetPlayer();
+
+ if (sender->IsInCombat())
+ return;
+
+ if (sender->HasAura(GM_SILENCE_AURA))
+ {
+ SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
+ return;
+ }
+
+ if (sender->isAFK()) // Already AFK
+ {
+ if (packet.Text.empty())
+ sender->ToggleAFK(); // Remove AFK
+ else
+ sender->autoReplyMsg = packet.Text; // Update message
+ }
+ else // New AFK mode
+ {
+ sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_AFK_DEFAULT) : packet.Text;
+
+ if (sender->isDND())
+ sender->ToggleDND();
+
+ sender->ToggleAFK();
+ }
+
+ sScriptMgr->OnPlayerChat(sender, CHAT_MSG_AFK, LANG_UNIVERSAL, packet.Text);
+}
+
+void WorldSession::HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet)
+{
+ Player* sender = GetPlayer();
+
+ if (sender->IsInCombat())
+ return;
+
+ if (sender->HasAura(GM_SILENCE_AURA))
+ {
+ SendNotification(GetTrinityString(LANG_GM_SILENCE), sender->GetName().c_str());
+ return;
+ }
+
+ if (sender->isDND()) // Already DND
+ {
+ if (packet.Text.empty())
+ sender->ToggleDND(); // Remove DND
+ else
+ sender->autoReplyMsg = packet.Text; // Update message
+ }
+ else // New DND mode
+ {
+ sender->autoReplyMsg = packet.Text.empty() ? GetTrinityString(LANG_PLAYER_DND_DEFAULT) : packet.Text;
+
+ if (sender->isAFK())
+ sender->ToggleAFK();
+
+ sender->ToggleDND();
+ }
+
+ sScriptMgr->OnPlayerChat(sender, CHAT_MSG_DND, LANG_UNIVERSAL, packet.Text);
+}
+
void WorldSession::HandleEmoteOpcode(WorldPacket& recvData)
{
if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
@@ -689,55 +540,46 @@ namespace Trinity
class EmoteChatBuilder
{
public:
- EmoteChatBuilder(Player const& player, uint32 text_emote, uint32 emote_num, Unit const* target)
- : i_player(player), i_text_emote(text_emote), i_emote_num(emote_num), i_target(target) { }
+ EmoteChatBuilder(Player const& player, uint32 soundIndex, uint32 emoteID, Unit const* target)
+ : _player(player), _soundIndex(soundIndex), _emoteID(emoteID), _target(target) { }
void operator()(WorldPacket& data, LocaleConstant loc_idx)
{
- std::string const name(i_target ? i_target->GetNameForLocaleIdx(loc_idx) : "");
- uint32 namlen = name.size();
-
- data.Initialize(SMSG_TEXT_EMOTE, 20 + namlen);
- data << i_player.GetGUID();
- data << uint32(i_text_emote);
- data << uint32(i_emote_num);
- data << uint32(namlen);
- if (namlen > 1)
- data << name;
- else
- data << uint8(0x00);
+ WorldPackets::Chat::STextEmote packet;
+ packet.SourceGUID = _player.GetGUID();
+ packet.SourceAccountGUID = _player.GetSession()->GetAccountGUID();
+ if (_target)
+ packet.TargetGUID = _target->GetGUID();
+ packet.EmoteID = _emoteID;
+ packet.SoundIndex = _soundIndex;
+ data = *packet.Write();
}
private:
- Player const& i_player;
- uint32 i_text_emote;
- uint32 i_emote_num;
- Unit const* i_target;
+ Player const& _player;
+ uint32 _soundIndex;
+ uint32 _emoteID;
+ Unit const* _target;
};
-} // namespace Trinity
+}
-void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
+void WorldSession::HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet)
{
- if (!GetPlayer()->IsAlive())
+ Player* player = GetPlayer();
+
+ if (!player->IsAlive())
return;
- if (!GetPlayer()->CanSpeak())
+ if (!player->CanSpeak())
{
std::string timeStr = secsToTimeString(m_muteTime - time(NULL));
SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str());
return;
}
- uint32 text_emote, emoteNum;
- ObjectGuid guid;
-
- recvData >> text_emote;
- recvData >> emoteNum;
- recvData >> guid;
-
- sScriptMgr->OnPlayerTextEmote(GetPlayer(), text_emote, emoteNum, guid);
+ sScriptMgr->OnPlayerTextEmote(player, packet.SoundIndex, packet.EmoteID, packet.Target);
- EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(text_emote);
+ EmotesTextEntry const* em = sEmotesTextStore.LookupEntry(packet.EmoteID);
if (!em)
return;
@@ -752,34 +594,34 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
break;
case EMOTE_STATE_DANCE:
case EMOTE_STATE_READ:
- GetPlayer()->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote_anim);
+ player->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote_anim);
break;
default:
// Only allow text-emotes for "dead" entities (feign death included)
- if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
+ if (player->HasUnitState(UNIT_STATE_DIED))
break;
- GetPlayer()->HandleEmoteCommand(emote_anim);
+ player->HandleEmoteCommand(emote_anim);
break;
}
- Unit* unit = ObjectAccessor::GetUnit(*_player, guid);
+ Unit* unit = ObjectAccessor::GetUnit(*_player, packet.Target);
- CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+ CellCoord p = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY());
Cell cell(p);
cell.SetNoCreate();
- Trinity::EmoteChatBuilder emote_builder(*GetPlayer(), text_emote, emoteNum, unit);
+ Trinity::EmoteChatBuilder emote_builder(*player, packet.SoundIndex, packet.EmoteID, unit);
Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > emote_do(emote_builder);
- Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
+ Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder > > emote_worker(player, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), emote_do);
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
- cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
+ cell.Visit(p, message, *player->GetMap(), *player, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
- GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, 0, unit);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, packet.SoundIndex, 0, 0, unit);
//Send scripted event call
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
- ((Creature*)unit)->AI()->ReceiveEmote(GetPlayer(), text_emote);
+ ((Creature*)unit)->AI()->ReceiveEmote(player, packet.SoundIndex);
}
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
@@ -811,9 +653,9 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
if (!player || !player->GetSession())
return;
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName());
- player->GetSession()->SendPacket(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName());
+ player->SendDirectMessage(packet.Write());
}
void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket)
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 097c47a228e..07258fbd976 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -1048,7 +1048,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint32(aurApp->GetBase()->GetId());
*data << uint16(aurApp->GetFlags());
- if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ if (aurApp->GetFlags() & AFLAG_SCALABLE)
{
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -1150,7 +1150,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint32(aurApp->GetBase()->GetId());
*data << uint16(aurApp->GetFlags());
- if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ if (aurApp->GetFlags() & AFLAG_SCALABLE)
{
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -1285,7 +1285,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
data << uint32(aurApp->GetBase()->GetId());
data << uint16(aurApp->GetFlags());
- if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ if (aurApp->GetFlags() & AFLAG_SCALABLE)
{
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -1338,7 +1338,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
data << uint32(aurApp->GetBase()->GetId());
data << uint16(aurApp->GetFlags());
- if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ if (aurApp->GetFlags() & AFLAG_SCALABLE)
{
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 95bcecbfdeb..54fb865c017 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -28,6 +28,8 @@
#include "ObjectAccessor.h"
#include "SpellInfo.h"
#include "DB2Stores.h"
+#include "NPCPackets.h"
+#include "ItemPackets.h"
#include <vector>
void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData)
@@ -560,18 +562,14 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType);
}
-void WorldSession::HandleListInventoryOpcode(WorldPacket& recvData)
+void WorldSession::HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet)
{
- ObjectGuid guid;
-
- recvData >> guid;
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
if (!GetPlayer()->IsAlive())
return;
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LIST_INVENTORY");
-
- SendListInventory(guid);
+ SendListInventory(packet.Unit);
}
void WorldSession::SendListInventory(ObjectGuid vendorGuid)
@@ -597,12 +595,10 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid)
VendorItemData const* vendorItems = vendor->GetVendorItems();
uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
- //if (rawItemCount > 300),
- // rawItemCount = 300; // client cap but uint8 max value is 255
+ WorldPackets::NPC::VendorInventory packet;
+ packet.Vendor = vendor->GetGUID();
- ByteBuffer itemsData(32 * rawItemCount);
- std::vector<bool> enablers;
- enablers.reserve(2 * rawItemCount);
+ packet.Items.resize(rawItemCount);
const float discountMod = _player->GetReputationPriceDiscount(vendor);
uint8 count = 0;
@@ -612,13 +608,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid)
if (!vendorItem)
continue;
+ WorldPackets::NPC::VendorItem& item = packet.Items[count];
+
if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM)
{
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
if (!itemTemplate)
continue;
- uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
+ int32 leftInStock = !vendorItem->maxcount ? -1 : vendor->GetVendorItemCurrentCount(vendorItem);
if (!_player->IsGameMaster()) // ignore conditions if GM on
{
// Respect allowed class
@@ -647,29 +645,15 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid)
if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES))
price -= CalculatePct(price, priceMod);
- itemsData << uint32(slot + 1); // client expects counting to start at 1
- itemsData << uint32(itemTemplate->MaxDurability);
+ item.MuID = slot + 1; // client expects counting to start at 1
+ item.Durability = itemTemplate->MaxDurability;
+ item.ExtendedCostID = vendorItem->ExtendedCost;
+ item.Type = vendorItem->Type;
+ item.Quantity = leftInStock;
+ item.StackCount = itemTemplate->BuyCount;
+ item.Price = price;
- if (vendorItem->ExtendedCost)
- {
- enablers.push_back(0);
- itemsData << uint32(vendorItem->ExtendedCost);
- }
- else
- enablers.push_back(1);
-
- enablers.push_back(1); // item is unlocked
-
- itemsData << uint32(vendorItem->item);
- itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
- itemsData << uint32(price);
- itemsData << uint32(itemTemplate->DisplayInfoID);
- // if (!unk "enabler") data << uint32(something);
- itemsData << int32(leftInStock);
- itemsData << uint32(itemTemplate->BuyCount);
-
- if (++count >= MAX_VENDOR_ITEMS)
- break;
+ item.Item.ItemID = vendorItem->item;
}
else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY)
{
@@ -680,70 +664,23 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid)
if (!vendorItem->ExtendedCost)
continue; // there's no price defined for currencies, only extendedcost is used
- itemsData << uint32(slot + 1); // client expects counting to start at 1
- itemsData << uint32(0); // max durability
-
- enablers.push_back(0);
- itemsData << uint32(vendorItem->ExtendedCost);
-
- enablers.push_back(1); // item is unlocked
-
- itemsData << uint32(vendorItem->item);
- itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
- itemsData << uint32(0); // price, only seen currency types that have Extended cost
- itemsData << uint32(0); // displayId
- // if (!unk "enabler") data << uint32(something);
- itemsData << int32(-1);
- itemsData << uint32(vendorItem->maxcount);
-
- if (++count >= MAX_VENDOR_ITEMS)
- break;
+ item.MuID = slot + 1; // client expects counting to start at 1
+ item.ExtendedCostID = vendorItem->ExtendedCost;
+ item.Item.ItemID = vendorItem->item;
+ item.Type = vendorItem->Type;
+ item.StackCount = vendorItem->maxcount;
}
- // else error
- }
-
- ObjectGuid guid = vendorGuid;
-
- WorldPacket data(SMSG_LIST_INVENTORY, 12 + itemsData.size());
-
- data.WriteBit(guid[1]);
- data.WriteBit(guid[0]);
-
- data.WriteBits(count, 21); // item count
-
- data.WriteBit(guid[3]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[7]);
-
- for (std::vector<bool>::const_iterator itr = enablers.begin(); itr != enablers.end(); ++itr)
- data.WriteBit(*itr);
-
- data.WriteBit(guid[4]);
+ else
+ continue;
- data.FlushBits();
- data.append(itemsData);
-
- data.WriteByteSeq(guid[5]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[6]);
-
- // It doesn't matter what value is used here (PROBABLY its full vendor size)
- // What matters is that if count of items we can see is 0 and this field is 1
- // then client will open the vendor list, otherwise it won't
- if (rawItemCount)
- data << uint8(rawItemCount);
- else
- data << uint8(vendor->IsArmorer());
+ if (++count >= MAX_VENDOR_ITEMS)
+ break;
+ }
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[7]);
+ // Resize vector to real size (some items can be skipped due to checks)
+ packet.Items.resize(count);
- SendPacket(&data);
+ SendPacket(packet.Write());
}
void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 613f1e46d7b..9598ce216fb 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -52,6 +52,7 @@
#include "Group.h"
#include "AccountMgr.h"
#include "Spell.h"
+#include "SpellPackets.h"
#include "BattlegroundMgr.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
@@ -538,12 +539,9 @@ void WorldSession::HandleRequestCemeteryList(WorldPacket& /*recvPacket*/)
SendPacket(&data);
}
-void WorldSession::HandleSetSelectionOpcode(WorldPacket& recvData)
+void WorldSession::HandleSetSelectionOpcode(WorldPackets::Misc::SetSelection& packet)
{
- ObjectGuid guid;
- recvData >> guid;
-
- _player->SetSelection(guid);
+ _player->SetSelection(packet.Selection);
}
void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData)
@@ -1041,17 +1039,17 @@ int32 WorldSession::HandleEnableNagleAlgorithm()
return 0;
}
-void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData)
+void WorldSession::HandleSetActionButtonOpcode(WorldPackets::Spells::SetActionButton& packet)
{
- uint8 button;
- uint32 packetData;
- recvData >> button >> packetData;
- TC_LOG_DEBUG("network", "CMSG_SET_ACTION_BUTTON Button: %u Data: %u", button, packetData);
+ uint32 action = ACTION_BUTTON_ACTION(packet.Action);
+ uint32 type = ACTION_BUTTON_TYPE(packet.Action);
+
+ TC_LOG_DEBUG("network", "CMSG_SET_ACTION_BUTTON Button: %u Action: %u Type: %u", packet.Index, action, type);
- if (!packetData)
- GetPlayer()->removeActionButton(button);
+ if (!packet.Action)
+ GetPlayer()->removeActionButton(packet.Index);
else
- GetPlayer()->addActionButton(button, ACTION_BUTTON_ACTION(packetData), ACTION_BUTTON_TYPE(packetData));
+ GetPlayer()->addActionButton(packet.Index, action, type);
}
void WorldSession::HandleCompleteCinematic(WorldPacket& /*recvData*/)
@@ -1867,74 +1865,6 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket)
_player->SetPendingBind(0, 0);
}
-void WorldSession::HandleRequestHotfix(WorldPacket& recvPacket)
-{
- uint32 type, count;
- recvPacket >> type;
-
- DB2StorageBase const* store = GetDB2Storage(type);
- if (!store)
- {
- TC_LOG_ERROR("network", "CMSG_REQUEST_HOTFIX: Received unknown hotfix type: %u", type);
- recvPacket.rfinish();
- return;
- }
-
- count = recvPacket.ReadBits(23);
-
- ObjectGuid* guids = new ObjectGuid[count];
- for (uint32 i = 0; i < count; ++i)
- {
- guids[i][0] = recvPacket.ReadBit();
- guids[i][4] = recvPacket.ReadBit();
- guids[i][7] = recvPacket.ReadBit();
- guids[i][2] = recvPacket.ReadBit();
- guids[i][5] = recvPacket.ReadBit();
- guids[i][3] = recvPacket.ReadBit();
- guids[i][6] = recvPacket.ReadBit();
- guids[i][1] = recvPacket.ReadBit();
- }
-
- uint32 entry;
- for (uint32 i = 0; i < count; ++i)
- {
- recvPacket.ReadByteSeq(guids[i][5]);
- recvPacket.ReadByteSeq(guids[i][6]);
- recvPacket.ReadByteSeq(guids[i][7]);
- recvPacket.ReadByteSeq(guids[i][0]);
- recvPacket.ReadByteSeq(guids[i][1]);
- recvPacket.ReadByteSeq(guids[i][3]);
- recvPacket.ReadByteSeq(guids[i][4]);
- recvPacket >> entry;
- recvPacket.ReadByteSeq(guids[i][2]);
-
- if (!store->HasRecord(entry))
- {
- WorldPacket data(SMSG_DB_REPLY, 4 * 4);
- data << -int32(entry);
- data << uint32(store->GetHash());
- data << uint32(time(NULL));
- data << uint32(0);
- SendPacket(&data);
- continue;
- }
-
- WorldPacket data(SMSG_DB_REPLY);
- data << int32(entry);
- data << uint32(store->GetHash());
- data << uint32(sObjectMgr->GetHotfixDate(entry, store->GetHash()));
-
- size_t sizePos = data.wpos();
- data << uint32(0); // size of next block
- store->WriteRecord(entry, uint32(GetSessionDbcLocale()), data);
- data.put<uint32>(sizePos, data.wpos() - sizePos - 4);
-
- SendPacket(&data);
- }
-
- delete[] guids;
-}
-
void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_UPDATE_MISSILE_TRAJECTORY");
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index adc2e185591..096eaac26fa 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -36,7 +36,7 @@
#define MOVEMENT_PACKET_TIME_DELAY 0
-void WorldSession::HandleMoveWorldportAckOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortAck& /*packet*/)
{
TC_LOG_DEBUG("network", "WORLD: got MSG_MOVE_WORLDPORT_ACK.");
HandleMoveWorldportAckOpcode();
@@ -197,41 +197,16 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->ProcessDelayedOperations();
}
-void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket)
+void WorldSession::HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet)
{
- TC_LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
-
- ObjectGuid guid;
- uint32 flags, time;
- recvPacket >> flags >> time;
-
- guid[5] = recvPacket.ReadBit();
- guid[0] = recvPacket.ReadBit();
- guid[1] = recvPacket.ReadBit();
- guid[6] = recvPacket.ReadBit();
- guid[3] = recvPacket.ReadBit();
- guid[7] = recvPacket.ReadBit();
- guid[2] = recvPacket.ReadBit();
- guid[4] = recvPacket.ReadBit();
-
- recvPacket.ReadByteSeq(guid[4]);
- recvPacket.ReadByteSeq(guid[2]);
- recvPacket.ReadByteSeq(guid[7]);
- recvPacket.ReadByteSeq(guid[6]);
- recvPacket.ReadByteSeq(guid[5]);
- recvPacket.ReadByteSeq(guid[1]);
- recvPacket.ReadByteSeq(guid[3]);
- recvPacket.ReadByteSeq(guid[0]);
-
- TC_LOG_DEBUG("network", "%s ", guid.ToString().c_str());
- TC_LOG_DEBUG("network", "Flags %u, time %u", flags, time/IN_MILLISECONDS);
+ TC_LOG_DEBUG("network", "CMSG_MOVE_TELEPORT_ACK: Guid: %s, Sequence: %u, Time: %u", packet.MoverGUID.ToString().c_str(), packet.AckIndex, packet.MoveTime);
Player* plMover = _player->m_mover->ToPlayer();
if (!plMover || !plMover->IsBeingTeleportedNear())
return;
- if (guid != plMover->GetGUID())
+ if (packet.MoverGUID != plMover->GetGUID())
return;
plMover->SetSemaphoreTeleportNear(false);
@@ -384,7 +359,7 @@ void WorldSession::HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMov
mover->UpdatePosition(movementInfo.pos);
WorldPackets::Movement::ServerPlayerMovement playerMovement;
- playerMovement.mover = mover;
+ playerMovement.movementInfo = &mover->m_movementInfo;
mover->SendMessageToSet(const_cast<WorldPacket*>(playerMovement.Write()), _player);
if (plrMover) // nothing is charmed, or player charmed
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index cc82063e074..90af94f9754 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -37,6 +37,7 @@
#include "ScriptMgr.h"
#include "CreatureAI.h"
#include "SpellInfo.h"
+#include "NPCPackets.h"
enum StableResultCode
{
@@ -75,18 +76,14 @@ void WorldSession::SendTabardVendorActivate(ObjectGuid guid)
SendPacket(&data);
}
-void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData)
+void WorldSession::HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet)
{
- ObjectGuid guid;
-
TC_LOG_DEBUG("network", "WORLD: Received CMSG_BANKER_ACTIVATE");
- recvData >> guid;
-
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BANKER);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_BANKER);
if (!unit)
{
- TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", guid.ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: HandleBankerActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str());
return;
}
@@ -94,7 +91,7 @@ void WorldSession::HandleBankerActivateOpcode(WorldPacket& recvData)
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
- SendShowBank(guid);
+ SendShowBank(packet.Unit);
}
void WorldSession::SendShowBank(ObjectGuid guid)
@@ -112,12 +109,9 @@ void WorldSession::SendShowMailBox(ObjectGuid guid)
SendPacket(&data);
}
-void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData)
+void WorldSession::HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet)
{
- ObjectGuid guid;
-
- recvData >> guid;
- SendTrainerList(guid);
+ SendTrainerList(packet.Unit);
}
void WorldSession::SendTrainerList(ObjectGuid guid)
@@ -148,18 +142,16 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
return;
}
- WorldPacket data(SMSG_TRAINER_LIST, 8+4+4+trainer_spells->spellList.size()*38 + strTitle.size()+1);
- data << guid;
- data << uint32(trainer_spells->trainerType);
- data << uint32(1); // different value for each trainer, also found in CMSG_TRAINER_BUY_SPELL
-
- size_t count_pos = data.wpos();
- data << uint32(trainer_spells->spellList.size());
+ WorldPackets::NPC::TrainerList packet;
+ packet.TrainerGUID = guid;
+ packet.TrainerType = trainer_spells->trainerType;
+ packet.Greeting = strTitle;
// reputation discount
float fDiscountMod = _player->GetReputationPriceDiscount(unit);
bool can_learn_primary_prof = GetPlayer()->GetFreePrimaryProfessionPoints() > 0;
+ packet.Spells.resize(trainer_spells->spellList.size());
uint32 count = 0;
for (TrainerSpellMap::const_iterator itr = trainer_spells->spellList.begin(); itr != trainer_spells->spellList.end(); ++itr)
{
@@ -185,22 +177,23 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
TrainerSpellState state = _player->GetTrainerSpellState(tSpell);
- data << uint32(tSpell->SpellID); // learned spell (or cast-spell in profession case)
- data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
- data << uint32(floor(tSpell->MoneyCost * fDiscountMod));
+ WorldPackets::NPC::TrainerListSpell& spell = packet.Spells[count];
+ spell.SpellID = tSpell->SpellID;
+ spell.MoneyCost = floor(tSpell->MoneyCost * fDiscountMod);
+ spell.ReqSkillLine = tSpell->ReqSkillLine;
+ spell.ReqSkillRank = tSpell->ReqSkillRank;
+ spell.ReqLevel = tSpell->ReqLevel;
+ spell.Usable = (state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
- data << uint8(tSpell->ReqLevel);
- data << uint32(tSpell->ReqSkillLine);
- data << uint32(tSpell->ReqSkillRank);
- //prev + req or req + 0
uint8 maxReq = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ /// @todo Update this when new spell system is ready
+ /*for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (!tSpell->ReqAbility[i])
continue;
if (uint32 prevSpellId = sSpellMgr->GetPrevSpellInChain(tSpell->ReqAbility[i]))
{
- data << uint32(prevSpellId);
+ spell.ReqAbility[maxReq] = prevSpellId;
++maxReq;
}
if (maxReq == 2)
@@ -208,29 +201,25 @@ void WorldSession::SendTrainerList(ObjectGuid guid, const std::string& strTitle)
SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->ReqAbility[i]);
for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
{
- data << uint32(itr2->second);
+ spell.ReqAbility[maxReq] = itr2->second;
++maxReq;
}
if (maxReq == 2)
break;
- }
- while (maxReq < 2)
+ }*/
+ while (maxReq < MAX_TRAINERSPELL_ABILITY_REQS)
{
- data << uint32(0);
+ spell.ReqAbility[maxReq] = 0;
++maxReq;
}
- data << uint32(primary_prof_first_rank && can_learn_primary_prof ? 1 : 0);
- // primary prof. learn confirmation dialog
- data << uint32(primary_prof_first_rank ? 1 : 0); // must be equal prev. field to have learn button in enabled state
-
++count;
}
- data << strTitle;
+ // Shrink to actual data size
+ packet.Spells.resize(count);
- data.put<uint32>(count_pos, count);
- SendPacket(&data);
+ SendPacket(packet.Write());
}
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
@@ -312,17 +301,14 @@ void WorldSession::SendTrainerBuyFailed(ObjectGuid guid, uint32 spellId, uint32
SendPacket(&data);
}
-void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
+void WorldSession::HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GOSSIP_HELLO");
- ObjectGuid guid;
- recvData >> guid;
-
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_NONE);
if (!unit)
{
- TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", guid.ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: HandleGossipHelloOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str());
return;
}
@@ -453,18 +439,15 @@ void WorldSession::SendSpiritResurrect()
_player->UpdateObjectVisibility();
}
-void WorldSession::HandleBinderActivateOpcode(WorldPacket& recvData)
+void WorldSession::HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet)
{
- ObjectGuid npcGUID;
- recvData >> npcGUID;
-
if (!GetPlayer()->IsInWorld() || !GetPlayer()->IsAlive())
return;
- Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID, UNIT_NPC_FLAG_INNKEEPER);
+ Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(packet.Unit, UNIT_NPC_FLAG_INNKEEPER);
if (!unit)
{
- TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", npcGUID.ToString().c_str());
+ TC_LOG_DEBUG("network", "WORLD: HandleBinderActivateOpcode - %s not found or you can not interact with him.", packet.Unit.ToString().c_str());
return;
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 699d91c4cc9..652b548b3a2 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -312,9 +312,9 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe
return;
}
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect: spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || spellInfo->Effects[i].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
+ if (effect && (effect->TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY || effect->TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY || effect->TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY))
return;
}
@@ -752,10 +752,10 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
charmInfo->SetSpellAutocast(spellInfo, state != 0);
}
-void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
+void WorldSession::HandlePetCastSpellOpcode(WorldPackets::Spells::SpellCastRequest& castRequest)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_PET_CAST_SPELL");
-
+ /*
ObjectGuid guid;
uint8 castCount;
uint32 spellId;
@@ -835,7 +835,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
spell->finish(false);
delete spell;
- }
+ }*/
}
void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName)
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index f432ff70275..fb8e45f5f42 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -239,88 +239,27 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/)
SendPacket(&data);
}
-void WorldSession::HandleNpcTextQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet)
{
- uint32 textID;
- uint64 guid;
+ TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", packet.TextID);
- recvData >> textID;
- TC_LOG_DEBUG("network", "WORLD: CMSG_NPC_TEXT_QUERY TextId: %u", textID);
+ GossipText const* gossip = sObjectMgr->GetGossipText(packet.TextID);
- recvData >> guid;
-
- GossipText const* gossip = sObjectMgr->GetGossipText(textID);
-
- WorldPacket data(SMSG_NPC_TEXT_UPDATE, 100); // guess size
- data << textID;
-
- if (!gossip)
+ WorldPackets::Query::QueryNPCTextResponse response;
+ response.TextID = packet.TextID;
+
+ if (gossip)
{
for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
{
- data << float(0);
- data << "Greetings $N";
- data << "Greetings $N";
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
+ response.Probabilities[i] = gossip->Options[i].Probability;
+ response.BroadcastTextID[i] = gossip->Options[i].BroadcastTextID;
}
- }
- else
- {
- std::string text0[MAX_GOSSIP_TEXT_OPTIONS], text1[MAX_GOSSIP_TEXT_OPTIONS];
- LocaleConstant locale = GetSessionDbLocaleIndex();
-
- for (uint8 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
- {
- BroadcastText const* bct = sObjectMgr->GetBroadcastText(gossip->Options[i].BroadcastTextID);
- if (bct)
- {
- text0[i] = bct->GetText(locale, GENDER_MALE, true);
- text1[i] = bct->GetText(locale, GENDER_FEMALE, true);
- }
- else
- {
- text0[i] = gossip->Options[i].Text_0;
- text1[i] = gossip->Options[i].Text_1;
- }
-
- if (locale != DEFAULT_LOCALE && !bct)
- {
- if (NpcTextLocale const* npcTextLocale = sObjectMgr->GetNpcTextLocale(textID))
- {
- ObjectMgr::GetLocaleString(npcTextLocale->Text_0[i], locale, text0[i]);
- ObjectMgr::GetLocaleString(npcTextLocale->Text_1[i], locale, text1[i]);
- }
- }
-
- data << gossip->Options[i].Probability;
-
- if (text0[i].empty())
- data << text1[i];
- else
- data << text0[i];
-
- if (text1[i].empty())
- data << text0[i];
- else
- data << text1[i];
-
- data << gossip->Options[i].Language;
- for (uint8 j = 0; j < MAX_GOSSIP_TEXT_EMOTES; ++j)
- {
- data << gossip->Options[i].Emotes[j]._Delay;
- data << gossip->Options[i].Emotes[j]._Emote;
- }
- }
+ response.Allow = true;
}
- SendPacket(&data);
+ SendPacket(response.Write());
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_NPC_TEXT_UPDATE");
}
@@ -492,3 +431,35 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recvData)
SendPacket(&data);
}
+
+void WorldSession::HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet)
+{
+ DB2StorageBase const* store = GetDB2Storage(packet.TableHash);
+ if (!store)
+ {
+ TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Received unknown hotfix type: %u", packet.TableHash);
+ return;
+ }
+
+ for (WorldPackets::Query::DBQueryRecord const& rec : packet.Queries)
+ {
+ WorldPackets::Query::DBReply response;
+ response.TableHash = packet.TableHash;
+
+ if (store->HasRecord(rec.RecordID))
+ {
+ response.RecordID = rec.RecordID;
+ response.Locale = GetSessionDbcLocale();
+ response.Timestamp = sObjectMgr->GetHotfixDate(rec.RecordID, packet.TableHash);
+ response.Data = store;
+ }
+ else
+ {
+ TC_LOG_ERROR("network", "CMSG_DB_QUERY_BULK: Entry %u does not exist in datastore: %u", rec.RecordID, packet.TableHash);
+ response.RecordID = -int32(rec.RecordID);
+ response.Timestamp = time(NULL);
+ }
+
+ SendPacket(response.Write());
+ }
+}
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 26451751b5d..f591a5fa988 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -31,17 +31,16 @@
#include "Battleground.h"
#include "ScriptMgr.h"
#include "GameObjectAI.h"
+#include "QuestPackets.h"
-void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
+void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet)
{
- ObjectGuid guid;
- recvData >> guid;
uint32 questStatus = DIALOG_STATUS_NONE;
- Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
+ Object* questGiver = ObjectAccessor::GetObjectByTypeMask(*_player, packet.QuestGiverGUID, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!questGiver)
{
- TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", guid.ToString().c_str());
+ TC_LOG_INFO("network", "Error in CMSG_QUESTGIVER_STATUS_QUERY, called for non-existing questgiver (%s)", packet.QuestGiverGUID.ToString().c_str());
return;
}
@@ -66,7 +65,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
}
//inform client about status of quest
- _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
+ _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, packet.QuestGiverGUID);
}
void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData)
@@ -639,19 +638,14 @@ void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
}
}
-void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& /*packet*/)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY");
- uint32 count = 0;
-
- WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4);
- data << uint32(count); // placeholder
+ WorldPackets::Quest::QuestGiverStatusMultiple response;
for (GuidSet::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
{
- uint32 questStatus = DIALOG_STATUS_NONE;
-
if (itr->IsAnyTypeCreature())
{
// need also pet quests case support
@@ -661,11 +655,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
if (!questgiver->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER))
continue;
- questStatus = _player->GetQuestDialogStatus(questgiver);
-
- data << questgiver->GetGUID();
- data << uint32(questStatus);
- ++count;
+ response.QuestGiver.emplace_back(questgiver->GetGUID(), _player->GetQuestDialogStatus(questgiver));
}
else if (itr->IsGameObject())
{
@@ -673,16 +663,11 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
if (!questgiver || questgiver->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER)
continue;
- questStatus = _player->GetQuestDialogStatus(questgiver);
-
- data << questgiver->GetGUID();
- data << uint32(questStatus);
- ++count;
+ response.QuestGiver.emplace_back(questgiver->GetGUID(), _player->GetQuestDialogStatus(questgiver));
}
}
- data.put<uint32>(0, count); // write real count
- SendPacket(&data);
+ SendPacket(response.Write());
}
void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/)
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index f0c1b28117b..278169c2d63 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -28,59 +28,22 @@
#include "WorldSession.h"
#include "TalentPackets.h"
-void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData)
+void WorldSession::HandleLearnTalentOpcode(WorldPackets::Talent::LearnTalent& packet)
{
- /* TODO: 6.x update packet struct (note: LearnTalent no longer has rank argument)
- uint32 talentId, requestedRank;
- recvData >> talentId >> requestedRank;
-
- if (_player->LearnTalent(talentId, requestedRank))
- _player->SendTalentsInfoData(false);*/
+ bool anythingLearned = false;
+ for (uint32 talentId : packet.Talents)
+ {
+ if (_player->LearnTalent(talentId))
+ anythingLearned = true;
+ }
+
+ if (anythingLearned)
+ _player->SendTalentsInfoData();
}
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
{
- /* TODO: 6.x update packet struct
TC_LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS");
-
- int32 tabPage;
- uint32 talentsCount;
- recvPacket >> tabPage; // talent tree
-
- // prevent cheating (selecting new tree with points already in another)
- if (tabPage >= 0) // -1 if player already has specialization
- {
- if (TalentTabEntry const* talentTabEntry = sTalentTabStore.LookupEntry(_player->GetPrimaryTalentTree(_player->GetActiveSpec())))
- {
- if (talentTabEntry->tabpage != uint32(tabPage))
- {
- recvPacket.rfinish();
- return;
- }
- }
- }
-
- recvPacket >> talentsCount;
-
- uint32 talentId, talentRank;
-
- // Client has max 21 talents for tree for 3 trees, rounded up : 70
- uint32 const MaxTalentsCount = 70;
-
- for (uint32 i = 0; i < talentsCount && i < MaxTalentsCount; ++i)
- {
- recvPacket >> talentId >> talentRank;
-
- if (!_player->LearnTalent(talentId, talentRank))
- {
- recvPacket.rfinish();
- break;
- }
- }
-
- _player->SendTalentsInfoData(false);
-
- recvPacket.rfinish();*/
}
void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 05f600e1207..a6bd43f72c6 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -153,7 +153,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
if (pUser->IsInCombat())
{
- for (int i = 0; i < proto->Effects.size(); ++i)
+ for (uint32 i = 0; i < proto->Effects.size(); ++i)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Effects[i].SpellID))
{
@@ -329,60 +329,71 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, go->GetEntry());
}
-void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleCastSpellOpcode(WorldPackets::Spells::SpellCastRequest& castRequest)
{
- uint32 spellId, glyphIndex;
- uint8 castCount, castFlags;
- recvPacket >> castCount;
- recvPacket >> spellId;
- recvPacket >> glyphIndex;
- recvPacket >> castFlags;
-
- TC_LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u, data length = %u", castCount, spellId, castFlags, (uint32)recvPacket.size());
+ TC_LOG_DEBUG("network", "WORLD: got cast spell packet, castCount: %u, spellId: %u, castFlags: %u", castRequest.CastID, castRequest.SpellID, castRequest.SendCastFlags);
// ignore for remote control state (for player case)
Unit* mover = _player->m_mover;
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
{
- recvPacket.rfinish(); // prevent spam at ignore packet
return;
}
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(castRequest.SpellID);
if (!spellInfo)
{
- TC_LOG_ERROR("network", "WORLD: unknown spell id %u", spellId);
- recvPacket.rfinish(); // prevent spam at ignore packet
+ TC_LOG_ERROR("network", "WORLD: unknown spell id %u", castRequest.SpellID);
return;
}
if (spellInfo->IsPassive())
{
- recvPacket.rfinish(); // prevent spam at ignore packet
return;
}
Unit* caster = mover;
- if (caster->GetTypeId() == TYPEID_UNIT && !caster->ToCreature()->HasSpell(spellId))
+ if (caster->GetTypeId() == TYPEID_UNIT && !caster->ToCreature()->HasSpell(castRequest.SpellID))
{
// If the vehicle creature does not have the spell but it allows the passenger to cast own spells
// change caster to player and let him cast
if (!_player->IsOnVehicle(caster) || spellInfo->CheckVehicle(_player) != SPELL_CAST_OK)
{
- recvPacket.rfinish(); // prevent spam at ignore packet
return;
}
caster = _player;
}
- if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(spellId))
+ if (caster->GetTypeId() == TYPEID_PLAYER && !caster->ToPlayer()->HasActiveSpell(castRequest.SpellID))
{
// not have spell in spellbook
- recvPacket.rfinish(); // prevent spam at ignore packet
return;
}
+
+ if (Player* plr = caster->ToPlayer())
+ {
+ uint32 specId = plr->GetActiveTalentSpec();
+ if (specId)
+ {
+ if (sSpecializationOverrideSpellMap.find(specId) != sSpecializationOverrideSpellMap.end())
+ {
+ if (sSpecializationOverrideSpellMap[specId].find(castRequest.SpellID) != sSpecializationOverrideSpellMap[specId].end())
+ {
+ SpellInfo const* newSpellInfo = sSpellMgr->GetSpellInfo(sSpecializationOverrideSpellMap[specId][castRequest.SpellID]);
+ if (newSpellInfo)
+ {
+ if (newSpellInfo->SpellLevel <= caster->getLevel())
+ {
+ spellInfo = newSpellInfo;
+ castRequest.SpellID = newSpellInfo->Id;
+ }
+ }
+ }
+ }
+ }
+ }
Unit::AuraEffectList swaps = mover->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
Unit::AuraEffectList const& swaps2 = mover->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
@@ -398,7 +409,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo((*itr)->GetAmount()))
{
spellInfo = newInfo;
- spellId = newInfo->Id;
+ castRequest.SpellID = newInfo->Id;
}
break;
}
@@ -410,21 +421,20 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
if (spellInfo->IsAutoRepeatRangedSpell() && caster->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)
&& caster->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_spellInfo == spellInfo)
{
- recvPacket.rfinish();
return;
}
// can't use our own spells when we're in possession of another unit,
if (_player->isPossessing())
{
- recvPacket.rfinish(); // prevent spam at ignore packet
return;
}
// client provided targets
- SpellCastTargets targets;
- targets.Read(recvPacket, caster);
- HandleClientCastFlags(recvPacket, castFlags, targets);
+ SpellCastTargets targets(caster, castRequest.TargetFlags, castRequest.UnitGuid, castRequest.ItemGuid, castRequest.SrcTransportGuid, castRequest.DstTransportGuid, castRequest.SrcPos, castRequest.DstPos, castRequest.Pitch, castRequest.Speed, castRequest.Name);
+
+
+ //HandleClientCastFlags(recvPacket, castFlags, targets);
// auto-selection buff level base at target level (in spellInfo)
if (targets.GetUnitTarget())
@@ -437,8 +447,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
}
Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE, ObjectGuid::Empty, false);
- spell->m_cast_count = castCount; // set count of casts
- spell->m_glyphIndex = glyphIndex;
+ spell->m_cast_count = castRequest.CastID; // set count of casts
+ spell->m_glyphIndex = castRequest.Misc; // 6.x Misc is just a guess
spell->prepare(&targets);
}
@@ -458,6 +468,10 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket)
uint32 spellId;
recvPacket >> spellId;
+ ObjectGuid guid;
+ recvPacket >> guid;
+
+
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
return;
@@ -485,7 +499,7 @@ void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket)
_player->RemoveOwnedAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_CANCEL);
// If spell being removed is a resource tracker, see if player was tracking both (herbs / minerals) and remove the other
- if (sWorld->getBoolConfig(CONFIG_ALLOW_TRACK_BOTH_RESOURCES) && spellInfo->HasAura(SPELL_AURA_TRACK_RESOURCES))
+ if (sWorld->getBoolConfig(CONFIG_ALLOW_TRACK_BOTH_RESOURCES) && spellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_TRACK_RESOURCES))
{
Unit::AuraEffectList const& auraEffects = _player->GetAuraEffectsByType(SPELL_AURA_TRACK_RESOURCES);
if (!auraEffects.empty())
@@ -760,14 +774,14 @@ void WorldSession::HandleRequestCategoryCooldowns(WorldPacket& /*recvPacket*/)
void WorldSession::SendSpellCategoryCooldowns()
{
- WorldPackets::Spell::CategoryCooldown cooldowns;
+ WorldPackets::Spells::CategoryCooldown cooldowns;
Unit::AuraEffectList const& categoryCooldownAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN);
for (AuraEffect* aurEff : categoryCooldownAuras)
{
uint32 categoryId = aurEff->GetMiscValue();
auto cItr = std::find_if(cooldowns.CategoryCooldowns.begin(), cooldowns.CategoryCooldowns.end(),
- [categoryId](WorldPackets::Spell::CategoryCooldown::CategoryCooldownInfo const& cooldown)
+ [categoryId](WorldPackets::Spells::CategoryCooldown::CategoryCooldownInfo const& cooldown)
{
return cooldown.Category == categoryId;
});
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 9aef1b62f7c..27b362faf90 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -96,7 +96,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance
{
// initialize reset time
// for normal instances if no creatures are killed the instance will reset in two hours
- if (entry->IsRaid() || difficulty > DUNGEON_DIFFICULTY_NORMAL)
+ if (entry->IsRaid() || difficulty > DIFFICULTY_NORMAL)
resetTime = GetResetTimeFor(mapId, difficulty);
else
{
@@ -213,7 +213,7 @@ time_t InstanceSave::GetResetTimeForDB()
{
// only save the reset time for normal instances
const MapEntry* entry = sMapStore.LookupEntry(GetMapId());
- if (!entry || entry->IsRaid() || GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC)
+ if (!entry || entry->IsRaid() || GetDifficulty() == DIFFICULTY_HEROIC)
return 0;
else
return GetResetTime();
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index b2c86d5152b..70db53ced8d 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -175,7 +175,7 @@ class InstanceSaveManager
uint16 mapid;
uint16 instanceId;
- InstResetEvent() : type(0), difficulty(DUNGEON_DIFFICULTY_NORMAL), mapid(0), instanceId(0) { }
+ InstResetEvent() : type(0), difficulty(DIFFICULTY_NORMAL), mapid(0), instanceId(0) { }
InstResetEvent(uint8 t, uint32 _mapid, Difficulty d, uint16 _instanceid)
: type(t), difficulty(d), mapid(_mapid), instanceId(_instanceid) { }
bool operator == (const InstResetEvent& e) const { return e.instanceId == instanceId; }
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index a8255d62777..1c968a495e9 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -128,7 +128,7 @@ void InstanceScript::LoadObjectData(ObjectData const* creatureData, ObjectData c
if (gameObjectData)
LoadObjectData(gameObjectData, _gameObjectInfo);
- TC_LOG_ERROR("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size());
+ TC_LOG_DEBUG("scripts", "InstanceScript::LoadObjectData: " SZFMTD " objects loaded.", _creatureInfo.size() + _gameObjectInfo.size());
}
void InstanceScript::LoadObjectData(ObjectData const* data, ObjectInfoMap& objectInfo)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 091fbb95aa5..7b7a0d5558d 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -386,15 +386,15 @@ class Map : public GridRefManager<NGridType>
// have meaning only for instanced map (that have set real difficulty)
Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); }
- bool IsRegularDifficulty() const { return GetDifficulty() == REGULAR_DIFFICULTY; }
+ bool IsRegularDifficulty() const { return GetDifficulty() == DIFFICULTY_NONE; }
MapDifficulty const* GetMapDifficulty() const;
bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); }
bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); }
bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); }
bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); }
- bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DUNGEON_DIFFICULTY_NORMAL; }
- bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; }
+ bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DIFFICULTY_NORMAL; }
+ bool IsHeroic() const { return IsRaid() ? i_spawnMode >= DIFFICULTY_10_HC : i_spawnMode >= DIFFICULTY_HEROIC; }
bool Is25ManRaid() const { return IsRaid() && i_spawnMode & RAID_DIFFICULTY_MASK_25MAN; } // since 25man difficulties are 1 and 3, we can check them like that
bool IsBattleground() const { return i_mapEntry && i_mapEntry->IsBattleground(); }
bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 8dfa4449e12..48e5161bcf1 100644
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -27,7 +27,7 @@
#include "Group.h"
#include "Player.h"
-MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL)
+MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DIFFICULTY_NORMAL)
{
// fill with zero
memset(&GridMapReference, 0, MAX_NUMBER_OF_GRIDS*MAX_NUMBER_OF_GRIDS*sizeof(uint16));
@@ -227,7 +227,7 @@ BattlegroundMap* MapInstanced::CreateBattleground(uint32 InstanceId, Battlegroun
TC_LOG_DEBUG("maps", "MapInstanced::CreateBattleground: map bg %d for %d created.", InstanceId, GetId());
- BattlegroundMap* map = new BattlegroundMap(GetId(), GetGridExpiry(), InstanceId, this, REGULAR_DIFFICULTY);
+ BattlegroundMap* map = new BattlegroundMap(GetId(), GetGridExpiry(), InstanceId, this, DIFFICULTY_NONE);
ASSERT(map->IsBattlegroundOrArena());
map->SetBG(bg);
bg->SetBgMap(map);
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index ac9e5918442..92d7335c7de 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -78,7 +78,7 @@ Map* MapManager::CreateBaseMap(uint32 id)
map = new MapInstanced(id, i_gridCleanUpDelay);
else
{
- map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
+ map = new Map(id, i_gridCleanUpDelay, 0, DIFFICULTY_NONE);
map->LoadRespawnTimes();
}
diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h
index 34733613c28..ede70719652 100644
--- a/src/server/game/Maps/TransportMgr.h
+++ b/src/server/game/Maps/TransportMgr.h
@@ -22,6 +22,7 @@
#include "Spline.h"
#include "DBCStores.h"
#include "ObjectGuid.h"
+#include "DB2Structure.h"
struct KeyFrame;
struct GameObjectTemplate;
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 68c30716ad9..c81ba4f4bbe 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -27,7 +27,36 @@ enum SpellEffIndex
{
EFFECT_0 = 0,
EFFECT_1 = 1,
- EFFECT_2 = 2
+ EFFECT_2 = 2,
+ EFFECT_3 = 3,
+ EFFECT_4 = 4,
+ EFFECT_5 = 5,
+ EFFECT_6 = 6,
+ EFFECT_7 = 7,
+ EFFECT_8 = 8,
+ EFFECT_9 = 9,
+ EFFECT_10 = 10,
+ EFFECT_11 = 11,
+ EFFECT_12 = 12,
+ EFFECT_13 = 13,
+ EFFECT_14 = 14,
+ EFFECT_15 = 15,
+ EFFECT_16 = 16,
+ EFFECT_17 = 17,
+ EFFECT_18 = 18,
+ EFFECT_19 = 19,
+ EFFECT_20 = 20,
+ EFFECT_21 = 21,
+ EFFECT_22 = 22,
+ EFFECT_23 = 23,
+ EFFECT_24 = 24,
+ EFFECT_25 = 25,
+ EFFECT_26 = 26,
+ EFFECT_27 = 27,
+ EFFECT_28 = 28,
+ EFFECT_29 = 29,
+ EFFECT_30 = 30,
+ EFFECT_31 = 31
};
// used in script definitions
@@ -58,9 +87,10 @@ enum Expansions
enum Gender
{
- GENDER_MALE = 0,
- GENDER_FEMALE = 1,
- GENDER_NONE = 2
+ GENDER_UNKNOWN = -1,
+ GENDER_MALE = 0,
+ GENDER_FEMALE = 1,
+ GENDER_NONE = 2
};
// ChrRaces.dbc (6.0.2.18988)
@@ -819,7 +849,7 @@ enum SpellAttr13
#define MAX_TALENT_GROUP 1
#define MIN_TALENT_GROUPS 1
#define MAX_TALENT_GROUPS 2
-#define MAX_GLYPH_SLOT_INDEX 9
+#define MAX_GLYPH_SLOT_INDEX 6
#define MIN_SPECIALIZATION_LEVEL 10
#define MAX_SPECIALIZATIONS 4
@@ -974,7 +1004,7 @@ enum Team
TEAM_OTHER = 0 // if ReputationListId > 0 && Flags != FACTION_FLAG_TEAM_HEADER
};
-enum SpellEffects
+enum SpellEffectName
{
SPELL_EFFECT_INSTAKILL = 1,
SPELL_EFFECT_SCHOOL_DAMAGE = 2,
@@ -1158,10 +1188,72 @@ enum SpellEffects
SPELL_EFFECT_180 = 180, // Unused (4.3.4)
SPELL_EFFECT_181 = 181, // Unused (4.3.4)
SPELL_EFFECT_182 = 182,
- TOTAL_SPELL_EFFECTS = 183,
+ SPELL_EFFECT_183 = 183,
+ SPELL_EFFECT_184 = 184,
+ SPELL_EFFECT_185 = 185,
+ SPELL_EFFECT_186 = 186,
+ SPELL_EFFECT_187 = 187,
+ SPELL_EFFECT_188 = 188,
+ SPELL_EFFECT_189 = 189,
+ SPELL_EFFECT_190 = 190,
+ SPELL_EFFECT_191 = 191,
+ SPELL_EFFECT_192 = 192,
+ SPELL_EFFECT_193 = 193,
+ SPELL_EFFECT_194 = 194,
+ SPELL_EFFECT_195 = 195,
+ SPELL_EFFECT_196 = 196,
+ SPELL_EFFECT_197 = 197,
+ SPELL_EFFECT_198 = 198,
+ SPELL_EFFECT_199 = 199,
+ SPELL_EFFECT_200 = 200,
+ SPELL_EFFECT_201 = 201,
+ SPELL_EFFECT_202 = 202,
+ SPELL_EFFECT_203 = 203,
+ SPELL_EFFECT_204 = 204,
+ SPELL_EFFECT_205 = 205,
+ SPELL_EFFECT_206 = 206,
+ SPELL_EFFECT_207 = 207,
+ SPELL_EFFECT_208 = 208,
+ SPELL_EFFECT_209 = 209,
+ SPELL_EFFECT_210 = 210,
+ SPELL_EFFECT_211 = 211,
+ SPELL_EFFECT_212 = 212,
+ SPELL_EFFECT_213 = 213,
+ SPELL_EFFECT_214 = 214,
+ SPELL_EFFECT_215 = 215,
+ SPELL_EFFECT_216 = 216,
+ SPELL_EFFECT_217 = 217,
+ SPELL_EFFECT_218 = 218,
+ SPELL_EFFECT_219 = 219,
+ SPELL_EFFECT_220 = 220,
+ SPELL_EFFECT_221 = 221,
+ SPELL_EFFECT_222 = 222,
+ SPELL_EFFECT_223 = 223,
+ SPELL_EFFECT_224 = 224,
+ SPELL_EFFECT_225 = 225,
+ SPELL_EFFECT_226 = 226,
+ SPELL_EFFECT_227 = 227,
+ SPELL_EFFECT_228 = 228,
+ SPELL_EFFECT_229 = 229,
+ SPELL_EFFECT_230 = 230,
+ SPELL_EFFECT_231 = 231,
+ SPELL_EFFECT_232 = 232,
+ SPELL_EFFECT_233 = 233,
+ SPELL_EFFECT_234 = 234,
+ SPELL_EFFECT_235 = 235,
+ SPELL_EFFECT_236 = 236,
+ SPELL_EFFECT_237 = 237,
+ SPELL_EFFECT_238 = 238,
+ SPELL_EFFECT_239 = 239,
+ SPELL_EFFECT_240 = 240,
+ SPELL_EFFECT_241 = 241,
+ SPELL_EFFECT_242 = 242,
+ SPELL_EFFECT_243 = 243,
+ SPELL_EFFECT_244 = 244,
+ TOTAL_SPELL_EFFECTS = 245,
};
-enum SpellCastResult // (6.0)
+enum SpellCastResult // 19116
{
SPELL_FAILED_SUCCESS = 0,
SPELL_FAILED_AFFECTING_COMBAT = 1,
@@ -1207,203 +1299,224 @@ enum SpellCastResult // (6.0)
SPELL_FAILED_GARRISON_OWNED = 41,
SPELL_FAILED_GARRISON_MAX_LEVEL = 42,
SPELL_FAILED_GARRISON_NOT_UPGRADEABLE = 43,
- SPELL_FAILED_HIGHLEVEL = 44,
- SPELL_FAILED_HUNGER_SATIATED = 45,
- SPELL_FAILED_IMMUNE = 46,
- SPELL_FAILED_INCORRECT_AREA = 47,
- SPELL_FAILED_INTERRUPTED = 48,
- SPELL_FAILED_INTERRUPTED_COMBAT = 49,
- SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 50,
- SPELL_FAILED_ITEM_GONE = 51,
- SPELL_FAILED_ITEM_NOT_FOUND = 52,
- SPELL_FAILED_ITEM_NOT_READY = 53,
- SPELL_FAILED_LEVEL_REQUIREMENT = 54,
- SPELL_FAILED_LINE_OF_SIGHT = 55,
- SPELL_FAILED_LOWLEVEL = 56,
- SPELL_FAILED_LOW_CASTLEVEL = 57,
- SPELL_FAILED_MAINHAND_EMPTY = 58,
- SPELL_FAILED_MOVING = 59,
- SPELL_FAILED_NEED_AMMO = 60,
- SPELL_FAILED_NEED_AMMO_POUCH = 61,
- SPELL_FAILED_NEED_EXOTIC_AMMO = 62,
- SPELL_FAILED_NEED_MORE_ITEMS = 63,
- SPELL_FAILED_NOPATH = 64,
- SPELL_FAILED_NOT_BEHIND = 65,
- SPELL_FAILED_NOT_FISHABLE = 66,
- SPELL_FAILED_NOT_FLYING = 67,
- SPELL_FAILED_NOT_HERE = 68,
- SPELL_FAILED_NOT_INFRONT = 69,
- SPELL_FAILED_NOT_IN_CONTROL = 70,
- SPELL_FAILED_NOT_KNOWN = 71,
- SPELL_FAILED_NOT_MOUNTED = 72,
- SPELL_FAILED_NOT_ON_TAXI = 73,
- SPELL_FAILED_NOT_ON_TRANSPORT = 74,
- SPELL_FAILED_NOT_READY = 75,
- SPELL_FAILED_NOT_SHAPESHIFT = 76,
- SPELL_FAILED_NOT_STANDING = 77,
- SPELL_FAILED_NOT_TRADEABLE = 78,
- SPELL_FAILED_NOT_TRADING = 79,
- SPELL_FAILED_NOT_UNSHEATHED = 80,
- SPELL_FAILED_NOT_WHILE_GHOST = 81,
- SPELL_FAILED_NOT_WHILE_LOOTING = 82,
- SPELL_FAILED_NO_AMMO = 83,
- SPELL_FAILED_NO_CHARGES_REMAIN = 84,
- SPELL_FAILED_NO_CHAMPION = 85,
- SPELL_FAILED_NO_COMBO_POINTS = 86,
- SPELL_FAILED_NO_DUELING = 87,
- SPELL_FAILED_NO_ENDURANCE = 88,
- SPELL_FAILED_NO_FISH = 89,
- SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 90,
- SPELL_FAILED_NO_MOUNTS_ALLOWED = 91,
- SPELL_FAILED_NO_PET = 92,
- SPELL_FAILED_NO_POWER = 93,
- SPELL_FAILED_NOTHING_TO_DISPEL = 94,
- SPELL_FAILED_NOTHING_TO_STEAL = 95,
- SPELL_FAILED_ONLY_ABOVEWATER = 96,
- SPELL_FAILED_ONLY_DAYTIME = 97,
- SPELL_FAILED_ONLY_INDOORS = 98,
- SPELL_FAILED_ONLY_MOUNTED = 99,
- SPELL_FAILED_ONLY_NIGHTTIME = 100,
- SPELL_FAILED_ONLY_OUTDOORS = 101,
- SPELL_FAILED_ONLY_SHAPESHIFT = 102,
- SPELL_FAILED_ONLY_STEALTHED = 103,
- SPELL_FAILED_ONLY_UNDERWATER = 104,
- SPELL_FAILED_OUT_OF_RANGE = 105,
- SPELL_FAILED_PACIFIED = 106,
- SPELL_FAILED_POSSESSED = 107,
- SPELL_FAILED_REAGENTS = 108,
- SPELL_FAILED_REQUIRES_AREA = 109,
- SPELL_FAILED_REQUIRES_SPELL_FOCUS = 110,
- SPELL_FAILED_ROOTED = 111,
- SPELL_FAILED_SILENCED = 112,
- SPELL_FAILED_SPELL_IN_PROGRESS = 113,
- SPELL_FAILED_SPELL_LEARNED = 114,
- SPELL_FAILED_SPELL_UNAVAILABLE = 115,
- SPELL_FAILED_STUNNED = 116,
- SPELL_FAILED_TARGETS_DEAD = 117,
- SPELL_FAILED_TARGET_AFFECTING_COMBAT = 118,
- SPELL_FAILED_TARGET_AURASTATE = 119,
- SPELL_FAILED_TARGET_DUELING = 120,
- SPELL_FAILED_TARGET_ENEMY = 121,
- SPELL_FAILED_TARGET_ENRAGED = 122,
- SPELL_FAILED_TARGET_FRIENDLY = 123,
- SPELL_FAILED_TARGET_IN_COMBAT = 124,
- SPELL_FAILED_TARGET_IN_PET_BATTLE = 125,
- SPELL_FAILED_TARGET_IS_PLAYER = 126,
- SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 127,
- SPELL_FAILED_TARGET_NOT_DEAD = 128,
- SPELL_FAILED_TARGET_NOT_IN_PARTY = 129,
- SPELL_FAILED_TARGET_NOT_LOOTED = 130,
- SPELL_FAILED_TARGET_NOT_PLAYER = 131,
- SPELL_FAILED_TARGET_NO_POCKETS = 132,
- SPELL_FAILED_TARGET_NO_WEAPONS = 133,
- SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 134,
- SPELL_FAILED_TARGET_UNSKINNABLE = 135,
- SPELL_FAILED_THIRST_SATIATED = 136,
- SPELL_FAILED_TOO_CLOSE = 137,
- SPELL_FAILED_TOO_MANY_OF_ITEM = 138,
- SPELL_FAILED_TOTEM_CATEGORY = 139,
- SPELL_FAILED_TOTEMS = 140,
- SPELL_FAILED_TRY_AGAIN = 141,
- SPELL_FAILED_UNIT_NOT_BEHIND = 142,
- SPELL_FAILED_UNIT_NOT_INFRONT = 143,
- SPELL_FAILED_VISION_OBSCURED = 144,
- SPELL_FAILED_WRONG_PET_FOOD = 145,
- SPELL_FAILED_NOT_WHILE_FATIGUED = 146,
- SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 147,
- SPELL_FAILED_NOT_WHILE_TRADING = 148,
- SPELL_FAILED_TARGET_NOT_IN_RAID = 149,
- SPELL_FAILED_TARGET_FREEFORALL = 150,
- SPELL_FAILED_NO_EDIBLE_CORPSES = 151,
- SPELL_FAILED_ONLY_BATTLEGROUNDS = 152,
- SPELL_FAILED_TARGET_NOT_GHOST = 153,
- SPELL_FAILED_TRANSFORM_UNUSABLE = 154,
- SPELL_FAILED_WRONG_WEATHER = 155,
- SPELL_FAILED_DAMAGE_IMMUNE = 156,
- SPELL_FAILED_PREVENTED_BY_MECHANIC = 157,
- SPELL_FAILED_PLAY_TIME = 158,
- SPELL_FAILED_REPUTATION = 159,
- SPELL_FAILED_MIN_SKILL = 160,
- SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND = 161,
- SPELL_FAILED_NOT_ON_SHAPESHIFT = 162,
- SPELL_FAILED_NOT_ON_STEALTHED = 163,
- SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 164,
- SPELL_FAILED_NOT_ON_MOUNTED = 165,
- SPELL_FAILED_TOO_SHALLOW = 166,
- SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 167,
- SPELL_FAILED_TARGET_IS_TRIVIAL = 168,
- SPELL_FAILED_BM_OR_INVISGOD = 169,
- SPELL_FAILED_GROUND_MOUNT_NOT_ALLOWED = 170,
- SPELL_FAILED_FLOATING_MOUNT_NOT_ALLOWED = 171,
- SPELL_FAILED_UNDERWATER_MOUNT_NOT_ALLOWED = 172,
- SPELL_FAILED_FLYING_MOUNT_NOT_ALLOWED = 173,
- SPELL_FAILED_APPRENTICE_RIDING_REQUIREMENT = 174,
- SPELL_FAILED_JOURNEYMAN_RIDING_REQUIREMENT = 175,
- SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 176,
- SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 177,
- SPELL_FAILED_MASTER_RIDING_REQUIREMENT = 178,
- SPELL_FAILED_COLD_RIDING_REQUIREMENT = 179,
- SPELL_FAILED_FLIGHT_MASTER_RIDING_REQUIREMENT = 180,
- SPELL_FAILED_CS_RIDING_REQUIREMENT = 181,
- SPELL_FAILED_PANDA_RIDING_REQUIREMENT = 182,
- SPELL_FAILED_MOUNT_NO_FLOAT_HERE = 183,
- SPELL_FAILED_MOUNT_NO_UNDERWATER_HERE = 184,
- SPELL_FAILED_MOUNT_ABOVE_WATER_HERE = 185,
- SPELL_FAILED_MOUNT_COLLECTED_ON_OTHER_CHAR = 186,
- SPELL_FAILED_NOT_IDLE = 187,
- SPELL_FAILED_NOT_INACTIVE = 188,
- SPELL_FAILED_PARTIAL_PLAYTIME = 189,
- SPELL_FAILED_NO_PLAYTIME = 190,
- SPELL_FAILED_NOT_IN_BATTLEGROUND = 191,
- SPELL_FAILED_NOT_IN_RAID_INSTANCE = 192,
- SPELL_FAILED_ONLY_IN_ARENA = 193,
- SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 194,
- SPELL_FAILED_ON_USE_ENCHANT = 195,
- SPELL_FAILED_NOT_ON_GROUND = 196,
- SPELL_FAILED_CUSTOM_ERROR = 197,
- SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 198,
- SPELL_FAILED_TOO_MANY_SOCKETS = 199,
- SPELL_FAILED_INVALID_GLYPH = 200,
- SPELL_FAILED_UNIQUE_GLYPH = 201,
- SPELL_FAILED_GLYPH_SOCKET_LOCKED = 202,
- SPELL_FAILED_GLYPH_EXCLUSIVE_CATEGORY = 203,
- SPELL_FAILED_GLYPH_INVALID_SPEC = 204,
- SPELL_FAILED_GLYPH_NO_SPEC = 205,
- SPELL_FAILED_NO_VALID_TARGETS = 206,
- SPELL_FAILED_ITEM_AT_MAX_CHARGES = 207,
- SPELL_FAILED_NOT_IN_BARBERSHOP = 208,
- SPELL_FAILED_FISHING_TOO_LOW = 209,
- SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 210,
- SPELL_FAILED_SUMMON_PENDING = 211,
- SPELL_FAILED_MAX_SOCKETS = 212,
- SPELL_FAILED_PET_CAN_RENAME = 213,
- SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 214,
- SPELL_FAILED_TARGET_HAS_RESURRECT_PENDING = 215,
- SPELL_FAILED_NO_ACTIONS = 216,
- SPELL_FAILED_CURRENCY_WEIGHT_MISMATCH = 217,
- SPELL_FAILED_WEIGHT_NOT_ENOUGH = 218,
- SPELL_FAILED_WEIGHT_TOO_MUCH = 219,
- SPELL_FAILED_NO_VACANT_SEAT = 220,
- SPELL_FAILED_NO_LIQUID = 221,
- SPELL_FAILED_ONLY_NOT_SWIMMING = 222,
- SPELL_FAILED_BY_NOT_MOVING = 223,
- SPELL_FAILED_IN_COMBAT_RES_LIMIT_REACHED = 224,
- SPELL_FAILED_NOT_IN_ARENA = 225,
- SPELL_FAILED_TARGET_NOT_GROUNDED = 226,
- SPELL_FAILED_EXCEEDED_WEEKLY_USAGE = 227,
- SPELL_FAILED_NOT_IN_LFG_DUNGEON = 228,
- SPELL_FAILED_BAD_TARGET_FILTER = 229,
- SPELL_FAILED_NOT_ENOUGH_TARGETS = 230,
- SPELL_FAILED_NO_SPEC = 231,
- SPELL_FAILED_CANT_ADD_BATTLE_PET = 232,
- SPELL_FAILED_CANT_UPGRADE_BATTLE_PET = 233,
- SPELL_FAILED_WRONG_BATTLE_PET_TYPE = 234,
- SPELL_FAILED_NO_DUNGEON_ENCOUNTER = 235,
- SPELL_FAILED_NO_TELEPORT_FROM_DUNGEON = 236,
- SPELL_FAILED_MAX_LEVEL_TOO_LOW = 237,
- SPELL_FAILED_CANT_REPLACE_ITEM_BONUS = 238,
- SPELL_FAILED_UNKNOWN = 254, // custom value, default case
- SPELL_CAST_OK = 255 // custom value, must not be sent to client
+ SPELL_FAILED_GARRISON_FOLLOWER_ON_MISSION = 44,
+ SPELL_FAILED_GARRISON_FOLLOWER_IN_BUILDING = 45,
+ SPELL_FAILED_GARRISON_FOLLOWER_MAX_LEVEL = 46,
+ SPELL_FAILED_GARRISON_FOLLOWER_MAX_ITEM_LEVEL = 47,
+ SPELL_FAILED_GARRISON_FOLLOWER_MAX_QUALITY = 48,
+ SPELL_FAILED_GARRISON_FOLLOWER_NOT_MAX_LEVEL = 49,
+ SPELL_FAILED_GARRISON_FOLLOWER_HAS_ABILITY = 50,
+ SPELL_FAILED_GARRISON_FOLLOWER_NO_OVERRIDEABLE_ABILITY = 51,
+ SPELL_FAILED_HIGHLEVEL = 52,
+ SPELL_FAILED_HUNGER_SATIATED = 53,
+ SPELL_FAILED_IMMUNE = 54,
+ SPELL_FAILED_INCORRECT_AREA = 55,
+ SPELL_FAILED_INTERRUPTED = 56,
+ SPELL_FAILED_INTERRUPTED_COMBAT = 57,
+ SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 58,
+ SPELL_FAILED_ITEM_GONE = 59,
+ SPELL_FAILED_ITEM_NOT_FOUND = 60,
+ SPELL_FAILED_ITEM_NOT_READY = 61,
+ SPELL_FAILED_LEVEL_REQUIREMENT = 62,
+ SPELL_FAILED_LINE_OF_SIGHT = 63,
+ SPELL_FAILED_LOWLEVEL = 64,
+ SPELL_FAILED_LOW_CASTLEVEL = 65,
+ SPELL_FAILED_MAINHAND_EMPTY = 66,
+ SPELL_FAILED_MOVING = 67,
+ SPELL_FAILED_NEED_AMMO = 68,
+ SPELL_FAILED_NEED_AMMO_POUCH = 69,
+ SPELL_FAILED_NEED_EXOTIC_AMMO = 70,
+ SPELL_FAILED_NEED_MORE_ITEMS = 71,
+ SPELL_FAILED_NOPATH = 72,
+ SPELL_FAILED_NOT_BEHIND = 73,
+ SPELL_FAILED_NOT_FISHABLE = 74,
+ SPELL_FAILED_NOT_FLYING = 75,
+ SPELL_FAILED_NOT_HERE = 76,
+ SPELL_FAILED_NOT_INFRONT = 77,
+ SPELL_FAILED_NOT_IN_CONTROL = 78,
+ SPELL_FAILED_NOT_KNOWN = 79,
+ SPELL_FAILED_NOT_MOUNTED = 80,
+ SPELL_FAILED_NOT_ON_TAXI = 81,
+ SPELL_FAILED_NOT_ON_TRANSPORT = 82,
+ SPELL_FAILED_NOT_READY = 83,
+ SPELL_FAILED_NOT_SHAPESHIFT = 84,
+ SPELL_FAILED_NOT_STANDING = 85,
+ SPELL_FAILED_NOT_TRADEABLE = 86,
+ SPELL_FAILED_NOT_TRADING = 87,
+ SPELL_FAILED_NOT_UNSHEATHED = 88,
+ SPELL_FAILED_NOT_WHILE_GHOST = 89,
+ SPELL_FAILED_NOT_WHILE_LOOTING = 90,
+ SPELL_FAILED_NO_AMMO = 91,
+ SPELL_FAILED_NO_CHARGES_REMAIN = 92,
+ SPELL_FAILED_NO_CHAMPION = 93,
+ SPELL_FAILED_NO_COMBO_POINTS = 94,
+ SPELL_FAILED_NO_DUELING = 95,
+ SPELL_FAILED_NO_ENDURANCE = 96,
+ SPELL_FAILED_NO_FISH = 97,
+ SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 98,
+ SPELL_FAILED_NO_MOUNTS_ALLOWED = 99,
+ SPELL_FAILED_NO_PET = 100,
+ SPELL_FAILED_NO_POWER = 101,
+ SPELL_FAILED_NOTHING_TO_DISPEL = 102,
+ SPELL_FAILED_NOTHING_TO_STEAL = 103,
+ SPELL_FAILED_ONLY_ABOVEWATER = 104,
+ SPELL_FAILED_ONLY_DAYTIME = 105,
+ SPELL_FAILED_ONLY_INDOORS = 106,
+ SPELL_FAILED_ONLY_MOUNTED = 107,
+ SPELL_FAILED_ONLY_NIGHTTIME = 108,
+ SPELL_FAILED_ONLY_OUTDOORS = 109,
+ SPELL_FAILED_ONLY_SHAPESHIFT = 110,
+ SPELL_FAILED_ONLY_STEALTHED = 111,
+ SPELL_FAILED_ONLY_UNDERWATER = 112,
+ SPELL_FAILED_OUT_OF_RANGE = 113,
+ SPELL_FAILED_PACIFIED = 114,
+ SPELL_FAILED_POSSESSED = 115,
+ SPELL_FAILED_REAGENTS = 116,
+ SPELL_FAILED_REQUIRES_AREA = 117,
+ SPELL_FAILED_REQUIRES_SPELL_FOCUS = 118,
+ SPELL_FAILED_ROOTED = 119,
+ SPELL_FAILED_SILENCED = 120,
+ SPELL_FAILED_SPELL_IN_PROGRESS = 121,
+ SPELL_FAILED_SPELL_LEARNED = 122,
+ SPELL_FAILED_SPELL_UNAVAILABLE = 123,
+ SPELL_FAILED_STUNNED = 124,
+ SPELL_FAILED_TARGETS_DEAD = 125,
+ SPELL_FAILED_TARGET_AFFECTING_COMBAT = 126,
+ SPELL_FAILED_TARGET_AURASTATE = 127,
+ SPELL_FAILED_TARGET_DUELING = 128,
+ SPELL_FAILED_TARGET_ENEMY = 129,
+ SPELL_FAILED_TARGET_ENRAGED = 130,
+ SPELL_FAILED_TARGET_FRIENDLY = 131,
+ SPELL_FAILED_TARGET_IN_COMBAT = 132,
+ SPELL_FAILED_TARGET_IN_PET_BATTLE = 133,
+ SPELL_FAILED_TARGET_IS_PLAYER = 134,
+ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 135,
+ SPELL_FAILED_TARGET_NOT_DEAD = 136,
+ SPELL_FAILED_TARGET_NOT_IN_PARTY = 137,
+ SPELL_FAILED_TARGET_NOT_LOOTED = 138,
+ SPELL_FAILED_TARGET_NOT_PLAYER = 139,
+ SPELL_FAILED_TARGET_NO_POCKETS = 140,
+ SPELL_FAILED_TARGET_NO_WEAPONS = 141,
+ SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 142,
+ SPELL_FAILED_TARGET_UNSKINNABLE = 143,
+ SPELL_FAILED_THIRST_SATIATED = 144,
+ SPELL_FAILED_TOO_CLOSE = 145,
+ SPELL_FAILED_TOO_MANY_OF_ITEM = 146,
+ SPELL_FAILED_TOTEM_CATEGORY = 147,
+ SPELL_FAILED_TOTEMS = 148,
+ SPELL_FAILED_TRY_AGAIN = 149,
+ SPELL_FAILED_UNIT_NOT_BEHIND = 150,
+ SPELL_FAILED_UNIT_NOT_INFRONT = 151,
+ SPELL_FAILED_VISION_OBSCURED = 152,
+ SPELL_FAILED_WRONG_PET_FOOD = 153,
+ SPELL_FAILED_NOT_WHILE_FATIGUED = 154,
+ SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 155,
+ SPELL_FAILED_NOT_WHILE_TRADING = 156,
+ SPELL_FAILED_TARGET_NOT_IN_RAID = 157,
+ SPELL_FAILED_TARGET_FREEFORALL = 158,
+ SPELL_FAILED_NO_EDIBLE_CORPSES = 159,
+ SPELL_FAILED_ONLY_BATTLEGROUNDS = 160,
+ SPELL_FAILED_TARGET_NOT_GHOST = 161,
+ SPELL_FAILED_TRANSFORM_UNUSABLE = 162,
+ SPELL_FAILED_WRONG_WEATHER = 163,
+ SPELL_FAILED_DAMAGE_IMMUNE = 164,
+ SPELL_FAILED_PREVENTED_BY_MECHANIC = 165,
+ SPELL_FAILED_PLAY_TIME = 166,
+ SPELL_FAILED_REPUTATION = 167,
+ SPELL_FAILED_MIN_SKILL = 168,
+ SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND = 169,
+ SPELL_FAILED_NOT_ON_SHAPESHIFT = 170,
+ SPELL_FAILED_NOT_ON_STEALTHED = 171,
+ SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 172,
+ SPELL_FAILED_NOT_ON_MOUNTED = 173,
+ SPELL_FAILED_TOO_SHALLOW = 174,
+ SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 175,
+ SPELL_FAILED_TARGET_IS_TRIVIAL = 176,
+ SPELL_FAILED_BM_OR_INVISGOD = 177,
+ SPELL_FAILED_GROUND_MOUNT_NOT_ALLOWED = 178,
+ SPELL_FAILED_FLOATING_MOUNT_NOT_ALLOWED = 179,
+ SPELL_FAILED_UNDERWATER_MOUNT_NOT_ALLOWED = 180,
+ SPELL_FAILED_FLYING_MOUNT_NOT_ALLOWED = 181,
+ SPELL_FAILED_APPRENTICE_RIDING_REQUIREMENT = 182,
+ SPELL_FAILED_JOURNEYMAN_RIDING_REQUIREMENT = 183,
+ SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 184,
+ SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 185,
+ SPELL_FAILED_MASTER_RIDING_REQUIREMENT = 186,
+ SPELL_FAILED_COLD_RIDING_REQUIREMENT = 187,
+ SPELL_FAILED_FLIGHT_MASTER_RIDING_REQUIREMENT = 188,
+ SPELL_FAILED_CS_RIDING_REQUIREMENT = 189,
+ SPELL_FAILED_PANDA_RIDING_REQUIREMENT = 190,
+ SPELL_FAILED_MOUNT_NO_FLOAT_HERE = 191,
+ SPELL_FAILED_MOUNT_NO_UNDERWATER_HERE = 192,
+ SPELL_FAILED_MOUNT_ABOVE_WATER_HERE = 193,
+ SPELL_FAILED_MOUNT_COLLECTED_ON_OTHER_CHAR = 194,
+ SPELL_FAILED_NOT_IDLE = 195,
+ SPELL_FAILED_NOT_INACTIVE = 196,
+ SPELL_FAILED_PARTIAL_PLAYTIME = 197,
+ SPELL_FAILED_NO_PLAYTIME = 198,
+ SPELL_FAILED_NOT_IN_BATTLEGROUND = 199,
+ SPELL_FAILED_NOT_IN_RAID_INSTANCE = 200,
+ SPELL_FAILED_ONLY_IN_ARENA = 201,
+ SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 202,
+ SPELL_FAILED_ON_USE_ENCHANT = 203,
+ SPELL_FAILED_NOT_ON_GROUND = 204,
+ SPELL_FAILED_CUSTOM_ERROR = 205,
+ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 206,
+ SPELL_FAILED_TOO_MANY_SOCKETS = 207,
+ SPELL_FAILED_INVALID_GLYPH = 208,
+ SPELL_FAILED_UNIQUE_GLYPH = 209,
+ SPELL_FAILED_GLYPH_SOCKET_LOCKED = 210,
+ SPELL_FAILED_GLYPH_EXCLUSIVE_CATEGORY = 211,
+ SPELL_FAILED_GLYPH_INVALID_SPEC = 212,
+ SPELL_FAILED_GLYPH_NO_SPEC = 213,
+ SPELL_FAILED_NO_VALID_TARGETS = 214,
+ SPELL_FAILED_ITEM_AT_MAX_CHARGES = 215,
+ SPELL_FAILED_NOT_IN_BARBERSHOP = 216,
+ SPELL_FAILED_FISHING_TOO_LOW = 217,
+ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 218,
+ SPELL_FAILED_SUMMON_PENDING = 219,
+ SPELL_FAILED_MAX_SOCKETS = 220,
+ SPELL_FAILED_PET_CAN_RENAME = 221,
+ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 222,
+ SPELL_FAILED_TARGET_HAS_RESURRECT_PENDING = 223,
+ SPELL_FAILED_NO_ACTIONS = 224,
+ SPELL_FAILED_CURRENCY_WEIGHT_MISMATCH = 225,
+ SPELL_FAILED_WEIGHT_NOT_ENOUGH = 226,
+ SPELL_FAILED_WEIGHT_TOO_MUCH = 227,
+ SPELL_FAILED_NO_VACANT_SEAT = 228,
+ SPELL_FAILED_NO_LIQUID = 229,
+ SPELL_FAILED_ONLY_NOT_SWIMMING = 230,
+ SPELL_FAILED_BY_NOT_MOVING = 231,
+ SPELL_FAILED_IN_COMBAT_RES_LIMIT_REACHED = 232,
+ SPELL_FAILED_NOT_IN_ARENA = 233,
+ SPELL_FAILED_TARGET_NOT_GROUNDED = 234,
+ SPELL_FAILED_EXCEEDED_WEEKLY_USAGE = 235,
+ SPELL_FAILED_NOT_IN_LFG_DUNGEON = 236,
+ SPELL_FAILED_BAD_TARGET_FILTER = 237,
+ SPELL_FAILED_NOT_ENOUGH_TARGETS = 238,
+ SPELL_FAILED_NO_SPEC = 239,
+ SPELL_FAILED_CANT_ADD_BATTLE_PET = 240,
+ SPELL_FAILED_CANT_UPGRADE_BATTLE_PET = 241,
+ SPELL_FAILED_WRONG_BATTLE_PET_TYPE = 242,
+ SPELL_FAILED_NO_DUNGEON_ENCOUNTER = 243,
+ SPELL_FAILED_NO_TELEPORT_FROM_DUNGEON = 244,
+ SPELL_FAILED_MAX_LEVEL_TOO_LOW = 245,
+ SPELL_FAILED_CANT_REPLACE_ITEM_BONUS = 246,
+ SPELL_FAILED_GRANT_PET_LEVEL_FAIL = 247,
+ SPELL_FAILED_SKILL_LINE_NOT_KNOWN = 248,
+ SPELL_FAILED_BLUEPRINT_KNOWN = 249,
+ SPELL_FAILED_FOLLOWER_KNOWN = 250,
+ SPELL_FAILED_CANT_OVERRIDE_ENCHANT_VISUAL = 251,
+ SPELL_FAILED_ITEM_NOT_A_WEAPON = 252,
+ SPELL_FAILED_SAME_ENCHANT_VISUAL = 253,
+ SPELL_FAILED_TOY_USE_LIMIT_REACHED = 254,
+ SPELL_FAILED_SHIPMENTS_FULL = 255,
+ SPELL_FAILED_HAS_MISSION = 256,
+ SPELL_FAILED_BUILDING_ACTIVATE_NOT_READY = 257,
+ SPELL_FAILED_NOT_SOULBOUND = 258,
+ SPELL_FAILED_RIDING_VEHICLE = 259,
+ SPELL_FAILED_UNKNOWN = 260, // custom value, default case
+ SPELL_CAST_OK = 0xFFFF // custom value, must not be sent to client
};
enum SpellCustomErrors
@@ -4128,8 +4241,22 @@ enum ChatMsg
CHAT_MSG_CURRENCY = 0x40
};
+#define GM_SILENCE_AURA 1852
+
#define MAX_CHAT_MSG_TYPE 0x41
+enum ChatFlags
+{
+ CHAT_FLAG_NONE = 0x00,
+ CHAT_FLAG_AFK = 0x01,
+ CHAT_FLAG_DND = 0x02,
+ CHAT_FLAG_GM = 0x04,
+ CHAT_FLAG_COM = 0x08, // Commentator
+ CHAT_FLAG_DEV = 0x10,
+ CHAT_FLAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper
+ CHAT_FLAG_MOBILE = 0x40
+};
+
enum ChatLinkColors
{
CHAT_LINK_COLOR_TRADE = 0xffffd000, // orange
@@ -4605,7 +4732,7 @@ enum GroupJoinBattlegroundResult
ERR_BATTLEGROUND_NOT_IN_BATTLEGROUND = 8, // You can't do that in a battleground.
ERR_BATTLEGROUND_JOIN_XP_GAIN = 9, // wtf, doesn't exist in client...
ERR_BATTLEGROUND_JOIN_RANGE_INDEX = 10, // Cannot join the queue unless all members of your party are in the same battleground level range.
- ERR_BATTLEGROUND_JOIN_TIMED_OUT = 11, // %s was unavailable to join the queue. (uint64 guid exist in client cache)
+ ERR_BATTLEGROUND_JOIN_TIMED_OUT = 11, // %s was unavailable to join the queue. (ObjectGuid exist in client cache)
//ERR_BATTLEGROUND_JOIN_TIMED_OUT = 12, // same as 11
//ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = 13, // same as 7
ERR_LFG_CANT_USE_BATTLEGROUND = 14, // You cannot queue for a battleground or arena while using the dungeon system.
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index 749b6be4ee5..560f40143bb 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -24,6 +24,7 @@
#include "Vehicle.h"
#include "WorldPacket.h"
#include "Opcodes.h"
+#include "MovementPackets.h"
namespace Movement
{
@@ -115,17 +116,11 @@ namespace Movement
unit->m_movementInfo.SetMovementFlags(moveFlags);
move_spline.Initialize(args);
- WorldPacket data(SMSG_MONSTER_MOVE, 64);
- data << unit->GetPackGUID();
- if (!unit->GetTransGUID().IsEmpty())
- {
- data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
- data << unit->GetTransGUID().WriteAsPacked();
- data << int8(unit->GetTransSeat());
- }
-
- PacketBuilder::WriteMonsterMove(move_spline, data);
- unit->SendMessageToSet(&data, true);
+ WorldPackets::Movement::MonsterMove packet;
+ packet.MoverGUID = unit->GetGUID();
+ packet.Pos = real_position;
+ PacketBuilder::WriteMonsterMove(move_spline, packet.SplineData);
+ unit->SendMessageToSet(packet.Write(), true);
return move_spline.Duration();
}
@@ -161,17 +156,18 @@ namespace Movement
move_spline.onTransport = transport;
move_spline.Initialize(args);
- WorldPacket data(SMSG_MONSTER_MOVE, 64);
- data << unit->GetPackGUID();
+ WorldPackets::Movement::MonsterMove packet;
+ packet.MoverGUID = unit->GetGUID();
+ packet.Pos = loc;
+ packet.SplineData.ID = move_spline.GetId();
+
if (transport)
{
- data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
- data << unit->GetTransGUID().WriteAsPacked();
- data << int8(unit->GetTransSeat());
+ packet.SplineData.Move.TransportGUID = unit->GetTransGUID();
+ packet.SplineData.Move.VehicleSeat = unit->GetTransSeat();
}
- PacketBuilder::WriteStopMovement(loc, args.splineId, data);
- unit->SendMessageToSet(&data, true);
+ unit->SendMessageToSet(packet.Write(), true);
}
MoveSplineInit::MoveSplineInit(Unit* m) : unit(m)
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
index 02fdabb3938..f13c69b97fd 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -21,132 +21,90 @@
#include "MoveSpline.h"
#include "WorldPacket.h"
#include "Object.h"
+#include "MovementPackets.h"
namespace Movement
{
- inline void operator << (ByteBuffer& b, const Vector3& v)
+ void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline)
{
- b << v.x << v.y << v.z;
- }
-
- inline void operator >> (ByteBuffer& b, Vector3& v)
- {
- b >> v.x >> v.y >> v.z;
- }
+ movementMonsterSpline.ID = move_spline.m_Id;
+ WorldPackets::Movement::MovementSpline& movementSpline = movementMonsterSpline.Move;
- enum MonsterMoveType
- {
- MonsterMoveNormal = 0,
- MonsterMoveStop = 1,
- MonsterMoveFacingSpot = 2,
- MonsterMoveFacingTarget = 3,
- MonsterMoveFacingAngle = 4
- };
-
- void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
- {
MoveSplineFlag splineflags = move_spline.splineflags;
+ splineflags.enter_cycle = move_spline.isCyclic();
+ movementSpline.Flags = uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move));
- data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
- data << move_spline.spline.getPoint(move_spline.spline.first());
- data << move_spline.GetId();
-
- switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
+ switch (move_spline.splineflags & MoveSplineFlag::Mask_Final_Facing)
{
+ case MoveSplineFlag::Final_Point:
+ movementSpline.Face = MONSTER_MOVE_FACING_SPOT;
+ movementSpline.FaceSpot = move_spline.facing.f;
+ break;
case MoveSplineFlag::Final_Target:
- data << uint8(MonsterMoveFacingTarget);
- data << move_spline.facing.target;
+ movementSpline.Face = MONSTER_MOVE_FACING_TARGET;
+ movementSpline.FaceGUID = move_spline.facing.target;
break;
case MoveSplineFlag::Final_Angle:
- data << uint8(MonsterMoveFacingAngle);
- data << move_spline.facing.angle;
- break;
- case MoveSplineFlag::Final_Point:
- data << uint8(MonsterMoveFacingSpot);
- data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
+ movementSpline.Face = MONSTER_MOVE_FACING_ANGLE;
+ movementSpline.FaceDirection = move_spline.facing.angle;
break;
default:
- data << uint8(MonsterMoveNormal);
+ movementSpline.Face = MONSTER_MOVE_NORMAL;
break;
}
- // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
- splineflags.enter_cycle = move_spline.isCyclic();
- data << uint32(splineflags & uint32(~MoveSplineFlag::Mask_No_Monster_Move));
-
if (splineflags.animation)
{
- data << splineflags.getAnimationId();
- data << move_spline.effect_start_time;
+ movementSpline.AnimTier = splineflags.getAnimationId();
+ movementSpline.TierTransStartTime = move_spline.effect_start_time;
}
- data << move_spline.Duration();
+ movementSpline.MoveTime = move_spline.Duration();
if (splineflags.parabolic)
{
- data << move_spline.vertical_acceleration;
- data << move_spline.effect_start_time;
+ movementSpline.JumpGravity = move_spline.vertical_acceleration;
+ movementSpline.SpecialTime = move_spline.effect_start_time;
}
- }
-
- void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data)
- {
- data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
- data << pos;
- data << splineId;
- data << uint8(MonsterMoveStop);
- }
-
- void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data)
- {
- uint32 last_idx = spline.getPointCount() - 3;
- Vector3 const* real_path = &spline.getPoint(1);
-
- data << last_idx;
- data << real_path[last_idx]; // destination
- if (last_idx > 1)
- {
- Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f;
- Vector3 offset;
- // first and last points already appended
- for (uint32 i = 1; i < last_idx; ++i)
- {
- offset = middle - real_path[i];
- data.appendPackXYZ(offset.x, offset.y, offset.z);
- }
- }
- }
-
- void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data)
- {
- uint32 count = spline.getPointCount() - 3;
- data << count;
- data.append<Vector3>(&spline.getPoint(2), count);
- }
-
- void WriteUncompressedCyclicPath(Spline<int32> const& spline, ByteBuffer& data)
- {
- uint32 count = spline.getPointCount() - 3;
- data << uint32(count + 1);
- data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done
- data.append<Vector3>(&spline.getPoint(1), count);
- }
-
- void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data)
- {
- WriteCommonMonsterMovePart(move_spline, data);
Spline<int32> const& spline = move_spline.spline;
- MoveSplineFlag splineflags = move_spline.splineflags;
+ std::vector<Vector3> const& array = spline.getPoints();
+
if (splineflags & MoveSplineFlag::UncompressedPath)
{
if (!splineflags.cyclic)
- WriteUncompressedPath(spline, data);
+ {
+ uint32 count = spline.getPointCount() - 3;
+ for (uint32 i = 2; i < count; ++i)
+ movementSpline.Points.push_back(array[i]);
+ }
else
- WriteUncompressedCyclicPath(spline, data);
+ {
+ uint32 count = spline.getPointCount() - 3;
+ movementSpline.Points.push_back(array[1]);
+ for (uint32 i = 1; i < count; ++i)
+ movementSpline.Points.push_back(array[i]);
+ }
}
else
- WriteLinearPath(spline, data);
+ {
+ uint32 last_idx = spline.getPointCount() - 3;
+ Vector3 const* real_path = &spline.getPoint(1);
+
+ movementSpline.Points.push_back(real_path[last_idx]);
+
+ if (last_idx > 1)
+ {
+ Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f;
+ Vector3 offset;
+ // first and last points already appended
+ for (uint32 i = 1; i < last_idx; ++i)
+ {
+ offset = middle - real_path[i];
+ movementSpline.PackedDeltas.push_back(offset);
+ }
+ }
+ }
}
void PacketBuilder::WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data)
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h
index 2878a330f67..720c0b3b244 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.h
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h
@@ -22,6 +22,7 @@
#include "Define.h" // for uint32
#include "G3D/Vector3.h"
+#include "MovementPackets.h"
using G3D::Vector3;
class ByteBuffer;
@@ -32,11 +33,8 @@ namespace Movement
class MoveSpline;
class PacketBuilder
{
- static void WriteCommonMonsterMovePart(const MoveSpline& mov, WorldPacket& data);
public:
-
- static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data);
- static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data);
+ static void WriteMonsterMove(const MoveSpline& mov, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline);
static void WriteCreate(MoveSpline const& moveSpline, ByteBuffer& data);
};
}
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
index a69af9e3a83..14c4e19b19b 100644
--- a/src/server/game/Movement/Spline/MovementTypedefs.h
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -21,6 +21,14 @@
#include "Common.h"
+enum MonsterMoveType
+{
+ MONSTER_MOVE_NORMAL = 0,
+ MONSTER_MOVE_FACING_SPOT = 1,
+ MONSTER_MOVE_FACING_TARGET = 2,
+ MONSTER_MOVE_FACING_ANGLE = 3
+};
+
namespace G3D
{
class Vector3;
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 89ca3749a05..f39314ba119 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -360,9 +360,6 @@ bool Quest::IsAllowedInRaid(Difficulty difficulty) const
uint32 Quest::CalculateHonorGain(uint8 level) const
{
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
-
uint32 honor = 0;
/*if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f)
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 359a8f3946a..3bf3464f016 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -18,6 +18,7 @@
#include "DatabaseEnv.h"
#include "ReputationMgr.h"
+#include "ReputationPackets.h"
#include "DBCStores.h"
#include "Player.h"
#include "WorldPacket.h"
@@ -199,38 +200,17 @@ void ReputationMgr::SendState(FactionState const* faction)
void ReputationMgr::SendInitialReputations()
{
- uint16 count = 256;
- WorldPacket data(SMSG_INITIALIZE_FACTIONS, 4 + count * 5);
- data << uint32(count);
-
- RepListID a = 0;
+ WorldPackets::Reputation::InitializeFactions initFactions;
for (FactionStateList::iterator itr = _factions.begin(); itr != _factions.end(); ++itr)
{
- // fill in absent fields
- for (; a != itr->first; ++a)
- {
- data << uint8(0);
- data << uint32(0);
- }
-
- // fill in encountered data
- data << uint8(itr->second.Flags);
- data << uint32(itr->second.Standing);
-
+ initFactions.FactionFlags[itr->first] = itr->second.Flags;
+ initFactions.FactionStandings[itr->first] = itr->second.Standing;
+ /// @todo faction bonus
itr->second.needSend = false;
-
- ++a;
}
- // fill in absent fields
- for (; a != count; ++a)
- {
- data << uint8(0);
- data << uint32(0);
- }
-
- _player->SendDirectMessage(&data);
+ _player->SendDirectMessage(initFactions.Write());
}
void ReputationMgr::SendStates()
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index ac0b5bbf2e6..95ac2d275da 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -34,6 +34,12 @@
#include "WorldPacket.h"
#include "WorldSession.h"
+// namespace
+// {
+ UnusedScriptContainer UnusedScripts;
+ UnusedScriptNamesContainer UnusedScriptNames;
+// }
+
// This is the global static registry of scripts.
template<class TScript>
class ScriptRegistry
@@ -89,6 +95,12 @@ class ScriptRegistry
{
ScriptPointerList[id] = script;
sScriptMgr->IncrementScriptCount();
+
+ #ifdef SCRIPTS
+ UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName());
+ if (itr != UnusedScriptNames.end() && *itr == script->GetName())
+ UnusedScriptNames.erase(itr);
+ #endif
}
else
{
@@ -106,8 +118,7 @@ class ScriptRegistry
// Avoid calling "delete script;" because we are currently in the script constructor
// In a valid scenario this will not happen because every script has a name assigned in the database
- // If that happens, it's acceptable to just leak a few bytes
-
+ UnusedScripts.push_back(script);
return;
}
}
@@ -189,6 +200,15 @@ void ScriptMgr::Initialize()
FillSpellSummary();
AddScripts();
+#ifdef SCRIPTS
+ for (std::string const& scriptName : UnusedScriptNames)
+ {
+ TC_LOG_ERROR("sql.sql", "ScriptName '%s' exists in database, but no core script found!", scriptName.c_str());
+ }
+#endif
+
+ UnloadUnusedScripts();
+
TC_LOG_INFO("server.loading", ">> Loaded %u C++ scripts in %u ms", GetScriptCount(), GetMSTimeDiffToNow(oldMSTime));
}
@@ -229,10 +249,19 @@ void ScriptMgr::Unload()
#undef SCR_CLEAR
+ UnloadUnusedScripts();
+
delete[] SpellSummary;
delete[] UnitAI::AISpellInfo;
}
+void ScriptMgr::UnloadUnusedScripts()
+{
+ for (size_t i = 0; i < UnusedScripts.size(); ++i)
+ delete UnusedScripts[i];
+ UnusedScripts.clear();
+}
+
void ScriptMgr::LoadDatabase()
{
sScriptSystemMgr->LoadScriptWaypoints();
@@ -256,70 +285,73 @@ void ScriptMgr::FillSpellSummary()
if (!pTempSpell)
continue;
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : pTempSpell->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
+ if (!effect)
+ continue;
+
// Spell targets self.
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SELF-1);
// Spell targets a single enemy.
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_ENEMY-1);
// Spell targets AoE at enemy.
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_SRC_CASTER ||
+ effect->TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_ENEMY-1);
// Spell targets an enemy.
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_DEST_TARGET_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_SRC_AREA_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_DEST_AREA_ENEMY ||
+ effect->TargetA.GetTarget() == TARGET_SRC_CASTER ||
+ effect->TargetA.GetTarget() == TARGET_DEST_DYNOBJ_ENEMY)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_ENEMY-1);
// Spell targets a single friend (or self).
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_SINGLE_FRIEND-1);
// Spell targets AoE friends.
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
+ effect->TargetA.GetTarget() == TARGET_SRC_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_AOE_FRIEND-1);
// Spell targets any friend (or self).
- if (pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
- pTempSpell->Effects[j].TargetA.GetTarget() == TARGET_SRC_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_ALLY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_TARGET_PARTY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_CASTER_AREA_PARTY ||
+ effect->TargetA.GetTarget() == TARGET_UNIT_LASTTARGET_AREA_PARTY ||
+ effect->TargetA.GetTarget() == TARGET_SRC_CASTER)
SpellSummary[i].Targets |= 1 << (SELECT_TARGET_ANY_FRIEND-1);
// Make sure that this spell includes a damage effect.
- if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE ||
- pTempSpell->Effects[j].Effect == SPELL_EFFECT_INSTAKILL ||
- pTempSpell->Effects[j].Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
- pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEALTH_LEECH)
+ if (effect->Effect == SPELL_EFFECT_SCHOOL_DAMAGE ||
+ effect->Effect == SPELL_EFFECT_INSTAKILL ||
+ effect->Effect == SPELL_EFFECT_ENVIRONMENTAL_DAMAGE ||
+ effect->Effect == SPELL_EFFECT_HEALTH_LEECH)
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_DAMAGE-1);
// Make sure that this spell includes a healing effect (or an apply aura with a periodic heal).
- if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL ||
- pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MAX_HEALTH ||
- pTempSpell->Effects[j].Effect == SPELL_EFFECT_HEAL_MECHANICAL ||
- (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA && pTempSpell->Effects[j].ApplyAuraName == 8))
+ if (effect->Effect == SPELL_EFFECT_HEAL ||
+ effect->Effect == SPELL_EFFECT_HEAL_MAX_HEALTH ||
+ effect->Effect == SPELL_EFFECT_HEAL_MECHANICAL ||
+ (effect->Effect == SPELL_EFFECT_APPLY_AURA && effect->ApplyAuraName == 8))
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_HEALING-1);
// Make sure that this spell applies an aura.
- if (pTempSpell->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
SpellSummary[i].Effects |= 1 << (SELECT_EFFECT_AURA-1);
}
}
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 5957f3a511a..4431f710976 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -872,6 +872,15 @@ class GroupScript : public ScriptObject
// Placed here due to ScriptRegistry::AddScript dependency.
#define sScriptMgr ScriptMgr::instance()
+// namespace
+// {
+ typedef std::vector<ScriptObject*> UnusedScriptContainer;
+ typedef std::list<std::string> UnusedScriptNamesContainer;
+
+ extern UnusedScriptContainer UnusedScripts;
+ extern UnusedScriptNamesContainer UnusedScriptNames;
+// }
+
// Manages registration, loading, and execution of scripts.
class ScriptMgr
{
@@ -900,6 +909,7 @@ class ScriptMgr
public: /* Unloading */
void Unload();
+ void UnloadUnusedScripts();
public: /* SpellScriptLoader */
diff --git a/src/server/game/Server/Packet.cpp b/src/server/game/Server/Packet.cpp
index ee805c18610..10b472bee67 100644
--- a/src/server/game/Server/Packet.cpp
+++ b/src/server/game/Server/Packet.cpp
@@ -17,164 +17,6 @@
#include "Packet.h"
-inline bool IsInstanceOnlyOpcode(uint32 opcode)
-{
- // TODO: Use names when known
- switch (opcode)
- {
- case 0x000F: // Client
- case 0x0111: // Client
- case 0x03E4: // Client
- case 0x0549: // Client
- case 0x054C: // Client
- case 0x055A: // Client
- case 0x056C: // Client
- case 0x057A: // Client
- case 0x057B: // Client
- case 0x05CC: // Client
- case 0x05EA: // Client
- case 0x05EC: // Client
- case 0x05F9: // Client
- case 0x05FB: // Client
- case 0x074C: // Client
- case 0x075B: // Client
- case 0x076C: // Client
- case 0x077B: // Client
- case 0x077C: // Client
- case 0x07CC: // Client
- case 0x07DB: // Client
- case 0x07EC: // Client
- case 0x07FB: // Client
- case 0x07FC: // Client
- case 0x0827: // Client
- case 0x0935: // Client
- case 0x0F0C: // ClientSpell
- case 0x0F10: // ClientSpell
- case 0x0F1B: // ClientSpell
- case 0x0F1C: // ClientSpell
- case 0x0F20: // ClientSpell
- case 0x0F2C: // ClientSpell
- case 0x0F2F: // ClientSpell
- case 0x0F3B: // ClientSpell
- case 0x0F8B: // ClientSpell
- case 0x0F8C: // ClientSpell
- case 0x0F90: // ClientSpell
- case 0x0F9F: // ClientSpell
- case 0x0FA0: // ClientSpell
- case SMSG_ATTACKSTOP: // Client
- case 0x14C9: // Client
- case 0x154A: // Client
- case 0x155A: // Client
- case 0x155C: // Client
- case SMSG_QUESTGIVER_STATUS: // ClientQuest
- case 0x156A: // Client
- case 0x156B: // Client
- case 0x157A: // Client
- case 0x157B: // Client
- case 0x15DC: // Client
- case 0x15EB: // Client
- case 0x15FB: // Client
- case 0x170C: // ClientSpell
- case 0x171C: // ClientSpell
- case 0x171F: // ClientSpell
- case 0x172C: // ClientSpell
- case 0x172F: // ClientSpell
- case 0x173C: // ClientSpell
- case 0x173F: // ClientSpell
- case 0x1740: // ClientSpell
- case 0x1790: // ClientSpell
- case 0x179B: // ClientSpell
- case 0x179F: // ClientSpell
- case SMSG_ATTACKSTART: // Client
- case 0x1D82: // ClientQuest
- case 0x1D83: // ClientQuest
- case 0x1D85: // ClientQuest
- case 0x1D87: // ClientQuest
- case 0x1D93: // ClientQuest
- case 0x1D96: // ClientQuest
- case 0x1D97: // ClientQuest
- case 0x1DA1: // ClientQuest
- case 0x1DA2: // ClientQuest
- case 0x1DA3: // ClientQuest
- case 0x1DA4: // ClientQuest
- case 0x1DA5: // ClientQuest
- case 0x1DA7: // ClientQuest
- case SMSG_QUERY_TIME_RESPONSE: // Client
- case 0x1DC2: // ClientQuest
- case 0x1DC6: // ClientQuest
- case 0x1DC7: // ClientQuest
- case 0x1DD2: // ClientQuest
- case 0x1DD3: // ClientQuest
- case 0x1DD6: // ClientQuest
- case 0x1DD7: // ClientQuest
- case 0x1DD8: // ClientQuest
- case 0x1DE4: // ClientQuest
- case 0x1DE5: // ClientQuest
- case 0x1DE7: // ClientQuest
- case 0x1F02: // ClientQuest
- case 0x1F06: // ClientQuest
- case 0x1F07: // ClientQuest
- case 0x1F0C: // ClientSpell
- case 0x1F12: // ClientQuest
- case 0x1F13: // ClientQuest
- case 0x1F16: // ClientQuest
- case 0x1F17: // ClientQuest
- case 0x1F18: // ClientQuest
- case 0x1F1C: // ClientSpell
- case 0x1F1F: // ClientSpell
- case 0x1F24: // ClientQuest
- case 0x1F25: // ClientQuest
- case 0x1F27: // ClientQuest
- case 0x1F2C: // ClientSpell
- case 0x1F2F: // ClientSpell
- case 0x1F3C: // ClientSpell
- case 0x1F3F: // ClientSpell
- case 0x1F40: // ClientSpell
- case 0x1F44: // ClientQuest
- case 0x1F48: // ClientQuest
- case 0x1F51: // ClientQuest
- case 0x1F55: // ClientQuest
- case 0x1F57: // ClientQuest
- case 0x1F61: // ClientQuest
- case 0x1F63: // ClientQuest
- case 0x1F64: // ClientQuest
- case 0x1F65: // ClientQuest
- case 0x1F67: // ClientQuest
- case 0x1F85: // ClientQuest
- case 0x1F86: // ClientQuest
- case 0x1F87: // ClientQuest
- case 0x1F90: // ClientSpell
- case 0x1F92: // ClientQuest
- case 0x1F94: // ClientQuest
- case 0x1F96: // ClientQuest
- case 0x1F97: // ClientQuest
- case 0x1F9B: // ClientSpell
- case 0x1F9F: // ClientSpell
- case 0x1FA1: // ClientQuest
- case 0x1FA2: // ClientQuest
- case 0x1FA3: // ClientQuest
- case 0x1FA4: // ClientQuest
- case 0x1FA5: // ClientQuest
- case 0x1FA7: // ClientQuest
- case 0x1FC2: // ClientQuest
- case 0x1FC6: // ClientQuest
- case 0x1FC7: // ClientQuest
- case 0x1FD2: // ClientQuest
- case 0x1FD3: // ClientQuest
- case 0x1FD6: // ClientQuest
- case 0x1FD7: // ClientQuest
- case 0x1FD8: // ClientQuest
- case 0x1FE4: // ClientQuest
- case 0x1FE5: // ClientQuest
- case 0x1FE7: // ClientQuest
- return true;
- default:
- return false;
- }
-}
-
WorldPackets::ServerPacket::ServerPacket(OpcodeServer opcode, size_t initialSize /*= 200*/) : Packet(WorldPacket(opcode, initialSize))
{
- if (IsInstanceOnlyOpcode(opcode))
- _connectionIndex = CONNECTION_TYPE_INSTANCE;
}
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.cpp b/src/server/game/Server/Packets/AuthenticationPackets.cpp
index 2bb1760b31c..a69e684438f 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.cpp
+++ b/src/server/game/Server/Packets/AuthenticationPackets.cpp
@@ -65,20 +65,20 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write()
if (SuccessInfo.HasValue)
{
- _worldPacket << uint32(SuccessInfo.value.VirtualRealmAddress);
- _worldPacket << uint32(SuccessInfo.value.VirtualRealms.size());
- _worldPacket << uint32(SuccessInfo.value.TimeRemain);
- _worldPacket << uint32(SuccessInfo.value.TimeOptions);
- _worldPacket << uint32(SuccessInfo.value.TimeRested);
- _worldPacket << uint8(SuccessInfo.value.ActiveExpansionLevel);
- _worldPacket << uint8(SuccessInfo.value.AccountExpansionLevel);
- _worldPacket << uint32(SuccessInfo.value.TimeSecondsUntilPCKick);
- _worldPacket << uint32(SuccessInfo.value.AvailableRaces->size());
- _worldPacket << uint32(SuccessInfo.value.AvailableClasses->size());
- _worldPacket << uint32(SuccessInfo.value.Templates.size());
- _worldPacket << uint32(SuccessInfo.value.CurrencyID);
-
- for (auto& realm : SuccessInfo.value.VirtualRealms)
+ _worldPacket << uint32(SuccessInfo.Value.VirtualRealmAddress);
+ _worldPacket << uint32(SuccessInfo.Value.VirtualRealms.size());
+ _worldPacket << uint32(SuccessInfo.Value.TimeRemain);
+ _worldPacket << uint32(SuccessInfo.Value.TimeOptions);
+ _worldPacket << uint32(SuccessInfo.Value.TimeRested);
+ _worldPacket << uint8(SuccessInfo.Value.ActiveExpansionLevel);
+ _worldPacket << uint8(SuccessInfo.Value.AccountExpansionLevel);
+ _worldPacket << uint32(SuccessInfo.Value.TimeSecondsUntilPCKick);
+ _worldPacket << uint32(SuccessInfo.Value.AvailableRaces->size());
+ _worldPacket << uint32(SuccessInfo.Value.AvailableClasses->size());
+ _worldPacket << uint32(SuccessInfo.Value.Templates.size());
+ _worldPacket << uint32(SuccessInfo.Value.CurrencyID);
+
+ for (auto& realm : SuccessInfo.Value.VirtualRealms)
{
_worldPacket << uint32(realm.RealmAddress);
_worldPacket.WriteBit(realm.IsLocal);
@@ -89,19 +89,19 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write()
_worldPacket.WriteString(realm.RealmNameNormalized);
}
- for (auto& race : *SuccessInfo.value.AvailableRaces)
+ for (auto& race : *SuccessInfo.Value.AvailableRaces)
{
_worldPacket << uint8(race.first); /// the current race
_worldPacket << uint8(race.second); /// the required Expansion
}
- for (auto& klass : *SuccessInfo.value.AvailableClasses)
+ for (auto& klass : *SuccessInfo.Value.AvailableClasses)
{
_worldPacket << uint8(klass.first); /// the current class
_worldPacket << uint8(klass.second); /// the required Expansion
}
- for (auto& templat : SuccessInfo.value.Templates)
+ for (auto& templat : SuccessInfo.Value.Templates)
{
_worldPacket << uint32(templat.TemplateSetId);
_worldPacket << uint32(templat.TemplateClasses.size());
@@ -117,23 +117,23 @@ WorldPacket const* WorldPackets::Auth::AuthResponse::Write()
_worldPacket.WriteString(templat.Description);
}
- _worldPacket.WriteBit(SuccessInfo.value.IsExpansionTrial);
- _worldPacket.WriteBit(SuccessInfo.value.ForceCharacterTemplate);
- _worldPacket.WriteBit(SuccessInfo.value.NumPlayersHorde != 0);
- _worldPacket.WriteBit(SuccessInfo.value.NumPlayersAlliance != 0);
- _worldPacket.WriteBit(SuccessInfo.value.IsVeteranTrial);
+ _worldPacket.WriteBit(SuccessInfo.Value.IsExpansionTrial);
+ _worldPacket.WriteBit(SuccessInfo.Value.ForceCharacterTemplate);
+ _worldPacket.WriteBit(SuccessInfo.Value.NumPlayersHorde.HasValue);
+ _worldPacket.WriteBit(SuccessInfo.Value.NumPlayersAlliance.HasValue);
+ _worldPacket.WriteBit(SuccessInfo.Value.IsVeteranTrial);
- if (SuccessInfo.value.NumPlayersHorde)
- _worldPacket << uint16(SuccessInfo.value.NumPlayersHorde);
+ if (SuccessInfo.Value.NumPlayersHorde.HasValue)
+ _worldPacket << uint16(SuccessInfo.Value.NumPlayersHorde.Value);
- if (SuccessInfo.value.NumPlayersAlliance)
- _worldPacket << uint16(SuccessInfo.value.NumPlayersAlliance);
+ if (SuccessInfo.Value.NumPlayersAlliance.HasValue)
+ _worldPacket << uint16(SuccessInfo.Value.NumPlayersAlliance.Value);
}
if (WaitInfo.HasValue)
{
- _worldPacket << uint32(WaitInfo.value.WaitCount);
- _worldPacket.WriteBit(WaitInfo.value.HasFCM);
+ _worldPacket << uint32(WaitInfo.Value.WaitCount);
+ _worldPacket.WriteBit(WaitInfo.Value.HasFCM);
}
_worldPacket.FlushBits();
diff --git a/src/server/game/Server/Packets/AuthenticationPackets.h b/src/server/game/Server/Packets/AuthenticationPackets.h
index e24c06396e0..dcc9a908539 100644
--- a/src/server/game/Server/Packets/AuthenticationPackets.h
+++ b/src/server/game/Server/Packets/AuthenticationPackets.h
@@ -34,13 +34,13 @@ namespace WorldPackets
class AuthChallenge final : public ServerPacket
{
public:
- AuthChallenge() : ServerPacket(SMSG_AUTH_CHALLENGE, 4 + 32 + 1), Challenge(0) { }
+ AuthChallenge() : ServerPacket(SMSG_AUTH_CHALLENGE, 4 + 32 + 1) { }
WorldPacket const* Write() override;
- uint32 Challenge;
+ uint32 Challenge = 0;
uint32 DosChallenge[8]; ///< Encryption seeds
- uint8 DosZeroBits;
+ uint8 DosZeroBits = 0;
};
class AuthSession final : public ClientPacket
@@ -118,8 +118,8 @@ namespace WorldPackets
bool IsExpansionTrial = false;
bool ForceCharacterTemplate = false; ///< forces the client to always use a character template when creating a new character. @see Templates. @todo implement
- uint16 NumPlayersHorde = 0; ///< number of horde players in this realm. @todo implement
- uint16 NumPlayersAlliance = 0; ///< number of alliance players in this realm. @todo implement
+ Optional<uint16> NumPlayersHorde; ///< number of horde players in this realm. @todo implement
+ Optional<uint16> NumPlayersAlliance; ///< number of alliance players in this realm. @todo implement
bool IsVeteranTrial = false; ///< @todo research
};
diff --git a/src/server/game/Server/Packets/ChannelPackets.cpp b/src/server/game/Server/Packets/ChannelPackets.cpp
index 8aa4ac51d42..bd1e62eadd6 100644
--- a/src/server/game/Server/Packets/ChannelPackets.cpp
+++ b/src/server/game/Server/Packets/ChannelPackets.cpp
@@ -18,14 +18,37 @@
#include "ChannelPackets.h"
#include "Channel.h"
+void WorldPackets::Channel::ChannelListRequest::Read()
+{
+ ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7));
+}
+
+WorldPacket const* WorldPackets::Channel::ChannelListResponse::Write()
+{
+ _worldPacket.WriteBit(_Display);
+ _worldPacket.WriteBits(_Channel.length(), 7);
+ _worldPacket << uint8(_ChannelFlags);
+ _worldPacket << uint32(_Members.size());
+ _worldPacket.WriteString(_Channel);
+
+ for (ChannelPlayer const& player : _Members)
+ {
+ _worldPacket << player.Guid;
+ _worldPacket << uint32(player.VirtualRealmAddress);
+ _worldPacket << uint8(player.Flags);
+ }
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Channel::ChannelNotify::Write()
{
_worldPacket.WriteBits(Type, 6);
- _worldPacket.WriteBits(Channel.length(), 7);
+ _worldPacket.WriteBits(_Channel.length(), 7);
_worldPacket.WriteBits(Sender.length(), 6);
_worldPacket << SenderGuid;
- _worldPacket << SenderBnetAccountID;
+ _worldPacket << SenderAccountID;
_worldPacket << uint32(SenderVirtualRealm);
_worldPacket << TargetGuid;
_worldPacket << uint32(TargetVirtualRealm);
@@ -37,7 +60,7 @@ WorldPacket const* WorldPackets::Channel::ChannelNotify::Write()
_worldPacket << uint8(NewFlags);
}
- _worldPacket.WriteString(Channel);
+ _worldPacket.WriteString(_Channel);
_worldPacket.WriteString(Sender);
return &_worldPacket;
@@ -45,12 +68,12 @@ WorldPacket const* WorldPackets::Channel::ChannelNotify::Write()
WorldPacket const* WorldPackets::Channel::ChannelNotifyJoined::Write()
{
- _worldPacket.WriteBits(Channel.length(), 7);
+ _worldPacket.WriteBits(_Channel.length(), 7);
_worldPacket.WriteBits(ChannelWelcomeMsg.length(), 10);
- _worldPacket << uint8(ChannelFlags);
+ _worldPacket << uint8(_ChannelFlags);
_worldPacket << int32(ChatChannelID);
_worldPacket << uint64(InstanceID);
- _worldPacket.WriteString(Channel);
+ _worldPacket.WriteString(_Channel);
_worldPacket.WriteString(ChannelWelcomeMsg);
return &_worldPacket;
@@ -76,3 +99,9 @@ void WorldPackets::Channel::JoinChannel::Read()
ChannelName = _worldPacket.ReadString(channelLength);
Password = _worldPacket.ReadString(passwordLength);
}
+
+void WorldPackets::Channel::LeaveChannel::Read()
+{
+ _worldPacket >> ZoneChannelID;
+ ChannelName = _worldPacket.ReadString(_worldPacket.ReadBits(7));
+}
diff --git a/src/server/game/Server/Packets/ChannelPackets.h b/src/server/game/Server/Packets/ChannelPackets.h
index b6c8eb3b928..e3d96c5c453 100644
--- a/src/server/game/Server/Packets/ChannelPackets.h
+++ b/src/server/game/Server/Packets/ChannelPackets.h
@@ -25,6 +25,42 @@ namespace WorldPackets
{
namespace Channel
{
+ class ChannelListRequest final : public ClientPacket
+ {
+ public:
+ ChannelListRequest(WorldPacket&& packet) : ClientPacket(std::move(packet))
+ {
+ ASSERT(packet.GetOpcode() == CMSG_CHANNEL_LIST || packet.GetOpcode() == CMSG_CHANNEL_DISPLAY_LIST);
+ }
+
+ void Read() override;
+
+ std::string ChannelName;
+ };
+
+ class ChannelListResponse final : public ServerPacket
+ {
+ public:
+ struct ChannelPlayer
+ {
+ ChannelPlayer(ObjectGuid const& guid, uint32 realm, uint8 flags) :
+ Guid(guid), VirtualRealmAddress(realm), Flags(flags) { }
+
+ ObjectGuid Guid; ///< Player Guid
+ uint32 VirtualRealmAddress;
+ uint8 Flags = 0; ///< @see enum ChannelMemberFlags
+ };
+
+ ChannelListResponse() : ServerPacket(SMSG_CHANNEL_LIST) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<ChannelPlayer> _Members;
+ std::string _Channel; ///< Channel Name
+ uint8 _ChannelFlags = 0; ///< @see enum ChannelFlags
+ bool _Display = false;
+ };
+
class ChannelNotify final : public ServerPacket
{
public:
@@ -34,11 +70,11 @@ namespace WorldPackets
std::string Sender;
ObjectGuid SenderGuid;
- ObjectGuid SenderBnetAccountID;
+ ObjectGuid SenderAccountID;
uint8 Type = 0; ///< @see enum ChatNotify
uint8 OldFlags = 0; ///< @see enum ChannelMemberFlags
uint8 NewFlags = 0; ///< @see enum ChannelMemberFlags
- std::string Channel;
+ std::string _Channel; ///< Channel Name
uint32 SenderVirtualRealm = 0;
ObjectGuid TargetGuid;
uint32 TargetVirtualRealm = 0;
@@ -55,8 +91,8 @@ namespace WorldPackets
std::string ChannelWelcomeMsg;
int32 ChatChannelID = 0;
int32 InstanceID = 0;
- uint8 ChannelFlags = 0; ///< @see enum ChannelFlags
- std::string Channel;
+ uint8 _ChannelFlags = 0; ///< @see enum ChannelFlags
+ std::string _Channel; ///< Channel Name
};
class ChannelNotifyLeft final : public ServerPacket
@@ -66,9 +102,9 @@ namespace WorldPackets
WorldPacket const* Write() override;
- std::string Channel;
+ std::string Channel; ///< Channel Name
int32 ChatChannelID = 0;
- bool Suspended = false;
+ bool Suspended = false; ///< User Leave - false, On Zone Change - true
};
class JoinChannel final : public ClientPacket
@@ -84,6 +120,17 @@ namespace WorldPackets
int32 ChatChannelId = 0;
bool Internal = false;
};
+
+ class LeaveChannel final : public ClientPacket
+ {
+ public:
+ LeaveChannel(WorldPacket&& packet) : ClientPacket(CMSG_LEAVE_CHANNEL, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 ZoneChannelID = 0;
+ std::string ChannelName;
+ };
}
}
diff --git a/src/server/game/Server/Packets/CharacterPackets.cpp b/src/server/game/Server/Packets/CharacterPackets.cpp
index 8fae98cf8f2..b5d26bf2968 100644
--- a/src/server/game/Server/Packets/CharacterPackets.cpp
+++ b/src/server/game/Server/Packets/CharacterPackets.cpp
@@ -200,7 +200,7 @@ void WorldPackets::Character::CreateChar::Read()
_worldPacket >> CreateInfo->OutfitId;
CreateInfo->Name = _worldPacket.ReadString(nameLength);
if (CreateInfo->TemplateSet.HasValue)
- _worldPacket >> CreateInfo->TemplateSet.value;
+ _worldPacket >> CreateInfo->TemplateSet.Value;
}
WorldPacket const* WorldPackets::Character::CharacterCreateResponse::Write()
@@ -234,7 +234,7 @@ WorldPacket const* WorldPackets::Character::CharacterRenameResult::Write()
_worldPacket.WriteBits(Name.length(), 6);
if (Guid.HasValue)
- _worldPacket << Guid.value;
+ _worldPacket << Guid.Value;
_worldPacket.WriteString(Name);
return &_worldPacket;
@@ -274,19 +274,19 @@ void WorldPackets::Character::CharRaceOrFactionChange::Read()
RaceOrFactionChangeInfo->Name = _worldPacket.ReadString(nameLength);
if (RaceOrFactionChangeInfo->SkinID.HasValue)
- _worldPacket >> RaceOrFactionChangeInfo->SkinID.value;
+ _worldPacket >> RaceOrFactionChangeInfo->SkinID.Value;
if (RaceOrFactionChangeInfo->HairColorID.HasValue)
- _worldPacket >> RaceOrFactionChangeInfo->HairColorID.value;
+ _worldPacket >> RaceOrFactionChangeInfo->HairColorID.Value;
if (RaceOrFactionChangeInfo->HairStyleID.HasValue)
- _worldPacket >> RaceOrFactionChangeInfo->HairStyleID.value;
+ _worldPacket >> RaceOrFactionChangeInfo->HairStyleID.Value;
if (RaceOrFactionChangeInfo->FacialHairStyleID.HasValue)
- _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID.value;
+ _worldPacket >> RaceOrFactionChangeInfo->FacialHairStyleID.Value;
if (RaceOrFactionChangeInfo->FaceID.HasValue)
- _worldPacket >> RaceOrFactionChangeInfo->FaceID.value;
+ _worldPacket >> RaceOrFactionChangeInfo->FaceID.Value;
}
WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write()
@@ -298,15 +298,15 @@ WorldPacket const* WorldPackets::Character::CharFactionChangeResult::Write()
if (Display.HasValue)
{
- _worldPacket.WriteBits(Display.value.Name.length(), 6);
- _worldPacket << uint8(Display.value.SexID);
- _worldPacket << uint8(Display.value.SkinID);
- _worldPacket << uint8(Display.value.HairColorID);
- _worldPacket << uint8(Display.value.HairStyleID);
- _worldPacket << uint8(Display.value.FacialHairStyleID);
- _worldPacket << uint8(Display.value.FaceID);
- _worldPacket << uint8(Display.value.RaceID);
- _worldPacket.WriteString(Display.value.Name);
+ _worldPacket.WriteBits(Display.Value.Name.length(), 6);
+ _worldPacket << uint8(Display.Value.SexID);
+ _worldPacket << uint8(Display.Value.SkinID);
+ _worldPacket << uint8(Display.Value.HairColorID);
+ _worldPacket << uint8(Display.Value.HairStyleID);
+ _worldPacket << uint8(Display.Value.FacialHairStyleID);
+ _worldPacket << uint8(Display.Value.FaceID);
+ _worldPacket << uint8(Display.Value.RaceID);
+ _worldPacket.WriteString(Display.Value.Name);
}
return &_worldPacket;
diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp
new file mode 100644
index 00000000000..7590a092b2c
--- /dev/null
+++ b/src/server/game/Server/Packets/ChatPackets.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "ChatPackets.h"
+
+void WorldPackets::Chat::ChatMessage::Read()
+{
+ _worldPacket >> Language;
+ uint32 len = _worldPacket.ReadBits(8);
+ Text = _worldPacket.ReadString(len);
+}
+
+void WorldPackets::Chat::ChatMessageWhisper::Read()
+{
+ _worldPacket >> Language;
+ uint32 targetLen = _worldPacket.ReadBits(9);
+ uint32 textLen = _worldPacket.ReadBits(8);
+ Target = _worldPacket.ReadString(targetLen);
+ Text = _worldPacket.ReadString(textLen);
+}
+
+void WorldPackets::Chat::ChatMessageChannel::Read()
+{
+ _worldPacket >> Language;
+ uint32 targetLen = _worldPacket.ReadBits(9);
+ uint32 textLen = _worldPacket.ReadBits(8);
+ _worldPacket.ResetBitPos();
+ Target = _worldPacket.ReadString(targetLen);
+ Text = _worldPacket.ReadString(textLen);
+}
+
+void WorldPackets::Chat::ChatAddonMessage::Read()
+{
+ uint32 prefixLen = _worldPacket.ReadBits(5);
+ uint32 textLen = _worldPacket.ReadBits(8);
+ Prefix = _worldPacket.ReadString(prefixLen);
+ Text = _worldPacket.ReadString(textLen);
+}
+
+void WorldPackets::Chat::ChatAddonMessageWhisper::Read()
+{
+ uint32 targetLen = _worldPacket.ReadBits(9);
+ uint32 prefixLen = _worldPacket.ReadBits(5);
+ uint32 textLen = _worldPacket.ReadBits(8);
+ Target = _worldPacket.ReadString(targetLen);
+ Prefix = _worldPacket.ReadString(prefixLen);
+ Text = _worldPacket.ReadString(textLen);
+}
+
+void WorldPackets::Chat::ChatMessageDND::Read()
+{
+ uint32 len = _worldPacket.ReadBits(8);
+ Text = _worldPacket.ReadString(len);
+}
+
+void WorldPackets::Chat::ChatMessageAFK::Read()
+{
+ uint32 len = _worldPacket.ReadBits(8);
+ Text = _worldPacket.ReadString(len);
+}
+
+void WorldPackets::Chat::ChatMessageEmote::Read()
+{
+ uint32 len = _worldPacket.ReadBits(8);
+ Text = _worldPacket.ReadString(len);
+}
+
+WorldPacket const* WorldPackets::Chat::Chat::Write()
+{
+ _worldPacket << SlashCmd;
+ _worldPacket << Language;
+ _worldPacket << SenderGUID;
+ _worldPacket << SenderGuildGUID;
+ _worldPacket << SenderAccountGUID;
+ _worldPacket << TargetGUID;
+ _worldPacket << TargetVirtualAddress;
+ _worldPacket << SenderVirtualAddress;
+ _worldPacket << PartyGUID;
+ _worldPacket << AchievementID;
+ _worldPacket << DisplayTime;
+ _worldPacket.WriteBits(SenderName.length(), 11);
+ _worldPacket.WriteBits(TargetName.length(), 11);
+ _worldPacket.WriteBits(Prefix.length(), 5);
+ _worldPacket.WriteBits(Channel.length(), 7);
+ _worldPacket.WriteBits(ChatText.length(), 12);
+ _worldPacket.WriteBits(ChatFlags, 10);
+ _worldPacket.WriteBit(HideChatLog);
+ _worldPacket.WriteBit(FakeSenderName);
+ _worldPacket.WriteString(SenderName);
+ _worldPacket.WriteString(TargetName);
+ _worldPacket.WriteString(Prefix);
+ _worldPacket.WriteString(Channel);
+ _worldPacket.WriteString(ChatText);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Chat::Emote::Write()
+{
+ _worldPacket << Guid;
+ _worldPacket << EmoteID;
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Chat::CTextEmote::Read()
+{
+ _worldPacket >> Target;
+ _worldPacket >> EmoteID;
+ _worldPacket >> SoundIndex;
+}
+
+WorldPacket const* WorldPackets::Chat::STextEmote::Write()
+{
+ _worldPacket << SourceGUID;
+ _worldPacket << SourceAccountGUID;
+ _worldPacket << EmoteID;
+ _worldPacket << SoundIndex;
+ _worldPacket << TargetGUID;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h
new file mode 100644
index 00000000000..9cdc534528f
--- /dev/null
+++ b/src/server/game/Server/Packets/ChatPackets.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ChatPackets_h__
+#define ChatPackets_h__
+
+#include "Packet.h"
+#include "SharedDefines.h"
+#include "ObjectGuid.h"
+
+namespace WorldPackets
+{
+ namespace Chat
+ {
+ // CMSG_MESSAGECHAT_GUILD
+ // CMSG_MESSAGECHAT_OFFICER
+ // CMSG_MESSAGECHAT_YELL
+ // CMSG_MESSAGECHAT_SAY
+ // CMSG_MESSAGECHAT_PARTY
+ // CMSG_MESSAGECHAT_RAID
+ // CMSG_MESSAGECHAT_RAID_WARNING
+ class ChatMessage final : public ClientPacket
+ {
+ public:
+ ChatMessage(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Text;
+ int32 Language = LANG_UNIVERSAL;
+ };
+
+ // CMSG_MESSAGECHAT_WHISPER
+ class ChatMessageWhisper final : public ClientPacket
+ {
+ public:
+ ChatMessageWhisper(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ int32 Language = LANG_UNIVERSAL;
+ std::string Text;
+ std::string Target;
+ };
+
+ // CMSG_MESSAGECHAT_CHANNEL
+ class ChatMessageChannel final : public ClientPacket
+ {
+ public:
+ ChatMessageChannel(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ int32 Language = LANG_UNIVERSAL;
+ std::string Text;
+ std::string Target;
+ };
+
+ // CMSG_MESSAGECHAT_ADDON_GUILD
+ // CMSG_MESSAGECHAT_ADDON_OFFICER
+ // CMSG_MESSAGECHAT_ADDON_PARTY
+ // CMSG_MESSAGECHAT_ADDON_RAID
+ class ChatAddonMessage final : public ClientPacket
+ {
+ public:
+ ChatAddonMessage(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Prefix;
+ std::string Text;
+ };
+
+ // CMSG_MESSAGECHAT_ADDON_WHISPER
+ class ChatAddonMessageWhisper final : public ClientPacket
+ {
+ public:
+ ChatAddonMessageWhisper(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Prefix;
+ std::string Target;
+ std::string Text;
+ };
+
+ class ChatMessageDND final : public ClientPacket
+ {
+ public:
+ ChatMessageDND(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_DND, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Text;
+ };
+
+ class ChatMessageAFK final : public ClientPacket
+ {
+ public:
+ ChatMessageAFK(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_AFK, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Text;
+ };
+
+ class ChatMessageEmote final : public ClientPacket
+ {
+ public:
+ ChatMessageEmote(WorldPacket&& packet) : ClientPacket(CMSG_MESSAGECHAT_EMOTE, std::move(packet)) { }
+
+ void Read() override;
+
+ std::string Text;
+ };
+
+ // SMSG_MESSAGECHAT
+ class Chat final : public ServerPacket
+ {
+ public:
+ Chat() : ServerPacket(SMSG_MESSAGECHAT, 100) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 SlashCmd = 0;
+ uint8 Language = LANG_UNIVERSAL;
+ ObjectGuid SenderGUID;
+ ObjectGuid SenderGuildGUID;
+ ObjectGuid SenderAccountGUID;
+ ObjectGuid TargetGUID;
+ ObjectGuid PartyGUID;
+ uint32 SenderVirtualAddress = 0;
+ uint32 TargetVirtualAddress = 0;
+ std::string SenderName;
+ std::string TargetName;
+ std::string Prefix;
+ std::string Channel;
+ std::string ChatText;
+ uint32 AchievementID = 0;
+ uint8 ChatFlags = 0;
+ float DisplayTime = 0.0f;
+ bool HideChatLog = false;
+ bool FakeSenderName = false;
+ };
+
+ class Emote final : public ServerPacket
+ {
+ public:
+ Emote() : ServerPacket(SMSG_EMOTE, 18 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ int32 EmoteID = 0;
+ };
+
+ class CTextEmote final : public ClientPacket
+ {
+ public:
+ CTextEmote(WorldPacket&& packet) : ClientPacket(CMSG_TEXT_EMOTE, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Target;
+ int32 EmoteID = 0;
+ int32 SoundIndex = -1;
+ };
+
+ class STextEmote final : public ServerPacket
+ {
+ public:
+ STextEmote() : ServerPacket(SMSG_TEXT_EMOTE, 3 * 18 + 2 * 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid SourceGUID;
+ ObjectGuid SourceAccountGUID;
+ ObjectGuid TargetGUID;
+ int32 SoundIndex = -1;
+ int32 EmoteID = 0;
+ };
+ }
+}
+
+#endif // ChatPackets_h__
diff --git a/src/server/game/Server/Packets/CombatLogPackets.cpp b/src/server/game/Server/Packets/CombatLogPackets.cpp
new file mode 100644
index 00000000000..128cc0d342f
--- /dev/null
+++ b/src/server/game/Server/Packets/CombatLogPackets.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "CombatLogPackets.h"
+#include "SpellPackets.h"
+
+WorldPacket const* WorldPackets::CombatLog::SpellNonMeleeDamageLog::Write()
+{
+ _worldPacket << Me;
+ _worldPacket << CasterGUID;
+ _worldPacket << SpellID;
+ _worldPacket << Damage;
+ _worldPacket << Overkill;
+ _worldPacket << SchoolMask;
+ _worldPacket << ShieldBlock;
+ _worldPacket << Resisted;
+ _worldPacket << Absorbed;
+
+ _worldPacket.WriteBit(Periodic);
+ _worldPacket.WriteBits(Flags, 9);
+ _worldPacket.WriteBit(false); // Debug info
+ _worldPacket.WriteBit(LogData.HasValue);
+ _worldPacket.FlushBits();
+
+ if (LogData.HasValue)
+ _worldPacket << LogData.Value;
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/CombatLogPackets.h b/src/server/game/Server/Packets/CombatLogPackets.h
new file mode 100644
index 00000000000..6cca0127ef6
--- /dev/null
+++ b/src/server/game/Server/Packets/CombatLogPackets.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CombatLogPackets_h__
+#define CombatLogPackets_h__
+
+#include "Packet.h"
+#include "SpellPackets.h"
+
+namespace WorldPackets
+{
+ namespace CombatLog
+ {
+ class SpellNonMeleeDamageLog final : public ServerPacket
+ {
+ public:
+ SpellNonMeleeDamageLog() : ServerPacket(SMSG_SPELLNONMELEEDAMAGELOG, 60) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Absorbed;
+ int32 ShieldBlock;
+ ObjectGuid Me;
+ int32 SpellID;
+ int32 Resisted;
+ bool Periodic;
+ uint8 SchoolMask;
+ ObjectGuid CasterGUID;
+ Optional<Spells::SpellCastLogData> LogData;
+ int32 Damage;
+ // Optional<SpellNonMeleeDamageLogDebugInfo> Debug Info;
+ int32 Flags;
+ int32 Overkill;
+ };
+ }
+}
+
+#endif // CombatLogPackets_h__
diff --git a/src/server/game/Server/Packets/CombatPackets.cpp b/src/server/game/Server/Packets/CombatPackets.cpp
index 17c0599d266..7793ef4ae30 100644
--- a/src/server/game/Server/Packets/CombatPackets.cpp
+++ b/src/server/game/Server/Packets/CombatPackets.cpp
@@ -16,8 +16,127 @@
*/
#include "CombatPackets.h"
+#include "SpellPackets.h"
void WorldPackets::Combat::AttackSwing::Read()
{
_worldPacket >> Victim;
}
+
+WorldPacket const* WorldPackets::Combat::AttackStart::Write()
+{
+ _worldPacket << Attacker;
+ _worldPacket << Victim;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::SAttackStop::Write()
+{
+ _worldPacket << Attacker;
+ _worldPacket << Victim;
+ _worldPacket.WriteBit(Dead);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::ThreatUpdate::Write()
+{
+ _worldPacket << UnitGUID;
+ _worldPacket << int32(ThreatList.size());
+ for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList)
+ {
+ _worldPacket << threatInfo.UnitGUID;
+ _worldPacket << threatInfo.Threat;
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::HighestThreatUpdate::Write()
+{
+ _worldPacket << UnitGUID;
+ _worldPacket << HighestThreatGUID;
+ _worldPacket << int32(ThreatList.size());
+ for (WorldPackets::Combat::ThreatInfo const& threatInfo : ThreatList)
+ {
+ _worldPacket << threatInfo.UnitGUID;
+ _worldPacket << threatInfo.Threat;
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::ThreatRemove::Write()
+{
+ _worldPacket << UnitGUID;
+ _worldPacket << AboutGUID;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::AIReaction::Write()
+{
+ _worldPacket << UnitGUID;
+ _worldPacket << Reaction;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Combat::AttackerStateUpdate::Write()
+{
+ if (_worldPacket.WriteBit(LogData.HasValue))
+ _worldPacket << LogData.Value;
+
+ // Placeholder for size which will be calculated at the end based on packet size
+ // Client uses this size to copy remaining packet to another CDataStore
+ _worldPacket << int32(0);
+ size_t pos = _worldPacket.wpos();
+
+ _worldPacket << HitInfo;
+ _worldPacket << AttackerGUID;
+ _worldPacket << VictimGUID;
+ _worldPacket << Damage;
+ _worldPacket << OverDamage;
+ if (_worldPacket.WriteBit(SubDmg.HasValue))
+ {
+ _worldPacket << SubDmg.Value.SchoolMask;
+ _worldPacket << SubDmg.Value.FDamage;
+ _worldPacket << SubDmg.Value.Damage;
+ if (HitInfo & (HITINFO_FULL_ABSORB | HITINFO_PARTIAL_ABSORB))
+ _worldPacket << SubDmg.Value.Absorbed;
+ if (HitInfo & (HITINFO_FULL_RESIST | HITINFO_PARTIAL_RESIST))
+ _worldPacket << SubDmg.Value.Resisted;
+ }
+
+ _worldPacket << VictimState;
+ _worldPacket << AttackerState;
+ _worldPacket << MeleeSpellID;
+ if (HitInfo & HITINFO_BLOCK)
+ _worldPacket << BlockAmount;
+ if (HitInfo & HITINFO_RAGE_GAIN)
+ _worldPacket << RageGained;
+ if (HitInfo & HITINFO_UNK1)
+ {
+ _worldPacket << UnkState.State1;
+ _worldPacket << UnkState.State2;
+ _worldPacket << UnkState.State3;
+ _worldPacket << UnkState.State4;
+ _worldPacket << UnkState.State5;
+ _worldPacket << UnkState.State6;
+ _worldPacket << UnkState.State7;
+ _worldPacket << UnkState.State8;
+ _worldPacket << UnkState.State9;
+ _worldPacket << UnkState.State10;
+ _worldPacket << UnkState.State11;
+ _worldPacket << UnkState.State12;
+ }
+ if (HitInfo & (HITINFO_BLOCK|HITINFO_UNK12))
+ _worldPacket << Unk;
+
+ // Update size placeholder
+ _worldPacket.put<int32>(pos - sizeof(int32), _worldPacket.wpos() - pos);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/CombatPackets.h b/src/server/game/Server/Packets/CombatPackets.h
index 2402daf6b22..5b2347e3edb 100644
--- a/src/server/game/Server/Packets/CombatPackets.h
+++ b/src/server/game/Server/Packets/CombatPackets.h
@@ -19,6 +19,8 @@
#define CombatPackets_h__
#include "Packet.h"
+#include "ObjectGuid.h"
+#include "SpellPackets.h"
namespace WorldPackets
{
@@ -39,7 +41,129 @@ namespace WorldPackets
public:
AttackStop(WorldPacket&& packet) : ClientPacket(CMSG_ATTACKSTOP, std::move(packet)) { }
- void Read() override {};
+ void Read() override { }
+ };
+
+ class AttackStart final : public ServerPacket
+ {
+ public:
+ AttackStart() : ServerPacket(SMSG_ATTACKSTART, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Attacker;
+ ObjectGuid Victim;
+ };
+
+ class SAttackStop final : public ServerPacket
+ {
+ public:
+ SAttackStop() : ServerPacket(SMSG_ATTACKSTOP, 17) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Attacker;
+ ObjectGuid Victim;
+ bool Dead = false;
+ };
+
+ struct ThreatInfo
+ {
+ ObjectGuid UnitGUID;
+ int32 Threat = 0;
+ };
+
+ class ThreatUpdate final : public ServerPacket
+ {
+ public:
+ ThreatUpdate() : ServerPacket(SMSG_THREAT_UPDATE, 24) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid UnitGUID;
+ std::vector<ThreatInfo> ThreatList;
+ };
+
+ class HighestThreatUpdate final : public ServerPacket
+ {
+ public:
+ HighestThreatUpdate() : ServerPacket(SMSG_HIGHEST_THREAT_UPDATE, 44) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid UnitGUID;
+ std::vector<ThreatInfo> ThreatList;
+ ObjectGuid HighestThreatGUID;
+ };
+
+ class ThreatRemove final : public ServerPacket
+ {
+ public:
+ ThreatRemove() : ServerPacket(SMSG_THREAT_REMOVE, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid AboutGUID; // Unit to remove threat from (e.g. player, pet, guardian)
+ ObjectGuid UnitGUID; // Unit being attacked (e.g. creature, boss)
+ };
+
+ class AIReaction final : public ServerPacket
+ {
+ public:
+ AIReaction() : ServerPacket(SMSG_AI_REACTION, 12) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid UnitGUID;
+ uint32 Reaction = 0;
+ };
+
+ struct SubDamage
+ {
+ int32 SchoolMask = 0;
+ float FDamage = 0.0f; // Float damage (Most of the time equals to Damage)
+ int32 Damage = 0;
+ int32 Absorbed = 0;
+ int32 Resisted = 0;
+ };
+
+ struct UnkAttackerState
+ {
+ int32 State1 = 0;
+ float State2 = 0.0f;
+ float State3 = 0.0f;
+ float State4 = 0.0f;
+ float State5 = 0.0f;
+ float State6 = 0.0f;
+ float State7 = 0.0f;
+ float State8 = 0.0f;
+ float State9 = 0.0f;
+ float State10 = 0.0f;
+ float State11 = 0.0f;
+ int32 State12 = 0;
+ };
+
+ class AttackerStateUpdate final : public ServerPacket
+ {
+ public:
+ AttackerStateUpdate() : ServerPacket(SMSG_ATTACKERSTATEUPDATE, 70) { }
+
+ WorldPacket const* Write() override;
+
+ Optional<WorldPackets::Spells::SpellCastLogData> LogData;
+ uint32 HitInfo = 0; // Flags
+ ObjectGuid AttackerGUID;
+ ObjectGuid VictimGUID;
+ int32 Damage = 0;
+ int32 OverDamage = -1; // (damage - health) or -1 if unit is still alive
+ Optional<SubDamage> SubDmg;
+ uint8 VictimState = 0;
+ int32 AttackerState = -1;
+ int32 MeleeSpellID = 0;
+ int32 BlockAmount = 0;
+ int32 RageGained = 0;
+ UnkAttackerState UnkState;
+ float Unk = 0.0f;
};
}
}
diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.cpp b/src/server/game/Server/Packets/EquipmentSetPackets.cpp
new file mode 100644
index 00000000000..07cab20debf
--- /dev/null
+++ b/src/server/game/Server/Packets/EquipmentSetPackets.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "EquipmentSetPackets.h"
+
+WorldPacket const* WorldPackets::EquipmentSet::EquipmentSetID::Write()
+{
+ _worldPacket << uint64(GUID);
+ _worldPacket << uint32(SetID);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::EquipmentSet::LoadEquipmentSet::Write()
+{
+ _worldPacket << uint32(SetData.size());
+
+ for (EquipmentSetInfo::EquipmentSetData const* equipSet : SetData)
+ {
+ _worldPacket << uint64(equipSet->Guid);
+ _worldPacket << uint32(equipSet->SetID);
+ _worldPacket << uint32(equipSet->IgnoreMask);
+
+ for (ObjectGuid const& guid : equipSet->Pieces)
+ _worldPacket << guid;
+
+ _worldPacket.WriteBits(equipSet->SetName.length(), 8);
+ _worldPacket.WriteBits(equipSet->SetIcon.length(), 9);
+ _worldPacket.WriteString(equipSet->SetName);
+ _worldPacket.WriteString(equipSet->SetIcon);
+ _worldPacket.FlushBits();
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::EquipmentSet::SaveEquipmentSet::Read()
+{
+ _worldPacket >> Set.Guid;
+ _worldPacket >> Set.SetID;
+ _worldPacket >> Set.IgnoreMask;
+
+ for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
+ _worldPacket >> Set.Pieces[i];
+
+ uint32 setNameLength = _worldPacket.ReadBits(8);
+ uint32 setIconLength = _worldPacket.ReadBits(9);
+
+ Set.SetName = _worldPacket.ReadString(setNameLength);
+ Set.SetIcon = _worldPacket.ReadString(setIconLength);
+}
diff --git a/src/server/game/Server/Packets/EquipmentSetPackets.h b/src/server/game/Server/Packets/EquipmentSetPackets.h
new file mode 100644
index 00000000000..b01c483f5ac
--- /dev/null
+++ b/src/server/game/Server/Packets/EquipmentSetPackets.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "Packet.h"
+#include "Player.h"
+
+namespace WorldPackets
+{
+ namespace EquipmentSet
+ {
+ class EquipmentSetID final : public ServerPacket
+ {
+ public:
+ EquipmentSetID() : ServerPacket(SMSG_EQUIPMENT_SET_SAVED, 8 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 GUID = 0; ///< Set Identifier
+ uint32 SetID = 0; ///< Index
+ };
+
+ class LoadEquipmentSet final : public ServerPacket
+ {
+ public:
+ LoadEquipmentSet() : ServerPacket(SMSG_EQUIPMENT_SET_LIST, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<EquipmentSetInfo::EquipmentSetData const*> SetData;
+ };
+
+ class SaveEquipmentSet final : public ClientPacket
+ {
+ public:
+ SaveEquipmentSet(WorldPacket&& packet) : ClientPacket(CMSG_EQUIPMENT_SET_SAVE, std::move(packet)) { }
+
+ void Read() override;
+
+ EquipmentSetInfo::EquipmentSetData Set;
+ };
+ }
+}
diff --git a/src/server/game/Server/Packets/GuildPackets.cpp b/src/server/game/Server/Packets/GuildPackets.cpp
index c853cf4cc19..f4159927543 100644
--- a/src/server/game/Server/Packets/GuildPackets.cpp
+++ b/src/server/game/Server/Packets/GuildPackets.cpp
@@ -33,16 +33,16 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write()
if (Info.HasValue)
{
- _worldPacket << Info.value.GuildGUID;
- _worldPacket << uint32(Info.value.VirtualRealmAddress);
- _worldPacket << uint32(Info.value.Ranks.size());
- _worldPacket << uint32(Info.value.EmblemStyle);
- _worldPacket << uint32(Info.value.EmblemColor);
- _worldPacket << uint32(Info.value.BorderStyle);
- _worldPacket << uint32(Info.value.BorderColor);
- _worldPacket << uint32(Info.value.BackgroundColor);
-
- for (GuildInfo::GuildInfoRank const& rank : Info.value.Ranks)
+ _worldPacket << Info.Value.GuildGUID;
+ _worldPacket << uint32(Info.Value.VirtualRealmAddress);
+ _worldPacket << uint32(Info.Value.Ranks.size());
+ _worldPacket << uint32(Info.Value.EmblemStyle);
+ _worldPacket << uint32(Info.Value.EmblemColor);
+ _worldPacket << uint32(Info.Value.BorderStyle);
+ _worldPacket << uint32(Info.Value.BorderColor);
+ _worldPacket << uint32(Info.Value.BackgroundColor);
+
+ for (GuildInfo::GuildInfoRank const& rank : Info.Value.Ranks)
{
_worldPacket << uint32(rank.RankID);
_worldPacket << uint32(rank.RankOrder);
@@ -51,8 +51,8 @@ WorldPacket const* WorldPackets::Guild::QueryGuildInfoResponse::Write()
_worldPacket.WriteString(rank.RankName);
}
- _worldPacket.WriteBits(Info.value.GuildName.size(), 7);
- _worldPacket.WriteString(Info.value.GuildName);
+ _worldPacket.WriteBits(Info.Value.GuildName.size(), 7);
+ _worldPacket.WriteString(Info.Value.GuildName);
}
_worldPacket.FlushBits();
diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp
new file mode 100644
index 00000000000..924a9eec352
--- /dev/null
+++ b/src/server/game/Server/Packets/ItemPackets.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "ItemPackets.h"
+
+WorldPacket const* WorldPackets::Item::SetProficiency::Write()
+{
+ _worldPacket << ProficiencyMask;
+ _worldPacket << ProficiencyClass;
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData)
+{
+ data << itemBonusInstanceData.Context;
+ data << uint32(itemBonusInstanceData.BonusListIDs.size());
+ for (uint32 bonusID : itemBonusInstanceData.BonusListIDs)
+ data << bonusID;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance)
+{
+ data << itemInstance.ItemID;
+ data << itemInstance.RandomPropertiesSeed;
+ data << itemInstance.RandomPropertiesID;
+
+ data.WriteBit(itemInstance.ItemBonus.HasValue);
+ data.WriteBit(!itemInstance.Modifications.empty());
+ data.FlushBits();
+
+ if (itemInstance.ItemBonus.HasValue)
+ data << itemInstance.ItemBonus.Value;
+
+ if (!itemInstance.Modifications.empty())
+ {
+ data << uint32(itemInstance.Modifications.size() * sizeof(uint32));
+ for (uint32 itemMod : itemInstance.Modifications)
+ data << itemMod;
+ }
+
+ return data;
+}
diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h
new file mode 100644
index 00000000000..72e2a02fbe2
--- /dev/null
+++ b/src/server/game/Server/Packets/ItemPackets.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ItemPackets_h__
+#define ItemPackets_h__
+
+#include "Packet.h"
+
+namespace WorldPackets
+{
+ namespace Item
+ {
+ class SetProficiency final : public ServerPacket
+ {
+ public:
+ SetProficiency() : ServerPacket(SMSG_SET_PROFICIENCY, 5) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 ProficiencyMask = 0;
+ uint8 ProficiencyClass = 0;
+ };
+
+ struct ItemBonusInstanceData
+ {
+ uint8 Context = 0;
+ std::vector<int32> BonusListIDs;
+ };
+
+ struct ItemInstance
+ {
+ uint32 ItemID = 0;
+ uint32 RandomPropertiesSeed = 0;
+ uint32 RandomPropertiesID = 0;
+ Optional<ItemBonusInstanceData> ItemBonus;
+ std::vector<int32> Modifications;
+ };
+ }
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemBonusInstanceData const& itemBonusInstanceData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemInstance const& itemInstance);
+
+#endif // ItemPackets_h__
diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp
index d223b73e310..154ff134a6a 100644
--- a/src/server/game/Server/Packets/MiscPackets.cpp
+++ b/src/server/game/Server/Packets/MiscPackets.cpp
@@ -17,6 +17,40 @@
#include "MiscPackets.h"
+WorldPacket const* WorldPackets::Misc::BindPointUpdate::Write()
+{
+ _worldPacket << float(BindPosition.x);
+ _worldPacket << float(BindPosition.y);
+ _worldPacket << float(BindPosition.z);
+ _worldPacket << uint32(BindMapID);
+ _worldPacket << uint32(BindAreaID);
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Misc::InvalidatePlayer::Write()
+{
+ _worldPacket << Guid;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Misc::LoginSetTimeSpeed::Write()
+{
+ _worldPacket.AppendPackedTime(ServerTime);
+ _worldPacket.AppendPackedTime(GameTime);
+ _worldPacket << float(NewSpeed);
+ _worldPacket << uint32(ServerTimeHolidayOffset);
+ _worldPacket << uint32(GameTimeHolidayOffset);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Misc::SetSelection::Read()
+{
+ _worldPacket >> Selection;
+}
+
void WorldPackets::Misc::ViolenceLevel::Read()
{
_worldPacket >> ViolenceLvl;
@@ -44,8 +78,40 @@ WorldPacket const* WorldPackets::Misc::UITime::Write()
WorldPacket const* WorldPackets::Misc::TutorialFlags::Write()
{
- for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
- _worldPacket << TutorialData[i];
+ _worldPacket.append(TutorialData, MAX_ACCOUNT_TUTORIAL_VALUES);
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Misc::TutorialSetFlag::Read()
+{
+ Action = _worldPacket.ReadBits(2);
+ _worldPacket >> TutorialBit;
+}
+
+WorldPacket const* WorldPackets::Misc::WorldServerInfo::Write()
+{
+ _worldPacket << uint32(DifficultyID);
+ _worldPacket << uint8(IsTournamentRealm);
+ _worldPacket << uint32(WeeklyReset);
+ _worldPacket.WriteBit(IneligibleForLootMask.HasValue);
+ _worldPacket.WriteBit(InstanceGroupSize.HasValue);
+ _worldPacket.WriteBit(RestrictedAccountMaxLevel.HasValue);
+ _worldPacket.WriteBit(RestrictedAccountMaxMoney.HasValue);
+
+ if (IneligibleForLootMask.HasValue)
+ _worldPacket << uint32(IneligibleForLootMask.Value);
+
+ if (InstanceGroupSize.HasValue)
+ _worldPacket << uint32(InstanceGroupSize.Value);
+
+ if (RestrictedAccountMaxLevel.HasValue)
+ _worldPacket << uint32(RestrictedAccountMaxLevel.Value);
+
+ if (RestrictedAccountMaxMoney.HasValue)
+ _worldPacket << uint32(RestrictedAccountMaxMoney.Value);
+
+ _worldPacket.FlushBits();
return &_worldPacket;
}
diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h
index 86f2f4c5eb4..dfff0e331fc 100644
--- a/src/server/game/Server/Packets/MiscPackets.h
+++ b/src/server/game/Server/Packets/MiscPackets.h
@@ -19,11 +19,61 @@
#define MiscPackets_h__
#include "Packet.h"
+#include "ObjectGuid.h"
+#include "WorldSession.h"
+#include "G3D/Vector3.h"
+#include "Object.h"
namespace WorldPackets
{
namespace Misc
{
+ class BindPointUpdate final : public ServerPacket
+ {
+ public:
+ BindPointUpdate() : ServerPacket(SMSG_BINDPOINTUPDATE, 20) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 BindMapID = MAPID_INVALID;
+ G3D::Vector3 BindPosition;
+ uint32 BindAreaID = 0;
+ };
+
+ class InvalidatePlayer final : public ServerPacket
+ {
+ public:
+ InvalidatePlayer() : ServerPacket(SMSG_INVALIDATE_PLAYER, 18) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Guid;
+ };
+
+ class LoginSetTimeSpeed final : public ServerPacket
+ {
+ public:
+ LoginSetTimeSpeed() : ServerPacket(SMSG_LOGIN_SETTIMESPEED, 20) { }
+
+ WorldPacket const* Write() override;
+
+ float NewSpeed = 0.0f;
+ int32 ServerTimeHolidayOffset = 0;
+ uint32 GameTime = 0;
+ uint32 ServerTime = 0;
+ int32 GameTimeHolidayOffset = 0;
+ };
+
+ class SetSelection final : public ClientPacket
+ {
+ public:
+ SetSelection(WorldPacket&& packet) : ClientPacket(CMSG_SET_SELECTION, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Selection; ///< Target
+ };
+
class ViolenceLevel final : public ClientPacket
{
public:
@@ -54,7 +104,7 @@ namespace WorldPackets
uint32 ClientTime = 0; // Client ticks in ms
uint32 SequenceIndex = 0; // Same index as in request
};
-
+
class UITime final : public ServerPacket
{
public:
@@ -64,15 +114,45 @@ namespace WorldPackets
uint32 Time = 0;
};
-
+
class TutorialFlags : public ServerPacket
{
public:
- TutorialFlags() : ServerPacket(SMSG_TUTORIAL_FLAGS, 32) { }
+ TutorialFlags() : ServerPacket(SMSG_TUTORIAL_FLAGS, 32)
+ {
+ std::memset(TutorialData, 0, sizeof(TutorialData));
+ }
+
+ WorldPacket const* Write() override;
+
+ uint32 TutorialData[MAX_ACCOUNT_TUTORIAL_VALUES];
+ };
+
+ class TutorialSetFlag final : public ClientPacket
+ {
+ public:
+ TutorialSetFlag(WorldPacket&& packet) : ClientPacket(CMSG_TUTORIAL_FLAG, std::move(packet)) { }
+
+ void Read() override;
+
+ uint8 Action = 0;
+ uint32 TutorialBit = 0;
+ };
+
+ class WorldServerInfo final : public ServerPacket
+ {
+ public:
+ WorldServerInfo() : ServerPacket(SMSG_WORLD_SERVER_INFO, 26) { }
WorldPacket const* Write() override;
- uint32 TutorialData[8];
+ Optional<uint32> IneligibleForLootMask; ///< Encountermask?
+ uint32 WeeklyReset = 0; ///< UnixTime of last Weekly Reset Time
+ Optional<uint32> InstanceGroupSize;
+ uint8 IsTournamentRealm = 0;
+ Optional<uint32> RestrictedAccountMaxLevel;
+ Optional<uint32> RestrictedAccountMaxMoney;
+ uint32 DifficultyID = 0;
};
}
}
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 45d5b86e3fd..0c4d4bcff40 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -16,162 +16,414 @@
*/
#include "MovementPackets.h"
+#include "MovementTypedefs.h"
+#include "Unit.h"
-void WorldPackets::Movement::ClientPlayerMovement::Read()
+ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector3 const& v)
+{
+ data << v.x << v.y << v.z;
+ return data;
+}
+
+ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v)
+{
+ data >> v.x >> v.y >> v.z;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo)
{
- _worldPacket >> movementInfo.guid;
- _worldPacket >> movementInfo.time;
- _worldPacket >> movementInfo.pos.m_positionX;
- _worldPacket >> movementInfo.pos.m_positionY;
- _worldPacket >> movementInfo.pos.m_positionZ;
- _worldPacket >> movementInfo.pos.m_orientation;
- _worldPacket >> movementInfo.pitch;
- _worldPacket >> movementInfo.splineElevation;
+ bool hasTransportData = !movementInfo.transport.guid.IsEmpty();
+ bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0;
+ bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0;
+ bool hasFallDirection = movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
+ bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0;
+
+ data << movementInfo.guid;
+ data << movementInfo.time;
+ data << movementInfo.pos.PositionXYZOStream();
+ data << movementInfo.pitch;
+ data << movementInfo.splineElevation;
+
+ uint32 removeMovementForcesCount = 0;
+ data << removeMovementForcesCount;
+
+ uint32 int168 = 0;
+ data << int168;
+
+ /*for (uint32 i = 0; i < removeMovementForcesCount; ++i)
+ {
+ data << ObjectGuid;
+ }*/
+
+ data.WriteBits(movementInfo.flags, 30);
+ data.WriteBits(movementInfo.flags2, 15);
+
+ data.WriteBit(hasTransportData);
+ data.WriteBit(hasFallData);
+
+ data.WriteBit(0); // HeightChangeFailed
+ data.WriteBit(0); // RemoteTimeValid
+
+ if (hasTransportData)
+ {
+ data << movementInfo.transport.guid;
+ data << movementInfo.transport.pos.PositionXYZOStream();
+ data << movementInfo.transport.seat;
+ data << movementInfo.transport.time;
+
+ data.WriteBit(hasTransportPrevTime);
+ data.WriteBit(hasTransportVehicleId);
+
+ if (hasTransportPrevTime)
+ data << movementInfo.transport.prevTime;
+
+ if (hasTransportVehicleId)
+ data << movementInfo.transport.vehicleId;
+ }
+
+ if (hasFallData)
+ {
+ data << movementInfo.jump.fallTime;
+ data << movementInfo.jump.zspeed;
+
+ data.WriteBit(hasFallDirection);
+ if (hasFallDirection)
+ {
+ data << movementInfo.jump.sinAngle;
+ data << movementInfo.jump.cosAngle;
+ data << movementInfo.jump.xyspeed;
+ }
+ }
+
+ data.FlushBits();
+
+ return data;
+}
+
+ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo)
+{
+ data >> movementInfo.guid;
+ data >> movementInfo.time;
+ data >> movementInfo.pos.PositionXYZOStream();
+ data >> movementInfo.pitch;
+ data >> movementInfo.splineElevation;
uint32 removeMovementForcesCount;
- _worldPacket >> removeMovementForcesCount;
+ data >> removeMovementForcesCount;
uint32 int168;
- _worldPacket >> int168;
+ data >> int168;
for (uint32 i = 0; i < removeMovementForcesCount; ++i)
{
ObjectGuid guid;
- _worldPacket >> guid;
+ data >> guid;
}
- // ResetBitReader
+ movementInfo.flags = data.ReadBits(30);
+ movementInfo.flags2 = data.ReadBits(15);
- movementInfo.flags = _worldPacket.ReadBits(30);
- movementInfo.flags2 = _worldPacket.ReadBits(15);
+ bool hasTransport = data.ReadBit();
+ bool hasFall = data.ReadBit();
- bool hasTransport = _worldPacket.ReadBit();
- bool hasFall = _worldPacket.ReadBit();
-
- _worldPacket.ReadBit(); // HeightChangeFailed
- _worldPacket.ReadBit(); // RemoteTimeValid
+ data.ReadBit(); // HeightChangeFailed
+ data.ReadBit(); // RemoteTimeValid
if (hasTransport)
{
- _worldPacket >> movementInfo.transport.guid;
- _worldPacket >> movementInfo.transport.pos.m_positionX;
- _worldPacket >> movementInfo.transport.pos.m_positionY;
- _worldPacket >> movementInfo.transport.pos.m_positionZ;
- _worldPacket >> movementInfo.transport.pos.m_orientation;
- _worldPacket >> movementInfo.transport.seat;
- _worldPacket >> movementInfo.transport.time;
+ data >> movementInfo.transport.guid;
+ data >> movementInfo.transport.pos.PositionXYZOStream();
+ data >> movementInfo.transport.seat;
+ data >> movementInfo.transport.time;
- bool hasPrevTime = _worldPacket.ReadBit();
- bool hasVehicleId = _worldPacket.ReadBit();
+ bool hasPrevTime = data.ReadBit();
+ bool hasVehicleId = data.ReadBit();
if (hasPrevTime)
- _worldPacket >> movementInfo.transport.prevTime;
+ data >> movementInfo.transport.prevTime;
if (hasVehicleId)
- _worldPacket >> movementInfo.transport.vehicleId;
+ data >> movementInfo.transport.vehicleId;
}
if (hasFall)
{
- _worldPacket >> movementInfo.jump.fallTime;
- _worldPacket >> movementInfo.jump.zspeed;
+ data >> movementInfo.jump.fallTime;
+ data >> movementInfo.jump.zspeed;
// ResetBitReader
- bool hasFallDirection = _worldPacket.ReadBit();
+ bool hasFallDirection = data.ReadBit();
if (hasFallDirection)
{
- _worldPacket >> movementInfo.jump.sinAngle;
- _worldPacket >> movementInfo.jump.cosAngle;
- _worldPacket >> movementInfo.jump.xyspeed;
+ data >> movementInfo.jump.sinAngle;
+ data >> movementInfo.jump.cosAngle;
+ data >> movementInfo.jump.xyspeed;
}
}
+
+ return data;
}
-WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write()
+void WorldPackets::Movement::ClientPlayerMovement::Read()
{
- MovementInfo const movementInfo = mover->m_movementInfo;
+ _worldPacket >> movementInfo;
+}
- bool hasMovementFlags = mover->GetUnitMovementFlags() != 0;
- bool hasMovementFlags2 = mover->GetExtraUnitMovementFlags() != 0;
- bool hasTransportData = !mover->GetTransGUID().IsEmpty();
- bool hasSpline = mover->IsSplineEnabled();
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey& monsterSplineFilterKey)
+{
+ data << monsterSplineFilterKey.Idx;
+ data << monsterSplineFilterKey.Speed;
- bool hasTransportPrevTime = hasTransportData && movementInfo.transport.prevTime != 0;
- bool hasTransportVehicleId = hasTransportData && movementInfo.transport.vehicleId != 0;
- bool hasPitch = mover->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mover->HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
- bool hasFallDirection = mover->HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
- bool hasFallData = hasFallDirection || movementInfo.jump.fallTime != 0;
- bool hasSplineElevation = mover->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter& monsterSplineFilter)
+{
+ data << uint32(monsterSplineFilter.FilterKeys.size());
+ data << monsterSplineFilter.BaseSpeed;
+ data << monsterSplineFilter.StartOffset;
+ data << monsterSplineFilter.DistToPrevFilterKey;
+ for (WorldPackets::Movement::MonsterSplineFilterKey& filterKey : monsterSplineFilter.FilterKeys)
+ data << filterKey;
+ data << monsterSplineFilter.AddedToStart;
+ data.WriteBits(monsterSplineFilter.FilterFlags, 2);
+ data.FlushBits();
+
+ return data;
+}
- _worldPacket << movementInfo.guid;
- _worldPacket << movementInfo.time;
- _worldPacket << movementInfo.pos.m_positionX;
- _worldPacket << movementInfo.pos.m_positionY;
- _worldPacket << movementInfo.pos.m_positionZ;
- _worldPacket << movementInfo.pos.m_orientation;
- _worldPacket << movementInfo.pitch;
- _worldPacket << movementInfo.splineElevation;
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline& movementSpline)
+{
+ data << movementSpline.Flags;
+ data << movementSpline.AnimTier;
+ data << movementSpline.TierTransStartTime;
+ data << movementSpline.Elapsed;
+ data << movementSpline.MoveTime;
+ data << movementSpline.JumpGravity;
+ data << movementSpline.SpecialTime;
+ data << int32(movementSpline.Points.size());
+ data << movementSpline.Mode;
+ data << movementSpline.VehicleExitVoluntary;
+ data << movementSpline.TransportGUID;
+ data << movementSpline.VehicleSeat;
+ data << int32(movementSpline.PackedDeltas.size());
+ for (G3D::Vector3 const& pos : movementSpline.Points)
+ data << pos;
+ for (G3D::Vector3 const& pos : movementSpline.PackedDeltas)
+ data.appendPackXYZ(pos.x, pos.y, pos.z);
+ data.WriteBits(movementSpline.Face, 2);
+ data.WriteBit(movementSpline.SplineFilter.HasValue);
+ data.FlushBits();
+
+ switch (movementSpline.Face)
+ {
+ case MONSTER_MOVE_FACING_SPOT:
+ data << movementSpline.FaceSpot;
+ break;
+ case MONSTER_MOVE_FACING_TARGET:
+ data << movementSpline.FaceDirection;
+ data << movementSpline.FaceGUID;
+ break;
+ case MONSTER_MOVE_FACING_ANGLE:
+ data << movementSpline.FaceDirection;
+ break;
+ }
- uint32 removeMovementForcesCount = 0;
- _worldPacket << removeMovementForcesCount;
+ if (movementSpline.SplineFilter.HasValue)
+ data << movementSpline.SplineFilter.Value;
- uint32 int168 = 0;
- _worldPacket << int168;
+ return data;
+}
- /*for (uint32 i = 0; i < removeMovementForcesCount; ++i)
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline& movementMonsterSpline)
+{
+ data << movementMonsterSpline.ID;
+ data << movementMonsterSpline.Destination;
+ data << movementMonsterSpline.Move;
+ data.WriteBit(movementMonsterSpline.CrzTeleport);
+
+ // Unk bits. 0 if monster is moving, 1 or 2 if stopped
+ if (movementMonsterSpline.Move.Flags)
+ data.WriteBits(0, 2);
+ else
+ data.WriteBits(2, 2);
+
+ data.FlushBits();
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Movement::MonsterMove::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << Pos;
+ _worldPacket << SplineData;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveSplineSetSpeed::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << Speed;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveSetSpeed::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << SequenceIndex;
+ _worldPacket << Speed;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveUpdateSpeed::Write()
+{
+ _worldPacket << *movementInfo;
+ _worldPacket << Speed;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveSplineSetFlag::Write()
+{
+ _worldPacket << MoverGUID;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::MoveSetFlag::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << SequenceIndex;
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::ServerPlayerMovement::Write()
+{
+ _worldPacket << *movementInfo;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Movement::TransferPending::Write()
+{
+ _worldPacket << int32(MapID);
+ _worldPacket.WriteBit(Ship.HasValue);
+ _worldPacket.WriteBit(TransferSpellID.HasValue);
+ if (Ship.HasValue)
{
- _worldPacket << ObjectGuid;
- }*/
+ _worldPacket << uint32(Ship.Value.ID);
+ _worldPacket << int32(Ship.Value.OriginMapID);
+ }
+
+ if (TransferSpellID.HasValue)
+ _worldPacket << int32(TransferSpellID.Value);
+
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+WorldPacket const* WorldPackets::Movement::TransferAborted::Write()
+{
+ _worldPacket << uint32(MapID);
+ _worldPacket << uint8(Arg);
+ _worldPacket.WriteBits(TransfertAbort, 5);
_worldPacket.FlushBits();
+ return &_worldPacket;
+}
- _worldPacket.WriteBits(movementInfo.flags, 30);
- _worldPacket.WriteBits(movementInfo.flags2, 15);
+WorldPacket const* WorldPackets::Movement::NewWorld::Write()
+{
+ _worldPacket << MapID;
+ _worldPacket << Pos.PositionXYZOStream();
+ _worldPacket << Reason;
+ return &_worldPacket;
+}
- _worldPacket.WriteBit(hasTransportData);
- _worldPacket.WriteBit(hasFallData);
+WorldPacket const* WorldPackets::Movement::MoveTeleport::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << SequenceIndex;
+ _worldPacket << Pos.PositionXYZOStream();
+ _worldPacket << Facing;
- _worldPacket.WriteBit(0); // HeightChangeFailed
- _worldPacket.WriteBit(0); // RemoteTimeValid
+ _worldPacket.WriteBit(TransportGUID.HasValue);
+ _worldPacket.WriteBit(Vehicle.HasValue);
+ _worldPacket.FlushBits();
- if (hasTransportData)
+ if (TransportGUID.HasValue)
+ _worldPacket << TransportGUID.Value;
+
+ if (Vehicle.HasValue)
{
- _worldPacket << movementInfo.transport.guid;
- _worldPacket << movementInfo.transport.pos.m_positionX;
- _worldPacket << movementInfo.transport.pos.m_positionY;
- _worldPacket << movementInfo.transport.pos.m_positionZ;
- _worldPacket << movementInfo.transport.pos.m_orientation;
- _worldPacket << movementInfo.transport.seat;
- _worldPacket << movementInfo.transport.time;
+ _worldPacket << Vehicle.Value.VehicleSeatIndex;
+ _worldPacket.WriteBit(Vehicle.Value.VehicleExitVoluntary);
+ _worldPacket.WriteBit(Vehicle.Value.VehicleExitTeleport);
+ _worldPacket.FlushBits();
+ }
- _worldPacket.WriteBit(hasTransportPrevTime);
- _worldPacket.WriteBit(hasTransportVehicleId);
+ return &_worldPacket;
+}
- if (hasTransportPrevTime)
- _worldPacket << movementInfo.transport.prevTime;
+WorldPacket const* WorldPackets::Movement::MoveUpdateTeleport::Write()
+{
+ _worldPacket << *movementInfo;
- if (hasTransportVehicleId)
- _worldPacket << movementInfo.transport.vehicleId;
+ _worldPacket << int32(MovementForces.size());
+ for (WorldPackets::Movement::MovementForce const& force : MovementForces)
+ {
+ _worldPacket << force.ID;
+ _worldPacket << force.Direction;
+ _worldPacket << force.TransportID;
+ _worldPacket << force.Magnitude;
+ _worldPacket.WriteBits(force.Type, 2);
+ _worldPacket.FlushBits();
}
- if (hasFallData)
- {
- _worldPacket << movementInfo.jump.fallTime;
- _worldPacket << movementInfo.jump.zspeed;
+ _worldPacket.WriteBit(WalkSpeed.HasValue);
+ _worldPacket.WriteBit(RunSpeed.HasValue);
+ _worldPacket.WriteBit(RunBackSpeed.HasValue);
+ _worldPacket.WriteBit(SwimSpeed.HasValue);
+ _worldPacket.WriteBit(SwimBackSpeed.HasValue);
+ _worldPacket.WriteBit(FlightSpeed.HasValue);
+ _worldPacket.WriteBit(FlightBackSpeed.HasValue);
+ _worldPacket.WriteBit(TurnRate.HasValue);
+ _worldPacket.WriteBit(PitchRate.HasValue);
- _worldPacket.FlushBits();
+ if (WalkSpeed.HasValue)
+ _worldPacket << WalkSpeed.Value;
- _worldPacket.WriteBit(hasFallDirection);
- if (hasFallDirection)
- {
- _worldPacket << movementInfo.jump.sinAngle;
- _worldPacket << movementInfo.jump.cosAngle;
- _worldPacket << movementInfo.jump.xyspeed;
- }
- }
+ if (RunSpeed.HasValue)
+ _worldPacket << RunSpeed.Value;
- _worldPacket.FlushBits();
+ if (RunBackSpeed.HasValue)
+ _worldPacket << RunBackSpeed.Value;
+
+ if (SwimSpeed.HasValue)
+ _worldPacket << SwimSpeed.Value;
+
+ if (SwimBackSpeed.HasValue)
+ _worldPacket << SwimBackSpeed.Value;
+
+ if (FlightSpeed.HasValue)
+ _worldPacket << FlightSpeed.Value;
+
+ if (FlightBackSpeed.HasValue)
+ _worldPacket << FlightBackSpeed.Value;
+
+ if (TurnRate.HasValue)
+ _worldPacket << TurnRate.Value;
+
+ if (PitchRate.HasValue)
+ _worldPacket << PitchRate.Value;
return &_worldPacket;
}
+
+void WorldPackets::Movement::MoveTeleportAck::Read()
+{
+ _worldPacket >> MoverGUID;
+ _worldPacket >> AckIndex;
+ _worldPacket >> MoveTime;
+}
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index f018757eada..6d5d10526b3 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -19,6 +19,8 @@
#define MovementPackets_h__
#include "Packet.h"
+#include "Object.h"
+#include <G3D/Vector3.h>
namespace WorldPackets
{
@@ -37,13 +39,250 @@ namespace WorldPackets
class ServerPlayerMovement final : public ServerPacket
{
public:
- ServerPlayerMovement() : ServerPacket(SMSG_PLAYER_MOVE) {}
+ ServerPlayerMovement() : ServerPacket(SMSG_PLAYER_MOVE) { }
WorldPacket const* Write() override;
- Unit* mover;
+ MovementInfo* movementInfo = nullptr;
+ };
+
+ struct MonsterSplineFilterKey
+ {
+ int16 Idx = 0;
+ int16 Speed = 0;
+ };
+
+ struct MonsterSplineFilter
+ {
+ std::vector<MonsterSplineFilterKey> FilterKeys;
+ uint8 FilterFlags = 0;
+ float BaseSpeed = 0.0f;
+ int16 StartOffset = 0;
+ float DistToPrevFilterKey = 0.0f;
+ int16 AddedToStart = 0;
+ };
+
+ struct MovementSpline
+ {
+ uint32 Flags = 0; // Spline flags
+ uint8 Face = 0; // Movement direction (see MonsterMoveType enum)
+ uint8 AnimTier = 0;
+ uint32 TierTransStartTime = 0;
+ uint32 Elapsed = 0;
+ uint32 MoveTime = 0;
+ float JumpGravity = 0.0f;
+ uint32 SpecialTime = 0;
+ std::vector<G3D::Vector3> Points; // Spline path
+ uint8 Mode = 0;
+ uint8 VehicleExitVoluntary = 0;
+ ObjectGuid TransportGUID;
+ uint8 VehicleSeat = 255;
+ std::vector<G3D::Vector3> PackedDeltas;
+ Optional<MonsterSplineFilter> SplineFilter;
+ float FaceDirection = 0.0f;
+ ObjectGuid FaceGUID;
+ G3D::Vector3 FaceSpot;
+ };
+
+ struct MovementMonsterSpline
+ {
+ uint32 ID = 0;
+ G3D::Vector3 Destination;
+ bool CrzTeleport = false;
+ MovementSpline Move;
+ };
+
+ class MonsterMove final : public ServerPacket
+ {
+ public:
+ MonsterMove() : ServerPacket(SMSG_MONSTER_MOVE) { }
+
+ WorldPacket const* Write() override;
+
+ MovementMonsterSpline SplineData;
+ ObjectGuid MoverGUID;
+ G3D::Vector3 Pos;
+ };
+
+ class MoveSplineSetSpeed : public ServerPacket
+ {
+ public:
+ MoveSplineSetSpeed(OpcodeServer opcode) : ServerPacket(opcode, 12) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ float Speed = 1.0f;
+ };
+
+ class MoveSetSpeed : public ServerPacket
+ {
+ public:
+ MoveSetSpeed(OpcodeServer opcode) : ServerPacket(opcode) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ uint32 SequenceIndex = 0; ///< Unit movement packet index, incremented each time
+ float Speed = 1.0f;
+ };
+
+ class MoveUpdateSpeed : public ServerPacket
+ {
+ public:
+ MoveUpdateSpeed(OpcodeServer opcode) : ServerPacket(opcode) { }
+
+ WorldPacket const* Write() override;
+
+ MovementInfo* movementInfo = nullptr;
+ float Speed = 1.0f;
+ };
+
+ class MoveSplineSetFlag final : public ServerPacket
+ {
+ public:
+ MoveSplineSetFlag(OpcodeServer opcode) : ServerPacket(opcode, 8) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ };
+
+ class MoveSetFlag final : public ServerPacket
+ {
+ public:
+ MoveSetFlag(OpcodeServer opcode) : ServerPacket(opcode, 12) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ uint32 SequenceIndex = 0; ///< Unit movement packet index, incremented each time
+ };
+
+ class TransferPending final : public ServerPacket
+ {
+ struct ShipTransferPending
+ {
+ uint32 ID = 0; ///< gameobject_template.entry of the transport the player is teleporting on
+ int32 OriginMapID = -1; ///< Map id the player is currently on (before teleport)
+ };
+
+ public:
+ TransferPending() : ServerPacket(SMSG_TRANSFER_PENDING, 16) { }
+
+ WorldPacket const* Write() override;
+
+ int32 MapID = -1;
+ Optional<ShipTransferPending> Ship;
+ Optional<int32> TransferSpellID;
+ };
+
+ class TransferAborted final : public ServerPacket
+ {
+ public:
+ TransferAborted() : ServerPacket(SMSG_TRANSFER_ABORTED, 4 + 1 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 TransfertAbort = 0;
+ uint8 Arg = 0;
+ uint32 MapID = 0;
+ };
+
+ class NewWorld final : public ServerPacket
+ {
+ public:
+ NewWorld() : ServerPacket(SMSG_NEW_WORLD, 24) { }
+
+ WorldPacket const* Write() override;
+
+ int32 MapID = 0;
+ uint32 Reason = 0;
+ Position Pos;
+ };
+
+ class WorldPortAck final : public ClientPacket
+ {
+ public:
+ WorldPortAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_WORLDPORT_ACK, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ struct VehicleTeleport
+ {
+ uint8 VehicleSeatIndex = 0;
+ bool VehicleExitVoluntary = false;
+ bool VehicleExitTeleport = false;
+ };
+
+ class MoveTeleport final : public ServerPacket
+ {
+ public:
+ MoveTeleport() : ServerPacket(SMSG_MOVE_TELEPORT, 12+4+16+16+4) { }
+
+ WorldPacket const* Write() override;
+
+ Position Pos;
+ Optional<VehicleTeleport> Vehicle;
+ uint32 SequenceIndex = 0;
+ ObjectGuid MoverGUID;
+ Optional<ObjectGuid> TransportGUID;
+ float Facing = 0.0f;
+ };
+
+ struct MovementForce
+ {
+ ObjectGuid ID;
+ G3D::Vector3 Direction;
+ uint32 TransportID = 0;
+ float Magnitude = 0;
+ uint8 Type = 0;
+ };
+
+ class MoveUpdateTeleport final : public ServerPacket
+ {
+ public:
+ MoveUpdateTeleport() : ServerPacket(SMSG_MOVE_UPDATE_TELEPORT) { }
+
+ WorldPacket const* Write() override;
+
+ MovementInfo* movementInfo = nullptr;
+ std::vector<MovementForce> MovementForces;
+ Optional<float> SwimBackSpeed;
+ Optional<float> FlightSpeed;
+ Optional<float> SwimSpeed;
+ Optional<float> WalkSpeed;
+ Optional<float> TurnRate;
+ Optional<float> RunSpeed;
+ Optional<float> FlightBackSpeed;
+ Optional<float> RunBackSpeed;
+ Optional<float> PitchRate;
+ };
+
+ class MoveTeleportAck final : public ClientPacket
+ {
+ public:
+ MoveTeleportAck(WorldPacket&& packet) : ClientPacket(CMSG_MOVE_TELEPORT_ACK, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid MoverGUID;
+ int32 AckIndex = 0;
+ int32 MoveTime = 0;
};
}
}
+ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector3 const& v);
+ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v);
+
+ByteBuffer& operator>>(ByteBuffer& data, MovementInfo& movementInfo);
+ByteBuffer& operator<<(ByteBuffer& data, MovementInfo& movementInfo);
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilterKey const& monsterSplineFilterKey);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MonsterSplineFilter const& monsterSplineFilter);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementSpline const& movementSpline);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Movement::MovementMonsterSpline const& movementMonsterSpline);
+
#endif // MovementPackets_h__
diff --git a/src/server/game/Server/Packets/NPCPackets.cpp b/src/server/game/Server/Packets/NPCPackets.cpp
new file mode 100644
index 00000000000..60dbed09f1b
--- /dev/null
+++ b/src/server/game/Server/Packets/NPCPackets.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "NPCPackets.h"
+#include "ItemPackets.h"
+
+void WorldPackets::NPC::Hello::Read()
+{
+ _worldPacket >> Unit;
+}
+
+WorldPacket const* WorldPackets::NPC::GossipMessage::Write()
+{
+ _worldPacket << GossipGUID;
+ _worldPacket << GossipID;
+ _worldPacket << FriendshipFactionID;
+ _worldPacket << TextID;
+
+ _worldPacket << int32(GossipOptions.size());
+ _worldPacket << int32(GossipText.size());
+
+ for (ClientGossipOptions const& options : GossipOptions)
+ {
+ _worldPacket << options.ClientOption;
+ _worldPacket << options.OptionNPC;
+ _worldPacket << options.OptionFlags;
+ _worldPacket << options.OptionCost;
+
+ _worldPacket.WriteBits(options.Text.size(), 12);
+ _worldPacket.WriteBits(options.Confirm.size(), 12);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(options.Text);
+ _worldPacket.WriteString(options.Confirm);
+ }
+
+ for (ClientGossipText const& text : GossipText)
+ {
+ _worldPacket << text.QuestID;
+ _worldPacket << text.QuestType;
+ _worldPacket << text.QuestLevel;
+ _worldPacket << text.QuestFlags[0];
+ _worldPacket << text.QuestFlags[1];
+
+ _worldPacket.WriteBit(text.Repeatable);
+ _worldPacket.WriteBits(text.QuestTitle.size(), 9);
+ _worldPacket.FlushBits();
+
+ _worldPacket.WriteString(text.QuestTitle);
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::NPC::VendorInventory::Write()
+{
+ _worldPacket << Vendor;
+ _worldPacket << Reason;
+
+ _worldPacket << int32(Items.size());
+ for (VendorItem const& item : Items)
+ {
+ _worldPacket << item.MuID;
+ _worldPacket << item.Type;
+ _worldPacket << item.Item;
+ _worldPacket << item.Quantity;
+ _worldPacket << item.Price;
+ _worldPacket << item.Durability;
+ _worldPacket << item.StackCount;
+ _worldPacket << item.ExtendedCostID;
+ _worldPacket << item.PlayerConditionFailed;
+
+ _worldPacket.WriteBit(item.DoNotFilterOnVendor);
+ _worldPacket.FlushBits();
+ }
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::NPC::TrainerList::Write()
+{
+ _worldPacket << TrainerGUID;
+ _worldPacket << TrainerType;
+ _worldPacket << TrainerID;
+
+ _worldPacket << int32(Spells.size());
+ for (TrainerListSpell const& spell : Spells)
+ {
+ _worldPacket << spell.SpellID;
+ _worldPacket << spell.MoneyCost;
+ _worldPacket << spell.ReqSkillLine;
+ _worldPacket << spell.ReqSkillRank;
+
+ for (uint32 i = 0; i < MAX_TRAINERSPELL_ABILITY_REQS; ++i)
+ _worldPacket << spell.ReqAbility[i];
+
+ _worldPacket << spell.Usable;
+ _worldPacket << spell.ReqLevel;
+ }
+
+ _worldPacket.WriteBits(Greeting.length(), 11);
+ _worldPacket.FlushBits();
+ _worldPacket.WriteString(Greeting);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/NPCPackets.h b/src/server/game/Server/Packets/NPCPackets.h
new file mode 100644
index 00000000000..221cb454765
--- /dev/null
+++ b/src/server/game/Server/Packets/NPCPackets.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NPCPackets_h__
+#define NPCPackets_h__
+
+#include "Packet.h"
+#include "ItemPackets.h"
+#include "Creature.h"
+
+namespace WorldPackets
+{
+ namespace NPC
+ {
+ // CMSG_BANKER_ACTIVATE
+ // CMSG_BINDER_ACTIVATE
+ // CMSG_BINDER_CONFIRM
+ // CMSG_GOSSIP_HELLO
+ // CMSG_LIST_INVENTORY
+ // CMSG_TRAINER_LIST
+ class Hello final : public ClientPacket
+ {
+ public:
+ Hello(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Unit;
+ };
+
+ struct ClientGossipOptions
+ {
+ int32 ClientOption = 0;
+ uint8 OptionNPC = 0;
+ uint8 OptionFlags = 0;
+ int32 OptionCost = 0;
+ std::string Text;
+ std::string Confirm;
+ };
+
+ struct ClientGossipText
+ {
+ int32 QuestID = 0;
+ int32 QuestType = 0;
+ int32 QuestLevel = 0;
+ bool Repeatable = false;
+ std::string QuestTitle;
+ int32 QuestFlags[2];
+ };
+
+ class GossipMessage final : public ServerPacket
+ {
+ public:
+ GossipMessage() : ServerPacket(SMSG_GOSSIP_MESSAGE, 200) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<ClientGossipOptions> GossipOptions;
+ int32 FriendshipFactionID = 0;
+ ObjectGuid GossipGUID;
+ std::vector<ClientGossipText> GossipText;
+ int32 TextID = 0;
+ int32 GossipID = 0;
+ };
+
+ struct VendorItem
+ {
+ int32 MuID = 0;
+ int32 Type = 0;
+ WorldPackets::Item::ItemInstance Item;
+ int32 Quantity = -1;
+ int32 Price = 0;
+ int32 Durability = 0;
+ int32 StackCount = 0;
+ int32 ExtendedCostID = 0;
+ int32 PlayerConditionFailed = 0;
+ bool DoNotFilterOnVendor = false;
+ };
+
+ class VendorInventory final : public ServerPacket
+ {
+ public:
+ VendorInventory() : ServerPacket(SMSG_LIST_INVENTORY, 600) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 Reason = 0;
+ std::vector<VendorItem> Items;
+ ObjectGuid Vendor;
+ };
+
+ struct TrainerListSpell
+ {
+ int32 SpellID = 0;
+ int32 MoneyCost = 0;
+ int32 ReqSkillLine = 0;
+ int32 ReqSkillRank = 0;
+ int32 ReqAbility[MAX_TRAINERSPELL_ABILITY_REQS];
+ uint8 Usable = 0;
+ uint8 ReqLevel = 0;
+ };
+
+ class TrainerList final : public ServerPacket
+ {
+ public:
+ TrainerList() : ServerPacket(SMSG_TRAINER_LIST, 150) { }
+
+ WorldPacket const* Write() override;
+
+ std::string Greeting;
+ int32 TrainerType = 0;
+ ObjectGuid TrainerGUID;
+ int32 TrainerID = 1;
+ std::vector<TrainerListSpell> Spells;
+ };
+ }
+}
+
+#endif // NPCPackets_h__
diff --git a/src/server/game/Server/Packets/QueryPackets.cpp b/src/server/game/Server/Packets/QueryPackets.cpp
index 0d1b861a9b5..335d261651a 100644
--- a/src/server/game/Server/Packets/QueryPackets.cpp
+++ b/src/server/game/Server/Packets/QueryPackets.cpp
@@ -97,10 +97,10 @@ void WorldPackets::Query::QueryPlayerName::Read()
Hint.NativeRealmAddress.HasValue = _worldPacket.ReadBit();
if (Hint.VirtualRealmAddress.HasValue)
- _worldPacket >> Hint.VirtualRealmAddress.value;
+ _worldPacket >> Hint.VirtualRealmAddress.Value;
if (Hint.NativeRealmAddress.HasValue)
- _worldPacket >> Hint.NativeRealmAddress.value;
+ _worldPacket >> Hint.NativeRealmAddress.Value;
}
WorldPacket const* WorldPackets::Query::QueryPlayerNameResponse::Write()
@@ -153,3 +153,58 @@ WorldPacket const* WorldPackets::Query::QueryPageTextResponse::Write()
return &_worldPacket;
}
+
+void WorldPackets::Query::QueryNPCText::Read()
+{
+ _worldPacket >> TextID;
+ _worldPacket >> Guid;
+}
+
+WorldPacket const* WorldPackets::Query::QueryNPCTextResponse::Write()
+{
+ _worldPacket << TextID;
+ _worldPacket.WriteBit(Allow);
+
+ if (Allow)
+ {
+ _worldPacket << int32(MAX_GOSSIP_TEXT_OPTIONS * (4 + 4));
+ for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
+ _worldPacket << Probabilities[i];
+ for (uint32 i = 0; i < MAX_GOSSIP_TEXT_OPTIONS; ++i)
+ _worldPacket << BroadcastTextID[i];
+ }
+
+ return &_worldPacket;
+}
+
+void WorldPackets::Query::DBQueryBulk::Read()
+{
+ _worldPacket >> TableHash;
+
+ uint32 count = _worldPacket.ReadBits(13);
+ _worldPacket.ResetBitPos();
+
+ Queries.resize(count);
+ for (uint32 i = 0; i < count; ++i)
+ {
+ _worldPacket >> Queries[i].GUID;
+ _worldPacket >> Queries[i].RecordID;
+ }
+}
+
+WorldPacket const* WorldPackets::Query::DBReply::Write()
+{
+ _worldPacket << TableHash;
+ _worldPacket << RecordID;
+ _worldPacket << Timestamp;
+
+ size_t sizePos = _worldPacket.wpos();
+ _worldPacket << int32(0); // size of next block
+
+ if (Data)
+ Data->WriteRecord(RecordID, Locale, _worldPacket);
+
+ _worldPacket.put<int32>(sizePos, _worldPacket.wpos() - sizePos - 4);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/QueryPackets.h b/src/server/game/Server/Packets/QueryPackets.h
index b7c57e94747..8b6eae8db56 100644
--- a/src/server/game/Server/Packets/QueryPackets.h
+++ b/src/server/game/Server/Packets/QueryPackets.h
@@ -20,6 +20,8 @@
#include "Packet.h"
#include "Creature.h"
+#include "NPCHandler.h"
+#include "DB2Stores.h"
namespace WorldPackets
{
@@ -141,6 +143,63 @@ namespace WorldPackets
PageTextInfo Info;
uint32 PageTextID = 0;
};
+
+ class QueryNPCText final : public ClientPacket
+ {
+ public:
+ QueryNPCText(WorldPacket&& packet) : ClientPacket(CMSG_NPC_TEXT_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Guid;
+ uint32 TextID = 0;
+ };
+
+ class QueryNPCTextResponse final : public ServerPacket
+ {
+ public:
+ QueryNPCTextResponse() : ServerPacket(SMSG_NPC_TEXT_UPDATE, 73) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 TextID = 0;
+ bool Allow = false;
+ float Probabilities[MAX_GOSSIP_TEXT_OPTIONS];
+ uint32 BroadcastTextID[MAX_GOSSIP_TEXT_OPTIONS];
+ };
+
+ struct DBQueryRecord
+ {
+ ObjectGuid GUID;
+ uint32 RecordID;
+ };
+
+ class DBQueryBulk final : public ClientPacket
+ {
+ public:
+ DBQueryBulk(WorldPacket&& packet) : ClientPacket(CMSG_DB_QUERY_BULK, std::move(packet)) { }
+
+ void Read() override;
+
+ uint32 TableHash = 0;
+ std::vector<DBQueryRecord> Queries;
+ };
+
+ class DBReply final : public ServerPacket
+ {
+ public:
+ DBReply() : ServerPacket(SMSG_DB_REPLY, 12) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 TableHash = 0;
+ uint32 Timestamp = 0;
+ int32 RecordID = 0;
+
+ // These are not sent directly
+ uint32 Locale = 0;
+ DB2StorageBase const* Data = nullptr;
+ };
}
}
diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp
new file mode 100644
index 00000000000..e20023d3dd2
--- /dev/null
+++ b/src/server/game/Server/Packets/QuestPackets.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "QuestPackets.h"
+
+void WorldPackets::Quest::QuestGiverStatusQuery::Read()
+{
+ _worldPacket >> QuestGiverGUID;
+}
+
+WorldPacket const* WorldPackets::Quest::QuestGiverStatus::Write()
+{
+ _worldPacket << QuestGiver.Guid;
+ _worldPacket << QuestGiver.Status;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Quest::QuestGiverStatusMultiple::Write()
+{
+ _worldPacket << int32(QuestGiver.size());
+ for (QuestGiverInfo const& questGiver : QuestGiver)
+ {
+ _worldPacket << questGiver.Guid;
+ _worldPacket << questGiver.Status;
+ }
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h
new file mode 100644
index 00000000000..12410380c3a
--- /dev/null
+++ b/src/server/game/Server/Packets/QuestPackets.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef QuestPackets_h__
+#define QuestPackets_h__
+
+#include "Packet.h"
+#include "QuestDef.h"
+#include "ObjectGuid.h"
+
+namespace WorldPackets
+{
+ namespace Quest
+ {
+ class QuestGiverStatusQuery final : public ClientPacket
+ {
+ public:
+ QuestGiverStatusQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUESTGIVER_STATUS_QUERY, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid QuestGiverGUID;
+ };
+
+ // Empty packet, server replies with quest giver status of visible creatures
+ class QuestGiverStatusMultipleQuery final : public ClientPacket
+ {
+ public:
+ QuestGiverStatusMultipleQuery(WorldPacket&& packet) : ClientPacket(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, std::move(packet)) { }
+
+ void Read() override { }
+ };
+
+ struct QuestGiverInfo
+ {
+ QuestGiverInfo() { }
+ QuestGiverInfo(ObjectGuid const& guid, uint32 status)
+ : Guid(guid), Status(status) { }
+
+ ObjectGuid Guid;
+ uint32 Status = DIALOG_STATUS_NONE;
+ };
+
+ class QuestGiverStatus final : public ServerPacket
+ {
+ public:
+ QuestGiverStatus() : ServerPacket(SMSG_QUESTGIVER_STATUS, 22) { }
+
+ WorldPacket const* Write() override;
+
+ QuestGiverInfo QuestGiver;
+ };
+
+ class QuestGiverStatusMultiple final : public ServerPacket
+ {
+ public:
+ QuestGiverStatusMultiple() : ServerPacket(SMSG_QUESTGIVER_STATUS_MULTIPLE, 24) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<QuestGiverInfo> QuestGiver;
+ };
+ }
+}
+
+#endif // QuestPackets_h__
diff --git a/src/server/game/Server/Packets/ReputationPackets.cpp b/src/server/game/Server/Packets/ReputationPackets.cpp
new file mode 100644
index 00000000000..4acecf851f4
--- /dev/null
+++ b/src/server/game/Server/Packets/ReputationPackets.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "ReputationPackets.h"
+
+WorldPacket const* WorldPackets::Reputation::InitializeFactions::Write()
+{
+ for (uint16 i = 0; i < FactionCount; ++i)
+ {
+ _worldPacket << uint8(FactionFlags[i]);
+ _worldPacket << int32(FactionStandings[i]);
+ }
+
+ for (uint16 i = 0; i < FactionCount; ++i)
+ _worldPacket.WriteBit(FactionHasBonus[i]);
+
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/ReputationPackets.h b/src/server/game/Server/Packets/ReputationPackets.h
new file mode 100644
index 00000000000..387ae9b0318
--- /dev/null
+++ b/src/server/game/Server/Packets/ReputationPackets.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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 2 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 <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "Packet.h"
+
+namespace WorldPackets
+{
+ namespace Reputation
+ {
+ static uint16 const FactionCount = 256;
+
+ class InitializeFactions final : public ServerPacket
+ {
+ public:
+ InitializeFactions() : ServerPacket(SMSG_INITIALIZE_FACTIONS, 1312)
+ {
+ for (uint16 i = 0; i < FactionCount; ++i)
+ {
+ FactionStandings[i] = 0;
+ FactionHasBonus[i] = false;
+ FactionFlags[i] = 0;
+ }
+ }
+
+ WorldPacket const* Write() override;
+
+ int32 FactionStandings[FactionCount];
+ bool FactionHasBonus[FactionCount]; ///< @todo: implement faction bonus
+ uint8 FactionFlags[FactionCount]; ///< @see enum FactionFlags
+ };
+ }
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 09914b292bb..233c35f7bbd 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -16,8 +16,10 @@
*/
#include "SpellPackets.h"
+#include "SpellAuraEffects.h"
+#include "MovementPackets.h"
-WorldPacket const* WorldPackets::Spell::CategoryCooldown::Write()
+WorldPacket const* WorldPackets::Spells::CategoryCooldown::Write()
{
_worldPacket.reserve(4 + 8 * CategoryCooldowns.size());
@@ -32,7 +34,7 @@ WorldPacket const* WorldPackets::Spell::CategoryCooldown::Write()
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spell::SendKnownSpells::Write()
+WorldPacket const* WorldPackets::Spells::SendKnownSpells::Write()
{
_worldPacket.reserve(1 + 4 * KnownSpells.size());
@@ -45,7 +47,7 @@ WorldPacket const* WorldPackets::Spell::SendKnownSpells::Write()
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spell::UpdateActionButtons::Write()
+WorldPacket const* WorldPackets::Spells::UpdateActionButtons::Write()
{
for (uint32 i = 0; i < MAX_ACTION_BUTTONS; ++i)
_worldPacket << ActionButtons[i];
@@ -55,7 +57,13 @@ WorldPacket const* WorldPackets::Spell::UpdateActionButtons::Write()
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spell::SendUnlearnSpells::Write()
+void WorldPackets::Spells::SetActionButton::Read()
+{
+ _worldPacket >> Action;
+ _worldPacket >> Index;
+}
+
+WorldPacket const* WorldPackets::Spells::SendUnlearnSpells::Write()
{
_worldPacket << uint32(Spells.size());
for (uint32 spellId : Spells)
@@ -64,3 +72,422 @@ WorldPacket const* WorldPackets::Spell::SendUnlearnSpells::Write()
return &_worldPacket;
}
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData)
+{
+ data << spellCastLogData.Health;
+ data << spellCastLogData.AttackPower;
+ data << spellCastLogData.SpellPower;
+ data << int32(spellCastLogData.PowerData.size());
+ for (WorldPackets::Spells::SpellLogPowerData const& powerData : spellCastLogData.PowerData)
+ {
+ data << powerData.PowerType;
+ data << powerData.Amount;
+ }
+ data.WriteBit(false);
+ // data << float // Unk data if bit is true
+ data.FlushBits();
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SendAuraUpdate::Write()
+{
+ return &_worldPacket;
+}
+
+void WorldPackets::Spells::SendAuraUpdate::Init(bool IsFullUpdate, ObjectGuid Target, uint32 Count)
+{
+ _worldPacket.WriteBit(IsFullUpdate);
+ _worldPacket << Target;
+ _worldPacket << uint32(Count);
+}
+
+void WorldPackets::Spells::SendAuraUpdate::BuildUpdatePacket(AuraApplication* aurApp, bool remove, uint16 level)
+{
+ _worldPacket << uint8(aurApp->GetSlot());
+ _worldPacket.ResetBitPos();
+ _worldPacket.WriteBit(!remove);
+
+ if (remove)
+ {
+ _worldPacket.FlushBits();
+ return;
+ }
+ Aura const* aura = aurApp->GetBase();
+ _worldPacket << uint32(aura->GetId());
+
+ uint8 flags = aurApp->GetFlags();
+ if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION))
+ flags |= AFLAG_DURATION;
+ _worldPacket << uint8(flags);
+
+ _worldPacket << uint32(aurApp->GetEffectMask());
+
+ _worldPacket << uint16(level);
+
+ // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
+ // stack amount has priority over charges (checked on retail with spell 50262)
+ _worldPacket << uint8(aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges());
+
+ uint32 int72 = 0;
+ _worldPacket << int72;
+
+ size_t pos = _worldPacket.wpos();
+ uint32 count = 0;
+ _worldPacket << count;
+
+ //for (int72)
+ // float
+
+ if (flags & AFLAG_SCALABLE)
+ {
+ for (AuraEffect const* effect : aura->GetAuraEffects())
+ {
+ if (effect && aurApp->HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
+ {
+ _worldPacket << int32(effect->GetAmount());
+ count++;
+ }
+ }
+ }
+
+ _worldPacket.put<uint32>(pos, count);
+
+ _worldPacket.ResetBitPos();
+
+ _worldPacket.WriteBit(!(flags & AFLAG_NOCASTER));
+ _worldPacket.WriteBit(aura->GetDuration());
+ _worldPacket.WriteBit(aura->GetMaxDuration());
+
+ if (!(flags & AFLAG_NOCASTER))
+ _worldPacket << aura->GetCasterGUID().WriteAsPacked();
+
+ if (aura->GetDuration())
+ {
+ _worldPacket << uint32(aura->GetDuration());
+ }
+
+ if (aura->GetMaxDuration())
+ {
+ _worldPacket << uint32(aura->GetMaxDuration());
+ }
+}
+
+void WorldPackets::Spells::SpellCastRequest::Read()
+{
+ if (_worldPacket.GetOpcode() == CMSG_PET_CAST_SPELL)
+ _worldPacket >> PetGuid;
+
+ _worldPacket >> CastID;
+ _worldPacket >> SpellID;
+ _worldPacket >> Misc;
+
+ _worldPacket.ResetBitPos();
+
+ TargetFlags = _worldPacket.ReadBits(21);
+ bool HasSrcLocation = _worldPacket.ReadBit();
+ bool HasDstLocation = _worldPacket.ReadBit();
+ bool HasOrientation = _worldPacket.ReadBit();
+ uint32 NameLen = _worldPacket.ReadBits(7);
+
+ _worldPacket >> UnitGuid;
+ _worldPacket >> ItemGuid;
+
+ if (HasSrcLocation)
+ {
+ _worldPacket >> SrcTransportGuid;
+ _worldPacket >> SrcPos.m_positionX;
+ _worldPacket >> SrcPos.m_positionY;
+ _worldPacket >> SrcPos.m_positionZ;
+ }
+
+ if (HasDstLocation)
+ {
+ _worldPacket >> DstTransportGuid;
+ _worldPacket >> DstPos.m_positionX;
+ _worldPacket >> DstPos.m_positionY;
+ _worldPacket >> DstPos.m_positionZ;
+ }
+
+ if (HasOrientation)
+ _worldPacket >> Orientation;
+
+ Name = _worldPacket.ReadString(NameLen);
+
+ _worldPacket >> Pitch;
+ _worldPacket >> Speed;
+
+ _worldPacket >> Guid;
+
+ _worldPacket.ResetBitPos();
+
+ SendCastFlags = _worldPacket.ReadBits(5);
+
+ bool HasMoveUpdate = _worldPacket.ReadBit();
+ uint32 SpellWeightCount = _worldPacket.ReadBits(2);
+
+ if (HasMoveUpdate)
+ {
+ _worldPacket >> movementInfo;
+ }
+
+ // SpellWeight
+ for (uint32 i = 0; i < SpellWeightCount; ++i)
+ {
+ _worldPacket.ResetBitPos();
+ uint32 Type = _worldPacket.ReadBits(2);
+ uint32 ID;
+ _worldPacket >> ID;
+ uint32 Quantity;
+ _worldPacket >> Quantity;
+ }
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation)
+{
+ data << targetLocation.Transport;
+ // data << targetLocation.Location.PositionXYZStream();
+ data << targetLocation.Location.m_positionX;
+ data << targetLocation.Location.m_positionY;
+ data << targetLocation.Location.m_positionZ;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData const& spellTargetData)
+{
+ data.WriteBits(spellTargetData.Flags, 21);
+ data.WriteBit(spellTargetData.SrcLocation.HasValue);
+ data.WriteBit(spellTargetData.DstLocation.HasValue);
+ data.WriteBit(spellTargetData.Orientation.HasValue);
+ data.WriteBits(spellTargetData.Name.size(), 7);
+ data.FlushBits();
+
+ data << spellTargetData.Unit;
+ data << spellTargetData.Item;
+
+ if (spellTargetData.SrcLocation.HasValue)
+ data << spellTargetData.SrcLocation.Value;
+
+ if (spellTargetData.DstLocation.HasValue)
+ data << spellTargetData.DstLocation.Value;
+
+ if (spellTargetData.Orientation.HasValue)
+ data << spellTargetData.Orientation.Value;
+
+ data.WriteString(spellTargetData.Name);
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus const& spellMissStatus)
+{
+ data.WriteBits(spellMissStatus.Reason, 4);
+ data.WriteBits(spellMissStatus.ReflectStatus, 4);
+ // No need to flush bits as we written exactly 8 bits (1 byte)
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellPowerData const& spellPowerData)
+{
+ data << spellPowerData.Cost;
+ data << spellPowerData.Type;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& runeData)
+{
+ data << runeData.Start;
+ data << runeData.Count;
+
+ data.WriteBits(runeData.Cooldowns.size(), 3);
+ data.FlushBits();
+
+ for (uint8 cd : runeData.Cooldowns)
+ data << cd;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::MissileTrajectoryResult const& missileTrajectory)
+{
+ data << missileTrajectory.TravelTime;
+ data << missileTrajectory.Pitch;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellAmmo const& spellAmmo)
+{
+ data << spellAmmo.DisplayID;
+ data << spellAmmo.InventoryType;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ProjectileVisualData const& projectileVisual)
+{
+ data << projectileVisual.ID[0];
+ data << projectileVisual.ID[1];
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::CreatureImmunities const& immunities)
+{
+ data << immunities.School;
+ data << immunities.Value;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHealPrediction const& spellPred)
+{
+ data << spellPred.Points;
+ data << spellPred.Type;
+ data << spellPred.BeaconGUID;
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData const& spellCastData)
+{
+ data << spellCastData.CasterGUID;
+ data << spellCastData.CasterUnit;
+ data << spellCastData.CastID;
+ data << spellCastData.SpellID;
+ data << spellCastData.CastFlags;
+ data << spellCastData.CastTime;
+ data << uint32(spellCastData.HitTargets.size());
+ data << uint32(spellCastData.MissTargets.size());
+ data << uint32(spellCastData.MissStatus.size());
+ data << spellCastData.Target;
+ data << uint32(spellCastData.RemainingPower.size());
+ data << spellCastData.MissileTrajectory;
+ data << spellCastData.Ammo;
+ data << spellCastData.DestLocSpellCastIndex;
+ data << uint32(spellCastData.TargetPoints.size());
+ data << spellCastData.Immunities;
+ data << spellCastData.Predict;
+
+ for (ObjectGuid const& target : spellCastData.HitTargets)
+ data << target;
+
+ for (ObjectGuid const& target : spellCastData.MissTargets)
+ data << target;
+
+ for (WorldPackets::Spells::SpellMissStatus const& status : spellCastData.MissStatus)
+ data << status;
+
+ for (WorldPackets::Spells::SpellPowerData const& power : spellCastData.RemainingPower)
+ data << power;
+
+ for (WorldPackets::Spells::TargetLocation const& targetLoc : spellCastData.TargetPoints)
+ data << targetLoc;
+
+ data.WriteBits(spellCastData.CastFlagsEx, 18);
+ data.WriteBit(spellCastData.RemainingRunes.HasValue);
+ data.WriteBit(spellCastData.ProjectileVisual.HasValue);
+ data.FlushBits();
+
+ if (spellCastData.RemainingRunes.HasValue)
+ data << spellCastData.RemainingRunes.Value;
+
+ if (spellCastData.ProjectileVisual.HasValue)
+ data << spellCastData.ProjectileVisual.Value;
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SpellStart::Write()
+{
+ _worldPacket << Cast;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::SpellGo::Write()
+{
+ _worldPacket << Cast;
+
+ _worldPacket.WriteBit(LogData.HasValue);
+ _worldPacket.FlushBits();
+
+ if (LogData.HasValue)
+ _worldPacket << LogData.Value;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::LearnedSpells::Write()
+{
+ _worldPacket << uint32(SpellID.size());
+ for (int32 spell : SpellID)
+ _worldPacket << spell;
+
+ _worldPacket.WriteBit(SuppressMessaging);
+ _worldPacket.FlushBits();
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::SpellFailure::Write()
+{
+ _worldPacket << CasterUnit;
+ _worldPacket << CastID;
+ _worldPacket << SpellID;
+ _worldPacket << Reason;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::SpellFailedOther::Write()
+{
+ _worldPacket << CasterUnit;
+ _worldPacket << CastID;
+ _worldPacket << SpellID;
+ _worldPacket << Reason;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::CastFailed::Write()
+{
+ _worldPacket << SpellID;
+ _worldPacket << Reason;
+ _worldPacket << FailedArg1;
+ _worldPacket << FailedArg2;
+ _worldPacket << CastID;
+
+ return &_worldPacket;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifierData const& spellModifierData)
+{
+ data << spellModifierData.ModifierValue;
+ data << spellModifierData.ClassIndex;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifier const& spellModifier)
+{
+ data << spellModifier.ModIndex;
+ data << uint32(spellModifier.ModifierData.size());
+ for (WorldPackets::Spells::SpellModifierData const& modData : spellModifier.ModifierData)
+ data << modData;
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Spells::SetSpellModifier::Write()
+{
+ _worldPacket << uint32(Modifiers.size());
+ for (WorldPackets::Spells::SpellModifier const& spellMod : Modifiers)
+ _worldPacket << spellMod;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Spells::SendRemovedSpell::Write()
+{
+ _worldPacket << uint32(Spells.size());
+ for (uint32 spellId : Spells)
+ _worldPacket << uint32(spellId);
+
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index 2b4e4c3c146..98882fc2e26 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -20,10 +20,12 @@
#include "Packet.h"
#include "Player.h"
+#include "SpellAuras.h"
+#include "Spell.h"
namespace WorldPackets
{
- namespace Spell
+ namespace Spells
{
class CategoryCooldown final : public ServerPacket
{
@@ -58,7 +60,10 @@ namespace WorldPackets
class UpdateActionButtons final : public ServerPacket
{
public:
- UpdateActionButtons() : ServerPacket(SMSG_ACTION_BUTTONS, MAX_ACTION_BUTTONS*8+1) { }
+ UpdateActionButtons() : ServerPacket(SMSG_ACTION_BUTTONS, MAX_ACTION_BUTTONS * 8 + 1)
+ {
+ std::memset(ActionButtons, 0, sizeof(ActionButtons));
+ }
WorldPacket const* Write() override;
@@ -72,6 +77,17 @@ namespace WorldPackets
*/
};
+ class SetActionButton final : public ClientPacket
+ {
+ public:
+ SetActionButton(WorldPacket&& packet) : ClientPacket(CMSG_SET_ACTION_BUTTON, std::move(packet)) {}
+
+ void Read() override;
+
+ uint64 Action = 0; ///< two packed uint32 (action and type)
+ uint8 Index = 0;
+ };
+
class SendUnlearnSpells final : public ServerPacket
{
public:
@@ -81,7 +97,273 @@ namespace WorldPackets
std::vector<uint32> Spells;
};
+
+ struct SpellLogPowerData
+ {
+ int32 PowerType = 0;
+ int32 Amount = 0;
+ };
+
+ struct SpellCastLogData
+ {
+ int32 Health = 0;
+ int32 AttackPower = 0;
+ int32 SpellPower = 0;
+ std::vector<SpellLogPowerData> PowerData;
+ };
+
+ class SendAuraUpdate final : public ServerPacket
+ {
+ public:
+ SendAuraUpdate() : ServerPacket(SMSG_AURA_UPDATE) { }
+
+ WorldPacket const* Write() override;
+ void Init(bool IsFullUpdate, ObjectGuid Target, uint32 Count);
+ void BuildUpdatePacket(AuraApplication* aurApp, bool remove, uint16 level);
+ };
+
+ class SpellCastRequest final : public ClientPacket
+ {
+ public:
+ SpellCastRequest(WorldPacket&& packet) : ClientPacket(std::move(packet))
+ {
+ ASSERT(packet.GetOpcode() == CMSG_CAST_SPELL || packet.GetOpcode() == CMSG_PET_CAST_SPELL);
+ }
+
+ void Read() override;
+
+ ObjectGuid PetGuid;
+ uint8 CastID;
+ uint32 SpellID;
+ uint32 Misc;
+ uint32 TargetFlags;
+ ObjectGuid UnitGuid;
+ ObjectGuid ItemGuid;
+
+ ObjectGuid SrcTransportGuid;
+ ObjectGuid DstTransportGuid;
+ Position SrcPos;
+ Position DstPos;
+ float Orientation;
+
+ std::string Name;
+ float Pitch;
+ float Speed;
+ ObjectGuid Guid;
+ uint32 SendCastFlags;
+
+ MovementInfo movementInfo;
+ };
+
+ struct TargetLocation
+ {
+ ObjectGuid Transport;
+ Position Location;
+ };
+
+ struct SpellTargetData
+ {
+ uint32 Flags = 0;
+ ObjectGuid Unit;
+ ObjectGuid Item;
+ Optional<TargetLocation> SrcLocation;
+ Optional<TargetLocation> DstLocation;
+ Optional<float> Orientation; // Not found in JAM structures
+ std::string Name;
+ };
+
+ struct SpellMissStatus
+ {
+ uint8 Reason = 0;
+ uint8 ReflectStatus = 0;
+ };
+
+ struct SpellPowerData
+ {
+ int32 Cost = 0;
+ int8 Type = 0;
+ };
+
+ struct RuneData
+ {
+ uint8 Start = 0;
+ uint8 Count = 0;
+ std::vector<uint8> Cooldowns;
+ };
+
+ struct MissileTrajectoryResult
+ {
+ uint32 TravelTime = 0;
+ float Pitch = 0.0f;
+ };
+
+ struct SpellAmmo
+ {
+ int32 DisplayID = 0;
+ int8 InventoryType = 0;
+ };
+
+ struct ProjectileVisualData
+ {
+ int32 ID[2];
+ };
+
+ struct CreatureImmunities
+ {
+ uint32 School = 0;
+ uint32 Value = 0;
+ };
+
+ struct SpellHealPrediction
+ {
+ ObjectGuid BeaconGUID;
+ uint32 Points = 0;
+ uint8 Type = 0;
+ };
+
+ struct SpellCastData
+ {
+ ObjectGuid CasterGUID;
+ ObjectGuid CasterUnit;
+ uint8 CastID = 0;
+ int32 SpellID = 0;
+ uint32 CastFlags = 0;
+ uint32 CastFlagsEx = 0;
+ uint32 CastTime = 0;
+ std::vector<ObjectGuid> HitTargets;
+ std::vector<ObjectGuid> MissTargets;
+ std::vector<SpellMissStatus> MissStatus;
+ SpellTargetData Target;
+ std::vector<SpellPowerData> RemainingPower;
+ Optional<RuneData> RemainingRunes;
+ MissileTrajectoryResult MissileTrajectory;
+ SpellAmmo Ammo;
+ Optional<ProjectileVisualData> ProjectileVisual;
+ uint8 DestLocSpellCastIndex = 0;
+ std::vector<TargetLocation> TargetPoints;
+ CreatureImmunities Immunities;
+ SpellHealPrediction Predict;
+ };
+
+ class SpellGo final : public ServerPacket
+ {
+ public:
+ SpellGo() : ServerPacket(SMSG_SPELL_GO) { }
+
+ WorldPacket const* Write() override;
+
+ Optional<SpellCastLogData> LogData;
+ SpellCastData Cast;
+ };
+
+ class SpellStart final : public ServerPacket
+ {
+ public:
+ SpellStart() : ServerPacket(SMSG_SPELL_START) { }
+
+ WorldPacket const* Write() override;
+
+ SpellCastData Cast;
+ };
+
+ class LearnedSpells final : public ServerPacket
+ {
+ public:
+ LearnedSpells() : ServerPacket(SMSG_LEARNED_SPELLS, 9) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<int32> SpellID;
+ bool SuppressMessaging = false;
+ };
+
+ class SpellFailure final : public ServerPacket
+ {
+ public:
+ SpellFailure() : ServerPacket(SMSG_SPELL_FAILURE, 16+4+1+1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid CasterUnit;
+ uint32 SpellID = 0;
+ uint8 Reason = 0;
+ uint8 CastID = 0;
+ };
+
+ class SpellFailedOther final : public ServerPacket
+ {
+ public:
+ SpellFailedOther() : ServerPacket(SMSG_SPELL_FAILED_OTHER, 16+4+1+1) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid CasterUnit;
+ uint32 SpellID = 0;
+ uint16 Reason = 0;
+ uint8 CastID = 0;
+ };
+
+ class CastFailed final : public ServerPacket
+ {
+ public:
+ CastFailed(OpcodeServer opcode) : ServerPacket(opcode, 4+4+4+4+1) { }
+
+ WorldPacket const* Write() override;
+
+ int32 Reason = 0;
+ int32 FailedArg1 = -1;
+ int32 FailedArg2 = -1;
+ int32 SpellID = 0;
+ uint8 CastID = 0;
+ };
+
+ struct SpellModifierData
+ {
+ float ModifierValue = 0.0f;
+ uint8 ClassIndex = 0;
+ };
+
+ struct SpellModifier
+ {
+ uint8 ModIndex = 0;
+ std::vector<SpellModifierData> ModifierData;
+ };
+
+ class SetSpellModifier final : public ServerPacket
+ {
+ public:
+ SetSpellModifier(OpcodeServer opcode) : ServerPacket(opcode, 20) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<SpellModifier> Modifiers;
+ };
+
+ class SendRemovedSpell final : public ServerPacket
+ {
+ public:
+ SendRemovedSpell() : ServerPacket(SMSG_REMOVED_SPELL, 4) { }
+
+ WorldPacket const* Write() override;
+
+ std::vector<uint32> Spells;
+ };
}
}
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData const& spellTargetData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus const& spellMissStatus);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellPowerData const& spellPowerData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& runeData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::MissileTrajectoryResult const& missileTrajectory);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellAmmo const& spellAmmo);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ProjectileVisualData const& projectileVisual);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::CreatureImmunities const& immunities);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHealPrediction const& spellPred);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData const& spellCastData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifierData const& spellModifierData);
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifier const& spellModifier);
+
#endif // SpellPackets_h__
diff --git a/src/server/game/Server/Packets/SystemPackets.cpp b/src/server/game/Server/Packets/SystemPackets.cpp
index 7c8ecce3db7..4a7be4ed591 100644
--- a/src/server/game/Server/Packets/SystemPackets.cpp
+++ b/src/server/game/Server/Packets/SystemPackets.cpp
@@ -43,22 +43,22 @@ WorldPacket const* WorldPackets::System::FeatureSystemStatus::Write()
if (EuropaTicketSystemStatus.HasValue)
{
- _worldPacket.WriteBit(EuropaTicketSystemStatus.value.UnkBit0);
- _worldPacket.WriteBit(EuropaTicketSystemStatus.value.UnkBit1);
- _worldPacket.WriteBit(EuropaTicketSystemStatus.value.TicketSystemEnabled);
- _worldPacket.WriteBit(EuropaTicketSystemStatus.value.SubmitBugEnabled);
-
- _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.MaxTries);
- _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.PerMilliseconds);
- _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.TryCount);
- _worldPacket << uint32(EuropaTicketSystemStatus.value.ThrottleState.LastResetTimeBeforeNow);
+ _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.UnkBit0);
+ _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.UnkBit1);
+ _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.TicketSystemEnabled);
+ _worldPacket.WriteBit(EuropaTicketSystemStatus.Value.SubmitBugEnabled);
+
+ _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.MaxTries);
+ _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.PerMilliseconds);
+ _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.TryCount);
+ _worldPacket << uint32(EuropaTicketSystemStatus.Value.ThrottleState.LastResetTimeBeforeNow);
}
if (SessionAlert.HasValue)
{
- _worldPacket << int32(SessionAlert.value.Delay);
- _worldPacket << int32(SessionAlert.value.Period);
- _worldPacket << int32(SessionAlert.value.DisplayTime);
+ _worldPacket << int32(SessionAlert.Value.Delay);
+ _worldPacket << int32(SessionAlert.Value.Period);
+ _worldPacket << int32(SessionAlert.Value.DisplayTime);
}
_worldPacket.FlushBits();
diff --git a/src/server/game/Server/Packets/TalentPackets.cpp b/src/server/game/Server/Packets/TalentPackets.cpp
index 4855f663662..d340b476cf9 100644
--- a/src/server/game/Server/Packets/TalentPackets.cpp
+++ b/src/server/game/Server/Packets/TalentPackets.cpp
@@ -41,3 +41,17 @@ void WorldPackets::Talent::SetSpecialization::Read()
{
_worldPacket >> SpecGroupIndex;
}
+
+
+void WorldPackets::Talent::LearnTalent::Read()
+{
+ uint32 count;
+ _worldPacket >> count;
+
+ for (uint32 i = 0; i < count; ++i)
+ {
+ uint16 talent;
+ _worldPacket >> talent;
+ Talents.push_back(talent);
+ }
+} \ No newline at end of file
diff --git a/src/server/game/Server/Packets/TalentPackets.h b/src/server/game/Server/Packets/TalentPackets.h
index 21753e22c8d..2bc8b3934a8 100644
--- a/src/server/game/Server/Packets/TalentPackets.h
+++ b/src/server/game/Server/Packets/TalentPackets.h
@@ -57,6 +57,19 @@ namespace WorldPackets
uint32 SpecGroupIndex = 0;
};
+
+ class LearnTalent final : public ClientPacket
+ {
+ public:
+ LearnTalent(WorldPacket&& packet) : ClientPacket(std::move(packet))
+ {
+ ASSERT(packet.GetOpcode() == CMSG_LEARN_TALENT);
+ }
+
+ void Read() override;
+ std::vector<uint16> Talents;
+
+ };
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 84efecae188..2129633b021 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -19,20 +19,25 @@
#include "Opcodes.h"
#include "WorldSession.h"
#include "Packets/CharacterPackets.h"
+#include "Packets/ChannelPackets.h"
+#include "Packets/ChatPackets.h"
#include "Packets/ClientConfigPackets.h"
#include "Packets/CombatPackets.h"
+#include "Packets/EquipmentSetPackets.h"
#include "Packets/GuildPackets.h"
#include "Packets/MiscPackets.h"
#include "Packets/MovementPackets.h"
+#include "Packets/NPCPackets.h"
#include "Packets/QueryPackets.h"
+#include "Packets/QuestPackets.h"
#include "Packets/TalentPackets.h"
#include "Packets/TradePackets.h"
template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)>
-class PacketHandler : public OpcodeHandler
+class PacketHandler : public ClientOpcodeHandler
{
public:
- PacketHandler(char const* _name, SessionStatus _status, PacketProcessing _processing) : OpcodeHandler(_name, _status, _processing) { }
+ PacketHandler(char const* name, SessionStatus status, PacketProcessing processing) : ClientOpcodeHandler(name, status, processing) { }
void Call(WorldSession* session, WorldPacket& packet) const override
{
@@ -43,10 +48,10 @@ public:
};
template<void(WorldSession::*HandlerFunction)(WorldPacket&)>
-class PacketHandler<WorldPacket, HandlerFunction> : public OpcodeHandler
+class PacketHandler<WorldPacket, HandlerFunction> : public ClientOpcodeHandler
{
public:
- PacketHandler(char const* _name, SessionStatus _status, PacketProcessing _processing) : OpcodeHandler(_name, _status, _processing) { }
+ PacketHandler(char const* name, SessionStatus status, PacketProcessing processing) : ClientOpcodeHandler(name, status, processing) { }
void Call(WorldSession* session, WorldPacket& packet) const override
{
@@ -57,9 +62,9 @@ public:
OpcodeTable opcodeTable;
template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)>
-void OpcodeTable::ValidateAndSetOpcode(OpcodeClient opcode, char const* name, SessionStatus status, PacketProcessing processing)
+void OpcodeTable::ValidateAndSetClientOpcode(OpcodeClient opcode, char const* name, SessionStatus status, PacketProcessing processing)
{
- if (uint32(opcode) == 0xBADD)
+ if (uint32(opcode) == NULL_OPCODE)
{
TC_LOG_ERROR("network", "Opcode %s does not have a value", name);
return;
@@ -80,9 +85,9 @@ void OpcodeTable::ValidateAndSetOpcode(OpcodeClient opcode, char const* name, Se
_internalTableClient[opcode] = new PacketHandler<PacketClass, HandlerFunction>(name, status, processing);
}
-void OpcodeTable::ValidateAndSetOpcode(OpcodeServer opcode, char const* name, SessionStatus status)
+void OpcodeTable::ValidateAndSetServerOpcode(OpcodeServer opcode, char const* name, SessionStatus status, ConnectionType conIdx)
{
- if (uint32(opcode) == 0xBADD)
+ if (uint32(opcode) == NULL_OPCODE)
{
TC_LOG_ERROR("network", "Opcode %s does not have a value", name);
return;
@@ -94,23 +99,35 @@ void OpcodeTable::ValidateAndSetOpcode(OpcodeServer opcode, char const* name, Se
return;
}
+ if (conIdx >= MAX_CONNECTION_TYPES)
+ {
+ TC_LOG_ERROR("network", "Tried to set invalid connection type %u for opcode %s", conIdx, name);
+ return;
+ }
+
+ if (IsInstanceOnlyOpcode(opcode) && conIdx != CONNECTION_TYPE_INSTANCE)
+ {
+ TC_LOG_ERROR("network", "Tried to set invalid connection type %u for instance only opcode %s", conIdx, name);
+ return;
+ }
+
if (_internalTableServer[opcode] != NULL)
{
TC_LOG_ERROR("network", "Tried to override server handler of %s with %s (opcode %u)", opcodeTable[opcode]->Name, name, opcode);
return;
}
- _internalTableServer[opcode] = new PacketHandler<WorldPacket, &WorldSession::Handle_ServerSide>(name, status, PROCESS_INPLACE);
+ _internalTableServer[opcode] = new ServerOpcodeHandler(name, status, conIdx);
}
/// Correspondence between opcodes and their names
void OpcodeTable::Initialize()
{
#define DEFINE_OPCODE_HANDLER_OLD(opcode, status, processing, handler) \
- ValidateAndSetOpcode<WorldPacket, handler>(opcode, #opcode, status, processing);
+ ValidateAndSetClientOpcode<WorldPacket, handler>(opcode, #opcode, status, processing);
#define DEFINE_HANDLER(opcode, status, processing, packetclass, handler) \
- ValidateAndSetOpcode<packetclass, handler>(opcode, #opcode, status, processing);
+ ValidateAndSetClientOpcode<packetclass, handler>(opcode, #opcode, status, processing);
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_LEVEL_GRANT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode );
@@ -154,7 +171,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_BANK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoDeclineGuildInvites );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BANKER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode );
+ DEFINE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBankerActivateOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse );
@@ -175,7 +192,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BATTLE_PET_SET_BATTLE_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BEGIN_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BINDER_ACTIVATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode );
+ DEFINE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUSY_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_BUYBACK_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem );
@@ -197,7 +214,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_GUILD_FILTER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_REMOVE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CALENDAR_UPDATE_EVENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode );
+ DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_AUTO_REPEAT_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_CAST, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_CHANNELLING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling );
@@ -206,15 +223,15 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_QUEUED_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CANCEL_TEMP_ENCHANTMENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode);
DEFINE_HANDLER(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, WorldPackets::Trade::CancelTrade, &WorldSession::HandleCancelTradeOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CAST_SPELL, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode );
+ DEFINE_HANDLER(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Spells::SpellCastRequest, &WorldSession::HandleCastSpellOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANGEPLAYER_DIFFICULTY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_ANNOUNCEMENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_BAN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_DISPLAY_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery );
+ DEFINE_HANDLER(CMSG_CHANNEL_DISPLAY_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::ChannelListRequest, &WorldSession::HandleChannelList);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_INVITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_KICK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList );
+ DEFINE_HANDLER(CMSG_CHANNEL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::ChannelListRequest, &WorldSession::HandleChannelList);
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MODERATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MODERATOR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator );
DEFINE_OPCODE_HANDLER_OLD(CMSG_CHANNEL_MUTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute );
@@ -260,7 +277,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_CORPSE_MAP_POSITION_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery );
DEFINE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Query::QueryCreature, &WorldSession::HandleCreatureQuery);
DEFINE_OPCODE_HANDLER_OLD(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_DB_QUERY_BULK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_HANDLER(CMSG_DB_QUERY_BULK, STATUS_AUTHED, PROCESS_INPLACE, WorldPackets::Query::DBQueryBulk, &WorldSession::HandleDBQueryBulk);
DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_FRIEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_IGNORE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_DEL_MUTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -275,7 +292,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_ENABLETAXI, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ENABLE_NAGLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_DELETE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_SAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave );
+ DEFINE_HANDLER(CMSG_EQUIPMENT_SET_SAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::EquipmentSet::SaveEquipmentSet, &WorldSession::HandleEquipmentSetSave);
DEFINE_OPCODE_HANDLER_OLD(CMSG_EQUIPMENT_SET_USE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse );
DEFINE_OPCODE_HANDLER_OLD(CMSG_FACTION_BONUS_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_FAR_SIGHT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode );
@@ -294,7 +311,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_SYSTEMSTATUS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GM_REPORT_LAG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode );
+ DEFINE_HANDLER(CMSG_GOSSIP_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleGossipHelloOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_GOSSIP_SELECT_OPTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GRANT_LEVEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel );
DEFINE_OPCODE_HANDLER_OLD(CMSG_GROUP_ASSISTANT_LEADER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode);
@@ -360,12 +377,12 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_REFUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_REFUND_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_ITEM_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_JOIN_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel );
+ DEFINE_HANDLER(CMSG_JOIN_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::JoinChannel, &WorldSession::HandleJoinChannel);
DEFINE_OPCODE_HANDLER_OLD(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_PREVIEW_TALENTS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_PREVIEW_TALENTS_PET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_LEARN_TALENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_LEAVE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel );
+ DEFINE_HANDLER(CMSG_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Talent::LearnTalent, &WorldSession::HandleLearnTalentOpcode);
+ DEFINE_HANDLER(CMSG_LEAVE_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Channel::LeaveChannel, &WorldSession::HandleLeaveChannel);
DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_GET_STATUS, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetStatus );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_JOIN, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LFG_LEAVE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode );
@@ -385,7 +402,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_POST_REQUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit );
DEFINE_OPCODE_HANDLER_OLD(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_LIST_INVENTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode );
+ DEFINE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleListInventoryOpcode);
DEFINE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::LoadingScreenNotify, &WorldSession::HandleLoadScreenOpcode);
DEFINE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutCancel, &WorldSession::HandleLogoutCancelOpcode);
DEFINE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Character::LogoutRequest, &WorldSession::HandleLogoutRequestOpcode);
@@ -403,25 +420,23 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_RETURN_TO_SENDER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_TAKE_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MAIL_TAKE_MONEY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_AFK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_DND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_GUILD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_OFFICER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_PARTY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_SAY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_WHISPER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MESSAGECHAT_YELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessage, &WorldSession::HandleChatAddonMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatAddonMessageWhisper, &WorldSession::HandleChatAddonMessageWhisperOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageAFK, &WorldSession::HandleChatMessageAFKOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageChannel, &WorldSession::HandleChatMessageChannelOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_DND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageDND, &WorldSession::HandleChatMessageDNDOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageEmote, &WorldSession::HandleChatMessageEmoteOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_SAY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
+ DEFINE_HANDLER(CMSG_MESSAGECHAT_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessageWhisper, &WorldSession::HandleChatMessageWhisperOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIGAME_MOVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MINIMAP_PING, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode );
@@ -471,12 +486,13 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_MOVE_STOP_STRAFE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_STOP_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes);
DEFINE_HANDLER(CMSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::ClientPlayerMovement, &WorldSession::HandleMovementOpcodes);
+ DEFINE_HANDLER(CMSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, WorldPackets::Movement::MoveTeleportAck, &WorldSession::HandleMoveTeleportAck);
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_MOVE_WORLDPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode );
+ DEFINE_HANDLER(CMSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, WorldPackets::Movement::WorldPortAck, &WorldSession::HandleMoveWorldportAckOpcode);
DEFINE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryPlayerName, &WorldSession::HandleNameQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_NPC_TEXT_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode );
+ DEFINE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Query::QueryNPCText, &WorldSession::HandleNpcTextQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_OFFER_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode );
@@ -494,7 +510,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ABANDON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_ACTION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_CANCEL_AURA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_CAST_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode );
+ DEFINE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::SpellCastRequest, &WorldSession::HandlePetCastSpellOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_LEARN_TALENT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_NAME_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery );
DEFINE_OPCODE_HANDLER_OLD(CMSG_PET_RENAME, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename );
@@ -523,8 +539,8 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_HELLO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode);
+ DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Quest::QuestGiverStatusMultipleQuery, &WorldSession::HandleQuestgiverStatusMultipleQuery);
+ DEFINE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Quest::QuestGiverStatusQuery, &WorldSession::HandleQuestgiverStatusQueryOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept );
DEFINE_OPCODE_HANDLER_OLD(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestNPCQuery );
@@ -546,7 +562,6 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::RequestAccountData, &WorldSession::HandleRequestAccountData);
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCategoryCooldowns );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_CEMETERY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestCemeteryList );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_HOTFIX, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode );
@@ -573,7 +588,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SETSHEATHED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIONBAR_TOGGLES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarToggles );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTION_BUTTON, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionButtonOpcode );
+ DEFINE_HANDLER(CMSG_SET_ACTION_BUTTON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::SetActionButton, &WorldSession::HandleSetActionButtonOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_MOVER, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); // STATUS_AUTHED
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_ALLOW_LOW_LEVEL_RAID1, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -591,7 +606,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SELECTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode );
+ DEFINE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::SetSelection, &WorldSession::HandleSetSelectionOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_SKILL_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_SET_SPECIALIZATION, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Talent::SetSpecialization, &WorldSession::HandleSetSpecializationOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode );
@@ -621,26 +636,24 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXINODE_STATUS_QUERY, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TAXIQUERYAVAILABLENODES, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TELEPORT_TO_UNIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TEXT_EMOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode );
+ DEFINE_HANDLER(CMSG_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::CTextEmote, &WorldSession::HandleTextEmoteOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_TIME_ADJUSTMENT_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_HANDLER(CMSG_TIME_SYNC_RESP, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Misc::TimeSyncResponse, &WorldSession::HandleTimeSyncResp);
DEFINE_OPCODE_HANDLER_OLD(CMSG_TIME_SYNC_RESP_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TOGGLE_PVP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TOTEM_DESTROYED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_BUY_SPELL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TRAINER_LIST, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode );
+ DEFINE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleTrainerListOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_TRANSMOGRIFY_ITEMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems );
DEFINE_OPCODE_HANDLER_OLD(CMSG_TURN_IN_PETITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_CLEAR, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_FLAG, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_TUTORIAL_RESET, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset );
+ DEFINE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Misc::TutorialSetFlag, &WorldSession::HandleTutorialFlag);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNACCEPT_TRADE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode );
DEFINE_HANDLER(CMSG_UNDELETE_CHARACTER, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::UndeleteCharacter, &WorldSession::HandleCharUndeleteOpcode);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNDELETE_COOLDOWN_STATUS_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUndeleteCooldownStatusQuery);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SKILL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode );
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(CMSG_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUnregisterAddonPrefixesOpcode);
- DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData );
+ DEFINE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::ClientConfig::UserClientUpdateAccountData, &WorldSession::HandleUpdateAccountData);
DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory );
DEFINE_OPCODE_HANDLER_OLD(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition );
DEFINE_OPCODE_HANDLER_OLD(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -664,8 +677,6 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER_OLD(MSG_INSPECT_ARENA_TEAMS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
DEFINE_OPCODE_HANDLER_OLD(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
@@ -689,733 +700,750 @@ void OpcodeTable::Initialize()
#undef DEFINE_OPCODE_HANDLER_OLD
#undef DEFINE_HANDLER
-#define DEFINE_SERVER_OPCODE_HANDLER(opcode, status) \
- ValidateAndSetOpcode(opcode, #opcode, status)
+#define DEFINE_SERVER_OPCODE_HANDLER(opcode, status, con) \
+ ValidateAndSetServerOpcode(opcode, #opcode, status, con)
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_UNIT_DESTROYED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_EVENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_LIST_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_NOTIFICATION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_NOTIFICATION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REMOVED_NOTIFICATION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_UPDATE_ALL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVAILABLE_VOICE_CHANNEL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVERAGE_ITEM_LEVEL_INFORM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BARBER_SHOP_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_PORT_DENIED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_RATED_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_QUEUED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_ACTIVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_REMOVED_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_UPDATED_ALERT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_FILTER_GUILD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_ADDED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_CALENDAR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_EVENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_NUM_PENDING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAMERA_SHAKE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_JOINED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_LEFT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_START, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_NOT_FOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_SERVER_DISCONNECTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_SERVER_RECONNECTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_WRONG_FACTION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COIN_REMOVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PARTY_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PLAYER_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_STATE_CHANGED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLAIN_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_MOVES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_PACKET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_CONNECT_FAIL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_DISCONNECT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_RECONNECT_TRY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_NOT_IN_INSTANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATURE_QUERY_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_REMOVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_RESTORED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_STUDIO_CREATE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTROY_OBJECT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DIFFERENT_INSTANCE_FROM_PARTY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISENCHANT_CREDIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISMOUNT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISMOUNTRESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPEL_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_GAME_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_PROMOTION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DROP_NEW_CONNECTION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_COUNTDOWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_INBOUNDS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_OUTOFBOUNDS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_REQUESTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_WINNER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUMP_RIDE_TICKETS_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ECHO_PARTY_SQUELCH, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_USE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FAILED_PLAYER_CONDITION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLOOD_DETECTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCEACTIONSHOW, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_PAGETEXT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_RESET_STATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMESPEED_SET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_SET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_EVENT_DEBUG_LOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_DB_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_RECEIVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_STATUS_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_CREATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_DELETETICKET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_GETTICKET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_SYSTEMSTATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_MESSAGECHAT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_STATUS_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GODMODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MAX_DAILY_XP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RECIPES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RENAMED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ADD_PASSIVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REMOVE_PASSIVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_SEND_PASSIVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TEXT_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_SPELL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_OFFER_CONTINUE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_REWARD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PROPOSAL_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_QUEUE_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_ROLE_CHECK_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_ROLE_CHOSEN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_SLOT_INVALID, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_TELEPORT_DENIED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_UPDATE_SEARCH, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_COMPLETE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ALL_PASSED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_CLEAR_MONEY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_CONTENTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ITEM_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_MASTER_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_MONEY_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RELEASE_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL_WON, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_SLOT_CHANGED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_START_ROLL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRRORIMAGE_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FEATHER_FALL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FORCE_RUN_SPEED_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FORCE_SWIM_SPEED_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_LAND_WALK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_COLLISION_HEIGHT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD_ABORT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PERIODICAURALOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOWLIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ADDED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BROKEN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_MODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_NAME_INVALID, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_REMOVED_SPELL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_RENAMEABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SLOT_UPDATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SPELLS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UPDATE_COMBO_POINTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYERBINDERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYERBOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_VEHICLE_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_DANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PONG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRE_RESURRECT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROCRESIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_RATING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_STATS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_OK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REAL_GROUP_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVED_MAIL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVED_SPELL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPORT_PVP_AFK_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_SETUP_HISTORY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_PERF, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOCKET_GEMS_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOR_START_EXPERIENCE_INCOMPLETE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLBREAKLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLDAMAGESHIELD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLDISPELLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLENERGIZELOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLHEALLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLINSTAKILLLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLINTERRUPTLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLLOGEXECUTE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLLOGMISS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLNONMELEEDAMAGELOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLORDAMAGE_IMMUNE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLSTEALLOG, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_ANIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_STOP_DANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_STOP_MIRROR_TIMER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_STREAMING_MOVIE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUMMON_CANCEL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUMMON_REQUEST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TAXINODE_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_COOLDOWN_STATUS_RESPONSE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_SPELLCAST_START, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_COMBO_POINTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICESESSION_FULL, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_ROSTER_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SET_TALKER_MUTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_FINISH, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARGAME_CHECK_ENTRY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARGAME_REQUEST_SENT, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEATHER, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_LAST_RESET, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_RESET_CURRENCY, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE_UPDATE, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHOIS, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_XP_GAIN_ABORTED, STATUS_UNHANDLED);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_UNHANDLED);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ADJUST_SPLINE_DURATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_UNIT_DESTROYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_EVENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_HELLO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_LIST_ITEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_OWNER_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUCTION_REMOVED_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVAILABLE_VOICE_CHANNEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_AVERAGE_ITEM_LEVEL_INFORM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BARBER_SHOP_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_PORT_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_RATED_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_QUEUED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_ACTIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_DISTRIBUTION_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_JOURNAL_LOCK_ACQUIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_REMOVED_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_UPDATED_ALERT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_FILTER_GUILD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_ADDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_CALENDAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_EVENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CALENDAR_SEND_NUM_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAMERA_SHAKE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_JOINED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY_LEFT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHANNEL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_PLAYER_NOT_FOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_SERVER_DISCONNECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_SERVER_RECONNECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CHAT_WRONG_FACTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COIN_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PARTY_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMMENTATOR_STATE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLAIN_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_MOVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_PACKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_CONNECT_FAIL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_DISCONNECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMSAT_RECONNECT_TRY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_NOT_IN_INSTANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATURE_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_RESTORED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DANCE_STUDIO_CREATE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTROY_OBJECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DIFFERENT_INSTANCE_FROM_PARTY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISENCHANT_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISMOUNT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISMOUNTRESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPEL_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_GAME_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DISPLAY_PROMOTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DROP_NEW_CONNECTION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_COUNTDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_INBOUNDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_OUTOFBOUNDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_REQUESTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUEL_WINNER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DUMP_RIDE_TICKETS_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ECHO_PARTY_SQUELCH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_USE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FAILED_PLAYER_CONDITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FLOOD_DETECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCEACTIONSHOW, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_PAGETEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMEOBJECT_RESET_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMESPEED_SET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_SET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAMETIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GAME_EVENT_DEBUG_LOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_COMPLETE_MISSION_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GARRISON_REMOTE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_DB_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_RECEIVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMRESPONSE_STATUS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_CREATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_DELETETICKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_GETTICKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_SYSTEMSTATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GMTICKET_UPDATETEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_MESSAGECHAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_CASE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_STATUS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GM_TICKET_SYSTEM_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GODMODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_BANK_MONEY_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_EVENT_PRESENCE_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MAX_DAILY_XP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RECIPES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RENAMED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ADD_PASSIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REFUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_REMOVE_PASSIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_SEND_PASSIVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TEXT_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEARNED_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_OFFER_CONTINUE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_REWARD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PROPOSAL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_QUEUE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_ROLE_CHECK_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_ROLE_CHOSEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_SLOT_INVALID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_TELEPORT_DENIED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_UPDATE_SEARCH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_COMPLETE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGOUT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ALL_PASSED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_CLEAR_MONEY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_CONTENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ITEM_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_MASTER_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_MONEY_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RELEASE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_ROLL_WON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_SLOT_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOOT_START_ROLL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAIL_QUERY_NEXT_TIME_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRRORIMAGE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNTSPECIAL_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_FEATHER_FALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_LAND_WALK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_TELEPORT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_COLLISION_HEIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NEW_WORLD_ABORT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PERIODICAURALOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOWLIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_ADDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_BROKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_NAME_INVALID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_NAME_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_REMOVED_SPELL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_RENAMEABLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SLOT_UPDATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UPDATE_COMBO_POINTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYERBINDERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYERBOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_VEHICLE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PONG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PRE_RESURRECT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROCRESIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PVP_SEASON, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_RATING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RATED_BG_STATS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_READ_ITEM_OK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_QUERY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REAL_GROUP_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RECEIVED_MAIL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REFRESH_SPELL_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVED_SPELL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPORT_PVP_AFK_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_SETUP_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESUME_COMMS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_CHARGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_SPELL_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_PERF, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MAX_WEEKLY_QUANTITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MOVEMENT_ANIM_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOCKET_GEMS_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SOR_START_EXPERIENCE_INCOMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLBREAKLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLDAMAGESHIELD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLDISPELLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLENERGIZELOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLHEALLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLINSTAKILLLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLINTERRUPTLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLLOGEXECUTE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLLOGMISS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLNONMELEEDAMAGELOG, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLORDAMAGE_IMMUNE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELLSTEALLOG, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_ANIM, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_STOP_DANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_STOP_MIRROR_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_STREAMING_MOVIE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUMMON_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUMMON_REQUEST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TAXINODE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_CHARACTER_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNDELETE_COOLDOWN_STATUS_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UNIT_SPELLCAST_START, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_COMBO_POINTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICESESSION_FULL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_ROSTER_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SET_TALKER_MUTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_FINISH, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARGAME_CHECK_ENTRY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARGAME_REQUEST_SENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEATHER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_LAST_RESET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_RESET_CURRENCY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHOIS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_XP_GAIN_ABORTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
#undef DEFINE_SERVER_OPCODE_HANDLER
};
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index aeb5bada68c..5556a4daf63 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -29,7 +29,10 @@
enum ConnectionType
{
CONNECTION_TYPE_REALM = 0,
- CONNECTION_TYPE_INSTANCE = 1
+ CONNECTION_TYPE_INSTANCE = 1,
+ MAX_CONNECTION_TYPES,
+
+ CONNECTION_TYPE_DEFAULT = -1
};
enum OpcodeMisc : uint32
@@ -144,15 +147,15 @@ enum OpcodeClient : uint32
CMSG_CANCEL_QUEUED_SPELL = 0xBADD,
CMSG_CANCEL_TEMP_ENCHANTMENT = 0xBADD,
CMSG_CANCEL_TRADE = 0x1159,
- CMSG_CAST_SPELL = 0xBADD,
+ CMSG_CAST_SPELL = 0x08FE,
CMSG_CHANGEPLAYER_DIFFICULTY = 0xBADD,
CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0xBADD,
CMSG_CHANNEL_ANNOUNCEMENTS = 0xBADD,
CMSG_CHANNEL_BAN = 0xBADD,
- CMSG_CHANNEL_DISPLAY_LIST = 0xBADD,
+ CMSG_CHANNEL_DISPLAY_LIST = 0x093B,
CMSG_CHANNEL_INVITE = 0xBADD,
CMSG_CHANNEL_KICK = 0xBADD,
- CMSG_CHANNEL_LIST = 0xBADD,
+ CMSG_CHANNEL_LIST = 0x093B,
CMSG_CHANNEL_MODERATE = 0xBADD,
CMSG_CHANNEL_MODERATOR = 0xBADD,
CMSG_CHANNEL_MUTE = 0xBADD,
@@ -193,7 +196,7 @@ enum OpcodeClient : uint32
CMSG_COMPLAIN = 0xBADD,
CMSG_COMPLETE_CINEMATIC = 0xBADD,
CMSG_COMPLETE_MOVIE = 0xBADD,
- CMSG_CONNECT_TO_FAILED = 0xBADD,
+ CMSG_CONNECT_TO_FAILED = 0x0135,
CMSG_CONTACT_LIST = 0xBADD,
CMSG_CORPSE_MAP_POSITION_QUERY = 0xBADD,
CMSG_CREATURE_QUERY = 0x0505,
@@ -314,8 +317,8 @@ enum OpcodeClient : uint32
CMSG_KEEP_ALIVE = 0xBADD,
CMSG_LEARN_PREVIEW_TALENTS = 0xBADD,
CMSG_LEARN_PREVIEW_TALENTS_PET = 0xBADD,
- CMSG_LEARN_TALENT = 0xBADD,
- CMSG_LEAVE_CHANNEL = 0xBADD,
+ CMSG_LEARN_TALENT = 0x0BB6,
+ CMSG_LEAVE_CHANNEL = 0x19F2,
CMSG_LFG_GET_STATUS = 0xBADD,
CMSG_LFG_JOIN = 0xBADD,
CMSG_LFG_LEAVE = 0xBADD,
@@ -335,7 +338,7 @@ enum OpcodeClient : uint32
CMSG_LF_GUILD_POST_REQUEST = 0xBADD,
CMSG_LF_GUILD_REMOVE_RECRUIT = 0xBADD,
CMSG_LF_GUILD_SET_GUILD_POST = 0xBADD,
- CMSG_LIST_INVENTORY = 0xBADD,
+ CMSG_LIST_INVENTORY = 0x0B39,
CMSG_LOAD_SCREEN = 0x0B08,
CMSG_LOGOUT_CANCEL = 0x03C2,
CMSG_LOGOUT_REQUEST = 0x1911,
@@ -354,22 +357,20 @@ enum OpcodeClient : uint32
CMSG_MAIL_TAKE_ITEM = 0xBADD,
CMSG_MAIL_TAKE_MONEY = 0xBADD,
CMSG_MEETINGSTONE_INFO = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_BATTLEGROUND = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_GUILD = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_OFFICER = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_PARTY = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_RAID = 0xBADD,
- CMSG_MESSAGECHAT_ADDON_WHISPER = 0xBADD,
+ CMSG_MESSAGECHAT_ADDON_GUILD = 0x137C,
+ CMSG_MESSAGECHAT_ADDON_OFFICER = 0x188A,
+ CMSG_MESSAGECHAT_ADDON_PARTY = 0x015C,
+ CMSG_MESSAGECHAT_ADDON_RAID = 0x082C,
+ CMSG_MESSAGECHAT_ADDON_WHISPER = 0x18A2,
CMSG_MESSAGECHAT_AFK = 0x1BDC,
- CMSG_MESSAGECHAT_BATTLEGROUND = 0xBADD,
CMSG_MESSAGECHAT_CHANNEL = 0x0913,
CMSG_MESSAGECHAT_DND = 0x0AAB,
CMSG_MESSAGECHAT_EMOTE = 0x113C,
CMSG_MESSAGECHAT_GUILD = 0x0B1B,
- CMSG_MESSAGECHAT_OFFICER = 0xBADD,
+ CMSG_MESSAGECHAT_OFFICER = 0x0114,
CMSG_MESSAGECHAT_PARTY = 0x0134,
- CMSG_MESSAGECHAT_RAID = 0xBADD,
- CMSG_MESSAGECHAT_RAID_WARNING = 0xBADD,
+ CMSG_MESSAGECHAT_RAID = 0x0B33,
+ CMSG_MESSAGECHAT_RAID_WARNING = 0x0313,
CMSG_MESSAGECHAT_SAY = 0x1884,
CMSG_MESSAGECHAT_WHISPER = 0x1829,
CMSG_MESSAGECHAT_YELL = 0x1161,
@@ -426,6 +427,7 @@ enum OpcodeClient : uint32
CMSG_MOVE_STOP_STRAFE = 0x01D1,
CMSG_MOVE_STOP_SWIM = 0x097C,
CMSG_MOVE_STOP_TURN = 0x0964,
+ CMSG_MOVE_TELEPORT_ACK = 0x0D01,
CMSG_MOVE_TIME_SKIPPED = 0x19C2,
CMSG_MOVE_TOGGLE_COLLISION_ACK = 0xBADD,
CMSG_MOVE_WATER_WALK_ACK = 0xBADD,
@@ -460,7 +462,7 @@ enum OpcodeClient : uint32
CMSG_PET_SPELL_AUTOCAST = 0xBADD,
CMSG_PET_STOP_ATTACK = 0xBADD,
CMSG_PING = 0x0416,
- CMSG_PLAYED_TIME = 0xBADD,
+ CMSG_PLAYED_TIME = 0x1BB2,
CMSG_PLAYER_DIFFICULTY_CHANGE = 0xBADD,
CMSG_PLAYER_LOGIN = 0x0B1D,
CMSG_PLAYER_LOGOUT = 0xBADD,
@@ -486,7 +488,7 @@ enum OpcodeClient : uint32
CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0xBADD,
CMSG_QUESTGIVER_REQUEST_REWARD = 0xBADD,
CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x0131,
- CMSG_QUESTGIVER_STATUS_QUERY = 0x0704,
+ CMSG_QUESTGIVER_STATUS_QUERY = 0x01E2,
CMSG_QUESTLOG_REMOVE_QUEST = 0xBADD,
CMSG_QUESTLOG_SWAP_QUEST = 0xBADD,
CMSG_QUEST_CONFIRM_ACCEPT = 0xBADD,
@@ -509,8 +511,7 @@ enum OpcodeClient : uint32
CMSG_REPORT_PVP_AFK = 0xBADD,
CMSG_REQUEST_ACCOUNT_DATA = 0x0F3E,
CMSG_REQUEST_CATEGORY_COOLDOWNS = 0xBADD,
- CMSG_REQUEST_CEMETERY_LIST = 0xBADD,
- CMSG_REQUEST_HOTFIX = 0xBADD,
+ CMSG_REQUEST_CEMETERY_LIST = 0x10A2,
CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0xBADD,
CMSG_REQUEST_PARTY_MEMBER_STATS = 0xBADD,
CMSG_REQUEST_PET_INFO = 0xBADD,
@@ -544,7 +545,7 @@ enum OpcodeClient : uint32
CMSG_SET_ACTIONBAR_TOGGLES = 0xBADD,
CMSG_SET_ACTION_BUTTON = 0x0599,
CMSG_SET_ACTIVE_MOVER = 0xBADD,
- CMSG_SET_ACTIVE_VOICE_CHANNEL = 0xBADD,
+ CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x031E,
CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0xBADD,
CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0xBADD,
CMSG_SET_CHANNEL_WATCH = 0xBADD,
@@ -609,9 +610,7 @@ enum OpcodeClient : uint32
CMSG_TRANSMOGRIFY_ITEMS = 0x0A85,
CMSG_TRIGGER_CINEMATIC_CHEAT = 0xBADD,
CMSG_TURN_IN_PETITION = 0xBADD,
- CMSG_TUTORIAL_CLEAR = 0xBADD,
- CMSG_TUTORIAL_FLAG = 0xBADD,
- CMSG_TUTORIAL_RESET = 0xBADD,
+ CMSG_TUTORIAL_FLAG = 0x0B16,
CMSG_UNACCEPT_TRADE = 0xBADD,
CMSG_UNDELETE_CHARACTER = 0x0D99,
CMSG_UNDELETE_COOLDOWN_STATUS_QUERY = 0x19A9,
@@ -624,7 +623,7 @@ enum OpcodeClient : uint32
CMSG_USED_FOLLOW = 0xBADD,
CMSG_USE_ITEM = 0x08B6,
CMSG_VIOLENCE_LEVEL = 0x098D,
- CMSG_VOICE_SESSION_ENABLE = 0xBADD,
+ CMSG_VOICE_SESSION_ENABLE = 0x1102,
CMSG_VOID_STORAGE_QUERY = 0x019E,
CMSG_VOID_STORAGE_TRANSFER = 0x0463,
CMSG_VOID_STORAGE_UNLOCK = 0x13BB,
@@ -654,8 +653,6 @@ enum OpcodeClient : uint32
MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0xBADD,
MSG_MOVE_SET_TURN_RATE_CHEAT = 0xBADD,
MSG_MOVE_SET_WALK_SPEED_CHEAT = 0xBADD,
- MSG_MOVE_TELEPORT = 0xBADD,
- MSG_MOVE_TELEPORT_ACK = 0xBADD,
MSG_MOVE_TELEPORT_CHEAT = 0xBADD,
MSG_MOVE_TIME_SKIPPED = 0xBADD,
MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0xBADD,
@@ -666,7 +663,6 @@ enum OpcodeClient : uint32
MSG_PARTY_ASSIGNMENT = 0xBADD,
MSG_PETITION_DECLINE = 0xBADD,
MSG_PETITION_RENAME = 0xBADD,
- MSG_PVP_LOG_DATA = 0xBADD,
MSG_QUERY_NEXT_MAIL_TIME = 0xBADD,
MSG_QUEST_PUSH_RESULT = 0xBADD,
MSG_RAID_READY_CHECK = 0xBADD,
@@ -688,12 +684,14 @@ enum OpcodeServer : uint32
SMSG_ACCOUNT_INFO_RESPONSE = 0xBADD,
SMSG_ACCOUNT_MOUNT_UPDATE = 0x0140,
SMSG_ACCOUNT_RESTRICTED_WARNING = 0xBADD,
+ SMSG_ACCOUNT_TOYS_UPDATE = 0x0590,
SMSG_ACHIEVEMENT_DELETED = 0xBADD,
SMSG_ACHIEVEMENT_EARNED = 0xBADD,
SMSG_ACTION_BUTTONS = 0x1D1F,
SMSG_ACTIVATETAXIREPLY = 0xBADD,
SMSG_ADDON_INFO = 0x1D9F,
SMSG_ADD_RUNE_POWER = 0xBADD,
+ SMSG_ADJUST_SPLINE_DURATION = 0x0104,
SMSG_AI_REACTION = 0x0BA1,
SMSG_ALL_ACHIEVEMENT_DATA = 0xBADD,
SMSG_ALL_ACHIEVEMENT_DATA_ACCOUNT = 0x0123,
@@ -727,12 +725,11 @@ enum OpcodeServer : uint32
SMSG_AUCTION_OWNER_NOTIFICATION = 0xBADD,
SMSG_AUCTION_REMOVED_NOTIFICATION = 0xBADD,
SMSG_AURACASTLOG = 0xBADD,
- SMSG_AURA_POINTS_DEPLETED = 0xBADD,
+ SMSG_AURA_POINTS_DEPLETED = 0x093B,
SMSG_AURA_UPDATE = 0x091C,
- SMSG_AURA_UPDATE_ALL = 0xBADD,
SMSG_AUTH_CHALLENGE = 0x1759,
SMSG_AUTH_RESPONSE = 0x0DA9,
- SMSG_AVAILABLE_VOICE_CHANNEL = 0xBADD,
+ SMSG_AVAILABLE_VOICE_CHANNEL = 0x04D4,
SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0xBADD,
SMSG_BARBER_SHOP_RESULT = 0xBADD,
SMSG_BATTLEFIELD_LIST = 0xBADD,
@@ -756,6 +753,7 @@ enum OpcodeServer : uint32
SMSG_BATTLEGROUND_INFO_THROTTLED = 0xBADD,
SMSG_BATTLEGROUND_PLAYER_JOINED = 0xBADD,
SMSG_BATTLEGROUND_PLAYER_LEFT = 0xBADD,
+ SMSG_BATTLE_PAY_DISTRIBUTION_UPDATE = 0x0BE3,
SMSG_BATTLE_PAY_GET_DISTRIBUTION_LIST_RESPONSE = 0x0F2A,
SMSG_BATTLE_PAY_GET_PRODUCT_LIST_RESPONSE = 0x12A4,
SMSG_BATTLE_PAY_GET_PURCHASE_LIST_RESPONSE = 0x168A,
@@ -790,7 +788,7 @@ enum OpcodeServer : uint32
SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0xBADD,
SMSG_CALENDAR_SEND_CALENDAR = 0xBADD,
SMSG_CALENDAR_SEND_EVENT = 0xBADD,
- SMSG_CALENDAR_SEND_NUM_PENDING = 0xBADD,
+ SMSG_CALENDAR_SEND_NUM_PENDING = 0x1B3A,
SMSG_CALENDAR_UPDATE_INVITE_LIST = 0xBADD,
SMSG_CAMERA_SHAKE = 0xBADD,
SMSG_CANCEL_AUTO_REPEAT = 0xBADD,
@@ -913,8 +911,10 @@ enum OpcodeServer : uint32
SMSG_FORCE_SET_VEHICLE_REC_ID = 0xBADD,
SMSG_FORGE_MASTER_SET = 0xBADD,
SMSG_FRIEND_STATUS = 0xBADD,
+ SMSG_GAMEOBJECT_ACTIVATE_ANIM_KIT = 0x038C,
SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x03EB,
SMSG_GAMEOBJECT_DESPAWN_ANIM = 0xBADD,
+ SMSG_GAMEOBJECT_DESPAWN = 0x0D29,
SMSG_GAMEOBJECT_PAGETEXT = 0xBADD,
SMSG_GAMEOBJECT_QUERY_RESPONSE = 0xBADD,
SMSG_GAMEOBJECT_RESET_STATE = 0xBADD,
@@ -922,8 +922,8 @@ enum OpcodeServer : uint32
SMSG_GAMETIME_SET = 0xBADD,
SMSG_GAMETIME_UPDATE = 0xBADD,
SMSG_GAME_EVENT_DEBUG_LOG = 0xBADD,
- SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT = 0xBADD,
SMSG_GARRISON_COMPLETE_MISSION_RESULT = 0x0952,
+ SMSG_GARRISON_REMOTE_INFO = 0x0151,
SMSG_GMRESPONSE_DB_ERROR = 0xBADD,
SMSG_GMRESPONSE_RECEIVED = 0xBADD,
SMSG_GMRESPONSE_STATUS_UPDATE = 0xBADD,
@@ -934,7 +934,9 @@ enum OpcodeServer : uint32
SMSG_GMTICKET_UPDATETEXT = 0xBADD,
SMSG_GM_MESSAGECHAT = 0xBADD,
SMSG_GM_PLAYER_INFO = 0xBADD,
+ SMSG_GM_TICKET_CASE_STATUS = 0x1D8D,
SMSG_GM_TICKET_STATUS_UPDATE = 0xBADD,
+ SMSG_GM_TICKET_SYSTEM_STATUS = 0x1229,
SMSG_GODMODE = 0xBADD,
SMSG_GOSSIP_COMPLETE = 0x15D1,
SMSG_GOSSIP_MESSAGE = 0x1746,
@@ -964,8 +966,10 @@ enum OpcodeServer : uint32
SMSG_GUILD_COMMAND_RESULT_2 = 0xBADD,
SMSG_GUILD_CRITERIA_DATA = 0xBADD,
SMSG_GUILD_CRITERIA_DELETED = 0xBADD,
+ SMSG_GUILD_CRITERIA_UPDATE = 0x1208,
SMSG_GUILD_DECLINE = 0xBADD,
SMSG_GUILD_EVENT = 0x1027,
+ SMSG_GUILD_EVENT_BANK_MONEY_CHANGED = 0x1077,
SMSG_GUILD_EVENT_LOG_QUERY_RESULT = 0xBADD,
SMSG_GUILD_EVENT_PRESENCE_CHANGE = 0x1228,
SMSG_GUILD_FLAGGED_FOR_RENAME = 0xBADD,
@@ -992,7 +996,7 @@ enum OpcodeServer : uint32
SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0xBADD,
SMSG_GUILD_REPUTATION_WEEKLY_CAP = 0xBADD,
SMSG_GUILD_RESET = 0xBADD,
- SMSG_GUILD_REWARDS_LIST = 0xBADD,
+ SMSG_GUILD_REWARDS_LIST = 0x1818,
SMSG_GUILD_ROSTER = 0x1026,
SMSG_GUILD_SET_NOTE = 0xBADD,
SMSG_GUILD_TRADESKILL_UPDATE = 0xBADD,
@@ -1016,12 +1020,13 @@ enum OpcodeServer : uint32
SMSG_INSPECT_RATED_BG_STATS = 0xBADD,
SMSG_INSPECT_RESULTS_UPDATE = 0xBADD,
SMSG_INSPECT_TALENT = 0xBADD,
+ SMSG_INSTANCE_INFO = 0x0DA0,
SMSG_INSTANCE_LOCK_WARNING_QUERY = 0xBADD,
SMSG_INSTANCE_RESET = 0xBADD,
SMSG_INSTANCE_RESET_FAILED = 0xBADD,
SMSG_INSTANCE_SAVE_CREATED = 0xBADD,
SMSG_INVALIDATE_DANCE = 0xBADD,
- SMSG_INVALIDATE_PLAYER = 0xBADD,
+ SMSG_INVALIDATE_PLAYER = 0x0B37,
SMSG_INVALID_PROMOTION_CODE = 0xBADD,
SMSG_INVENTORY_CHANGE_FAILURE = 0xBADD,
SMSG_ITEM_ADD_PASSIVE = 0xBADD,
@@ -1038,7 +1043,7 @@ enum OpcodeServer : uint32
SMSG_JOINED_BATTLEGROUND_QUEUE = 0xBADD,
SMSG_KICK_REASON = 0xBADD,
SMSG_LEARNED_DANCE_MOVES = 0xBADD,
- SMSG_LEARNED_SPELL = 0xBADD,
+ SMSG_LEARNED_SPELLS = 0x08AB,
SMSG_LEVELUP_INFO = 0xBADD,
SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0xBADD,
SMSG_LFG_DISABLED = 0xBADD,
@@ -1087,6 +1092,7 @@ enum OpcodeServer : uint32
SMSG_LOOT_SLOT_CHANGED = 0xBADD,
SMSG_LOOT_START_ROLL = 0xBADD,
SMSG_MAIL_LIST_RESULT = 0x0B3F,
+ SMSG_MAIL_QUERY_NEXT_TIME_RESULT = 0x153D,
SMSG_MAP_OBJ_EVENTS = 0xBADD,
SMSG_MEETINGSTONE_COMPLETE = 0xBADD,
SMSG_MEETINGSTONE_IN_PROGRESS = 0xBADD,
@@ -1101,7 +1107,7 @@ enum OpcodeServer : uint32
SMSG_MISSILE_CANCEL = 0xBADD,
SMSG_MODIFY_COOLDOWN = 0xBADD,
SMSG_MONEY_NOTIFY = 0xBADD,
- SMSG_MONSTER_MOVE = 0xBADD,
+ SMSG_MONSTER_MOVE = 0x0994,
SMSG_MONSTER_MOVE_TRANSPORT = 0xBADD,
SMSG_MOTD = 0x0442,
SMSG_MOUNTRESULT = 0xBADD,
@@ -1109,49 +1115,48 @@ enum OpcodeServer : uint32
SMSG_MOVE_COLLISION_DISABLE = 0xBADD,
SMSG_MOVE_COLLISION_ENABLE = 0xBADD,
SMSG_MOVE_FEATHER_FALL = 0xBADD,
- SMSG_MOVE_FORCE_RUN_SPEED_CHANGE = 0x08F5,
- SMSG_MOVE_FORCE_SWIM_SPEED_CHANGE = 0x061A,
SMSG_MOVE_GRAVITY_DISABLE = 0x02C6,
SMSG_MOVE_GRAVITY_ENABLE = 0xBADD,
SMSG_MOVE_KNOCK_BACK = 0xBADD,
- SMSG_MOVE_LAND_WALK = 0xBADD,
+ SMSG_MOVE_LAND_WALK = 0x13DA,
SMSG_MOVE_NORMAL_FALL = 0xBADD,
SMSG_MOVE_ROOT = 0x1B5A,
SMSG_MOVE_SET_ACTIVE_MOVER = 0xBADD,
- SMSG_MOVE_SET_CAN_FLY = 0xBADD,
+ SMSG_MOVE_SET_CAN_FLY = 0x01F6,
SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0xBADD,
SMSG_MOVE_SET_COLLISION_HEIGHT = 0x008D,
SMSG_MOVE_SET_COMPOUND_STATE = 0xBADD,
SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0xBADD,
SMSG_MOVE_SET_FLIGHT_SPEED = 0xBADD,
- SMSG_MOVE_SET_HOVER = 0xBADD,
+ SMSG_MOVE_SET_HOVER = 0x0296,
SMSG_MOVE_SET_PITCH_RATE = 0xBADD,
SMSG_MOVE_SET_RUN_BACK_SPEED = 0xBADD,
- SMSG_MOVE_SET_RUN_SPEED = 0xBADD,
+ SMSG_MOVE_SET_RUN_SPEED = 0x08F5,
SMSG_MOVE_SET_SWIM_BACK_SPEED = 0xBADD,
- SMSG_MOVE_SET_SWIM_SPEED = 0xBADD,
+ SMSG_MOVE_SET_SWIM_SPEED = 0x061A,
SMSG_MOVE_SET_TURN_RATE = 0xBADD,
SMSG_MOVE_SET_VEHICLE_REC_ID = 0xBADD,
SMSG_MOVE_SET_WALK_IN_AIR = 0xBADD,
SMSG_MOVE_SET_WALK_SPEED = 0xBADD,
+ SMSG_MOVE_TELEPORT = 0x03A6,
SMSG_MOVE_UNROOT = 0xBADD,
- SMSG_MOVE_UNSET_CAN_FLY = 0xBADD,
+ SMSG_MOVE_UNSET_CAN_FLY = 0x0BAE,
SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0xBADD,
- SMSG_MOVE_UNSET_HOVER = 0xBADD,
+ SMSG_MOVE_UNSET_HOVER = 0x01A5,
SMSG_MOVE_UNSET_WALK_IN_AIR = 0xBADD,
SMSG_MOVE_UPDATE_COLLISION_HEIGHT = 0xBADD,
SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED = 0xBADD,
SMSG_MOVE_UPDATE_FLIGHT_SPEED = 0xBADD,
SMSG_MOVE_UPDATE_KNOCK_BACK = 0xBADD,
- SMSG_MOVE_UPDATE_PITCH_RATE = 0xBADD,
- SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0xBADD,
- SMSG_MOVE_UPDATE_RUN_SPEED = 0xBADD,
- SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0xBADD,
- SMSG_MOVE_UPDATE_SWIM_SPEED = 0xBADD,
+ SMSG_MOVE_UPDATE_PITCH_RATE = 0x13D9,
+ SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0x09DE,
+ SMSG_MOVE_UPDATE_RUN_SPEED = 0x09AD,
+ SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0x1083,
+ SMSG_MOVE_UPDATE_SWIM_SPEED = 0x0B95,
SMSG_MOVE_UPDATE_TELEPORT = 0x03D5,
- SMSG_MOVE_UPDATE_TURN_RATE = 0xBADD,
- SMSG_MOVE_UPDATE_WALK_SPEED = 0xBADD,
- SMSG_MOVE_WATER_WALK = 0xBADD,
+ SMSG_MOVE_UPDATE_TURN_RATE = 0x08BE,
+ SMSG_MOVE_UPDATE_WALK_SPEED = 0x01E5,
+ SMSG_MOVE_WATER_WALK = 0x02A6,
SMSG_MULTIPLE_PACKETS = 0xBADD,
SMSG_NAME_QUERY_RESPONSE = 0x0828,
SMSG_NEW_TAXI_PATH = 0xBADD,
@@ -1265,9 +1270,10 @@ enum OpcodeServer : uint32
SMSG_REFER_A_FRIEND_EXPIRED = 0xBADD,
SMSG_REFER_A_FRIEND_FAILURE = 0xBADD,
SMSG_REFORGE_RESULT = 0xBADD,
- SMSG_REMOVED_SPELL = 0xBADD,
+ SMSG_REFRESH_SPELL_HISTORY = 0x0A2A,
+ SMSG_REMOVED_SPELL = 0x0B3B,
SMSG_REPORT_PVP_AFK_RESULT = 0xBADD,
- SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0xBADD,
+ SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x059E,
SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0xBADD,
SMSG_RESEARCH_COMPLETE = 0xBADD,
SMSG_RESEARCH_SETUP_HISTORY = 0x0A25,
@@ -1283,13 +1289,17 @@ enum OpcodeServer : uint32
SMSG_RWHOIS = 0xBADD,
SMSG_SELL_ITEM = 0xBADD,
SMSG_SEND_MAIL_RESULT = 0x0302,
- SMSG_SEND_UNLEARN_SPELLS = 0x1A82,
+ SMSG_SEND_SPELL_CHARGES = 0x1A82,
+ SMSG_SEND_SPELL_HISTORY = 0x1933,
+ SMSG_SEND_UNLEARN_SPELLS = 0x0BCB,
SMSG_SERVERTIME = 0xBADD,
SMSG_SERVER_FIRST_ACHIEVEMENT = 0xBADD,
SMSG_SERVER_INFO_RESPONSE = 0xBADD,
SMSG_SERVER_MESSAGE = 0x0683,
SMSG_SERVER_PERF = 0xBADD,
SMSG_SET_AI_ANIM_KIT = 0x0335,
+ SMSG_SET_ALL_TASK_PROGRESS = 0x1B52,
+ SMSG_SET_CURRENCY = 0x17BE,
SMSG_SET_DF_FAST_LAUNCH_RESULT = 0xBADD,
SMSG_SET_FACTION_ATWAR = 0xBADD,
SMSG_SET_FACTION_NOT_VISIBLE = 0xBADD,
@@ -1297,6 +1307,7 @@ enum OpcodeServer : uint32
SMSG_SET_FACTION_VISIBLE = 0x138B,
SMSG_SET_FLAT_SPELL_MODIFIER = 0x1884,
SMSG_SET_FORCED_REACTIONS = 0x09A9,
+ SMSG_SET_MAX_WEEKLY_QUANTITY = 0x1489,
SMSG_SET_MELEE_ANIM_KIT = 0xBADD,
SMSG_SET_MOVEMENT_ANIM_KIT = 0xBADD,
SMSG_SET_PCT_SPELL_MODIFIER = 0x113C,
@@ -1365,6 +1376,7 @@ enum OpcodeServer : uint32
SMSG_SPLINE_MOVE_WATER_WALK = 0xBADD,
SMSG_STABLE_RESULT = 0xBADD,
SMSG_STANDSTATE_UPDATE = 0x1311,
+ SMSG_START_ELAPSED_TIMERS = 0x093F,
SMSG_START_MIRROR_TIMER = 0xBADD,
SMSG_START_TIMER = 0xBADD,
SMSG_STOP_DANCE = 0xBADD,
@@ -1379,11 +1391,11 @@ enum OpcodeServer : uint32
SMSG_TALENTS_ERROR = 0xBADD,
SMSG_TALENTS_INFO = 0x012D,
SMSG_TALENTS_INVOLUNTARILY_RESET = 0xBADD,
- SMSG_TAXINODE_STATUS = 0xBADD,
+ SMSG_TAXINODE_STATUS = 0x0338,
SMSG_TEST_DROP_RATE_RESULT = 0xBADD,
SMSG_TEXT_EMOTE = 0x0383,
SMSG_THREAT_CLEAR = 0xBADD,
- SMSG_THREAT_REMOVE = 0xBADD,
+ SMSG_THREAT_REMOVE = 0x0F3D,
SMSG_THREAT_UPDATE = 0x03A9,
SMSG_TIME_ADJUSTMENT = 0xBADD,
SMSG_TIME_SYNC_REQ = 0x03B1,
@@ -1415,6 +1427,7 @@ enum OpcodeServer : uint32
SMSG_UPDATE_LAST_INSTANCE = 0xBADD,
SMSG_UPDATE_OBJECT = 0x122C,
SMSG_UPDATE_SERVER_PLAYER_POSITION = 0xBADD,
+ SMSG_UPDATE_TASK_PROGRESS = 0x1209,
SMSG_UPDATE_WORLD_STATE = 0x03EC,
SMSG_USERLIST_ADD = 0xBADD,
SMSG_USERLIST_REMOVE = 0xBADD,
@@ -1422,7 +1435,7 @@ enum OpcodeServer : uint32
SMSG_VOICESESSION_FULL = 0xBADD,
SMSG_VOICE_CHAT_STATUS = 0xBADD,
SMSG_VOICE_PARENTAL_CONTROLS = 0xBADD,
- SMSG_VOICE_SESSION_LEAVE = 0xBADD,
+ SMSG_VOICE_SESSION_LEAVE = 0x0403,
SMSG_VOICE_SESSION_ROSTER_UPDATE = 0xBADD,
SMSG_VOICE_SET_TALKER_MUTED = 0xBADD,
SMSG_VOID_ITEM_SWAP_RESPONSE = 0x1131,
@@ -1448,6 +1461,162 @@ enum OpcodeServer : uint32
SMSG_ZONE_UNDER_ATTACK = 0x1401
};
+inline bool IsInstanceOnlyOpcode(uint32 opcode)
+{
+ // TODO: Use names when known
+ switch (opcode)
+ {
+ case 0x000F: // Client
+ case 0x0111: // Client
+ case 0x03E4: // Client
+ case 0x0549: // Client
+ case 0x054C: // Client
+ case 0x055A: // Client
+ case 0x056C: // Client
+ case 0x057A: // Client
+ case 0x057B: // Client
+ case 0x05CC: // Client
+ case 0x05EA: // Client
+ case 0x05EC: // Client
+ case 0x05F9: // Client
+ case 0x05FB: // Client
+ case 0x074C: // Client
+ case 0x075B: // Client
+ case 0x076C: // Client
+ case 0x077B: // Client
+ case 0x077C: // Client
+ case 0x07CC: // Client
+ case 0x07DB: // Client
+ case 0x07EC: // Client
+ case 0x07FB: // Client
+ case 0x07FC: // Client
+ case 0x0827: // Client
+ case 0x0935: // Client
+ case 0x0F0C: // ClientSpell
+ case 0x0F10: // ClientSpell
+ case 0x0F1B: // ClientSpell
+ case 0x0F1C: // ClientSpell
+ case 0x0F20: // ClientSpell
+ case 0x0F2C: // ClientSpell
+ case 0x0F2F: // ClientSpell
+ case 0x0F3B: // ClientSpell
+ case 0x0F8B: // ClientSpell
+ case 0x0F8C: // ClientSpell
+ case 0x0F90: // ClientSpell
+ case 0x0F9F: // ClientSpell
+ case 0x0FA0: // ClientSpell
+ case SMSG_ATTACKSTOP: // Client
+ case 0x14C9: // Client
+ case 0x154A: // Client
+ case 0x155A: // Client
+ case 0x155C: // Client
+ case SMSG_QUESTGIVER_STATUS: // ClientQuest
+ case 0x156A: // Client
+ case 0x156B: // Client
+ case 0x157A: // Client
+ case 0x157B: // Client
+ case 0x15DC: // Client
+ case 0x15EB: // Client
+ case 0x15FB: // Client
+ case 0x170C: // ClientSpell
+ case 0x171C: // ClientSpell
+ case 0x171F: // ClientSpell
+ case 0x172C: // ClientSpell
+ case 0x172F: // ClientSpell
+ case 0x173C: // ClientSpell
+ case 0x173F: // ClientSpell
+ case 0x1740: // ClientSpell
+ case 0x1790: // ClientSpell
+ case 0x179B: // ClientSpell
+ case 0x179F: // ClientSpell
+ case SMSG_ATTACKSTART: // Client
+ case 0x1D82: // ClientQuest
+ case 0x1D83: // ClientQuest
+ case 0x1D85: // ClientQuest
+ case 0x1D87: // ClientQuest
+ case 0x1D93: // ClientQuest
+ case 0x1D96: // ClientQuest
+ case 0x1D97: // ClientQuest
+ case 0x1DA1: // ClientQuest
+ case 0x1DA2: // ClientQuest
+ case 0x1DA3: // ClientQuest
+ case 0x1DA4: // ClientQuest
+ case 0x1DA5: // ClientQuest
+ case 0x1DA7: // ClientQuest
+ case SMSG_QUERY_TIME_RESPONSE: // Client
+ case 0x1DC2: // ClientQuest
+ case 0x1DC6: // ClientQuest
+ case 0x1DC7: // ClientQuest
+ case 0x1DD2: // ClientQuest
+ case 0x1DD3: // ClientQuest
+ case 0x1DD6: // ClientQuest
+ case 0x1DD7: // ClientQuest
+ case 0x1DD8: // ClientQuest
+ case 0x1DE4: // ClientQuest
+ case 0x1DE5: // ClientQuest
+ case 0x1DE7: // ClientQuest
+ case 0x1F02: // ClientQuest
+ case 0x1F06: // ClientQuest
+ case 0x1F07: // ClientQuest
+ case 0x1F0C: // ClientSpell
+ case 0x1F12: // ClientQuest
+ case 0x1F13: // ClientQuest
+ case 0x1F16: // ClientQuest
+ case 0x1F17: // ClientQuest
+ case 0x1F18: // ClientQuest
+ case 0x1F1C: // ClientSpell
+ case 0x1F1F: // ClientSpell
+ case 0x1F24: // ClientQuest
+ case 0x1F25: // ClientQuest
+ case 0x1F27: // ClientQuest
+ case 0x1F2C: // ClientSpell
+ case 0x1F2F: // ClientSpell
+ case 0x1F3C: // ClientSpell
+ case 0x1F3F: // ClientSpell
+ case 0x1F40: // ClientSpell
+ case 0x1F44: // ClientQuest
+ case 0x1F48: // ClientQuest
+ case 0x1F51: // ClientQuest
+ case 0x1F55: // ClientQuest
+ case 0x1F57: // ClientQuest
+ case 0x1F61: // ClientQuest
+ case 0x1F63: // ClientQuest
+ case 0x1F64: // ClientQuest
+ case 0x1F65: // ClientQuest
+ case 0x1F67: // ClientQuest
+ case 0x1F85: // ClientQuest
+ case 0x1F86: // ClientQuest
+ case 0x1F87: // ClientQuest
+ case 0x1F90: // ClientSpell
+ case 0x1F92: // ClientQuest
+ case 0x1F94: // ClientQuest
+ case 0x1F96: // ClientQuest
+ case 0x1F97: // ClientQuest
+ case 0x1F9B: // ClientSpell
+ case 0x1F9F: // ClientSpell
+ case 0x1FA1: // ClientQuest
+ case 0x1FA2: // ClientQuest
+ case 0x1FA3: // ClientQuest
+ case 0x1FA4: // ClientQuest
+ case 0x1FA5: // ClientQuest
+ case 0x1FA7: // ClientQuest
+ case 0x1FC2: // ClientQuest
+ case 0x1FC6: // ClientQuest
+ case 0x1FC7: // ClientQuest
+ case 0x1FD2: // ClientQuest
+ case 0x1FD3: // ClientQuest
+ case 0x1FD6: // ClientQuest
+ case 0x1FD7: // ClientQuest
+ case 0x1FD8: // ClientQuest
+ case 0x1FE4: // ClientQuest
+ case 0x1FE5: // ClientQuest
+ case 0x1FE7: // ClientQuest
+ return true;
+ default:
+ return false;
+ }
+}
+
/// Player state
enum SessionStatus
{
@@ -1479,18 +1648,33 @@ class WorldSession;
class OpcodeHandler
{
public:
- OpcodeHandler(char const* _name, SessionStatus _status, PacketProcessing _processing)
- : Name(_name), Status(_status), ProcessingPlace(_processing) { }
-
+ OpcodeHandler(char const* name, SessionStatus status) : Name(name), Status(status) { }
virtual ~OpcodeHandler() { }
- virtual void Call(WorldSession* session, WorldPacket& packet) const = 0;
-
char const* Name;
SessionStatus Status;
+};
+
+class ClientOpcodeHandler : public OpcodeHandler
+{
+public:
+ ClientOpcodeHandler(char const* name, SessionStatus status, PacketProcessing processing)
+ : OpcodeHandler(name, status), ProcessingPlace(processing) { }
+
+ virtual void Call(WorldSession* session, WorldPacket& packet) const = 0;
+
PacketProcessing ProcessingPlace;
};
+class ServerOpcodeHandler : public OpcodeHandler
+{
+public:
+ ServerOpcodeHandler(char const* name, SessionStatus status, ConnectionType conIdx)
+ : OpcodeHandler(name, status), ConnectionIndex(conIdx) { }
+
+ ConnectionType ConnectionIndex;
+};
+
class OpcodeTable
{
public:
@@ -1514,24 +1698,24 @@ class OpcodeTable
void Initialize();
- OpcodeHandler const* operator[](OpcodeClient index) const
+ ClientOpcodeHandler const* operator[](OpcodeClient index) const
{
return _internalTableClient[index];
}
- OpcodeHandler const* operator[](OpcodeServer index) const
+ ServerOpcodeHandler const* operator[](OpcodeServer index) const
{
return _internalTableServer[index];
}
private:
template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)>
- void ValidateAndSetOpcode(OpcodeClient opcode, char const* name, SessionStatus status, PacketProcessing processing);
+ void ValidateAndSetClientOpcode(OpcodeClient opcode, char const* name, SessionStatus status, PacketProcessing processing);
- void ValidateAndSetOpcode(OpcodeServer opcode, char const* name, SessionStatus status);
+ void ValidateAndSetServerOpcode(OpcodeServer opcode, char const* name, SessionStatus status, ConnectionType conIdx);
- OpcodeHandler* _internalTableClient[NUM_OPCODE_HANDLERS];
- OpcodeHandler* _internalTableServer[NUM_OPCODE_HANDLERS];
+ ClientOpcodeHandler* _internalTableClient[NUM_OPCODE_HANDLERS];
+ ServerOpcodeHandler* _internalTableServer[NUM_OPCODE_HANDLERS];
};
extern OpcodeTable opcodeTable;
diff --git a/src/server/game/Server/WorldPacket.h b/src/server/game/Server/WorldPacket.h
index 65b2f6fcae1..270f2598553 100644
--- a/src/server/game/Server/WorldPacket.h
+++ b/src/server/game/Server/WorldPacket.h
@@ -27,11 +27,11 @@ class WorldPacket : public ByteBuffer
{
public:
// just container for later use
- WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE), _connection(CONNECTION_TYPE_REALM)
+ WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE), _connection(CONNECTION_TYPE_DEFAULT)
{
}
- WorldPacket(uint32 opcode, size_t res = 200, ConnectionType connection = CONNECTION_TYPE_REALM) : ByteBuffer(res),
+ WorldPacket(uint32 opcode, size_t res = 200, ConnectionType connection = CONNECTION_TYPE_DEFAULT) : ByteBuffer(res),
m_opcode(opcode), _connection(connection) { }
WorldPacket(WorldPacket&& packet) : ByteBuffer(std::move(packet)), m_opcode(packet.m_opcode), _connection(packet._connection)
@@ -56,7 +56,7 @@ class WorldPacket : public ByteBuffer
WorldPacket(uint32 opcode, MessageBuffer&& buffer, ConnectionType connection) : ByteBuffer(std::move(buffer)), m_opcode(opcode), _connection(connection) { }
- void Initialize(uint32 opcode, size_t newres = 200, ConnectionType connection = CONNECTION_TYPE_REALM)
+ void Initialize(uint32 opcode, size_t newres = 200, ConnectionType connection = CONNECTION_TYPE_DEFAULT)
{
clear();
_storage.reserve(newres);
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 18fe28344b0..3a9f5e70204 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -60,7 +60,7 @@ std::string const DefaultPlayerName = "<none>";
bool MapSessionFilter::Process(WorldPacket* packet)
{
- OpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
+ ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
//let's check if our opcode can be really processed in Map::Update()
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
@@ -82,7 +82,8 @@ bool MapSessionFilter::Process(WorldPacket* packet)
//OR packet handler is not thread-safe!
bool WorldSessionFilter::Process(WorldPacket* packet)
{
- OpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
+ ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
+
//check if packet handler is supposed to be safe
if (opHandle->ProcessingPlace == PROCESS_INPLACE)
return true;
@@ -121,7 +122,7 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr
m_sessionDbLocaleIndex(locale),
m_latency(0),
m_clientTimeDelay(0),
- m_TutorialsChanged(false),
+ _tutorialsChanged(false),
_filterAddonMessages(false),
recruiterId(recruiter),
isRecruiter(isARecruiter),
@@ -130,7 +131,7 @@ WorldSession::WorldSession(uint32 id, uint32 battlenetAccountId, std::shared_ptr
forceExit(false),
m_currentBankerGUID()
{
- memset(m_Tutorials, 0, sizeof(m_Tutorials));
+ memset(_tutorials, 0, sizeof(_tutorials));
if (sock)
{
@@ -193,9 +194,6 @@ std::string WorldSession::GetPlayerInfo() const
/// Send a packet to the client
void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
{
- if (!m_Socket[packet->GetConnection()])
- return;
-
if (packet->GetOpcode() == NULL_OPCODE)
{
TC_LOG_ERROR("network.opcode", "Prevented sending of NULL_OPCODE to %s", GetPlayerInfo().c_str());
@@ -207,10 +205,38 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
return;
}
+ ServerOpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
+
+ if (!handler)
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending of opcode %u with non existing handler to %s", packet->GetOpcode(), GetPlayerInfo().c_str());
+ return;
+ }
+
+ // Default connection index defined in Opcodes.cpp table
+ ConnectionType conIdx = handler->ConnectionIndex;
+
+ // Override connection index
+ if (packet->GetConnection() != CONNECTION_TYPE_DEFAULT)
+ {
+ if (packet->GetConnection() != CONNECTION_TYPE_INSTANCE && IsInstanceOnlyOpcode(packet->GetOpcode()))
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending of instance only opcode %u with connection type %u to %s", packet->GetOpcode(), packet->GetConnection(), GetPlayerInfo().c_str());
+ return;
+ }
+
+ conIdx = packet->GetConnection();
+ }
+
+ if (!m_Socket[conIdx])
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending of %s to non existent socket %u to %s", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())).c_str(), conIdx, GetPlayerInfo().c_str());
+ return;
+ }
+
if (!forced)
{
- OpcodeHandler const* handler = opcodeTable[static_cast<OpcodeServer>(packet->GetOpcode())];
- if (!handler || handler->Status == STATUS_UNHANDLED)
+ if (handler->Status == STATUS_UNHANDLED)
{
TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(static_cast<OpcodeServer>(packet->GetOpcode())).c_str(), GetPlayerInfo().c_str());
return;
@@ -253,7 +279,7 @@ void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/
sScriptMgr->OnPacketSend(this, *packet);
- m_Socket[packet->GetConnection()]->SendPacket(*packet);
+ m_Socket[conIdx]->SendPacket(*packet);
}
/// Add an incoming packet to the queue
@@ -311,7 +337,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
if (!AntiDOS.EvaluateOpcode(*packet, currentTime))
KickPlayer();
- OpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
+ ClientOpcodeHandler const* opHandle = opcodeTable[static_cast<OpcodeClient>(packet->GetOpcode())];
try
{
switch (opHandle->Status)
@@ -695,7 +721,7 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask)
{
for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i)
if (mask & (1 << i))
- m_accountData[i] = AccountData();
+ _accountData[i] = AccountData();
if (!result)
return;
@@ -718,20 +744,20 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask)
continue;
}
- m_accountData[type].Time = time_t(fields[1].GetUInt32());
- m_accountData[type].Data = fields[2].GetString();
+ _accountData[type].Time = time_t(fields[1].GetUInt32());
+ _accountData[type].Data = fields[2].GetString();
}
while (result->NextRow());
}
-void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data)
+void WorldSession::SetAccountData(AccountDataType type, uint32 time, std::string const& data)
{
if ((1 << type) & GLOBAL_CACHE_MASK)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_ACCOUNT_DATA);
stmt->setUInt32(0, GetAccountId());
stmt->setUInt8(1, type);
- stmt->setUInt32(2, uint32(tm));
+ stmt->setUInt32(2, time);
stmt->setString(3, data);
CharacterDatabase.Execute(stmt);
}
@@ -744,38 +770,38 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string c
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_PLAYER_ACCOUNT_DATA);
stmt->setUInt64(0, m_GUIDLow);
stmt->setUInt8(1, type);
- stmt->setUInt32(2, uint32(tm));
+ stmt->setUInt32(2, time);
stmt->setString(3, data);
CharacterDatabase.Execute(stmt);
}
- m_accountData[type].Time = tm;
- m_accountData[type].Data = data;
+ _accountData[type].Time = time_t(time);
+ _accountData[type].Data = data;
}
void WorldSession::LoadTutorialsData()
{
- memset(m_Tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
+ memset(_tutorials, 0, sizeof(uint32) * MAX_ACCOUNT_TUTORIAL_VALUES);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_TUTORIALS);
stmt->setUInt32(0, GetAccountId());
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
- m_Tutorials[i] = (*result)[i].GetUInt32();
+ _tutorials[i] = (*result)[i].GetUInt32();
- m_TutorialsChanged = false;
+ _tutorialsChanged = false;
}
void WorldSession::SendTutorialsData()
{
WorldPackets::Misc::TutorialFlags packet;
- memcpy(packet.TutorialData, m_Tutorials, sizeof(packet.TutorialData));
+ memcpy(packet.TutorialData, _tutorials, sizeof(_tutorials));
SendPacket(packet.Write());
}
-void WorldSession::SaveTutorialsData(SQLTransaction &trans)
+void WorldSession::SaveTutorialsData(SQLTransaction& trans)
{
- if (!m_TutorialsChanged)
+ if (!_tutorialsChanged)
return;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_HAS_TUTORIALS);
@@ -784,11 +810,11 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
// Modify data in DB
stmt = CharacterDatabase.GetPreparedStatement(hasTutorials ? CHAR_UPD_TUTORIALS : CHAR_INS_TUTORIALS);
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
- stmt->setUInt32(i, m_Tutorials[i]);
+ stmt->setUInt32(i, _tutorials[i]);
stmt->setUInt32(MAX_ACCOUNT_TUTORIAL_VALUES, GetAccountId());
trans->Append(stmt);
- m_TutorialsChanged = false;
+ _tutorialsChanged = false;
}
void WorldSession::ReadAddonsInfo(ByteBuffer& data)
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index b508acb604e..b95b3ce4330 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -102,20 +102,52 @@ namespace WorldPackets
class UserClientUpdateAccountData;
}
+ namespace Channel
+ {
+ class ChannelListRequest;
+ class JoinChannel;
+ class LeaveChannel;
+ }
+
+ namespace Chat
+ {
+ class ChatMessage;
+ class ChatMessageWhisper;
+ class ChatMessageChannel;
+ class ChatAddonMessage;
+ class ChatAddonMessageWhisper;
+ class ChatMessageAFK;
+ class ChatMessageDND;
+ class ChatMessageEmote;
+ class CTextEmote;
+ }
+
namespace Combat
{
class AttackSwing;
class AttackStop;
}
+ namespace EquipmentSet
+ {
+ class SaveEquipmentSet;
+ }
+
namespace Guild
{
class QueryGuildInfo;
}
-
+
+ namespace Spells
+ {
+ class SpellCastRequest;
+ class SetActionButton;
+ }
+
namespace Talent
{
class SetSpecialization;
+ class LearnTalent;
}
namespace Trade
@@ -125,8 +157,22 @@ namespace WorldPackets
namespace Misc
{
+ class SetSelection;
class ViolenceLevel;
class TimeSyncResponse;
+ class TutorialSetFlag;
+ }
+
+ namespace Movement
+ {
+ class ClientPlayerMovement;
+ class WorldPortAck;
+ class MoveTeleportAck;
+ }
+
+ namespace NPC
+ {
+ class Hello;
}
namespace Query
@@ -134,11 +180,14 @@ namespace WorldPackets
class QueryCreature;
class QueryPlayerName;
class QueryPageText;
+ class QueryNPCText;
+ class DBQueryBulk;
}
- namespace Movement
+ namespace Quest
{
- class ClientPlayerMovement;
+ class QuestGiverStatusQuery;
+ class QuestGiverStatusMultipleQuery;
}
}
@@ -161,6 +210,41 @@ enum AccountDataType
#define REGISTERED_ADDON_PREFIX_SOFTCAP 64
+enum TutorialAction
+{
+ TUTORIAL_ACTION_UPDATE = 0,
+ TUTORIAL_ACTION_CLEAR = 1,
+ TUTORIAL_ACTION_RESET = 2
+};
+
+/*
+enum Tutorials
+{
+ TUTORIAL_TALENT = 0,
+ TUTORIAL_SPEC = 1,
+ TUTORIAL_GLYPH = 2,
+ TUTORIAL_SPELLBOOK = 3,
+ TUTORIAL_PROFESSIONS = 4,
+ TUTORIAL_CORE_ABILITITES = 5,
+ TUTORIAL_PET_JOURNAL = 6,
+ TUTORIAL_WHAT_HAS_CHANGED = 7,
+ TUTORIAL_GARRISON_BUILDING = 8,
+ TUTORIAL_GARRISON_MISSION_LIST = 9,
+ TUTORIAL_GARRISON_MISSION_PAGE = 10,
+ TUTORIAL_GARRISON_LANDING = 11,
+ TUTORIAL_GARRISON_ZONE_ABILITY = 12,
+ TUTORIAL_WORLD_MAP_FRAME = 13,
+ TUTORIAL_CLEAN_UP_BAGS = 14,
+ TUTORIAL_BAG_SETTINGS = 15,
+ TUTORIAL_REAGENT_BANK_UNLOCK = 16,
+ TUTORIAL_TOYBOX_FAVORITE = 17,
+ TUTORIAL_TOYBOX_MOUSEWHEEL_PAGING = 18,
+ TUTORIAL_LFG_LIST = 19
+};
+*/
+
+#define MAX_ACCOUNT_TUTORIAL_VALUES 8
+
struct AccountData
{
time_t Time = 0;
@@ -302,7 +386,9 @@ class WorldSession
AccountTypes GetSecurity() const { return _security; }
uint32 GetAccountId() const { return _accountId; }
+ ObjectGuid GetAccountGUID() const { return ObjectGuid::Create<HighGuid::WowAccount>(GetAccountId()); }
uint32 GetBattlenetAccountId() const { return _battlenetAccountId; }
+ ObjectGuid GetBattlenetAccountGUID() const { return ObjectGuid::Create<HighGuid::BNetAccount>(GetBattlenetAccountId()); }
Player* GetPlayer() const { return _player; }
std::string const& GetPlayerName() const;
std::string GetPlayerInfo() const;
@@ -377,21 +463,21 @@ class WorldSession
bool CheckStableMaster(ObjectGuid guid);
// Account Data
- AccountData const* GetAccountData(AccountDataType type) const { return &m_accountData[type]; }
- void SetAccountData(AccountDataType type, time_t tm, std::string const& data);
+ AccountData const* GetAccountData(AccountDataType type) const { return &_accountData[type]; }
+ void SetAccountData(AccountDataType type, uint32 time, std::string const& data);
void LoadGlobalAccountData();
void LoadAccountData(PreparedQueryResult result, uint32 mask);
void LoadTutorialsData();
void SendTutorialsData();
void SaveTutorialsData(SQLTransaction& trans);
- uint32 GetTutorialInt(uint8 index) const { return m_Tutorials[index]; }
+ uint32 GetTutorialInt(uint8 index) const { return _tutorials[index]; }
void SetTutorialInt(uint8 index, uint32 value)
{
- if (m_Tutorials[index] != value)
+ if (_tutorials[index] != value)
{
- m_Tutorials[index] = value;
- m_TutorialsChanged = true;
+ _tutorials[index] = value;
+ _tutorialsChanged = true;
}
}
//used with item_page table
@@ -547,7 +633,7 @@ class WorldSession
// Knockback
void HandleMoveKnockBackAck(WorldPacket& recvPacket);
- void HandleMoveTeleportAck(WorldPacket& recvPacket);
+ void HandleMoveTeleportAck(WorldPackets::Movement::MoveTeleportAck& packet);
void HandleForceSpeedChangeAck(WorldPacket& recvData);
void HandleSetCollisionHeightAck(WorldPacket& recvPacket);
@@ -575,7 +661,7 @@ class WorldSession
void HandleTogglePvP(WorldPacket& recvPacket);
void HandleZoneUpdateOpcode(WorldPacket& recvPacket);
- void HandleSetSelectionOpcode(WorldPacket& recvPacket);
+ void HandleSetSelectionOpcode(WorldPackets::Misc::SetSelection& packet);
void HandleStandStateChangeOpcode(WorldPacket& recvPacket);
void HandleEmoteOpcode(WorldPacket& recvPacket);
void HandleContactListOpcode(WorldPacket& recvPacket);
@@ -597,21 +683,20 @@ class WorldSession
void HandleUpdateAccountData(WorldPackets::ClientConfig::UserClientUpdateAccountData& packet);
void HandleRequestAccountData(WorldPackets::ClientConfig::RequestAccountData& request);
- void HandleSetActionButtonOpcode(WorldPacket& recvPacket);
+ void HandleSetActionButtonOpcode(WorldPackets::Spells::SetActionButton& packet);
void HandleGameObjectUseOpcode(WorldPacket& recPacket);
void HandleMeetingStoneInfo(WorldPacket& recPacket);
void HandleGameobjectReportUse(WorldPacket& recvPacket);
void HandleNameQueryOpcode(WorldPackets::Query::QueryPlayerName& packet);
-
void HandleQueryTimeOpcode(WorldPacket& recvPacket);
-
void HandleCreatureQuery(WorldPackets::Query::QueryCreature& packet);
+ void HandleDBQueryBulk(WorldPackets::Query::DBQueryBulk& packet);
void HandleGameObjectQueryOpcode(WorldPacket& recvPacket);
- void HandleMoveWorldportAckOpcode(WorldPacket& recvPacket);
+ void HandleMoveWorldportAckOpcode(WorldPackets::Movement::WorldPortAck& packet);
void HandleMoveWorldportAckOpcode(); // for server-side calls
void HandleMovementOpcodes(WorldPackets::Movement::ClientPlayerMovement& packet);
@@ -706,16 +791,16 @@ class WorldSession
void SendActivateTaxiReply(ActivateTaxiReply reply);
void HandleTabardVendorActivateOpcode(WorldPacket& recvPacket);
- void HandleBankerActivateOpcode(WorldPacket& recvPacket);
+ void HandleBankerActivateOpcode(WorldPackets::NPC::Hello& packet);
void HandleBuyBankSlotOpcode(WorldPacket& recvPacket);
- void HandleTrainerListOpcode(WorldPacket& recvPacket);
+ void HandleTrainerListOpcode(WorldPackets::NPC::Hello& packet);
void HandleTrainerBuySpellOpcode(WorldPacket& recvPacket);
void HandlePetitionShowListOpcode(WorldPacket& recvPacket);
- void HandleGossipHelloOpcode(WorldPacket& recvPacket);
+ void HandleGossipHelloOpcode(WorldPackets::NPC::Hello& packet);
void HandleGossipSelectOptionOpcode(WorldPacket& recvPacket);
void HandleSpiritHealerActivateOpcode(WorldPacket& recvPacket);
- void HandleNpcTextQueryOpcode(WorldPacket& recvPacket);
- void HandleBinderActivateOpcode(WorldPacket& recvPacket);
+ void HandleNpcTextQueryOpcode(WorldPackets::Query::QueryNPCText& packet);
+ void HandleBinderActivateOpcode(WorldPackets::NPC::Hello& packet);
void HandleListStabledPetsOpcode(WorldPacket& recvPacket);
void HandleStablePet(WorldPacket& recvPacket);
void HandleStablePetCallback(PreparedQueryResult result);
@@ -770,7 +855,7 @@ class WorldSession
void HandleSellItemOpcode(WorldPacket& recvPacket);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPacket& recvPacket);
- void HandleListInventoryOpcode(WorldPacket& recvPacket);
+ void HandleListInventoryOpcode(WorldPackets::NPC::Hello& packet);
void HandleAutoStoreBagItemOpcode(WorldPacket& recvPacket);
void HandleReadItem(WorldPacket& recvPacket);
void HandleAutoEquipItemSlotOpcode(WorldPacket& recvPacket);
@@ -786,20 +871,20 @@ class WorldSession
void HandleUseItemOpcode(WorldPacket& recvPacket);
void HandleOpenItemOpcode(WorldPacket& recvPacket);
- void HandleCastSpellOpcode(WorldPacket& recvPacket);
+ void HandleCastSpellOpcode(WorldPackets::Spells::SpellCastRequest& castRequest);
void HandleCancelCastOpcode(WorldPacket& recvPacket);
void HandleCancelAuraOpcode(WorldPacket& recvPacket);
void HandleCancelGrowthAuraOpcode(WorldPacket& recvPacket);
void HandleCancelAutoRepeatSpellOpcode(WorldPacket& recvPacket);
- void HandleLearnTalentOpcode(WorldPacket& recvPacket);
+ void HandleLearnTalentOpcode(WorldPackets::Talent::LearnTalent& packet);
void HandleLearnPreviewTalents(WorldPacket& recvPacket);
void HandleTalentWipeConfirmOpcode(WorldPacket& recvPacket);
void HandleUnlearnSkillOpcode(WorldPacket& recvPacket);
void HandleSetSpecializationOpcode(WorldPackets::Talent::SetSpecialization& packet);
- void HandleQuestgiverStatusQueryOpcode(WorldPacket& recvPacket);
- void HandleQuestgiverStatusMultipleQuery(WorldPacket& recvPacket);
+ void HandleQuestgiverStatusQueryOpcode(WorldPackets::Quest::QuestGiverStatusQuery& packet);
+ void HandleQuestgiverStatusMultipleQuery(WorldPackets::Quest::QuestGiverStatusMultipleQuery& packet);
void HandleQuestgiverHelloOpcode(WorldPacket& recvPacket);
void HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvPacket);
void HandleQuestgiverQueryQuestOpcode(WorldPacket& recvPacket);
@@ -815,13 +900,21 @@ class WorldSession
void HandlePushQuestToParty(WorldPacket& recvPacket);
void HandleQuestPushResult(WorldPacket& recvPacket);
- void HandleMessagechatOpcode(WorldPacket& recvPacket);
- void HandleAddonMessagechatOpcode(WorldPacket& recvPacket);
+ void HandleChatMessageOpcode(WorldPackets::Chat::ChatMessage& packet);
+ void HandleChatMessageWhisperOpcode(WorldPackets::Chat::ChatMessageWhisper& packet);
+ void HandleChatMessageChannelOpcode(WorldPackets::Chat::ChatMessageChannel& packet);
+ void HandleChatMessage(ChatMsg type, uint32 lang, std::string msg, std::string target = "");
+ void HandleChatAddonMessageOpcode(WorldPackets::Chat::ChatAddonMessage& packet);
+ void HandleChatAddonMessageWhisperOpcode(WorldPackets::Chat::ChatAddonMessageWhisper& packet);
+ void HandleChatAddonMessage(ChatMsg type, std::string prefix, std::string text, std::string target = "");
+ void HandleChatMessageAFKOpcode(WorldPackets::Chat::ChatMessageAFK& packet);
+ void HandleChatMessageDNDOpcode(WorldPackets::Chat::ChatMessageDND& packet);
+ void HandleChatMessageEmoteOpcode(WorldPackets::Chat::ChatMessageEmote& packet);
void SendPlayerNotFoundNotice(std::string const& name);
void SendPlayerAmbiguousNotice(std::string const& name);
void SendWrongFactionNotice();
void SendChatRestrictedNotice(ChatRestrictionType restriction);
- void HandleTextEmoteOpcode(WorldPacket& recvPacket);
+ void HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet);
void HandleChatIgnoredOpcode(WorldPacket& recvPacket);
void HandleUnregisterAddonPrefixesOpcode(WorldPacket& recvPacket);
@@ -833,9 +926,9 @@ class WorldSession
void HandleResurrectResponseOpcode(WorldPacket& recvPacket);
void HandleSummonResponseOpcode(WorldPacket& recvData);
- void HandleJoinChannel(WorldPacket& recvPacket);
- void HandleLeaveChannel(WorldPacket& recvPacket);
- void HandleChannelList(WorldPacket& recvPacket);
+ void HandleJoinChannel(WorldPackets::Channel::JoinChannel& packet);
+ void HandleLeaveChannel(WorldPackets::Channel::LeaveChannel& packet);
+ void HandleChannelList(WorldPackets::Channel::ChannelListRequest& packet);
void HandleChannelPassword(WorldPacket& recvPacket);
void HandleChannelSetOwner(WorldPacket& recvPacket);
void HandleChannelOwner(WorldPacket& recvPacket);
@@ -850,7 +943,6 @@ class WorldSession
void HandleChannelAnnouncements(WorldPacket& recvPacket);
void HandleChannelModerate(WorldPacket& recvPacket);
void HandleChannelDeclineInvite(WorldPacket& recvPacket);
- void HandleChannelDisplayListQuery(WorldPacket& recvPacket);
void HandleGetChannelMemberCount(WorldPacket& recvPacket);
void HandleSetChannelWatch(WorldPacket& recvPacket);
@@ -859,9 +951,7 @@ class WorldSession
void HandlePageTextQueryOpcode(WorldPackets::Query::QueryPageText& packet);
- void HandleTutorialFlag (WorldPacket& recvData);
- void HandleTutorialClear(WorldPacket& recvData);
- void HandleTutorialReset(WorldPacket& recvData);
+ void HandleTutorialFlag(WorldPackets::Misc::TutorialSetFlag& packet);
//Pet
void HandlePetAction(WorldPacket& recvData);
@@ -873,7 +963,7 @@ class WorldSession
void HandlePetRename(WorldPacket& recvData);
void HandlePetCancelAuraOpcode(WorldPacket& recvPacket);
void HandlePetSpellAutocastOpcode(WorldPacket& recvPacket);
- void HandlePetCastSpellOpcode(WorldPacket& recvPacket);
+ void HandlePetCastSpellOpcode(WorldPackets::Spells::SpellCastRequest& castRequest);
void HandlePetLearnTalent(WorldPacket& recvPacket);
void HandleLearnPreviewTalentsPet(WorldPacket& recvPacket);
@@ -1046,7 +1136,7 @@ class WorldSession
void HandleRemoveGlyph(WorldPacket& recvData);
void HandleQueryInspectAchievements(WorldPacket& recvData);
void HandleGuildAchievementProgressQuery(WorldPacket& recvData);
- void HandleEquipmentSetSave(WorldPacket& recvData);
+ void HandleEquipmentSetSave(WorldPackets::EquipmentSet::SaveEquipmentSet& packet);
void HandleEquipmentSetDelete(WorldPacket& recvData);
void HandleEquipmentSetUse(WorldPacket& recvData);
void HandleWorldStateUITimerUpdate(WorldPacket& recvData);
@@ -1056,7 +1146,6 @@ class WorldSession
void HandleEjectPassenger(WorldPacket& data);
void HandleEnterPlayerVehicle(WorldPacket& data);
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
- void HandleRequestHotfix(WorldPacket& recvPacket);
void HandleUpdateMissileTrajectory(WorldPacket& recvPacket);
void HandleViolenceLevel(WorldPackets::Misc::ViolenceLevel& violenceLevel);
void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket);
@@ -1141,7 +1230,7 @@ class WorldSession
ObjectGuid::LowType m_GUIDLow; // set logined or recently logout player (while m_playerRecentlyLogout set)
Player* _player;
- std::shared_ptr<WorldSocket> m_Socket[2];
+ std::shared_ptr<WorldSocket> m_Socket[MAX_CONNECTION_TYPES];
std::string m_Address; // Current Remote Address
// std::string m_LAddress; // Last Attempted Remote Adress - we can not set attempted ip for a non-existing session!
@@ -1165,9 +1254,9 @@ class WorldSession
LocaleConstant m_sessionDbLocaleIndex;
std::atomic<uint32> m_latency;
std::atomic<uint32> m_clientTimeDelay;
- AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];
- uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
- bool m_TutorialsChanged;
+ AccountData _accountData[NUM_ACCOUNT_DATA_TYPES];
+ uint32 _tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
+ bool _tutorialsChanged;
AddonsList m_addonsList;
std::vector<std::string> _registeredAddonPrefixes;
bool _filterAddonMessages;
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index aa1426d5fd2..7f4b2cc906e 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -55,8 +55,8 @@ uint32 const SizeOfClientHeader[2][2] =
uint32 const SizeOfServerHeader[2] = { sizeof(uint16) + sizeof(uint32), sizeof(uint32) };
WorldSocket::WorldSocket(tcp::socket&& socket) : Socket(std::move(socket)),
- _type(CONNECTION_TYPE_REALM), _authSeed(rand32()),
- _OverSpeedPings(0), _worldSession(nullptr), _initialized(false)
+ _type(CONNECTION_TYPE_REALM), _authSeed(rand32()), _OverSpeedPings(0),
+ _worldSession(nullptr), _compressionStream(nullptr), _initialized(false)
{
_headerBuffer.Resize(SizeOfClientHeader[0][0]);
}
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index 628e4e0721d..e75a3424c2f 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -23,14 +23,12 @@
enum AURA_FLAGS
{
AFLAG_NONE = 0x00,
- AFLAG_EFF_INDEX_0 = 0x01,
- AFLAG_EFF_INDEX_1 = 0x02,
- AFLAG_EFF_INDEX_2 = 0x04,
- AFLAG_CASTER = 0x08,
- AFLAG_POSITIVE = 0x10,
- AFLAG_DURATION = 0x20,
- AFLAG_ANY_EFFECT_AMOUNT_SENT = 0x40, // used with AFLAG_EFF_INDEX_0/1/2
- AFLAG_NEGATIVE = 0x80
+ AFLAG_NOCASTER = 0x01,
+ AFLAG_POSITIVE = 0x02,
+ AFLAG_DURATION = 0x04,
+ AFLAG_SCALABLE = 0x08,
+ AFLAG_NEGATIVE = 0x10,
+ AFLAG_UNK20 = 0x20
};
// these are modes, in which aura effect handler may be called
@@ -430,7 +428,114 @@ enum AuraType
SPELL_AURA_368 = 368, // Not used in 4.3.4
SPELL_AURA_ENABLE_POWER_BAR_TIMER = 369,
SPELL_AURA_SET_FAIR_FAR_CLIP = 370, // Overrides client's View Distance setting to max("Fair", current_setting)
- TOTAL_AURAS = 371 // 4.3.4
+ SPELL_AURA_371 = 371,
+ SPELL_AURA_372 = 372,
+ SPELL_AURA_373 = 373,
+ SPELL_AURA_374 = 374,
+ SPELL_AURA_375 = 375,
+ SPELL_AURA_376 = 376,
+ SPELL_AURA_377 = 377,
+ SPELL_AURA_378 = 378,
+ SPELL_AURA_379 = 379,
+ SPELL_AURA_380 = 380,
+ SPELL_AURA_381 = 381,
+ SPELL_AURA_382 = 382,
+ SPELL_AURA_383 = 383,
+ SPELL_AURA_384 = 384,
+ SPELL_AURA_385 = 385,
+ SPELL_AURA_386 = 386,
+ SPELL_AURA_387 = 387,
+ SPELL_AURA_388 = 388,
+ SPELL_AURA_389 = 389,
+ SPELL_AURA_390 = 390,
+ SPELL_AURA_391 = 391,
+ SPELL_AURA_392 = 392,
+ SPELL_AURA_393 = 393,
+ SPELL_AURA_394 = 394,
+ SPELL_AURA_395 = 395,
+ SPELL_AURA_396 = 396,
+ SPELL_AURA_397 = 397,
+ SPELL_AURA_398 = 398,
+ SPELL_AURA_399 = 399,
+ SPELL_AURA_400 = 400,
+ SPELL_AURA_401 = 401,
+ SPELL_AURA_402 = 402,
+ SPELL_AURA_403 = 403,
+ SPELL_AURA_404 = 404,
+ SPELL_AURA_405 = 405,
+ SPELL_AURA_406 = 406,
+ SPELL_AURA_407 = 407,
+ SPELL_AURA_408 = 408,
+ SPELL_AURA_409 = 409,
+ SPELL_AURA_410 = 410,
+ SPELL_AURA_411 = 411,
+ SPELL_AURA_412 = 412,
+ SPELL_AURA_413 = 413,
+ SPELL_AURA_414 = 414,
+ SPELL_AURA_415 = 415,
+ SPELL_AURA_416 = 416,
+ SPELL_AURA_417 = 417,
+ SPELL_AURA_418 = 418,
+ SPELL_AURA_419 = 419,
+ SPELL_AURA_420 = 420,
+ SPELL_AURA_421 = 421,
+ SPELL_AURA_422 = 422,
+ SPELL_AURA_423 = 423,
+ SPELL_AURA_424 = 424,
+ SPELL_AURA_425 = 425,
+ SPELL_AURA_426 = 426,
+ SPELL_AURA_427 = 427,
+ SPELL_AURA_428 = 428,
+ SPELL_AURA_429 = 429,
+ SPELL_AURA_430 = 430,
+ SPELL_AURA_431 = 431,
+ SPELL_AURA_432 = 432,
+ SPELL_AURA_433 = 433,
+ SPELL_AURA_434 = 434,
+ SPELL_AURA_435 = 435,
+ SPELL_AURA_436 = 436,
+ SPELL_AURA_437 = 437,
+ SPELL_AURA_438 = 438,
+ SPELL_AURA_439 = 439,
+ SPELL_AURA_440 = 440,
+ SPELL_AURA_441 = 441,
+ SPELL_AURA_442 = 442,
+ SPELL_AURA_443 = 443,
+ SPELL_AURA_444 = 444,
+ SPELL_AURA_445 = 445,
+ SPELL_AURA_446 = 446,
+ SPELL_AURA_447 = 447,
+ SPELL_AURA_448 = 448,
+ SPELL_AURA_449 = 449,
+ SPELL_AURA_450 = 450,
+ SPELL_AURA_451 = 451,
+ SPELL_AURA_452 = 452,
+ SPELL_AURA_453 = 453,
+ SPELL_AURA_454 = 454,
+ SPELL_AURA_455 = 455,
+ SPELL_AURA_456 = 456,
+ SPELL_AURA_457 = 457,
+ SPELL_AURA_458 = 458,
+ SPELL_AURA_459 = 459,
+ SPELL_AURA_460 = 460,
+ SPELL_AURA_461 = 461,
+ SPELL_AURA_462 = 462,
+ SPELL_AURA_463 = 463,
+ SPELL_AURA_464 = 464,
+ SPELL_AURA_465 = 465,
+ SPELL_AURA_466 = 466,
+ SPELL_AURA_467 = 467,
+ SPELL_AURA_468 = 468,
+ SPELL_AURA_469 = 469,
+ SPELL_AURA_471 = 471,
+ SPELL_AURA_472 = 472,
+ SPELL_AURA_473 = 473,
+ SPELL_AURA_474 = 474,
+ SPELL_AURA_475 = 475,
+ SPELL_AURA_476 = 476,
+ SPELL_AURA_477 = 477,
+ SPELL_AURA_478 = 478,
+ TOTAL_AURAS = 479 // 4.3.4
};
enum AuraObjectType
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c55c92d296e..88cb4c942b9 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -429,11 +429,119 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleUnused, //368 unused (4.3.4)
&AuraEffect::HandleNULL, //369 SPELL_AURA_ENABLE_POWER_BAR_TIMER
&AuraEffect::HandleNULL, //370 SPELL_AURA_SET_FAIR_FAR_CLIP
+ &AuraEffect::HandleNULL, //371
+ &AuraEffect::HandleNULL, //372
+ &AuraEffect::HandleNULL, //373
+ &AuraEffect::HandleNULL, //374
+ &AuraEffect::HandleNULL, //375
+ &AuraEffect::HandleNULL, //376
+ &AuraEffect::HandleNULL, //377
+ &AuraEffect::HandleNULL, //378
+ &AuraEffect::HandleNULL, //379
+ &AuraEffect::HandleNULL, //380
+ &AuraEffect::HandleNULL, //381
+ &AuraEffect::HandleNULL, //382
+ &AuraEffect::HandleNULL, //383
+ &AuraEffect::HandleNULL, //384
+ &AuraEffect::HandleNULL, //385
+ &AuraEffect::HandleNULL, //386
+ &AuraEffect::HandleNULL, //387
+ &AuraEffect::HandleNULL, //388
+ &AuraEffect::HandleNULL, //389
+ &AuraEffect::HandleNULL, //390
+ &AuraEffect::HandleNULL, //391
+ &AuraEffect::HandleNULL, //392
+ &AuraEffect::HandleNULL, //393
+ &AuraEffect::HandleNULL, //394
+ &AuraEffect::HandleNULL, //395
+ &AuraEffect::HandleNULL, //396
+ &AuraEffect::HandleNULL, //397
+ &AuraEffect::HandleNULL, //398
+ &AuraEffect::HandleNULL, //399
+ &AuraEffect::HandleNULL, //400
+ &AuraEffect::HandleNULL, //401
+ &AuraEffect::HandleNULL, //402
+ &AuraEffect::HandleNULL, //403
+ &AuraEffect::HandleNULL, //404
+ &AuraEffect::HandleNULL, //405
+ &AuraEffect::HandleNULL, //406
+ &AuraEffect::HandleNULL, //407
+ &AuraEffect::HandleNULL, //408
+ &AuraEffect::HandleNULL, //409
+ &AuraEffect::HandleNULL, //410
+ &AuraEffect::HandleNULL, //411
+ &AuraEffect::HandleNULL, //412
+ &AuraEffect::HandleNULL, //413
+ &AuraEffect::HandleNULL, //414
+ &AuraEffect::HandleNULL, //415
+ &AuraEffect::HandleNULL, //416
+ &AuraEffect::HandleNULL, //417
+ &AuraEffect::HandleNULL, //418
+ &AuraEffect::HandleNULL, //419
+ &AuraEffect::HandleNULL, //420
+ &AuraEffect::HandleNULL, //421
+ &AuraEffect::HandleNULL, //422
+ &AuraEffect::HandleNULL, //423
+ &AuraEffect::HandleNULL, //424
+ &AuraEffect::HandleNULL, //425
+ &AuraEffect::HandleNULL, //426
+ &AuraEffect::HandleNULL, //427
+ &AuraEffect::HandleNULL, //428
+ &AuraEffect::HandleNULL, //429
+ &AuraEffect::HandleNULL, //430
+ &AuraEffect::HandleNULL, //431
+ &AuraEffect::HandleNULL, //432
+ &AuraEffect::HandleNULL, //433
+ &AuraEffect::HandleNULL, //434
+ &AuraEffect::HandleNULL, //435
+ &AuraEffect::HandleNULL, //436
+ &AuraEffect::HandleNULL, //437
+ &AuraEffect::HandleNULL, //438
+ &AuraEffect::HandleNULL, //439
+ &AuraEffect::HandleNULL, //440
+ &AuraEffect::HandleNULL, //441
+ &AuraEffect::HandleNULL, //442
+ &AuraEffect::HandleNULL, //443
+ &AuraEffect::HandleNULL, //444
+ &AuraEffect::HandleNULL, //445
+ &AuraEffect::HandleNULL, //446
+ &AuraEffect::HandleNULL, //447
+ &AuraEffect::HandleNULL, //448
+ &AuraEffect::HandleNULL, //449
+ &AuraEffect::HandleNULL, //450
+ &AuraEffect::HandleNULL, //451
+ &AuraEffect::HandleNULL, //452
+ &AuraEffect::HandleNULL, //453
+ &AuraEffect::HandleNULL, //454
+ &AuraEffect::HandleNULL, //455
+ &AuraEffect::HandleNULL, //456
+ &AuraEffect::HandleNULL, //457
+ &AuraEffect::HandleNULL, //458
+ &AuraEffect::HandleNULL, //459
+ &AuraEffect::HandleNULL, //460
+ &AuraEffect::HandleNULL, //461
+ &AuraEffect::HandleNULL, //462
+ &AuraEffect::HandleNULL, //463
+ &AuraEffect::HandleNULL, //464
+ &AuraEffect::HandleNULL, //465
+ &AuraEffect::HandleNULL, //466
+ &AuraEffect::HandleNULL, //467
+ &AuraEffect::HandleNULL, //468
+ &AuraEffect::HandleNULL, //469
+ &AuraEffect::HandleNULL, //471
+ &AuraEffect::HandleNULL, //472
+ &AuraEffect::HandleNULL, //473
+ &AuraEffect::HandleNULL, //474
+ &AuraEffect::HandleNULL, //475
+ &AuraEffect::HandleNULL, //476
+ &AuraEffect::HandleNULL, //477
+ &AuraEffect::HandleNULL, //478
};
-AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster):
+AuraEffect::AuraEffect(Aura* base, uint32 effIndex, int32 *baseAmount, Unit* caster) :
m_base(base), m_spellInfo(base->GetSpellInfo()),
-m_baseAmount(baseAmount ? *baseAmount : m_spellInfo->Effects[effIndex].BasePoints),
+_effectInfo(base->GetSpellEffectInfo(effIndex)),
+m_baseAmount(baseAmount ? *baseAmount : base->GetSpellEffectInfo(effIndex)->BasePoints),
m_damage(0), m_critChance(0.0f), m_donePct(1.0f),
m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex),
m_canBeRecalculated(true), m_isPeriodic(false)
@@ -476,10 +584,10 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
// default amount calculation
int32 amount = 0;
- if (!(m_spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(m_spellInfo->Effects[m_effIndex].BonusCoefficient, 0.0f))
- amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit());
+ if (!(m_spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(GetSpellEffectInfo()->BonusCoefficient, 0.0f))
+ amount = GetSpellEffectInfo()->CalcValue(caster, &m_baseAmount, GetBase()->GetOwner()->ToUnit());
else if (caster && caster->GetTypeId() == TYPEID_PLAYER)
- amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * m_spellInfo->Effects[m_effIndex].BonusCoefficient);
+ amount = int32(caster->GetFloatValue(PLAYER_MASTERY) * GetSpellEffectInfo()->BonusCoefficient);
// check item enchant aura cast
if (!amount && caster)
@@ -604,7 +712,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= true*/, bool load /*= false*/)
{
- m_period = m_spellInfo->Effects[m_effIndex].ApplyAuraPeriod;
+ m_period = GetSpellEffectInfo()->ApplyAuraPeriod;
// prepare periodics
switch (GetAuraType())
@@ -694,7 +802,7 @@ void AuraEffect::CalculateSpellMod()
m_spellmod->type = SpellModType(uint32(GetAuraType())); // SpellModType value == spell aura types
m_spellmod->spellId = GetId();
- m_spellmod->mask = GetSpellInfo()->Effects[GetEffIndex()].SpellClassMask;
+ m_spellmod->mask = GetSpellEffectInfo()->SpellClassMask;
m_spellmod->charges = GetBase()->GetCharges();
}
m_spellmod->value = GetAmount();
@@ -1021,7 +1129,7 @@ bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
return false;
// Check EffectClassMask
- if (m_spellInfo->Effects[m_effIndex].SpellClassMask & spell->SpellFamilyFlags)
+ if (GetSpellEffectInfo()->SpellClassMask & spell->SpellFamilyFlags)
return true;
return false;
}
@@ -1091,6 +1199,7 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
switch (GetAuraType())
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
+ case SPELL_AURA_PROC_TRIGGER_SPELL_2:
HandleProcTriggerSpellAuraProc(aurApp, eventInfo);
break;
case SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE:
@@ -1105,6 +1214,9 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
case SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE:
HandleRaidProcFromChargeWithValueAuraProc(aurApp, eventInfo);
break;
+ case SPELL_AURA_PROC_ON_POWER_AMOUNT:
+ HandleProcTriggerSpellOnPowerAmountAuraProc(aurApp, eventInfo);
+ break;
default:
break;
}
@@ -1114,7 +1226,7 @@ void AuraEffect::HandleProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
void AuraEffect::CleanupTriggeredSpells(Unit* target)
{
- uint32 tSpellId = m_spellInfo->Effects[GetEffIndex()].TriggerSpell;
+ uint32 tSpellId = GetSpellEffectInfo()->TriggerSpell;
if (!tSpellId)
return;
@@ -1127,8 +1239,8 @@ void AuraEffect::CleanupTriggeredSpells(Unit* target)
// needed for spell 43680, maybe others
/// @todo is there a spell flag, which can solve this in a more sophisticated way?
- if (m_spellInfo->Effects[GetEffIndex()].ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
- uint32(m_spellInfo->GetDuration()) == m_spellInfo->Effects[GetEffIndex()].ApplyAuraPeriod)
+ if (GetSpellEffectInfo()->ApplyAuraName == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
+ uint32(m_spellInfo->GetDuration()) == GetSpellEffectInfo()->ApplyAuraPeriod)
return;
target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
@@ -1268,30 +1380,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
target->CastSpell(target, 24932, true, NULL, this);
}
- // Heart of the Wild
- if (AuraEffect const* heartOfTheWild = target->GetAuraEffectOfRankedSpell(17003, EFFECT_0))
- {
- uint32 heartOfTheWildSpellId = 0;
- int32 heartOfTheWildAmount = 0;
-
- switch (GetMiscValue())
- {
- case FORM_CAT:
- heartOfTheWildSpellId = 24900;
- heartOfTheWildAmount = heartOfTheWild->GetSpellInfo()->Effects[EFFECT_1].CalcValue();
- break;
- case FORM_BEAR:
- heartOfTheWildSpellId = 24899;
- heartOfTheWildAmount = heartOfTheWild->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
- break;
- default:
- break;
- }
-
- if (heartOfTheWildSpellId)
- target->CastCustomSpell(target, heartOfTheWildSpellId, &heartOfTheWildAmount, NULL, NULL, true, NULL, this);
- }
-
switch (GetMiscValue())
{
case FORM_CAT:
@@ -1327,12 +1415,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
int32 bp = aurEff->GetAmount();
target->CastCustomSpell(target, 48418, &bp, NULL, NULL, true);
}
- // Survival of the Fittest
- if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DRUID, 961, EFFECT_0))
- {
- int32 bp = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster());
- target->CastCustomSpell(target, 62069, &bp, NULL, NULL, true, 0, this);
- }
break;
case FORM_MOONKIN:
// Master Shapeshifter - Moonkin
@@ -2594,9 +2676,8 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
vehicleId = creatureInfo->VehicleId;
//some spell has one aura of mount and one of vehicle
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (GetSpellInfo()->Effects[i].Effect == SPELL_EFFECT_SUMMON
- && GetSpellInfo()->Effects[i].MiscValue == GetMiscValue())
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
+ if (effect && effect->Effect == SPELL_EFFECT_SUMMON && effect->MiscValue == GetMiscValue())
displayId = 0;
}
@@ -4598,8 +4679,9 @@ void AuraEffect::HandleNoReagentUseAura(AuraApplication const* aurApp, uint8 mod
flag128 mask;
Unit::AuraEffectList const& noReagent = target->GetAuraEffectsByType(SPELL_AURA_NO_REAGENT_USE);
- for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
- mask |= (*i)->m_spellInfo->Effects[(*i)->m_effIndex].SpellClassMask;
+ for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ if (SpellEffectInfo const* effect = (*i)->GetSpellEffectInfo())
+ mask |= effect->SpellClassMask;
target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
@@ -5021,11 +5103,11 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
if (GetAmount() <= 0)
return;
- if (GetSpellInfo()->Effects[m_effIndex].ItemType == 0)
+ if (GetSpellEffectInfo()->ItemType == 0)
return;
// Soul Shard
- if (GetSpellInfo()->Effects[m_effIndex].ItemType == 6265)
+ if (GetSpellEffectInfo()->ItemType == 6265)
{
// Soul Shard only from units that grant XP or honor
if (!plCaster->isHonorOrXPTarget(target) ||
@@ -5038,16 +5120,16 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
uint32 count = m_amount;
ItemPosCountVec dest;
- InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellInfo()->Effects[m_effIndex].ItemType, count, &noSpaceForCount);
+ InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellEffectInfo()->ItemType, count, &noSpaceForCount);
if (msg != EQUIP_ERR_OK)
{
count-=noSpaceForCount;
- plCaster->SendEquipError(msg, NULL, NULL, GetSpellInfo()->Effects[m_effIndex].ItemType);
+ plCaster->SendEquipError(msg, NULL, NULL, GetSpellEffectInfo()->ItemType);
if (count == 0)
return;
}
- Item* newitem = plCaster->StoreNewItem(dest, GetSpellInfo()->Effects[m_effIndex].ItemType, true);
+ Item* newitem = plCaster->StoreNewItem(dest, GetSpellEffectInfo()->ItemType, true);
if (!newitem)
{
plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
@@ -5186,19 +5268,19 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
{
Unit* target = aurApp->GetTarget();
- uint32 triggeredSpellId = sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->Effects[m_effIndex].TriggerSpell, target);
+ uint32 triggeredSpellId = GetSpellEffectInfo()->TriggerSpell;
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggeredSpellId);
if (!triggeredSpellInfo)
return;
+ Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? GetCaster() : target;
+ if (!caster)
+ return;
+
if (mode & AURA_EFFECT_HANDLE_REAL)
{
if (apply)
{
- Unit* caster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCaster() : target;
-
- if (!caster)
- return;
// If amount avalible cast with basepoints (Crypt Fever for example)
if (GetAmount())
caster->CastCustomSpell(target, triggeredSpellId, &m_amount, NULL, NULL, true, NULL, this);
@@ -5207,13 +5289,13 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo
}
else
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
target->RemoveAura(triggeredSpellId, casterGUID, 0, aurApp->GetRemoveMode());
}
}
else if (mode & AURA_EFFECT_HANDLE_REAPPLY && apply)
{
- ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? GetCasterGUID() : target->GetGUID();
+ ObjectGuid casterGUID = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, caster->GetMap()->GetDifficulty()) ? GetCasterGUID() : target->GetGUID();
// change the stack amount to be equal to stack amount of our aura
if (Aura* triggeredAura = target->GetAura(triggeredSpellId, casterGUID))
triggeredAura->ModStackAmount(GetBase()->GetStackAmount() - triggeredAura->GetStackAmount());
@@ -5384,7 +5466,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
}
case 62292: // Blaze (Pool of Tar)
// should we use custom damage?
- target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true);
+ target->CastSpell((Unit*)NULL, GetSpellEffectInfo()->TriggerSpell, true);
break;
case 62399: // Overload Circuit
if (target->GetMap()->IsDungeon() && int(target->GetAppliedAuras().count(62399)) >= (target->GetMap()->IsHeroic() ? 4 : 2))
@@ -5408,7 +5490,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
// Mirror Image
if (GetId() == 55342)
// Set name of summons to name of caster
- target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true);
+ target->CastSpell((Unit*)NULL, GetSpellEffectInfo()->TriggerSpell, true);
break;
}
case SPELLFAMILY_DRUID:
@@ -5501,7 +5583,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) const
{
// generic casting code with custom spells and target/caster customs
- uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId);
SpellInfo const* auraSpellInfo = GetSpellInfo();
@@ -5765,7 +5847,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
if (triggeredSpellInfo)
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
{
triggerCaster->CastSpell(target, triggeredSpellInfo, true, NULL, this);
TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id);
@@ -5782,10 +5864,10 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
void AuraEffect::HandlePeriodicTriggerSpellWithValueAuraTick(Unit* target, Unit* caster) const
{
- uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
- if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target)
+ if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, target->GetMap()->GetDifficulty()) ? caster : target)
{
int32 basepoints = GetAmount();
triggerCaster->CastCustomSpell(target, triggerSpellId, &basepoints, &basepoints, &basepoints, true, nullptr, this);
@@ -5808,7 +5890,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
}
// Consecrate ticks can miss and will not show up in the combat log
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -5827,11 +5909,14 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
break;
case 38772: // Grievous Wound
{
- uint32 percent = GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster);
- if (!target->HealthBelowPct(percent))
+ if (SpellEffectInfo const* effect = GetSpellInfo()->GetEffect(DIFFICULTY_NONE, EFFECT_1))
{
- target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
- return;
+ uint32 percent = effect->CalcValue(caster);
+ if (!target->HealthBelowPct(percent))
+ {
+ target->RemoveAurasDueToSpell(GetSpellInfo()->Id);
+ return;
+ }
}
break;
}
@@ -5843,7 +5928,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
// AOE spells are not affected by the new periodic system.
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -5854,11 +5939,11 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
{
if (isAreaAura)
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
- damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
+ damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
@@ -5902,7 +5987,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = uint32(target->CountPctFromMaxHealth(damage));
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
- if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
@@ -5950,6 +6035,18 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
}
+bool AuraEffect::IsAreaAuraEffect() const
+{
+ if (_effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PET ||
+ _effectInfo->Effect == SPELL_EFFECT_APPLY_AREA_AURA_OWNER)
+ return true;
+ return false;
+}
+
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
{
if (!caster || !target->IsAlive())
@@ -5961,7 +6058,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
return;
}
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -5969,7 +6066,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
uint32 resist = 0;
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
uint32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -5977,12 +6074,12 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
{
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
+ damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellDamagePctDone(target, m_spellInfo, DOT);
}
- damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
// Calculate armor mitigation
- if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
+ if (caster->IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
@@ -5990,7 +6087,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
}
if (!(m_spellInfo->AttributesEx4 & SPELL_ATTR4_FIXED_DAMAGE))
- if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
+ if (GetSpellEffectInfo()->IsTargetingArea() || isAreaAura)
{
damage = int32(float(damage) * target->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (caster->GetTypeId() != TYPEID_PLAYER)
@@ -6032,10 +6129,10 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
if (caster->IsAlive())
{
- float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
- uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetBase()->GetStackAmount()));
- heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount()));
+ uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()));
+ heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()));
int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal);
caster->getHostileRefManager().threatAssist(caster, gain * 0.5f, GetSpellInfo());
@@ -6063,7 +6160,7 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
caster->ModifyHealth(-(int32)damage);
TC_LOG_DEBUG("spells", "PeriodicTick: donator %u target %u damage %u.", caster->GetEntry(), target->GetEntry(), damage);
- float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
damage = int32(damage * gainMultiplier);
@@ -6089,7 +6186,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (GetBase()->IsPermanent() && target->IsFullHealth())
return;
- bool isAreaAura = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
+ bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = isAreaAura ? std::max(GetAmount(), 0) : m_damage;
@@ -6131,8 +6228,8 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
damage += addition;
}
if (isAreaAura)
- damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
- damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
+ damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount()) * caster->SpellHealingPctDone(target, m_spellInfo);
+ damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetSpellEffectInfo(), GetBase()->GetStackAmount());
}
bool crit = false;
@@ -6196,7 +6293,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
return;
}
- if (GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ if (GetSpellEffectInfo()->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE)
return;
@@ -6219,7 +6316,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
int32 drainedAmount = -target->ModifyPower(powerType, -drainAmount);
- float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float gainMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
SpellPeriodicAuraLogInfo pInfo(this, drainedAmount, 0, 0, 0, gainMultiplier, false);
target->SendPeriodicAuraLog(&pInfo);
@@ -6336,7 +6433,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
- float dmgMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
+ float dmgMultiplier = GetSpellEffectInfo()->CalcValueMultiplier(caster);
SpellInfo const* spellProto = GetSpellInfo();
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
@@ -6365,7 +6462,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellInfo()->Effects[GetEffIndex()].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId());
@@ -6380,7 +6477,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp
Unit* triggerCaster = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
- uint32 triggerSpellId = GetSpellInfo()->Effects[m_effIndex].TriggerSpell;
+ uint32 triggerSpellId = GetSpellEffectInfo()->TriggerSpell;
if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
{
int32 basepoints0 = GetAmount();
@@ -6396,8 +6493,8 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
Unit* target = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
SpellNonMeleeDamage damageInfo(target, triggerTarget, GetId(), GetSpellInfo()->SchoolMask);
- uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE);
- damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
+ uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE, GetSpellEffectInfo());
+ damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE, GetSpellEffectInfo());
target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo());
target->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
target->SendSpellNonMeleeDamageLog(&damageInfo);
@@ -6438,7 +6535,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE
{
if (Unit* caster = GetCaster())
{
- float radius = GetSpellInfo()->Effects[GetEffIndex()].CalcRadius(caster);
+ float radius = GetSpellEffectInfo()->CalcRadius(caster);
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
@@ -6479,7 +6576,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
{
if (Unit* caster = GetCaster())
{
- float radius = GetSpellInfo()->Effects[GetEffIndex()].CalcRadius(caster);
+ float radius = GetSpellEffectInfo()->CalcRadius(caster);
if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius))
{
@@ -6494,6 +6591,35 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
target->CastCustomSpell(target, triggerSpellId, &value, NULL, NULL, true, NULL, this, GetCasterGUID());
}
+void AuraEffect::HandleProcTriggerSpellOnPowerAmountAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
+{
+ // Power amount required to proc the spell
+ int32 powerAmountRequired = GetAmount();
+ // Power type required to proc
+ Powers powerRequired = Powers(_effectInfo->MiscValue);
+
+ if (!powerRequired || !powerAmountRequired)
+ {
+ TC_LOG_ERROR("spells", "AuraEffect::HandleProcTriggerSpellOnPowerAmountAuraProc: Spell %u have 0 PowerAmountRequired in EffectAmount[%d] or 0 PowerRequired in EffectMiscValue", GetId(), GetEffIndex());
+ return /*false*/;
+ }
+
+ Unit* triggerCaster = aurApp->GetTarget();
+ Unit* triggerTarget = eventInfo.GetProcTarget();
+
+ if (triggerCaster->GetPower(powerRequired) != powerAmountRequired)
+ return /*false*/;
+
+ uint32 triggerSpellId = _effectInfo->TriggerSpell;
+ if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId))
+ {
+ TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellOnPowerAmountAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId());
+ triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, nullptr, this);
+ }
+ else
+ TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellOnPowerAmountAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId());
+}
+
void AuraEffect::HandleAuraForceWeather(AuraApplication const* aurApp, uint8 mode, bool apply) const
{
if (!(mode & AURA_EFFECT_HANDLE_REAL))
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 22571f4851e..ebfeece4c7c 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -29,13 +29,13 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const* aurApp, uin
class AuraEffect
{
- friend void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
- friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
friend Aura::~Aura();
- private:
- ~AuraEffect();
- explicit AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster);
+
public:
+ ~AuraEffect();
+ AuraEffect(Aura* base, uint32 effIndex, int32 *baseAmount, Unit* caster);
Unit* GetCaster() const { return GetBase()->GetCaster(); }
ObjectGuid GetCasterGUID() const { return GetBase()->GetCasterGUID(); }
Aura* GetBase() const { return m_base; }
@@ -49,9 +49,9 @@ class AuraEffect
int32 GetBaseAmount() const { return m_baseAmount; }
int32 GetPeriod() const { return m_period; }
- int32 GetMiscValueB() const { return m_spellInfo->Effects[m_effIndex].MiscValueB; }
- int32 GetMiscValue() const { return m_spellInfo->Effects[m_effIndex].MiscValue; }
- AuraType GetAuraType() const { return (AuraType)m_spellInfo->Effects[m_effIndex].ApplyAuraName; }
+ int32 GetMiscValueB() const { return GetSpellEffectInfo()->MiscValueB; }
+ int32 GetMiscValue() const { return GetSpellEffectInfo()->MiscValue; }
+ AuraType GetAuraType() const { return (AuraType)GetSpellEffectInfo()->ApplyAuraName; }
int32 GetAmount() const { return m_amount; }
void SetAmount(int32 amount) { m_amount = amount; m_canBeRecalculated = false;}
@@ -87,7 +87,7 @@ class AuraEffect
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
bool IsAffectingSpell(SpellInfo const* spell) const;
- bool HasSpellClassMask() const { return m_spellInfo->Effects[m_effIndex].SpellClassMask; }
+ bool HasSpellClassMask() const { return GetSpellEffectInfo()->SpellClassMask; }
void SendTickImmune(Unit* target, Unit* caster) const;
void PeriodicTick(AuraApplication * aurApp, Unit* caster) const;
@@ -98,10 +98,18 @@ class AuraEffect
// add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
void HandleShapeshiftBoosts(Unit* target, bool apply) const;
+
+ SpellEffectInfo const* GetSpellEffectInfo() const { return _effectInfo; }
+
+ bool IsEffect() const { return _effectInfo->Effect != 0; }
+ bool IsEffect(SpellEffectName effectName) const { return _effectInfo->Effect == uint32(effectName); }
+ bool IsAreaAuraEffect() const;
+
private:
Aura* const m_base;
SpellInfo const* const m_spellInfo;
+ SpellEffectInfo const* _effectInfo;
int32 const m_baseAmount;
int32 m_amount;
@@ -312,6 +320,7 @@ class AuraEffect
void HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo);
void HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo);
void HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo);
+ void HandleProcTriggerSpellOnPowerAmountAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo);
};
namespace Trinity
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 67df56d892e..9037715152a 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -26,6 +26,7 @@
#include "Unit.h"
#include "Spell.h"
#include "SpellAuraEffects.h"
+#include "SpellPackets.h"
#include "DynamicObject.h"
#include "ObjectAccessor.h"
#include "Util.h"
@@ -37,9 +38,9 @@
#include "Vehicle.h"
#include "Config.h"
-AuraApplication::AuraApplication(Unit* target, Unit* caster, Aura* aura, uint8 effMask):
+AuraApplication::AuraApplication(Unit* target, Unit* caster, Aura* aura, uint32 effMask):
_target(target), _base(aura), _removeMode(AURA_REMOVE_NONE), _slot(MAX_AURAS),
-_flags(AFLAG_NONE), _effectsToApply(effMask), _needClientUpdate(false)
+_flags(AFLAG_NONE), _effectsToApply(effMask), _needClientUpdate(false), _effectMask(0)
{
ASSERT(GetTarget() && GetBase());
@@ -113,19 +114,19 @@ void AuraApplication::_Remove()
}
}
-void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
+void AuraApplication::_InitFlags(Unit* caster, uint32 effMask)
{
// mark as selfcast if needed
- _flags |= (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_CASTER : AFLAG_NONE;
+ _flags |= (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) ? AFLAG_NONE : AFLAG_NOCASTER;
// aura is cast by self or an enemy
// one negative effect and we know aura is negative
if (IsSelfcast() || !caster || !caster->IsFriendlyTo(GetTarget()))
{
bool negativeFound = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
{
- if (((1<<i) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(i))
+ if (effect && ((1 << effect->EffectIndex) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
{
negativeFound = true;
break;
@@ -138,9 +139,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
else
{
bool positiveFound = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetBase()->GetSpellEffectInfos())
{
- if (((1<<i) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(i))
+ if (effect && ((1 << effect->EffectIndex) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(effect->EffectIndex))
{
positiveFound = true;
break;
@@ -150,12 +151,17 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
}
if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT)
- _flags |= AFLAG_ANY_EFFECT_AMOUNT_SENT;
+ _flags |= AFLAG_SCALABLE;
}
void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
{
AuraEffect* aurEff = GetBase()->GetEffect(effIndex);
+ if (!aurEff)
+ {
+ TC_LOG_ERROR("spells", "Aura %u has no effect at effectIndex %u but _HandleEffect was called", GetBase()->GetSpellInfo()->Id, uint32(effIndex));
+ return;
+ }
ASSERT(aurEff);
ASSERT(HasEffect(effIndex) == (!apply));
ASSERT((1<<effIndex) & _effectsToApply);
@@ -163,14 +169,14 @@ void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
if (apply)
{
- ASSERT(!(_flags & (1<<effIndex)));
- _flags |= 1<<effIndex;
+ ASSERT(!(_effectMask & (1<<effIndex)));
+ _effectMask |= 1<<effIndex;
aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, true);
}
else
{
- ASSERT(_flags & (1<<effIndex));
- _flags &= ~(1<<effIndex);
+ ASSERT(_effectMask & (1<<effIndex));
+ _effectMask &= ~(1<<effIndex);
aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, false);
// Remove all triggered by aura spells vs unlimited duration
@@ -193,7 +199,7 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
Aura const* aura = GetBase();
data << uint32(aura->GetId());
- uint32 flags = _flags;
+ uint8 flags = _flags;
if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION))
flags |= AFLAG_DURATION;
data << uint16(flags);
@@ -202,7 +208,7 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
// stack amount has priority over charges (checked on retail with spell 50262)
data << uint8(aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges());
- if (!(flags & AFLAG_CASTER))
+ if (!(flags & AFLAG_NOCASTER))
data << aura->GetCasterGUID().WriteAsPacked();
if (flags & AFLAG_DURATION)
@@ -211,44 +217,43 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
data << uint32(aura->GetDuration());
}
- if (flags & AFLAG_ANY_EFFECT_AMOUNT_SENT)
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (AuraEffect const* eff = aura->GetEffect(i))
- if (HasEffect(i)) // Not all of aura's effects have to be applied on every target
- data << int32(eff->GetAmount());
+ if (flags & AFLAG_SCALABLE)
+ for (AuraEffect const* effect : GetBase()->GetAuraEffects())
+ if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
+ data << int32(effect->GetAmount());
}
void AuraApplication::ClientUpdate(bool remove)
{
_needClientUpdate = false;
- WorldPacket data(SMSG_AURA_UPDATE);
- data << GetTarget()->GetPackGUID();
- BuildUpdatePacket(data, remove);
+ WorldPackets::Spells::SendAuraUpdate update;
+ update.Init(false, GetTarget()->GetGUID(), 1);
+ update.BuildUpdatePacket(this, remove, GetTarget()->getLevel()); // TODO 6.x should be caster's level
- _target->SendMessageToSet(&data, true);
+ _target->SendMessageToSet(const_cast<WorldPacket*>(update.Write()), true);
}
-uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner)
+uint32 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner)
{
ASSERT(spellProto);
ASSERT(owner);
- uint8 effMask = 0;
+ uint32 effMask = 0;
switch (owner->GetTypeId())
{
case TYPEID_UNIT:
case TYPEID_PLAYER:
- for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
{
- if (spellProto->Effects[i].IsUnitOwnedAuraEffect())
- effMask |= 1 << i;
+ if (effect && effect->IsUnitOwnedAuraEffect())
+ effMask |= 1 << effect->EffectIndex;
}
break;
case TYPEID_DYNAMICOBJECT:
- for (uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellProto->GetEffectsForDifficulty(owner->GetMap()->GetDifficulty()))
{
- if (spellProto->Effects[i].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
- effMask |= 1 << i;
+ if (effect && effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ effMask |= 1 << effect->EffectIndex;
}
break;
default:
@@ -257,7 +262,7 @@ uint8 Aura::BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleE
return effMask & avalibleEffectMask;
}
-Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
+Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/, bool* refresh /*= NULL*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -265,9 +270,10 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas
ASSERT(tryEffMask <= MAX_EFFECT_MASK);
if (refresh)
*refresh = false;
- uint8 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
+ uint32 effMask = Aura::BuildEffectMaskForOwner(spellproto, tryEffMask, owner);
if (!effMask)
return NULL;
+
if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID))
{
// we've here aura, which script triggered removal after modding stack amount
@@ -283,7 +289,7 @@ Aura* Aura::TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMas
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
-Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
+Aura* Aura::TryCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount /*= NULL*/, Item* castItem /*= NULL*/, ObjectGuid casterGUID /*= ObjectGuid::Empty*/)
{
ASSERT(spellproto);
ASSERT(owner);
@@ -295,7 +301,7 @@ Aura* Aura::TryCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject
return Create(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
}
-Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID)
+Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
{
ASSERT(effMask);
ASSERT(spellproto);
@@ -354,7 +360,6 @@ m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEven
m_duration = m_maxDuration;
m_procCharges = CalcMaxCharges(caster);
m_isUsingCharges = m_procCharges != 0;
- memset(m_effects, 0, sizeof(m_effects));
// m_casterLevel = cast item level/caster level, caster level should be saved to db, confirmed with sniffs
}
@@ -366,15 +371,27 @@ AuraScript* Aura::GetScriptByName(std::string const& scriptName) const
return NULL;
}
-void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount)
+SpellEffectInfo const* Aura::GetSpellEffectInfo(uint32 index) const
+{
+ if (index >= _spelEffectInfos.size())
+ return nullptr;
+
+ return _spelEffectInfos[index];
+}
+
+void Aura::_InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount)
{
// shouldn't be in constructor - functions in AuraEffect::AuraEffect use polymorphism
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ _spelEffectInfos = m_spellInfo->GetEffectsForDifficulty(GetOwner()->GetMap()->GetDifficulty());
+
+ ASSERT(!_spelEffectInfos.empty());
+
+ _effects.resize(GetSpellEffectInfos().size());
+
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (effMask & (uint8(1) << i))
- m_effects[i] = new AuraEffect(this, i, baseAmount ? baseAmount + i : NULL, caster);
- else
- m_effects[i] = NULL;
+ if (effect && effMask & (uint8(1) << effect->EffectIndex))
+ _effects[effect->EffectIndex] = new AuraEffect(this, effect->EffectIndex, baseAmount ? baseAmount + effect->EffectIndex : NULL, caster);
}
}
@@ -389,9 +406,9 @@ Aura::~Aura()
m_loadedScripts.erase(itr);
}
- // free effects memory
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- delete m_effects[i];
+ // free effects memory todo 6.x
+ //for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ // delete m_effects[i];
ASSERT(m_applications.empty());
_DeleteRemovedApplications();
@@ -407,6 +424,14 @@ Unit* Aura::GetCaster() const
return ObjectAccessor::GetUnit(*GetOwner(), GetCasterGUID());
}
+AuraEffect* Aura::GetEffect(uint32 index) const
+{
+ if (index >= _effects.size())
+ return nullptr;
+
+ return _effects[index];
+}
+
AuraObjectType Aura::GetType() const
{
return (m_owner->GetTypeId() == TYPEID_DYNAMICOBJECT) ? DYNOBJ_AURA_TYPE : UNIT_AURA_TYPE;
@@ -494,7 +519,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
// fill up to date target list
// target, effMask
- std::map<Unit*, uint8> targets;
+ std::map<Unit*, uint32> targets;
FillTargetMap(targets, caster);
@@ -503,7 +528,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
// mark all auras as ready to remove
for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end();++appIter)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(appIter->second->GetTarget());
+ std::map<Unit*, uint32>::iterator existing = targets.find(appIter->second->GetTarget());
// not found in current area - remove the aura
if (existing == targets.end())
targetsToRemove.push_back(appIter->second->GetTarget());
@@ -520,7 +545,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
}
// register auras for units
- for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr!= targets.end();)
+ for (std::map<Unit*, uint32>::iterator itr = targets.begin(); itr!= targets.end();)
{
// aura mustn't be already applied on target
if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
@@ -613,7 +638,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply)
return;
// apply aura effects for units
- for (std::map<Unit*, uint8>::iterator itr = targets.begin(); itr!= targets.end();++itr)
+ for (std::map<Unit*, uint32>::iterator itr = targets.begin(); itr!= targets.end();++itr)
{
if (AuraApplication * aurApp = GetApplicationOfTarget(itr->first->GetGUID()))
{
@@ -674,9 +699,9 @@ void Aura::UpdateOwner(uint32 diff, WorldObject* owner)
m_updateTargetMapInterval -= diff;
// update aura effects
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
- m_effects[i]->Update(diff, caster);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effect->Update(diff, caster);
// remove spellmods after effects update
if (modSpell)
@@ -880,9 +905,9 @@ void Aura::SetStackAmount(uint8 stackAmount)
if (!(*apptItr)->GetRemoveMode())
HandleAuraSpecificMods(*apptItr, caster, false, true);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i))
- m_effects[i]->ChangeAmount(m_effects[i]->CalculateAmount(caster), false, true);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effect->ChangeAmount(effect->CalculateAmount(caster), false, true);
for (std::list<AuraApplication*>::const_iterator apptItr = applications.begin(); apptItr != applications.end(); ++apptItr)
if (!(*apptItr)->GetRemoveMode())
@@ -945,11 +970,11 @@ void Aura::RefreshSpellMods()
player->RestoreAllSpellMods(0, this);
}
-bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
+bool Aura::HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const
{
uint32 count = 0;
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i) && AuraType(GetSpellInfo()->Effects[i].ApplyAuraName) == auraType)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ if (effect && HasEffect(effect->EffectIndex) && AuraType(effect->ApplyAuraName) == auraType)
++count;
return count > 1;
@@ -957,8 +982,8 @@ bool Aura::HasMoreThanOneEffectForType(AuraType auraType) const
bool Aura::IsArea() const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i) && GetSpellInfo()->Effects[i].IsAreaAuraEffect())
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ if (effect && HasEffect(effect->EffectIndex) && effect->IsAreaAuraEffect())
return true;
return false;
@@ -1020,7 +1045,7 @@ bool Aura::CanBeSaved() const
bool Aura::CanBeSentToClient() const
{
- return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect() || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
+ return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficulty() : DIFFICULTY_NONE) || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
}
bool Aura::IsSingleTargetWith(Aura const* aura) const
@@ -1080,7 +1105,7 @@ int32 Aura::CalcDispelChance(Unit* auraTarget, bool offensive) const
return 100 - resistChance;
}
-void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount)
+void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 *amount)
{
m_maxDuration = maxduration;
m_duration = duration;
@@ -1088,22 +1113,23 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint
m_isUsingCharges = m_procCharges != 0;
m_stackAmount = stackamount;
Unit* caster = GetCaster();
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i])
- {
- m_effects[i]->SetAmount(amount[i]);
- m_effects[i]->SetCanBeRecalculated((recalculateMask & (1 << i)) != 0);
- m_effects[i]->CalculatePeriodic(caster, false, true);
- m_effects[i]->CalculateSpellMod();
- m_effects[i]->RecalculateAmount(caster);
- }
+ for (AuraEffect* effect : GetAuraEffects())
+ {
+ if (!effect)
+ continue;
+ effect->SetAmount(amount[effect->GetEffIndex()]);
+ effect->SetCanBeRecalculated((recalculateMask & (1 << effect->GetEffIndex())) != 0);
+ effect->CalculatePeriodic(caster, false, true);
+ effect->CalculateSpellMod();
+ effect->RecalculateAmount(caster);
+ }
}
bool Aura::HasEffectType(AuraType type) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* effect : GetAuraEffects())
{
- if (HasEffect(i) && m_effects[i]->GetAuraType() == type)
+ if (effect && effect->GetAuraType() == type)
return true;
}
return false;
@@ -1113,17 +1139,26 @@ void Aura::RecalculateAmountOfEffects()
{
ASSERT (!IsRemoved());
Unit* caster = GetCaster();
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (HasEffect(i))
- m_effects[i]->RecalculateAmount(caster);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect && !IsRemoved())
+ effect->RecalculateAmount(caster);
}
void Aura::HandleAllEffects(AuraApplication * aurApp, uint8 mode, bool apply)
{
ASSERT (!IsRemoved());
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_effects[i] && !IsRemoved())
- m_effects[i]->HandleEffect(aurApp, mode, apply);
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect && !IsRemoved())
+ effect->HandleEffect(aurApp, mode, apply);
+}
+
+uint32 Aura::GetEffectMask() const
+{
+ uint32 effMask = 0;
+ for (AuraEffect* effect : GetAuraEffects())
+ if (effect)
+ effMask |= 1 << effect->GetEffIndex();
+ return effMask;
}
void Aura::GetApplicationList(std::list<AuraApplication*> & applicationList) const
@@ -1310,8 +1345,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// Improved Devouring Plague
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 0))
{
- uint32 damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT);
- damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT);
+ uint32 damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), DOT, GetEffect(0)->GetSpellEffectInfo());
+ damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetEffect(0)->GetSpellEffectInfo());
int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100;
int32 heal = int32(CalculatePct(basepoints0, 15));
@@ -1517,47 +1552,40 @@ void Aura::HandleAuraSpecificPeriodics(AuraApplication const* aurApp, Unit* cast
if (!caster || aurApp->GetRemoveMode())
return;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (AuraEffect* effect : GetAuraEffects())
{
- if (!HasEffect(i))
+ if (!effect || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
continue;
- if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
- continue;
-
- switch (m_spellInfo->Effects[i].ApplyAuraName)
+ switch (effect->GetSpellEffectInfo()->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
case SPELL_AURA_PERIODIC_LEECH:
{
- AuraEffect* aurEff = GetEffect(i);
-
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(aurEff->GetAmount(), 0);
+ uint32 damage = std::max(effect->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aurEff->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
- aurEff->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
- aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ effect->SetDonePct(caster->SpellDamagePctDone(target, m_spellInfo, DOT)); // Calculate done percentage first!
+ effect->SetDamage(caster->SpellDamageBonusDone(target, m_spellInfo, damage, DOT, effect->GetSpellEffectInfo(), GetStackAmount()) * effect->GetDonePct());
+ effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_OBS_MOD_HEALTH:
{
- AuraEffect* aurEff = GetEffect(i);
-
// ignore non positive values (can be result apply spellmods to aura damage
- uint32 damage = std::max(aurEff->GetAmount(), 0);
+ uint32 damage = std::max(effect->GetAmount(), 0);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aurEff->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
- aurEff->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, GetStackAmount()) * aurEff->GetDonePct());
- aurEff->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
+ effect->SetDonePct(caster->SpellHealingPctDone(target, m_spellInfo)); // Calculate done percentage first!
+ effect->SetDamage(caster->SpellHealingBonusDone(target, m_spellInfo, damage, DOT, effect->GetSpellEffectInfo(), GetStackAmount()) * effect->GetDonePct());
+ effect->SetCritChance(caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()));
break;
}
default:
@@ -1605,12 +1633,17 @@ bool Aura::CanStackWith(Aura const* existingAura) const
if (IsPassive() && sameCaster && m_spellInfo->IsDifferentRankOf(existingSpellInfo))
return false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : existingAura->GetSpellEffectInfos())
{
// prevent remove triggering aura by triggered aura
- if (existingSpellInfo->Effects[i].TriggerSpell == GetId()
- // prevent remove triggered aura by triggering aura refresh
- || m_spellInfo->Effects[i].TriggerSpell == existingAura->GetId())
+ if (effect && effect->TriggerSpell == GetId())
+ return true;
+ }
+
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
+ {
+ // prevent remove triggered aura by triggering aura refresh
+ if (effect && effect->TriggerSpell == existingAura->GetId())
return true;
}
@@ -1620,7 +1653,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const
// * The minimap tracking list will only show a check mark next to the last skill activated
// Sometimes this bugs out and doesn't switch the check mark. It has no effect on the actual tracking though.
// * The minimap dots are yellow for both resources
- if (m_spellInfo->HasAura(SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(SPELL_AURA_TRACK_RESOURCES))
+ if (m_spellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES) && existingSpellInfo->HasAura(GetOwner()->GetMap()->GetDifficulty(), SPELL_AURA_TRACK_RESOURCES))
return sWorld->getBoolConfig(CONFIG_ALLOW_TRACK_BOTH_RESOURCES);
// check spell specific stack rules
@@ -1659,7 +1692,10 @@ bool Aura::CanStackWith(Aura const* existingAura) const
// check same periodic auras
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- switch (m_spellInfo->Effects[i].ApplyAuraName)
+ SpellEffectInfo const* effect = GetSpellEffectInfo(i);
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE:
@@ -1673,9 +1709,12 @@ bool Aura::CanStackWith(Aura const* existingAura) const
case SPELL_AURA_OBS_MOD_POWER:
case SPELL_AURA_OBS_MOD_HEALTH:
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
- // periodic auras which target areas are not allowed to stack this way (replenishment for example)
- if (m_spellInfo->Effects[i].IsTargetingArea() || existingSpellInfo->Effects[i].IsTargetingArea())
- break;
+ {
+ SpellEffectInfo const* existingEffect = GetSpellEffectInfo(i);
+ // periodic auras which target areas are not allowed to stack this way (replenishment for example)
+ if (effect->IsTargetingArea() || (existingEffect && existingEffect->IsTargetingArea()))
+ break;
+ }
return true;
default:
break;
@@ -2246,7 +2285,7 @@ void Aura::CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraAppli
}
}
-UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
+UnitAura::UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
: Aura(spellproto, owner, caster, castItem, casterGUID)
{
m_AuraDRGroup = DIMINISHING_NONE;
@@ -2280,31 +2319,31 @@ void UnitAura::Remove(AuraRemoveMode removeMode)
GetUnitOwner()->RemoveOwnedAura(this, removeMode);
}
-void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
+void UnitAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster)
{
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (!HasEffect(effIndex))
+ if (!effect || !HasEffect(effect->EffectIndex))
continue;
UnitList targetList;
// non-area aura
- if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
targetList.push_back(GetUnitOwner());
}
else
{
- float radius = GetSpellInfo()->Effects[effIndex].CalcRadius(caster);
+ float radius = effect->CalcRadius(caster);
if (!GetUnitOwner()->HasUnitState(UNIT_STATE_ISOLATED))
{
- switch (GetSpellInfo()->Effects[effIndex].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
{
targetList.push_back(GetUnitOwner());
- Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
+ Trinity::AnyGroupedUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius, effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID);
Trinity::UnitListSearcher<Trinity::AnyGroupedUnitInObjectRangeCheck> searcher(GetUnitOwner(), targetList, u_check);
GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
@@ -2340,16 +2379,16 @@ void UnitAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster)
for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
+ std::map<Unit*, uint32>::iterator existing = targets.find(*itr);
if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ existing->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[*itr] = 1 << effect->EffectIndex;
}
}
}
-DynObjAura::DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
+DynObjAura::DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID)
: Aura(spellproto, owner, caster, castItem, casterGUID)
{
LoadScripts();
@@ -2374,18 +2413,18 @@ void DynObjAura::Remove(AuraRemoveMode removeMode)
_Remove(removeMode);
}
-void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*/)
+void DynObjAura::FillTargetMap(std::map<Unit*, uint32> & targets, Unit* /*caster*/)
{
Unit* dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
float radius = GetDynobjOwner()->GetRadius();
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetSpellEffectInfos())
{
- if (!HasEffect(effIndex))
+ if (!effect || !HasEffect(effect->EffectIndex))
continue;
UnitList targetList;
- if (GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
- || GetSpellInfo()->Effects[effIndex].TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
+ if (effect->TargetB.GetTarget() == TARGET_DEST_DYNOBJ_ALLY
+ || effect->TargetB.GetTarget() == TARGET_UNIT_DEST_AREA_ALLY)
{
Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targetList, u_check);
@@ -2400,11 +2439,11 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*
for (UnitList::iterator itr = targetList.begin(); itr!= targetList.end();++itr)
{
- std::map<Unit*, uint8>::iterator existing = targets.find(*itr);
+ std::map<Unit*, uint32>::iterator existing = targets.find(*itr);
if (existing != targets.end())
- existing->second |= 1<<effIndex;
+ existing->second |= 1 << effect->EffectIndex;
else
- targets[*itr] = 1<<effIndex;
+ targets[*itr] = 1 << effect->EffectIndex;
}
}
}
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index f69d9baafe0..c2c356efa4b 100644
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -41,24 +41,25 @@ class ChargeDropEvent;
class AuraApplication
{
- friend void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask);
+ friend void Unit::_ApplyAura(AuraApplication * aurApp, uint32 effMask);
friend void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
friend void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex);
friend void Unit::RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode);
- friend AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask);
+ friend AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint32 effMask);
private:
Unit* const _target;
Aura* const _base;
AuraRemoveMode _removeMode:8; // Store info for know remove aura reason
uint8 _slot; // Aura slot on unit
uint8 _flags; // Aura info flag
- uint8 _effectsToApply; // Used only at spell hit to determine which effect should be applied
+ uint32 _effectsToApply; // Used only at spell hit to determine which effect should be applied
bool _needClientUpdate:1;
+ uint32 _effectMask;
- explicit AuraApplication(Unit* target, Unit* caster, Aura* base, uint8 effMask);
+ explicit AuraApplication(Unit* target, Unit* caster, Aura* base, uint32 effMask);
void _Remove();
private:
- void _InitFlags(Unit* caster, uint8 effMask);
+ void _InitFlags(Unit* caster, uint32 effMask);
void _HandleEffect(uint8 effIndex, bool apply);
public:
@@ -67,10 +68,10 @@ class AuraApplication
uint8 GetSlot() const { return _slot; }
uint8 GetFlags() const { return _flags; }
- uint8 GetEffectMask() const { return _flags & (AFLAG_EFF_INDEX_0 | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2); }
- bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return (_flags & (1 << effect)) != 0; }
+ uint32 GetEffectMask() const { return _effectMask; }
+ bool HasEffect(uint8 effect) const { ASSERT(effect < MAX_SPELL_EFFECTS); return (_effectMask & (1 << effect)) != 0; }
bool IsPositive() const { return (_flags & AFLAG_POSITIVE) != 0; }
- bool IsSelfcast() const { return (_flags & AFLAG_CASTER) != 0; }
+ bool IsSelfcast() const { return (_flags & AFLAG_NOCASTER) == 0; }
uint8 GetEffectsToApply() const { return _effectsToApply; }
void SetRemoveMode(AuraRemoveMode mode) { _removeMode = mode; }
@@ -84,16 +85,16 @@ class AuraApplication
class Aura
{
- friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
typedef std::map<ObjectGuid, AuraApplication*> ApplicationMap;
- static uint8 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint8 avalibleEffectMask, WorldObject* owner);
- static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint8 tryEffMask, WorldObject* owner, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
- static Aura* TryCreate(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
- static Aura* Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount, Item* castItem, ObjectGuid casterGUID);
+ static uint32 BuildEffectMaskForOwner(SpellInfo const* spellProto, uint32 avalibleEffectMask, WorldObject* owner);
+ static Aura* TryRefreshStackOrCreate(SpellInfo const* spellproto, uint32 tryEffMask, WorldObject* owner, Unit* caster, int32 *baseAmount = NULL, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty, bool* refresh = NULL);
+ static Aura* TryCreate(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem = NULL, ObjectGuid casterGUID = ObjectGuid::Empty);
+ static Aura* Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
explicit Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID);
- void _InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount);
+ void _InitEffects(uint32 effMask, Unit* caster, int32 *baseAmount);
virtual ~Aura();
SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
@@ -113,7 +114,7 @@ class Aura
void _Remove(AuraRemoveMode removeMode);
virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
- virtual void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) = 0;
+ virtual void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) = 0;
void UpdateTargetMap(Unit* caster, bool apply = true);
void _RegisterForTargets() {Unit* caster = GetCaster(); UpdateTargetMap(caster, false);}
@@ -152,7 +153,7 @@ class Aura
uint8 GetCasterLevel() const { return m_casterLevel; }
- bool HasMoreThanOneEffectForType(AuraType auraType) const;
+ bool HasMoreThanOneEffectForType(AuraType auraType, uint32 difficulty) const;
bool IsArea() const;
bool IsPassive() const;
bool IsDeathPersistent() const;
@@ -175,13 +176,14 @@ class Aura
void UnregisterSingleTarget();
int32 CalcDispelChance(Unit* auraTarget, bool offensive) const;
- void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount);
+ void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 *baseAmount);
// helpers for aura effects
bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != NULL; }
bool HasEffectType(AuraType type) const;
- AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; }
- uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; }
+ //AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return Effects[effIndex]; }
+ AuraEffect* GetEffect(uint32 index) const;
+ uint32 GetEffectMask() const;
void RecalculateAmountOfEffects();
void HandleAllEffects(AuraApplication * aurApp, uint8 mode, bool apply);
@@ -242,6 +244,12 @@ class Aura
AuraScript* GetScriptByName(std::string const& scriptName) const;
std::list<AuraScript*> m_loadedScripts;
+
+ AuraEffectVector GetAuraEffects() const { return _effects; }
+
+ SpellEffectInfoVector GetSpellEffectInfos() const { return _spelEffectInfos; }
+ SpellEffectInfo const* GetSpellEffectInfo(uint32 index) const;
+
private:
void _DeleteRemovedApplications();
protected:
@@ -260,7 +268,7 @@ class Aura
uint8 m_procCharges; // Aura charges (0 for infinite)
uint8 m_stackAmount; // Aura stack amount
- AuraEffect* m_effects[3];
+ //AuraEffect* m_effects[3];
ApplicationMap m_applications;
bool m_isRemoved:1;
@@ -271,20 +279,23 @@ class Aura
private:
Unit::AuraApplicationList m_removedApplications;
+
+ AuraEffectVector _effects;
+ SpellEffectInfoVector _spelEffectInfos;
};
class UnitAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
- protected:
- explicit UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
+ explicit UnitAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+
void _ApplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
void _UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * aurApp) override;
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
+ void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) override;
// Allow Apply Aura Handler to modify and access m_AuraDRGroup
void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
@@ -296,13 +307,13 @@ class UnitAura : public Aura
class DynObjAura : public Aura
{
- friend Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
- protected:
- explicit DynObjAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+ friend Aura* Aura::Create(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
public:
+ explicit DynObjAura(SpellInfo const* spellproto, uint32 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, ObjectGuid casterGUID);
+
void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) override;
- void FillTargetMap(std::map<Unit*, uint8> & targets, Unit* caster) override;
+ void FillTargetMap(std::map<Unit*, uint32> & targets, Unit* caster) override;
};
class ChargeDropEvent : public BasicEvent
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8583d055123..f376e0979b2 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -57,6 +57,7 @@
#include "DB2Stores.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
+#include "SpellPackets.h"
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -118,6 +119,28 @@ SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget()
m_targetMask = 0;
}
+SpellCastTargets::SpellCastTargets(Unit* caster, uint32 targetMask, ObjectGuid targetGuid, ObjectGuid itemTargetGuid, ObjectGuid srcTransportGuid, ObjectGuid destTransportGuid, Position srcPos, Position destPos, float elevation, float missileSpeed, std::string targetString) :
+ m_targetMask(targetMask), m_objectTargetGUID(targetGuid), m_itemTargetGUID(itemTargetGuid), m_elevation(elevation), m_speed(missileSpeed), m_strTarget(targetString)
+{
+ m_objectTarget = NULL;
+ m_itemTarget = NULL;
+ m_itemTargetEntry = 0;
+
+ m_src._transportGUID = srcTransportGuid;
+ if (m_src._transportGUID != ObjectGuid::Empty)
+ m_src._transportOffset.Relocate(srcPos);
+ else
+ m_src._position.Relocate(srcPos);
+
+ m_dst._transportGUID = destTransportGuid;
+ if (m_dst._transportGUID != ObjectGuid::Empty)
+ m_dst._transportOffset.Relocate(destPos);
+ else
+ m_dst._position.Relocate(destPos);
+
+ Update(caster);
+}
+
SpellCastTargets::~SpellCastTargets() { }
void SpellCastTargets::Read(ByteBuffer& data, Unit* caster)
@@ -173,9 +196,41 @@ void SpellCastTargets::Read(ByteBuffer& data, Unit* caster)
Update(caster);
}
-void SpellCastTargets::Write(ByteBuffer& data)
+void SpellCastTargets::Write(WorldPackets::Spells::SpellTargetData& data)
{
- data << uint32(m_targetMask);
+ data.Flags = m_targetMask;
+
+ if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_MINIPET))
+ data.Unit = m_objectTargetGUID;
+
+ if (m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM) && m_itemTarget)
+ data.Item = m_itemTarget->GetGUID();
+
+ if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
+ {
+ WorldPackets::Spells::TargetLocation& target = data.SrcLocation.Value;
+ target.Transport = m_src._transportGUID; // relative position guid here - transport for example
+ if (!m_src._transportGUID.IsEmpty())
+ target.Location = m_src._transportOffset;
+ else
+ target.Location = m_src._position;
+ data.SrcLocation.HasValue = true;
+ }
+
+ if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
+ {
+ WorldPackets::Spells::TargetLocation& target = data.DstLocation.Value;
+ target.Transport = m_dst._transportGUID; // relative position guid here - transport for example
+ if (!m_dst._transportGUID.IsEmpty())
+ target.Location = m_dst._transportOffset;
+ else
+ target.Location = m_dst._position;
+ data.DstLocation.HasValue = true;
+ }
+
+ if (m_targetMask & TARGET_FLAG_STRING)
+ data.Name = m_strTarget;
+ /*data << uint32(m_targetMask);
if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_ENEMY | TARGET_FLAG_UNIT_MINIPET))
data << m_objectTargetGUID.WriteAsPacked();
@@ -207,7 +262,7 @@ void SpellCastTargets::Write(ByteBuffer& data)
}
if (m_targetMask & TARGET_FLAG_STRING)
- data << m_strTarget;
+ data << m_strTarget;*/
}
ObjectGuid SpellCastTargets::GetOrigUnitTargetGUID() const
@@ -507,20 +562,26 @@ void SpellCastTargets::OutDebug() const
TC_LOG_INFO("spells", "elevation: %f", m_elevation);
}
-SpellValue::SpellValue(SpellInfo const* proto)
+SpellValue::SpellValue(Difficulty diff, SpellInfo const* proto)
{
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- EffectBasePoints[i] = proto->Effects[i].BasePoints;
+ // todo 6.x
+ SpellEffectInfoVector effects = proto->GetEffectsForDifficulty(diff);
+ ASSERT(effects.size() <= MAX_SPELL_EFFECTS);
+ for (SpellEffectInfo const* effect : effects)
+ if (effect)
+ EffectBasePoints[effect->EffectIndex] = effect->BasePoints;
+
MaxAffectedTargets = proto->MaxAffectedTargets;
RadiusMod = 1.0f;
AuraStackAmount = 1;
}
Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) :
-m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
-m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
-, m_spellValue(new SpellValue(m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
+m_spellInfo(info), m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster),
+m_spellValue(new SpellValue(caster->GetMap()->GetDifficulty(), m_spellInfo)), m_preGeneratedPath(PathGenerator(m_caster))
{
+ _effects = info->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty());
+
m_customError = SPELL_CUSTOM_ERROR_NONE;
m_skipCheck = skipCheck;
m_selfContainer = NULL;
@@ -592,7 +653,9 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
gameObjTarget = NULL;
destTarget = NULL;
damage = 0;
+ variance = 0.0f;
effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH;
+ effectInfo = nullptr;
m_diminishLevel = DIMINISHING_LEVEL_1;
m_diminishGroup = DIMINISHING_NONE;
m_damage = 0;
@@ -764,36 +827,40 @@ void Spell::SelectSpellTargets()
SelectExplicitTargets();
uint32 processedAreaEffectsMask = 0;
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+
+ for (SpellEffectInfo const* effect : GetEffects())
{
+ if (!effect)
+ continue;
+
// not call for empty effect.
// Also some spells use not used effect targets for store targets for dummy effect in triggered spells
- if (!m_spellInfo->Effects[i].IsEffect())
+ if (!effect->IsEffect())
continue;
// set expected type of implicit targets to be sent to client
- uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
+ uint32 implicitTargetMask = GetTargetFlagMask(effect->TargetA.GetObjectType()) | GetTargetFlagMask(effect->TargetB.GetObjectType());
if (implicitTargetMask & TARGET_FLAG_UNIT)
m_targets.SetTargetFlag(TARGET_FLAG_UNIT);
if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
- SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
- SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
+ SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetA, processedAreaEffectsMask);
+ SelectEffectImplicitTargets(SpellEffIndex(effect->EffectIndex), effect->TargetB, processedAreaEffectsMask);
// Select targets of effect based on effect type
// those are used when no valid target could be added for spell effect based on spell target type
// some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
// some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
// some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
- SelectEffectTypeImplicitTargets(i);
+ SelectEffectTypeImplicitTargets(effect->EffectIndex);
if (m_targets.HasDst())
- AddDestTarget(*m_targets.GetDst(), i);
+ AddDestTarget(*m_targets.GetDst(), effect->EffectIndex);
if (m_spellInfo->IsChanneled())
{
- uint8 mask = (1 << i);
+ uint32 mask = (1 << effect->EffectIndex);
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
if (ihit->effectMask & mask)
@@ -863,18 +930,23 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
// targets for effect already selected
if (effectMask & processedEffectMask)
return;
- // choose which targets we can select at once
- for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
+ if (SpellEffectInfo const* _effect = GetEffect(effIndex))
{
- SpellEffectInfo const* effects = GetSpellInfo()->Effects;
- if (effects[j].IsEffect() &&
- effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
- effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
- effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
- effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
- CheckScriptEffectImplicitTargets(effIndex, j))
+ // choose which targets we can select at once
+ for (SpellEffectInfo const* effect : GetEffects())
{
- effectMask |= 1 << j;
+ //for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
+ if (!effect || effect->EffectIndex <= uint32(effIndex))
+ continue;
+ if (effect->IsEffect() &&
+ _effect->TargetA.GetTarget() == effect->TargetA.GetTarget() &&
+ _effect->TargetB.GetTarget() == effect->TargetB.GetTarget() &&
+ _effect->ImplicitTargetConditions == effect->ImplicitTargetConditions &&
+ _effect->CalcRadius(m_caster) == effect->CalcRadius(m_caster) &&
+ CheckScriptEffectImplicitTargets(effIndex, effect->EffectIndex))
+ {
+ effectMask |= 1 << effect->EffectIndex;
+ }
}
}
processedEffectMask |= effectMask;
@@ -1009,6 +1081,10 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
return;
}
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return;
+
float range = 0.0f;
switch (targetType.GetCheckType())
{
@@ -1030,7 +1106,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
break;
}
- ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
+ ConditionList* condList = effect->ImplicitTargetConditions;
// handle emergency case - try to use other provided targets if no conditions provided
if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
@@ -1116,9 +1192,12 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
std::list<WorldObject*> targets;
SpellTargetObjectTypes objectType = targetType.GetObjectType();
SpellTargetCheckTypes selectionType = targetType.GetCheckType();
- ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return;
+ ConditionList* condList = effect->ImplicitTargetConditions;
float coneAngle = float(M_PI) / 2;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
{
@@ -1199,8 +1278,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
std::list<WorldObject*> targets;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
- SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return;
+ float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
+ SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect->ImplicitTargetConditions);
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
@@ -1236,7 +1318,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
{
/// @todo fix this check
- if (m_spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || m_spellInfo->HasEffect(SPELL_EFFECT_BIND))
+ if (HasEffect(SPELL_EFFECT_TELEPORT_UNITS) || HasEffect(SPELL_EFFECT_BIND))
dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
else if (st->target_mapId == m_caster->GetMapId())
dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
@@ -1284,23 +1366,26 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
}
default:
{
- float dist;
- float angle = targetType.CalcDirectionAngle();
- float objSize = m_caster->GetObjectSize();
- if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
- dist = PET_FOLLOW_DIST;
- else
- dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ if (SpellEffectInfo const* effect = GetEffect(effIndex))
+ {
+ float dist;
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = m_caster->GetObjectSize();
+ if (targetType.GetTarget() == TARGET_DEST_CASTER_SUMMON)
+ dist = PET_FOLLOW_DIST;
+ else
+ dist = effect->CalcRadius(m_caster);
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
- dist = objSize + (dist - objSize) * float(rand_norm());
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_CASTER_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
- Position pos = dest._position;
- m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ Position pos = dest._position;
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
- dest.Relocate(pos);
+ dest.Relocate(pos);
+ }
break;
}
}
@@ -1323,18 +1408,21 @@ void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplici
break;
default:
{
- float angle = targetType.CalcDirectionAngle();
- float objSize = target->GetObjectSize();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (dist < objSize)
- dist = objSize;
- else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
- dist = objSize + (dist - objSize) * float(rand_norm());
-
- Position pos = dest._position;
- target->MovePositionToFirstCollision(pos, dist, angle);
-
- dest.Relocate(pos);
+ if (SpellEffectInfo const* effect = GetEffect(effIndex))
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float objSize = target->GetObjectSize();
+ float dist = effect->CalcRadius(m_caster);
+ if (dist < objSize)
+ dist = objSize;
+ else if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
+ dist = objSize + (dist - objSize) * float(rand_norm());
+
+ Position pos = dest._position;
+ target->MovePositionToFirstCollision(pos, dist, angle);
+
+ dest.Relocate(pos);
+ }
break;
}
}
@@ -1365,15 +1453,18 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
return;
default:
{
- float angle = targetType.CalcDirectionAngle();
- float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
- if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
- dist *= float(rand_norm());
+ if (SpellEffectInfo const* effect = GetEffect(effIndex))
+ {
+ float angle = targetType.CalcDirectionAngle();
+ float dist = effect->CalcRadius(m_caster);
+ if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
+ dist *= float(rand_norm());
- Position pos = dest._position;
- m_caster->MovePositionToFirstCollision(pos, dist, angle);
+ Position pos = dest._position;
+ m_caster->MovePositionToFirstCollision(pos, dist, angle);
- dest.Relocate(pos);
+ dest.Relocate(pos);
+ }
break;
}
}
@@ -1451,21 +1542,25 @@ void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImpli
void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
{
- uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTargets;
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return;
+
+ uint32 maxTargets = effect->ChainTargets;
if (Player* modOwner = m_caster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
if (maxTargets > 1)
{
// mark damage multipliers as used
- for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
- if (effMask & (1 << k))
- m_damageMultipliers[k] = 1.0f;
+ for (SpellEffectInfo const* eff : GetEffects())
+ if (eff && (effMask & (1 << eff->EffectIndex)))
+ m_damageMultipliers[eff->EffectIndex] = 1.0f;
m_applyMultiplierMask |= effMask;
std::list<WorldObject*> targets;
SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()
- , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
+ , effect->ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
// Chain primary target is added earlier
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
@@ -1644,11 +1739,14 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
veh->SetLastShootPos(*m_targets.GetDstPos());
}
-void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
+void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
{
// special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
/// @todo this is a workaround - target shouldn't be stored in target map for those spells
- switch (m_spellInfo->Effects[effIndex].Effect)
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return;
+ switch (effect->Effect)
{
case SPELL_EFFECT_SUMMON_RAF_FRIEND:
case SPELL_EFFECT_SUMMON_PLAYER:
@@ -1667,17 +1765,17 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
}
// select spell implicit targets based on effect type
- if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
+ if (!effect->GetImplicitTargetType())
return;
- uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
+ uint32 targetMask = effect->GetMissingTargetMask();
if (!targetMask)
return;
WorldObject* target = NULL;
- switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
+ switch (effect->GetImplicitTargetType())
{
// add explicit object target or self to the target map
case EFFECT_IMPLICIT_TARGET_EXPLICIT:
@@ -2012,9 +2110,9 @@ void Spell::CleanupTargetList()
void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*= true*/, bool implicit /*= true*/, Position const* losPosition /*= nullptr*/)
{
- for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
- if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex, losPosition))
- effectMask &= ~(1 << effIndex);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (!effect->IsEffect() || !CheckEffectTarget(target, effect->EffectIndex, losPosition)))
+ effectMask &= ~(1 << effect->EffectIndex);
// no effects left
if (!effectMask)
@@ -2025,9 +2123,9 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
return;
// Check for effect immune skip if immuned
- for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
- if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex))
- effectMask &= ~(1 << effIndex);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && target->IsImmunedToSpellEffect(m_spellInfo, effect->EffectIndex))
+ effectMask &= ~(1 << effect->EffectIndex);
ObjectGuid targetGUID = target->GetGUID();
@@ -2120,19 +2218,22 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
{
- for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (!m_spellInfo->Effects[effIndex].IsEffect())
- effectMask &= ~(1 << effIndex);
+ if (!effect)
+ continue;
+
+ if (!effect->IsEffect())
+ effectMask &= ~(1 << effect->EffectIndex);
else
{
- switch (m_spellInfo->Effects[effIndex].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_GAMEOBJECT_DAMAGE:
case SPELL_EFFECT_GAMEOBJECT_REPAIR:
case SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE:
if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
- effectMask &= ~(1 << effIndex);
+ effectMask &= ~(1 << effect->EffectIndex);
break;
default:
break;
@@ -2187,9 +2288,9 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
void Spell::AddItemTarget(Item* item, uint32 effectMask)
{
- for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
- if (!m_spellInfo->Effects[effIndex].IsEffect())
- effectMask &= ~(1 << effIndex);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (!effect || !effect->IsEffect())
+ effectMask &= ~(1 << effect->EffectIndex);
// no effects left
if (!effectMask)
@@ -2234,10 +2335,10 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
uint8 farMask = 0;
// create far target mask
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
- if ((1 << i) & mask)
- farMask |= (1 << i);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && effect->IsFarUnitTargetEffect())
+ if ((1 << effect->EffectIndex) & mask)
+ farMask |= (1 << effect->EffectIndex);
if (!farMask)
return;
@@ -2248,9 +2349,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
// do far effects on the unit
// can't use default call because of threading, do stuff as fast as possible
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (farMask & (1 << i))
- HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ for(SpellEffectInfo const* effect : GetEffects())
+ if (effect && (farMask & (1 << effect->EffectIndex)))
+ HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
return;
}
@@ -2433,7 +2534,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
}
}
- if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)))
+ if (missInfo != SPELL_MISS_EVADE && !m_caster->IsFriendlyTo(unit) && (!m_spellInfo->IsPositive() || HasEffect(SPELL_EFFECT_DISPEL)))
{
m_caster->CombatStart(unit, !(m_spellInfo->AttributesEx3 & SPELL_ATTR3_NO_INITIAL_AGGRO));
@@ -2474,10 +2575,10 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
// disable effects to which unit is immune
SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
- for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber))
- if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
- effectMask &= ~(1 << effectNumber);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex)))
+ if (unit->IsImmunedToSpellEffect(m_spellInfo, effect->EffectIndex))
+ effectMask &= ~(1 << effect->EffectIndex);
if (!effectMask)
return returnVal;
@@ -2535,9 +2636,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
}
uint8 aura_effmask = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
- aura_effmask |= 1 << i;
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex) && effect->IsUnitOwnedAuraEffect()))
+ aura_effmask |= 1 << effect->EffectIndex;
// Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
m_diminishGroup = GetDiminishingReturnsGroupForSpell(m_spellInfo, m_triggeredByAuraSpell != nullptr);
@@ -2557,18 +2658,21 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
// Select rank for aura with level requirements only in specific cases
// Unit has to be target only of aura effect, both caster and target have to be players, target has to be other than unit target
SpellInfo const* aurSpellInfo = m_spellInfo;
- int32 basePoints[3];
+ int32 basePoints[MAX_SPELL_EFFECTS];
if (scaleAura)
{
aurSpellInfo = m_spellInfo->GetAuraRankForLevel(unitTarget->getLevel());
ASSERT(aurSpellInfo);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : aurSpellInfo->GetEffectsForDifficulty(0))
{
- basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
- if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
+ basePoints[effect->EffectIndex] = effect->BasePoints;
+ if (SpellEffectInfo const* myEffect = GetEffect(effect->EffectIndex))
{
- aurSpellInfo = m_spellInfo;
- break;
+ if (myEffect->Effect != effect->Effect)
+ {
+ aurSpellInfo = m_spellInfo;
+ break;
+ }
}
}
}
@@ -2577,7 +2681,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
bool refresh = false;
m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit,
- m_originalCaster, (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh);
+ m_originalCaster, (aurSpellInfo == m_spellInfo) ? m_spellValue->EffectBasePoints : basePoints, m_CastItem, ObjectGuid::Empty, &refresh);
if (m_spellAura)
{
// Set aura stack amount to desired value
@@ -2599,8 +2703,8 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
m_spellAura->Remove();
bool found = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex) && effect->Effect != SPELL_EFFECT_APPLY_AURA))
found = true;
if (!found)
return SPELL_MISS_IMMUNE;
@@ -2624,10 +2728,11 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
{
int32 origDuration = duration;
duration = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (AuraEffect const* eff = m_spellAura->GetEffect(i))
- if (int32 period = eff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
- duration = std::max(std::max(origDuration / period, 1) * period, duration);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect)
+ if (AuraEffect const* eff = m_spellAura->GetEffect(effect->EffectIndex))
+ if (int32 period = eff->GetPeriod()) // period is hastened by UNIT_MOD_CAST_SPEED
+ duration = std::max(std::max(origDuration / period, 1) * period, duration);
// if there is no periodic effect
if (!duration)
@@ -2646,9 +2751,9 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
}
}
- for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber))
- HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex)))
+ HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
return SPELL_MISS_NONE;
}
@@ -2742,9 +2847,9 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target)
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers();
- for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber))
- HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex)))
+ HandleEffects(NULL, NULL, go, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
CallScriptOnHitHandlers();
CallScriptAfterHitHandlers();
@@ -2759,9 +2864,9 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target)
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers();
- for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber))
- HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (effectMask & (1 << effect->EffectIndex)))
+ HandleEffects(NULL, target->item, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT_TARGET);
CallScriptOnHitHandlers();
@@ -2776,9 +2881,9 @@ bool Spell::UpdateChanneledTargetList()
uint8 channelTargetEffectMask = m_channelTargetEffectMask;
uint8 channelAuraMask = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
- channelAuraMask |= 1<<i;
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ channelAuraMask |= 1 << effect->EffectIndex;
channelAuraMask &= channelTargetEffectMask;
@@ -2843,15 +2948,15 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
// Fill aura scaling information
if (m_caster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_SCALING))
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
// Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
- if (m_spellInfo->IsPositiveEffect(i))
+ if (m_spellInfo->IsPositiveEffect(effect->EffectIndex))
{
- m_auraScaleMask |= (1 << i);
- if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
+ m_auraScaleMask |= (1 << effect->EffectIndex);
+ if (m_spellValue->EffectBasePoints[effect->EffectIndex] != effect->BasePoints)
{
m_auraScaleMask = 0;
break;
@@ -2966,8 +3071,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
if (!(_triggeredCastFlags & TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS) && m_spellInfo->IsBreakingStealth())
{
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST);
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_spellInfo->Effects[i].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT)
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && effect->GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT)
{
m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_SPELL_ATTACK);
break;
@@ -3296,10 +3401,6 @@ void Spell::handle_immediate()
// Remove used for cast item if need (it can be already NULL after TakeReagents call
TakeCastItem();
- // handle ammo consumption for thrown weapons
- if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled())
- TakeAmmo();
-
if (m_spellState != SPELL_STATE_CASTING)
finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
}
@@ -3391,14 +3492,14 @@ void Spell::_handle_immediate_phase()
PrepareScriptHitHandlers();
// handle effects with SPELL_EFFECT_HANDLE_HIT mode
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
// don't do anything for empty effect
- if (!m_spellInfo->Effects[j].IsEffect())
+ if (!effect || !effect->IsEffect())
continue;
// call effect handlers to handle destination hit
- HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT);
+ HandleEffects(NULL, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_HIT);
}
// process items
@@ -3436,7 +3537,7 @@ void Spell::_handle_finish_phase()
HandleHolyPower(m_caster->m_movedPlayer);
}
- if (m_caster->m_extraAttacks && m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
+ if (m_caster->m_extraAttacks && HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
{
if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID()))
m_caster->HandleProcExtraAttackFor(victim);
@@ -3494,9 +3595,10 @@ void Spell::update(uint32 difftime)
// check if the player caster has moved before the spell finished
// with the exception of spells affected with SPELL_AURA_CAST_WHILE_WALKING effect
+ SpellEffectInfo const* effect = GetEffect(EFFECT_0);
if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) &&
m_caster->isMoving() && (m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) &&
- (m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
+ ((effect && effect->Effect != SPELL_EFFECT_STUCK) || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR)) &&
!m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
// don't cancel for melee, autorepeat, triggered and instant spells
@@ -3671,17 +3773,18 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas
if (result == SPELL_CAST_OK)
return;
- WorldPacket data(opcode, (4+1+1));
- data << uint8(cast_count);
- data << uint32(spellInfo->Id);
- data << uint8(result); // problem
+ WorldPackets::Spells::CastFailed packet(opcode);
+ packet.CastID = cast_count;
+ packet.SpellID = spellInfo->Id;
+ packet.Reason = result;
+
switch (result)
{
case SPELL_FAILED_NOT_READY:
- data << uint32(0); // unknown (value 1 update cooldowns on client flag)
+ packet.FailedArg1 = 0; // unknown (value 1 update cooldowns on client flag)
break;
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
- data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
+ packet.FailedArg1 = spellInfo->RequiresSpellFocus; // SpellFocusObject.dbc id
break;
case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
// hardcode areas limitation case
@@ -3689,71 +3792,71 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas
{
case 41617: // Cenarion Mana Salve
case 41619: // Cenarion Healing Salve
- data << uint32(3905);
+ packet.FailedArg1 = 3905;
break;
case 41618: // Bottled Nethergon Energy
case 41620: // Bottled Nethergon Vapor
- data << uint32(3842);
+ packet.FailedArg1 = 3842;
break;
case 45373: // Bloodberry Elixir
- data << uint32(4075);
+ packet.FailedArg1 = 4075;
break;
default: // default case (don't must be)
- data << uint32(0);
+ packet.FailedArg1 = 0;
break;
}
break;
case SPELL_FAILED_TOTEMS:
if (spellInfo->Totem[0])
- data << uint32(spellInfo->Totem[0]);
+ packet.FailedArg1 = spellInfo->Totem[0];
if (spellInfo->Totem[1])
- data << uint32(spellInfo->Totem[1]);
+ packet.FailedArg2 = spellInfo->Totem[1];
break;
case SPELL_FAILED_TOTEM_CATEGORY:
if (spellInfo->TotemCategory[0])
- data << uint32(spellInfo->TotemCategory[0]);
+ packet.FailedArg1 = spellInfo->TotemCategory[0];
if (spellInfo->TotemCategory[1])
- data << uint32(spellInfo->TotemCategory[1]);
+ packet.FailedArg2 = spellInfo->TotemCategory[1];
break;
case SPELL_FAILED_EQUIPPED_ITEM_CLASS:
case SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND:
case SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND:
- data << uint32(spellInfo->EquippedItemClass);
- data << uint32(spellInfo->EquippedItemSubClassMask);
+ packet.FailedArg1 = spellInfo->EquippedItemClass;
+ packet.FailedArg2 = spellInfo->EquippedItemSubClassMask;
break;
case SPELL_FAILED_TOO_MANY_OF_ITEM:
{
- uint32 item = 0;
- for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
- if (spellInfo->Effects[eff].ItemType)
- item = spellInfo->Effects[eff].ItemType;
- ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
- if (proto && proto->ItemLimitCategory)
- data << uint32(proto->ItemLimitCategory);
- break;
+ uint32 item = 0;
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
+ if (effect->ItemType)
+ item = effect->ItemType;
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
+ if (proto && proto->ItemLimitCategory)
+ packet.FailedArg1 = proto->ItemLimitCategory;
+ break;
}
case SPELL_FAILED_PREVENTED_BY_MECHANIC:
- data << uint32(spellInfo->GetAllEffectsMechanicMask()); // SpellMechanic.dbc id
+ packet.FailedArg1 = spellInfo->GetAllEffectsMechanicMask(); // SpellMechanic.dbc id
break;
case SPELL_FAILED_NEED_EXOTIC_AMMO:
- data << uint32(spellInfo->EquippedItemSubClassMask); // seems correct...
+ packet.FailedArg1 = spellInfo->EquippedItemSubClassMask; // seems correct...
break;
case SPELL_FAILED_NEED_MORE_ITEMS:
- data << uint32(0); // Item id
- data << uint32(0); // Item count?
+ packet.FailedArg1 = 0; // Item id
+ packet.FailedArg2 = 0; // Item count?
break;
case SPELL_FAILED_MIN_SKILL:
- data << uint32(0); // SkillLine.dbc id
- data << uint32(0); // required skill value
+ packet.FailedArg1 = 0; // SkillLine.dbc id
+ packet.FailedArg2 = 0; // required skill value
break;
case SPELL_FAILED_FISHING_TOO_LOW:
- data << uint32(0); // required fishing skill
+ packet.FailedArg1 = 0; // required fishing skill
break;
case SPELL_FAILED_CUSTOM_ERROR:
- data << uint32(customError);
+ packet.FailedArg1 = customError;
break;
case SPELL_FAILED_SILENCED:
- data << uint32(0); // Unknown
+ packet.FailedArg1 = 0; // Unknown
break;
case SPELL_FAILED_REAGENTS:
{
@@ -3773,14 +3876,15 @@ void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cas
}
}
- data << uint32(missingItem); // first missing item
+ packet.FailedArg1 = missingItem; // first missing item
break;
}
// TODO: SPELL_FAILED_NOT_STANDING
default:
break;
}
- caster->GetSession()->SendPacket(&data);
+
+ caster->GetSession()->SendPacket(packet.Write());
}
void Spell::SendSpellStart()
@@ -3788,7 +3892,7 @@ void Spell::SendSpellStart()
if (!IsNeedSendToClient())
return;
- //TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
+ TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
@@ -3803,7 +3907,81 @@ void Spell::SendSpellStart()
if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNES)
castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
- WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
+ WorldPackets::Spells::SpellStart packet;
+ WorldPackets::Spells::SpellCastData& castData = packet.Cast;
+
+ if (m_CastItem)
+ castData.CasterGUID = m_CastItem->GetGUID();
+ else
+ castData.CasterGUID = m_caster->GetGUID();
+
+ castData.CasterUnit = m_caster->GetGUID();
+ castData.CastID = m_cast_count; // pending spell cast?
+ castData.SpellID = m_spellInfo->Id;
+ castData.CastFlags = castFlags;
+ castData.CastTime = m_casttime;
+
+ m_targets.Write(castData.Target);
+
+ if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ {
+ /// @todo Implement multiple power types
+ WorldPackets::Spells::SpellPowerData powerData;
+ powerData.Type = m_spellInfo->PowerType;
+ powerData.Cost = m_caster->GetPower((Powers)m_spellInfo->PowerType);
+ castData.RemainingPower.push_back(powerData);
+ }
+
+ if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
+ {
+ WorldPackets::Spells::RuneData& runeData = castData.RemainingRunes.Value;
+ //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
+ //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
+ if (Player* player = m_caster->ToPlayer())
+ {
+ runeData.Start = m_runesState; // runes state before
+ runeData.Count = player->GetRunesState(); // runes state after
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ // float casts ensure the division is performed on floats as we need float result
+ float baseCd = float(player->GetRuneBaseCooldown(i));
+ runeData.Cooldowns.push_back((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
+ }
+ }
+ else
+ {
+ runeData.Start = 0;
+ runeData.Count = 0;
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ runeData.Cooldowns.push_back(0);
+ }
+
+ castData.RemainingRunes.HasValue = true;
+ }
+
+ /** @todo implement spell ammo packet data
+ if (castFlags & CAST_FLAG_PROJECTILE)
+ {
+ castData.Ammo.DisplayID = 0;
+ castData.Ammo.InventoryType = 0;
+ }**/
+
+ /** @todo implement spell immunity packet data
+ if (castFlags & CAST_FLAG_IMMUNITY)
+ {
+ castData.Immunities.School = 0;
+ castData.Immunities.Value = 0;
+ }**/
+
+ /** @todo implement heal prediction packet data
+ if (castFlags & CAST_FLAG_HEAL_PREDICTION)
+ {
+ castData.Predict.BeconGUID = ??
+ castData.Predict.Points = 0;
+ castData.Predict.Type = 0;
+ }**/
+
+ /*WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
if (m_CastItem)
data << m_CastItem->GetPackGUID();
else
@@ -3863,9 +4041,9 @@ void Spell::SendSpellStart()
data << uint8(0); // unkByte
// if (unkByte == 2)
// data.append(0);
- }
+ }*/
- m_caster->SendMessageToSet(&data, true);
+ m_caster->SendMessageToSet(packet.Write(), true);
}
void Spell::SendSpellGo()
@@ -3874,7 +4052,7 @@ void Spell::SendSpellGo()
if (!IsNeedSendToClient())
return;
- //TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
+ TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
uint32 castFlags = CAST_FLAG_UNKNOWN_9;
@@ -3897,7 +4075,7 @@ void Spell::SendSpellGo()
castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
}
- if (m_spellInfo->HasEffect(SPELL_EFFECT_ACTIVATE_RUNE))
+ if (HasEffect(SPELL_EFFECT_ACTIVATE_RUNE))
castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
if (m_targets.HasTraj())
@@ -3906,7 +4084,68 @@ void Spell::SendSpellGo()
if (!m_spellInfo->StartRecoveryTime)
castFlags |= CAST_FLAG_NO_GCD;
- WorldPacket data(SMSG_SPELL_GO, 50); // guess size
+ WorldPackets::Spells::SpellGo packet;
+ WorldPackets::Spells::SpellCastData& castData = packet.Cast;
+
+ if (m_CastItem)
+ castData.CasterGUID = m_CastItem->GetGUID();
+ else
+ castData.CasterGUID = m_caster->GetGUID();
+
+ castData.CasterUnit = m_caster->GetGUID();
+ castData.CastID = m_cast_count; // pending spell cast?
+ castData.SpellID = m_spellInfo->Id;
+ castData.CastFlags = castFlags;
+ castData.CastTime = getMSTime();
+
+ /// @todo implement multiple targets
+ if (m_targets.GetUnitTarget())
+ castData.HitTargets.push_back(m_targets.GetUnitTargetGUID());
+
+ m_targets.Write(castData.Target);
+
+ if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
+ {
+ /// @todo Implement multiple power types
+ WorldPackets::Spells::SpellPowerData powerData;
+ powerData.Type = m_spellInfo->PowerType;
+ powerData.Cost = m_caster->GetPower((Powers)m_spellInfo->PowerType);
+ castData.RemainingPower.push_back(powerData);
+ }
+
+ if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
+ {
+ WorldPackets::Spells::RuneData& runeData = castData.RemainingRunes.Value;
+ //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
+ //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
+ if (Player* player = m_caster->ToPlayer())
+ {
+ runeData.Start = m_runesState; // runes state before
+ runeData.Count = player->GetRunesState(); // runes state after
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ // float casts ensure the division is performed on floats as we need float result
+ float baseCd = float(player->GetRuneBaseCooldown(i));
+ runeData.Cooldowns.push_back((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
+ }
+ }
+ else
+ {
+ runeData.Start = 0;
+ runeData.Count = 0;
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ runeData.Cooldowns.push_back(0);
+ }
+
+ castData.RemainingRunes.HasValue = true;
+ }
+
+ if (castFlags & CAST_FLAG_ADJUST_MISSILE)
+ {
+ castData.MissileTrajectory.TravelTime = m_delayMoment;
+ castData.MissileTrajectory.Pitch = m_targets.GetElevation();
+ }
+ /*WorldPacket data(SMSG_SPELL_GO, 50); // guess size
if (m_CastItem)
data << m_CastItem->GetPackGUID();
@@ -3922,7 +4161,7 @@ void Spell::SendSpellGo()
WriteSpellGoTargets(&data);
- m_targets.Write(data);
+ //m_targets.Write(data);
if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
data << uint32(m_caster->GetPower((Powers)m_spellInfo->PowerType));
@@ -3970,7 +4209,7 @@ void Spell::SendSpellGo()
if (m_targets.GetTargetMask() & TARGET_FLAG_EXTRA_TARGETS)
{
data << uint32(0); // Extra targets count
- /*
+
for (uint8 i = 0; i < count; ++i)
{
data << float(0); // Target Position X
@@ -3978,10 +4217,10 @@ void Spell::SendSpellGo()
data << float(0); // Target Position Z
data << uint64(0); // Target Guid
}
- */
- }
- m_caster->SendMessageToSet(&data, true);
+ }*/
+
+ m_caster->SendMessageToSet(packet.Write(), true);
}
/// Writes miss and hit targets for a SMSG_SPELL_GO packet
@@ -4052,9 +4291,9 @@ void Spell::SendLogExecute()
data << uint32(m_spellInfo->Id);
uint8 effCount = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (m_effectExecuteData[i])
+ if (effect && m_effectExecuteData[effect->EffectIndex])
++effCount;
}
@@ -4062,17 +4301,17 @@ void Spell::SendLogExecute()
return;
data << uint32(effCount);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (!m_effectExecuteData[i])
+ if (!effect || !m_effectExecuteData[effect->EffectIndex])
continue;
- data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
+ data << uint32(effect->Effect); // spell effect
- data.append(*m_effectExecuteData[i]);
+ data.append(*m_effectExecuteData[effect->EffectIndex]);
- delete m_effectExecuteData[i];
- m_effectExecuteData[i] = NULL;
+ delete m_effectExecuteData[effect->EffectIndex];
+ m_effectExecuteData[effect->EffectIndex] = NULL;
}
m_caster->SendMessageToSet(&data, true);
}
@@ -4184,19 +4423,19 @@ void Spell::ExecuteLogEffectResurrect(uint8 effIndex, Unit* target)
void Spell::SendInterrupted(uint8 result)
{
- WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));
- data << m_caster->GetPackGUID();
- data << uint8(m_cast_count);
- data << uint32(m_spellInfo->Id);
- data << uint8(result);
- m_caster->SendMessageToSet(&data, true);
+ WorldPackets::Spells::SpellFailure failurePacket;
+ failurePacket.CasterUnit = m_caster->GetGUID();
+ failurePacket.CastID = m_cast_count;
+ failurePacket.SpellID = m_spellInfo->Id;
+ failurePacket.Reason = result;
+ m_caster->SendMessageToSet(failurePacket.Write(), true);
- data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));
- data << m_caster->GetPackGUID();
- data << uint8(m_cast_count);
- data << uint32(m_spellInfo->Id);
- data << uint8(result);
- m_caster->SendMessageToSet(&data, true);
+ WorldPackets::Spells::SpellFailedOther failedPacket;
+ failedPacket.CasterUnit = m_caster->GetGUID();
+ failedPacket.CastID = m_cast_count;
+ failedPacket.SpellID = m_spellInfo->Id;
+ failedPacket.Reason = result;
+ m_caster->SendMessageToSet(failedPacket.Write(), true);
}
void Spell::SendChannelUpdate(uint32 time)
@@ -4407,36 +4646,6 @@ void Spell::TakePower()
m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4));
}
-void Spell::TakeAmmo()
-{
- if (m_attackType == RANGED_ATTACK && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
-
- // wands don't have ammo
- if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
- return;
-
- if ((pItem->GetTemplate()->InventoryType == INVTYPE_THROWN ||
- pItem->GetTemplate()->InventoryType == INVTYPE_RANGED ||
- pItem->GetTemplate()->InventoryType == INVTYPE_RANGEDRIGHT)
- && roll_chance_f(sWorld->getRate(RATE_DURABILITY_LOSS_DAMAGE)))
- {
- if (pItem->GetMaxStackCount() == 1)
- {
- // decrease durability for non-stackable throw weapon
- m_caster->ToPlayer()->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_RANGED);
- }
- else
- {
- // decrease items amount for stackable throw weapon
- uint32 count = 1;
- m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
- }
- }
- }
-}
-
SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
{
if (m_spellInfo->PowerType != POWER_RUNES || !runeCostID)
@@ -4693,11 +4902,17 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
gameObjTarget = pGOTarget;
destTarget = &m_destTargets[i]._position;
- uint8 eff = m_spellInfo->Effects[i].Effect;
+ effectInfo = GetEffect(i);
+ if (!effectInfo)
+ {
+ TC_LOG_ERROR("spells", "Spell: %u HandleEffects at EffectIndex: %u missing effect", m_spellInfo->Id, i);
+ return;
+ }
+ uint32 eff = effectInfo->Effect;
- TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff);
+ TC_LOG_DEBUG("spells", "Spell: %u Effect: %u", m_spellInfo->Id, eff);
- damage = CalculateDamage(i, unitTarget);
+ damage = CalculateDamage(i, unitTarget, &variance);
bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
@@ -4816,9 +5031,9 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_CASTER_AURASTATE;
// Note: spell 62473 requres casterAuraSpell = triggering spell
- if (m_spellInfo->CasterAuraSpell && !m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->CasterAuraSpell, m_caster)))
+ if (m_spellInfo->CasterAuraSpell && !m_caster->HasAura(m_spellInfo->CasterAuraSpell))
return SPELL_FAILED_CASTER_AURASTATE;
- if (m_spellInfo->ExcludeCasterAuraSpell && m_caster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeCasterAuraSpell, m_caster)))
+ if (m_spellInfo->ExcludeCasterAuraSpell && m_caster->HasAura(m_spellInfo->ExcludeCasterAuraSpell))
return SPELL_FAILED_CASTER_AURASTATE;
if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
@@ -4831,7 +5046,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->isMoving() && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
// skip stuck spell to allow use it in falling case and apply spell limitations at movement
- if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || m_spellInfo->Effects[0].Effect != SPELL_EFFECT_STUCK) &&
+ SpellEffectInfo const* effect = GetEffect(EFFECT_0);
+ if ((!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_FAR) || (effect && effect->Effect != SPELL_EFFECT_STUCK)) &&
(IsAutoRepeat() || (m_spellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED) != 0))
return SPELL_FAILED_MOVING;
}
@@ -4916,9 +5132,9 @@ SpellCastResult Spell::CheckCast(bool strict)
}
// check pet presence
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
+ if (effect && effect->TargetA.GetTarget() == TARGET_UNIT_PET)
{
if (!m_caster->GetGuardianPet())
{
@@ -5009,10 +5225,12 @@ SpellCastResult Spell::CheckCast(bool strict)
if (castResult != SPELL_CAST_OK)
return castResult;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
+ if (!effect)
+ continue;
// for effects of spells that have only one target
- switch (m_spellInfo->Effects[i].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_DUMMY:
{
@@ -5039,7 +5257,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return SPELL_FAILED_BAD_TARGETS;
- if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
+ if (effect->TargetA.GetTarget() != TARGET_UNIT_PET)
break;
Pet* pet = m_caster->ToPlayer()->GetPet();
@@ -5047,7 +5265,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!pet)
return SPELL_FAILED_NO_PET;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell);
if (!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
@@ -5078,7 +5296,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!pet || pet->GetOwner() != m_caster)
return SPELL_FAILED_BAD_TARGETS;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effect->TriggerSpell);
if (!learn_spellproto)
return SPELL_FAILED_NOT_KNOWN;
@@ -5090,7 +5308,7 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_EFFECT_APPLY_GLYPH:
{
- uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
+ uint32 glyphId = effect->MiscValue;
if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
if (m_caster->HasAura(gp->SpellID))
return SPELL_FAILED_UNIQUE_GLYPH;
@@ -5127,7 +5345,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (Unit* target = m_targets.GetUnitTarget())
- if (target != m_caster && target->getPowerType() != Powers(m_spellInfo->Effects[i].MiscValue))
+ if (target != m_caster && target->getPowerType() != Powers(effect->MiscValue))
return SPELL_FAILED_BAD_TARGETS;
break;
}
@@ -5200,13 +5418,13 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_EFFECT_OPEN_LOCK:
{
- if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
- m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
+ if (effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
+ effect->TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
break;
if (m_caster->GetTypeId() != TYPEID_PLAYER // only players can open locks, gather etc.
// we need a go target in case of TARGET_GAMEOBJECT_TARGET
- || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
+ || (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
return SPELL_FAILED_BAD_TARGETS;
Item* pTempItem = NULL;
@@ -5219,7 +5437,7 @@ SpellCastResult Spell::CheckCast(bool strict)
pTempItem = m_caster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID());
// we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
- if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
+ if (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
!m_targets.GetGOTarget() &&
(!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
return SPELL_FAILED_BAD_TARGETS;
@@ -5246,7 +5464,7 @@ SpellCastResult Spell::CheckCast(bool strict)
int32 skillValue = 0;
// check lock compatibility
- SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
+ SpellCastResult res = CanOpenLock(effect->EffectIndex, lockId, skillId, reqSkillValue, skillValue);
if (res != SPELL_CAST_OK)
return res;
@@ -5274,7 +5492,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// This is generic summon effect
case SPELL_EFFECT_SUMMON:
{
- SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
+ SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(effect->MiscValueB);
if (!SummonProperties)
break;
switch (SummonProperties->Category)
@@ -5408,9 +5626,11 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[i].ApplyAuraName)
+ if (!effect)
+ continue;
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS_PET:
{
@@ -5432,8 +5652,8 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!m_caster->GetCharmerGUID().IsEmpty())
return SPELL_FAILED_CHARMED;
- if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_CHARM
- || m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
+ if (effect->ApplyAuraName == SPELL_AURA_MOD_CHARM
+ || effect->ApplyAuraName == SPELL_AURA_MOD_POSSESS)
{
if (!m_caster->GetPetGUID().IsEmpty())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -5456,7 +5676,7 @@ SpellCastResult Spell::CheckCast(bool strict)
if (target->GetOwner() && target->GetOwner()->GetTypeId() == TYPEID_PLAYER)
return SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED;
- int32 damage = CalculateDamage(i, target);
+ int32 damage = CalculateDamage(effect->EffectIndex, target);
if (damage && int32(target->getLevel()) > damage)
return SPELL_FAILED_HIGHLEVEL;
}
@@ -5508,7 +5728,7 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_AURA_PERIODIC_MANA_LEECH:
{
- if (m_spellInfo->Effects[i].IsTargetingArea())
+ if (effect->IsTargetingArea())
break;
if (!m_targets.GetUnitTarget())
@@ -5608,14 +5828,17 @@ SpellCastResult Spell::CheckCasterAuras() const
// We use bitmasks so the loop is done only once and not on every aura check below.
if (m_spellInfo->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
- school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
- else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
- mechanic_immune |= 1 << uint32(m_spellInfo->Effects[i].MiscValue);
- else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
- dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
+ if (!effect)
+ continue;
+
+ if (effect->ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
+ school_immune |= uint32(effect->MiscValue);
+ else if (effect->ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
+ mechanic_immune |= 1 << uint32(effect->MiscValue);
+ else if (effect->ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
+ dispel_immune |= SpellInfo::GetDispelMask(DispelType(effect->MiscValue));
}
// immune movement impairment and loss of control
if (m_spellInfo->Id == 42292 || m_spellInfo->Id == 59752 || m_spellInfo->Id == 19574)
@@ -5684,9 +5907,12 @@ SpellCastResult Spell::CheckCasterAuras() const
//Make a second check for spell failed so the right SPELL_FAILED message is returned.
//That is needed when your casting is prevented by multiple states and you are only immune to some of them.
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (AuraEffect* part = aura->GetEffect(i))
+ if (!effect)
+ continue;
+
+ if (AuraEffect* part = aura->GetEffect(effect->EffectIndex))
{
switch (part->GetAuraType())
{
@@ -5758,25 +5984,28 @@ bool Spell::CanAutoCast(Unit* target)
{
ObjectGuid targetguid = target->GetGUID();
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (m_spellInfo->Effects[j].Effect == SPELL_EFFECT_APPLY_AURA)
+ if (!effect)
+ continue;
+
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
if (m_spellInfo->StackAmount <= 1)
{
- if (target->HasAuraEffect(m_spellInfo->Id, j))
+ if (target->HasAuraEffect(m_spellInfo->Id, effect->EffectIndex))
return false;
}
else
{
- if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, j))
+ if (AuraEffect* aureff = target->GetAuraEffect(m_spellInfo->Id, effect->EffectIndex))
if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
return false;
}
}
- else if (m_spellInfo->Effects[j].IsAreaAuraEffect())
+ else if (effect->IsAreaAuraEffect())
{
- if (target->HasAuraEffect(m_spellInfo->Id, j))
+ if (target->HasAuraEffect(m_spellInfo->Id, effect->EffectIndex))
return false;
}
}
@@ -5921,13 +6150,13 @@ SpellCastResult Spell::CheckItems()
{
// such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
SpellCastResult failReason = SPELL_CAST_OK;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
// skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
- if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
+ if (!effect || effect->TargetA.GetTarget() == TARGET_UNIT_PET)
continue;
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
+ if (effect->Effect == SPELL_EFFECT_HEAL)
{
if (m_targets.GetUnitTarget()->IsFullHealth())
{
@@ -5942,15 +6171,15 @@ SpellCastResult Spell::CheckItems()
}
// Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
+ if (effect->Effect == SPELL_EFFECT_ENERGIZE)
{
- if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
+ if (effect->MiscValue < 0 || effect->MiscValue >= int8(MAX_POWERS))
{
failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
continue;
}
- Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
+ Powers power = Powers(effect->MiscValue);
if (m_targets.GetUnitTarget()->GetPower(power) == m_targets.GetUnitTarget()->GetMaxPower(power))
{
failReason = SPELL_FAILED_ALREADY_AT_FULL_POWER;
@@ -6048,34 +6277,37 @@ SpellCastResult Spell::CheckItems()
}
// special checks for spell effects
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[i].Effect)
+ if (!effect)
+ continue;
+
+ switch (effect->Effect)
{
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_ITEM_2:
{
- if (!IsTriggered() && m_spellInfo->Effects[i].ItemType)
+ if (!IsTriggered() && effect->ItemType)
{
ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1);
if (msg != EQUIP_ERR_OK)
{
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(effect->ItemType);
/// @todo Needs review
if (pProto && !(pProto->ItemLimitCategory))
{
- player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType);
+ player->SendEquipError(msg, NULL, NULL, effect->ItemType);
return SPELL_FAILED_DONT_REPORT;
}
else
{
if (!(m_spellInfo->SpellFamilyName == SPELLFAMILY_MAGE && (m_spellInfo->SpellFamilyFlags[0] & 0x40000000)))
return SPELL_FAILED_TOO_MANY_OF_ITEM;
- else if (!(player->HasItemCount(m_spellInfo->Effects[i].ItemType)))
+ else if (!(player->HasItemCount(effect->ItemType)))
return SPELL_FAILED_TOO_MANY_OF_ITEM;
- else
- player->CastSpell(m_caster, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
+ else if (SpellEffectInfo const* efi = GetEffect(EFFECT_1))
+ player->CastSpell(m_caster, efi->CalcValue(), false); // move this to anywhere
return SPELL_FAILED_DONT_REPORT;
}
}
@@ -6083,7 +6315,7 @@ SpellCastResult Spell::CheckItems()
break;
}
case SPELL_EFFECT_ENCHANT_ITEM:
- if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
+ if (effect->ItemType && m_targets.GetItemTarget()
&& (m_targets.GetItemTarget()->IsVellum()))
{
// cannot enchant vellum for other player
@@ -6093,10 +6325,10 @@ SpellCastResult Spell::CheckItems()
if (m_CastItem && m_CastItem->GetTemplate()->Flags[0] & ITEM_PROTO_FLAG_TRIGGERED_CAST)
return SPELL_FAILED_TOTEM_CATEGORY;
ItemPosCountVec dest;
- InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, effect->ItemType, 1);
if (msg != EQUIP_ERR_OK)
{
- player->SendEquipError(msg, NULL, NULL, m_spellInfo->Effects[i].ItemType);
+ player->SendEquipError(msg, NULL, NULL, effect->ItemType);
return SPELL_FAILED_DONT_REPORT;
}
}
@@ -6123,7 +6355,7 @@ SpellCastResult Spell::CheckItems()
}
}
- SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
+ SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(effect->MiscValue);
// do not allow adding usable enchantments to items that have use effect already
if (enchantEntry)
{
@@ -6168,7 +6400,7 @@ SpellCastResult Spell::CheckItems()
// Not allow enchant in trade slot for some enchant type
if (item->GetOwner() != m_caster)
{
- uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
+ uint32 enchant_id = effect->MiscValue;
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
return SPELL_FAILED_ERROR;
@@ -6285,7 +6517,7 @@ SpellCastResult Spell::CheckItems()
}
case SPELL_EFFECT_CREATE_MANA_GEM:
{
- uint32 item_id = m_spellInfo->Effects[i].ItemType;
+ uint32 item_id = effect->ItemType;
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
if (!pProto)
@@ -6457,9 +6689,12 @@ bool Spell::UpdatePointers()
WorldObject* transport = NULL;
// update effect destinations (in case of moved transport dest target)
- for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- SpellDestination& dest = m_destTargets[effIndex];
+ if (!effect)
+ continue;
+
+ SpellDestination& dest = m_destTargets[effect->EffectIndex];
if (!dest._transportGUID)
continue;
@@ -6490,7 +6725,11 @@ CurrentSpellTypes Spell::GetCurrentContainer() const
bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const
{
- switch (m_spellInfo->Effects[eff].ApplyAuraName)
+ SpellEffectInfo const* effect = GetEffect(eff);
+ if (!effect)
+ return false;
+
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM:
@@ -6520,7 +6759,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo
/// @todo shit below shouldn't be here, but it's temporary
//Check targets for LOS visibility (except spells without range limitations)
- switch (m_spellInfo->Effects[eff].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_RESURRECT_NEW:
// player far away, maybe his corpse near?
@@ -6731,21 +6970,19 @@ bool Spell::IsValidDeadOrAliveTarget(Unit const* target) const
void Spell::HandleLaunchPhase()
{
// handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
// don't do anything for empty effect
- if (!m_spellInfo->Effects[i].IsEffect())
+ if (!effect || !effect->IsEffect())
continue;
- HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH);
+ HandleEffects(NULL, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH);
}
float multiplier[MAX_SPELL_EFFECTS];
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_applyMultiplierMask & (1 << i))
- multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
-
- bool usesAmmo = (m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE) != 0;
+ for (SpellEffectInfo const* effect : GetEffects())
+ if (effect && (m_applyMultiplierMask & (1 << effect->EffectIndex)))
+ multiplier[effect->EffectIndex] = effect->CalcDamageMultiplier(m_originalCaster, this);
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
@@ -6755,31 +6992,6 @@ void Spell::HandleLaunchPhase()
if (!mask)
continue;
- // do not consume ammo anymore for Hunter's volley spell
- if (IsTriggered() && m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER && m_spellInfo->IsTargetingArea())
- usesAmmo = false;
-
- if (usesAmmo)
- {
- bool ammoTaken = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
- {
- if (!(mask & 1<<i))
- continue;
- switch (m_spellInfo->Effects[i].Effect)
- {
- case SPELL_EFFECT_SCHOOL_DAMAGE:
- case SPELL_EFFECT_WEAPON_DAMAGE:
- case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- ammoTaken=true;
- TakeAmmo();
- }
- if (ammoTaken)
- break;
- }
- }
DoAllEffectOnLaunchTarget(target, multiplier);
}
}
@@ -6796,18 +7008,18 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
if (!unit)
return;
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if (targetInfo.effectMask & (1<<i))
+ if (effect && (targetInfo.effectMask & (1<<effect->EffectIndex)))
{
m_damage = 0;
m_healing = 0;
- HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
+ HandleEffects(unit, NULL, NULL, effect->EffectIndex, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
if (m_damage > 0)
{
- if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
+ if (effect->IsTargetingArea() || effect->IsAreaAuraEffect() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA))
{
m_damage = int32(float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask));
if (m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -6822,10 +7034,10 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier)
}
}
- if (m_applyMultiplierMask & (1 << i))
+ if (m_applyMultiplierMask & (1 << effect->EffectIndex))
{
- m_damage = int32(m_damage * m_damageMultipliers[i]);
- m_damageMultipliers[i] *= multiplier[i];
+ m_damage = int32(m_damage * m_damageMultipliers[effect->EffectIndex]);
+ m_damageMultipliers[effect->EffectIndex] *= multiplier[effect->EffectIndex];
}
targetInfo.damage += m_damage;
}
@@ -6845,6 +7057,10 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
if (!lockInfo)
return SPELL_FAILED_BAD_TARGETS;
+ SpellEffectInfo const* effect = GetEffect(effIndex);
+ if (!effect)
+ return SPELL_FAILED_BAD_TARGETS; // no idea about correct error
+
bool reqKey = false; // some locks not have reqs
for (int j = 0; j < MAX_LOCK_CASE; ++j)
@@ -6863,7 +7079,7 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
reqKey = true;
// wrong locktype, skip
- if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
+ if (uint32(effect->MiscValue) != lockInfo->Index[j])
continue;
skillId = SkillByLockType(LockType(lockInfo->Index[j]));
@@ -6878,8 +7094,8 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
// skill bonus provided by casting spell (mostly item spells)
// add the effect base points modifier from the spell cast (cheat lock / skeleton key etc.)
- if (m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
- skillValue += m_spellInfo->Effects[effIndex].CalcValue();
+ if (effect->TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || effect->TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
+ skillValue += effect->CalcValue();
if (skillValue < reqSkillValue)
return SPELL_FAILED_LOW_CASTLEVEL;
@@ -6898,17 +7114,15 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk
void Spell::SetSpellValue(SpellValueMod mod, int32 value)
{
+ if (mod < SPELLVALUE_BASE_POINT_END)
+ {
+ if (SpellEffectInfo const* effect = GetEffect(mod))
+ m_spellValue->EffectBasePoints[mod] = effect->CalcBaseValue(value);
+ return;
+ }
+
switch (mod)
{
- case SPELLVALUE_BASE_POINT0:
- m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
- break;
- case SPELLVALUE_BASE_POINT1:
- m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
- break;
- case SPELLVALUE_BASE_POINT2:
- m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
- break;
case SPELLVALUE_RADIUS_MOD:
m_spellValue->RadiusMod = (float)value / 10000;
break;
@@ -6931,7 +7145,7 @@ void Spell::FinishTargetProcessing()
SendLogExecute();
}
-void Spell::InitEffectExecuteData(uint8 effIndex)
+void Spell::InitEffectExecuteData(uint32 effIndex)
{
ASSERT(effIndex < MAX_SPELL_EFFECTS);
if (!m_effectExecuteData[effIndex])
@@ -7193,9 +7407,9 @@ bool Spell::CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByA
{
bool only_on_caster = (triggeredByAura && (triggeredByAura->AttributesEx4 & SPELL_ATTR4_PROC_ONLY_ON_CASTER));
// If triggeredByAura has SPELL_ATTR4_PROC_ONLY_ON_CASTER then it can only proc on a cast spell with TARGET_UNIT_CASTER
- for (uint8 i = 0;i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
+ if (effect && ((effMask & (1 << effect->EffectIndex)) && (!only_on_caster || (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER))))
return true;
}
return false;
@@ -7236,19 +7450,23 @@ void Spell::PrepareTriggersExecutedOnHit()
continue;
SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
uint32 auraSpellIdx = (*i)->GetEffIndex();
- if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
+ // todo 6.x
+ if (SpellEffectInfo const* auraEffect = auraSpellInfo->GetEffect(m_caster->GetMap()->GetDifficulty(), auraSpellIdx))
{
- // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
- // this possibly needs fixing
- int32 auraBaseAmount = (*i)->GetBaseAmount();
- // proc chance is stored in effect amount
- int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
- // build trigger and add to the list
- HitTriggerSpell spellTriggerInfo;
- spellTriggerInfo.triggeredSpell = spellInfo;
- spellTriggerInfo.triggeredByAura = auraSpellInfo;
- spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
- m_hitTriggerSpells.push_back(spellTriggerInfo);
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraEffect->TriggerSpell))
+ {
+ // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
+ // this possibly needs fixing
+ int32 auraBaseAmount = (*i)->GetBaseAmount();
+ // proc chance is stored in effect amount
+ int32 chance = m_caster->CalculateSpellDamage(NULL, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
+ // build trigger and add to the list
+ HitTriggerSpell spellTriggerInfo;
+ spellTriggerInfo.triggeredSpell = spellInfo;
+ spellTriggerInfo.triggeredByAura = auraSpellInfo;
+ spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
+ m_hitTriggerSpells.push_back(spellTriggerInfo);
+ }
}
}
}
@@ -7321,6 +7539,16 @@ void Spell::CancelGlobalCooldown()
m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
}
+bool Spell::HasEffect(SpellEffectName effect) const
+{
+ for (SpellEffectInfo const* eff : GetEffects())
+ {
+ if (eff && eff->IsEffect(effect))
+ return true;
+ }
+ return false;
+}
+
namespace Trinity
{
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index dc07449c41f..57302c4f32e 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -25,6 +25,14 @@
#include "SpellInfo.h"
#include "PathGenerator.h"
+namespace WorldPackets
+{
+ namespace Spells
+ {
+ struct SpellTargetData;
+ }
+}
+
class Unit;
class Player;
class GameObject;
@@ -99,10 +107,11 @@ class SpellCastTargets
{
public:
SpellCastTargets();
+ SpellCastTargets(Unit* caster, uint32 targetMask, ObjectGuid targetGuid, ObjectGuid itemTargetGuid, ObjectGuid srcTransportGuid, ObjectGuid destTransportGuid, Position srcPos, Position destPos, float elevation, float missileSpeed, std::string targetString);
~SpellCastTargets();
void Read(ByteBuffer& data, Unit* caster);
- void Write(ByteBuffer& data);
+ void Write(WorldPackets::Spells::SpellTargetData& data);
uint32 GetTargetMask() const { return m_targetMask; }
void SetTargetMask(uint32 newMask) { m_targetMask = newMask; }
@@ -168,6 +177,7 @@ class SpellCastTargets
void Update(Unit* caster);
void OutDebug() const;
+ std::string GetTargetString() const { return m_strTarget; }
private:
uint32 m_targetMask;
@@ -191,7 +201,7 @@ class SpellCastTargets
struct SpellValue
{
- explicit SpellValue(SpellInfo const* proto);
+ explicit SpellValue(Difficulty diff, SpellInfo const* proto);
int32 EffectBasePoints[MAX_SPELL_EFFECTS];
uint32 MaxAffectedTargets;
float RadiusMod;
@@ -377,7 +387,7 @@ class Spell
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask);
void SelectImplicitTrajTargets(SpellEffIndex effIndex);
- void SelectEffectTypeImplicitTargets(uint8 effIndex);
+ void SelectEffectTypeImplicitTargets(uint32 effIndex);
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList);
template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius);
@@ -394,7 +404,6 @@ class Spell
void cast(bool skipCheck = false);
void finish(bool ok = true);
void TakePower();
- void TakeAmmo();
void TakeRunePower(bool didHit);
void TakeReagents();
@@ -417,7 +426,7 @@ class Spell
SpellCastResult CheckCasterAuras() const;
SpellCastResult CheckArenaAndRatedBattlegroundCastRules();
- int32 CalculateDamage(uint8 i, Unit const* target) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]); }
+ int32 CalculateDamage(uint8 i, Unit const* target, float* var = nullptr) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i], var); }
bool HaveTargetsForEffect(uint8 effect) const;
void Delayed();
@@ -503,6 +512,24 @@ class Spell
void CleanupTargetList();
void SetSpellValue(SpellValueMod mod, int32 value);
+
+ SpellEffectInfoVector GetEffects() const { return _effects; }
+ SpellEffectInfo const* GetEffect(uint32 index) const
+ {
+ if (index >= _effects.size())
+ return nullptr;
+
+ return _effects[index];
+ }
+
+ bool HasEffect(SpellEffectName effect) const;
+
+ Spell** m_selfContainer; // pointer to our spell container (if applicable)
+
+ SpellInfo const* GetTriggeredByAuraSpell() const { return m_triggeredByAuraSpell; }
+
+ int32 GetTimer() const { return m_timer; }
+
protected:
bool HasGlobalCooldown() const;
void TriggerGlobalCooldown();
@@ -518,8 +545,6 @@ class Spell
// e.g. damage around area spell trigered by victim aura and damage enemies of aura caster
Unit* m_originalCaster; // cached pointer for m_originalCaster, updated at Spell::UpdatePointers()
- Spell** m_selfContainer; // pointer to our spell container (if applicable)
-
//Spell data
SpellSchoolMask m_spellSchoolMask; // Spell school (can be overwrite for some spells (wand shoot for example)
WeaponAttackType m_attackType; // For weapon based attack
@@ -558,7 +583,9 @@ class Spell
GameObject* gameObjTarget;
WorldLocation* destTarget;
int32 damage;
+ float variance;
SpellEffectHandleMode effectHandleMode;
+ SpellEffectInfo const* effectInfo;
// used in effects handlers
Aura* m_spellAura;
@@ -591,7 +618,7 @@ class Spell
uint64 timeDelay;
SpellMissInfo missCondition:8;
SpellMissInfo reflectResult:8;
- uint8 effectMask:8;
+ uint32 effectMask:32;
bool processed:1;
bool alive:1;
bool crit:1;
@@ -599,13 +626,13 @@ class Spell
int32 damage;
};
std::list<TargetInfo> m_UniqueTargetInfo;
- uint8 m_channelTargetEffectMask; // Mask req. alive targets
+ uint32 m_channelTargetEffectMask; // Mask req. alive targets
struct GOTargetInfo
{
ObjectGuid targetGUID;
uint64 timeDelay;
- uint8 effectMask:8;
+ uint32 effectMask:32;
bool processed:1;
};
std::list<GOTargetInfo> m_UniqueGOTargetInfo;
@@ -613,7 +640,7 @@ class Spell
struct ItemTargetInfo
{
Item *item;
- uint8 effectMask;
+ uint32 effectMask;
};
std::list<ItemTargetInfo> m_UniqueItemInfo;
@@ -638,7 +665,7 @@ class Spell
void FinishTargetProcessing();
// spell execution log
- void InitEffectExecuteData(uint8 effIndex);
+ void InitEffectExecuteData(uint32 effIndex);
void CheckEffectExecuteData();
// Scripting system
@@ -689,7 +716,7 @@ class Spell
SpellInfo const* m_triggeredByAuraSpell;
bool m_skipCheck;
- uint8 m_auraScaleMask;
+ uint32 m_auraScaleMask;
PathGenerator m_preGeneratedPath;
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS];
@@ -704,6 +731,8 @@ class Spell
Spell(Spell const& right) = delete;
Spell& operator=(Spell const& right) = delete;
+
+ SpellEffectInfoVector _effects;
};
namespace Trinity
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 9c12abbe6e2..e3d2b9d3d1f 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -252,6 +252,68 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectUnused, //180 SPELL_EFFECT_180 unused
&Spell::EffectUnused, //181 SPELL_EFFECT_181 unused
&Spell::EffectNULL, //182 SPELL_EFFECT_182
+ &Spell::EffectNULL, //183 SPELL_EFFECT_183
+ &Spell::EffectNULL, //184 SPELL_EFFECT_184
+ &Spell::EffectNULL, //185 SPELL_EFFECT_185
+ &Spell::EffectNULL, //186 SPELL_EFFECT_186
+ &Spell::EffectNULL, //187 SPELL_EFFECT_187
+ &Spell::EffectNULL, //188 SPELL_EFFECT_188
+ &Spell::EffectNULL, //189 SPELL_EFFECT_189
+ &Spell::EffectNULL, //190 SPELL_EFFECT_190
+ &Spell::EffectNULL, //191 SPELL_EFFECT_191
+ &Spell::EffectNULL, //192 SPELL_EFFECT_192
+ &Spell::EffectNULL, //193 SPELL_EFFECT_193
+ &Spell::EffectNULL, //194 SPELL_EFFECT_194
+ &Spell::EffectNULL, //195 SPELL_EFFECT_195
+ &Spell::EffectNULL, //196 SPELL_EFFECT_196
+ &Spell::EffectNULL, //197 SPELL_EFFECT_197
+ &Spell::EffectNULL, //198 SPELL_EFFECT_198
+ &Spell::EffectNULL, //199 SPELL_EFFECT_199
+ &Spell::EffectNULL, //200 SPELL_EFFECT_200
+ &Spell::EffectNULL, //201 SPELL_EFFECT_201
+ &Spell::EffectNULL, //202 SPELL_EFFECT_202
+ &Spell::EffectNULL, //203 SPELL_EFFECT_203
+ &Spell::EffectNULL, //204 SPELL_EFFECT_204
+ &Spell::EffectNULL, //205 SPELL_EFFECT_205
+ &Spell::EffectNULL, //206 SPELL_EFFECT_206
+ &Spell::EffectNULL, //207 SPELL_EFFECT_207
+ &Spell::EffectNULL, //208 SPELL_EFFECT_208
+ &Spell::EffectNULL, //209 SPELL_EFFECT_209
+ &Spell::EffectNULL, //210 SPELL_EFFECT_210
+ &Spell::EffectNULL, //211 SPELL_EFFECT_211
+ &Spell::EffectNULL, //212 SPELL_EFFECT_212
+ &Spell::EffectNULL, //213 SPELL_EFFECT_213
+ &Spell::EffectNULL, //214 SPELL_EFFECT_214
+ &Spell::EffectNULL, //215 SPELL_EFFECT_215
+ &Spell::EffectNULL, //216 SPELL_EFFECT_216
+ &Spell::EffectNULL, //217 SPELL_EFFECT_217
+ &Spell::EffectNULL, //218 SPELL_EFFECT_218
+ &Spell::EffectNULL, //219 SPELL_EFFECT_219
+ &Spell::EffectNULL, //220 SPELL_EFFECT_220
+ &Spell::EffectNULL, //221 SPELL_EFFECT_221
+ &Spell::EffectNULL, //222 SPELL_EFFECT_222
+ &Spell::EffectNULL, //223 SPELL_EFFECT_223
+ &Spell::EffectNULL, //224 SPELL_EFFECT_224
+ &Spell::EffectNULL, //225 SPELL_EFFECT_225
+ &Spell::EffectNULL, //226 SPELL_EFFECT_226
+ &Spell::EffectNULL, //227 SPELL_EFFECT_227
+ &Spell::EffectNULL, //228 SPELL_EFFECT_228
+ &Spell::EffectNULL, //229 SPELL_EFFECT_229
+ &Spell::EffectNULL, //230 SPELL_EFFECT_230
+ &Spell::EffectNULL, //231 SPELL_EFFECT_231
+ &Spell::EffectNULL, //232 SPELL_EFFECT_232
+ &Spell::EffectNULL, //233 SPELL_EFFECT_233
+ &Spell::EffectNULL, //234 SPELL_EFFECT_234
+ &Spell::EffectNULL, //235 SPELL_EFFECT_235
+ &Spell::EffectNULL, //236 SPELL_EFFECT_236
+ &Spell::EffectNULL, //237 SPELL_EFFECT_237
+ &Spell::EffectNULL, //238 SPELL_EFFECT_238
+ &Spell::EffectNULL, //239 SPELL_EFFECT_239
+ &Spell::EffectNULL, //240 SPELL_EFFECT_240
+ &Spell::EffectNULL, //241 SPELL_EFFECT_241
+ &Spell::EffectNULL, //242 SPELL_EFFECT_242
+ &Spell::EffectNULL, //243 SPELL_EFFECT_243
+ &Spell::EffectNULL, //244 SPELL_EFFECT_244
};
void Spell::EffectNULL(SpellEffIndex /*effIndex*/)
@@ -284,7 +346,7 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex)
return;
uint32 health = damage;
- uint32 mana = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 mana = effectInfo->MiscValue;
ExecuteLogEffectResurrect(effIndex, target);
target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
@@ -359,7 +421,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
{
// Consumption
case 28865:
- damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == REGULAR_DIFFICULTY ? 2750 : 4250);
+ damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == DIFFICULTY_NONE ? 2750 : 4250);
break;
// percent from health with min
case 25599: // Thundercrash
@@ -419,23 +481,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
case SPELLFAMILY_PRIEST:
{
- // Improved Mind Blast (Mind Blast in shadow form bonus)
- if (m_caster->GetShapeshiftForm() == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
- {
- Unit::AuraEffectList const& ImprMindBlast = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_FLAT_MODIFIER);
- for (Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
- {
- if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_PRIEST &&
- ((*i)->GetSpellInfo()->SpellIconID == 95))
- {
- int chance = (*i)->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster);
- if (roll_chance_i(chance))
- // Mind Trauma
- m_caster->CastSpell(unitTarget, 48301, true, nullptr);
- break;
- }
- }
- }
break;
}
case SPELLFAMILY_DRUID:
@@ -464,31 +509,14 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x00010000, 0, 0, m_caster->GetGUID()))
{
// count consumed deadly poison doses at target
- bool needConsume = true;
uint32 spellId = aurEff->GetId();
uint32 doses = aurEff->GetBase()->GetStackAmount();
if (doses > combo)
doses = combo;
- // Master Poisoner
- Unit::AuraEffectList const& auraList = player->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
- for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
- {
- if ((*iter)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellInfo()->SpellIconID == 1960)
- {
- uint32 chance = (*iter)->GetSpellInfo()->Effects[EFFECT_2].CalcValue(m_caster);
-
- if (chance && roll_chance_i(chance))
- needConsume = false;
-
- break;
- }
- }
-
- if (needConsume)
- for (uint32 i = 0; i < doses; ++i)
- unitTarget->RemoveAuraFromStack(spellId, m_caster->GetGUID());
+ for (uint32 i = 0; i < doses; ++i)
+ unitTarget->RemoveAuraFromStack(spellId, m_caster->GetGUID());
damage *= doses;
damage += int32(player->GetTotalAttackPowerValue(BASE_ATTACK) * 0.09f * combo);
@@ -533,10 +561,11 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
}
- if (m_originalCaster && damage > 0 && apply_direct_bonus)
+ if (m_originalCaster && apply_direct_bonus)
{
- damage = m_originalCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
- damage = unitTarget->SpellDamageBonusTaken(m_originalCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
+ uint32 bonus = m_originalCaster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
+ damage = bonus + uint32(bonus * variance);
+ damage = unitTarget->SpellDamageBonusTaken(m_originalCaster, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
}
m_damage += damage;
@@ -612,16 +641,16 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
}
-void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
+void Spell::EffectTriggerSpell(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET
&& effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = effectInfo->TriggerSpell;
/// @todo move those to spell scripts
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
+ if (effectInfo->Effect == SPELL_EFFECT_TRIGGER_SPELL
&& effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
// special cases
@@ -718,13 +747,13 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -738,7 +767,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
+ if (effectInfo->Effect == SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE)
{
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
values.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
@@ -754,13 +783,13 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
}
-void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
+void Spell::EffectTriggerMissileSpell(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET
&& effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = effectInfo->TriggerSpell;
// normal case
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
@@ -773,13 +802,13 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
SpellCastTargets targets;
if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET)
{
- if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo))
+ if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()))
return;
targets.SetUnitTarget(unitTarget);
}
else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
{
- if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
+ if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, m_caster->GetMap()->GetDifficulty()) && (effectInfo->GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
return;
if (spellInfo->GetExplicitTargetMask() & TARGET_FLAG_DEST_LOCATION)
@@ -790,7 +819,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
+ if (effectInfo->Effect == SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE)
{
// maybe need to set value only when basepoints == 0?
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
@@ -807,7 +836,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex)
m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID);
}
-void Spell::EffectForceCast(SpellEffIndex effIndex)
+void Spell::EffectForceCast(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -815,7 +844,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
if (!unitTarget)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = effectInfo->TriggerSpell;
// normal case
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
@@ -826,7 +855,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
return;
}
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
+ if (effectInfo->Effect == SPELL_EFFECT_FORCE_CAST && damage)
{
switch (m_spellInfo->Id)
{
@@ -850,7 +879,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
CustomSpellValues values;
// set basepoints for trigger with value effect
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
+ if (effectInfo->Effect == SPELL_EFFECT_FORCE_CAST_WITH_VALUE)
{
// maybe need to set value only when basepoints == 0?
values.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
@@ -864,12 +893,12 @@ void Spell::EffectForceCast(SpellEffIndex effIndex)
unitTarget->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK);
}
-void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex)
+void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = effectInfo->TriggerSpell;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
if (!spellInfo)
@@ -924,12 +953,15 @@ void Spell::EffectJumpDest(SpellEffIndex effIndex)
void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & speedZ)
{
- if (m_spellInfo->Effects[i].MiscValue)
- speedZ = float(m_spellInfo->Effects[i].MiscValue)/10;
- else if (m_spellInfo->Effects[i].MiscValueB)
- speedZ = float(m_spellInfo->Effects[i].MiscValueB)/10;
- else
- speedZ = 10.0f;
+ if (SpellEffectInfo const* effect = GetEffect(i))
+ {
+ if (effect->MiscValue)
+ speedZ = float(effect->MiscValue) / 10;
+ else if (effect->MiscValueB)
+ speedZ = float(effect->MiscValueB) / 10;
+ else
+ speedZ = 10.0f;
+ }
speedXY = dist * 10.0f / speedZ;
}
@@ -1087,7 +1119,7 @@ void Spell::EffectApplyAreaAura(SpellEffIndex effIndex)
m_spellAura->_ApplyEffectForTargets(effIndex);
}
-void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex)
+void Spell::EffectUnlearnSpecialization(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -1096,7 +1128,7 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 spellToUnlearn = effectInfo->TriggerSpell;
player->RemoveSpell(spellToUnlearn);
@@ -1108,17 +1140,18 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (effectInfo->MiscValue < 0 || effectInfo->MiscValue >= int8(MAX_POWERS))
return;
- Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers powerType = Powers(effectInfo->MiscValue);
if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
return;
// add spell damage bonus
- damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
- damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
+ uint32 bonus = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
+ damage = bonus + uint32(bonus * variance);
+ damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
@@ -1127,7 +1160,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
// Don't restore from self drain
if (m_caster != unitTarget)
{
- gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ gainMultiplier = effectInfo->CalcValueMultiplier(m_originalCaster, this);
int32 gain = int32(newDamage* gainMultiplier);
@@ -1136,7 +1169,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, gainMultiplier);
}
-void Spell::EffectSendEvent(SpellEffIndex effIndex)
+void Spell::EffectSendEvent(SpellEffIndex /*effIndex*/)
{
// we do not handle a flag dropping or clicking on flag in battleground by sendevent system
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET
@@ -1159,7 +1192,7 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
// this check was requested by scripters, but it has some downsides:
// now it's impossible to script (using sEventScripts) a cast which misses all targets
// or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
- if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
+ if (effectInfo->GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
return;
// some spells have no target entries in dbc and they use focus target
if (focusObject)
@@ -1167,14 +1200,14 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex)
/// @todo there should be a possibility to pass dest target to event script
}
- TC_LOG_DEBUG("spells", "Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
+ TC_LOG_DEBUG("spells", "Spell ScriptStart %u for spellid %u in EffectSendEvent ", effectInfo->MiscValue, m_spellInfo->Id);
if (ZoneScript* zoneScript = m_caster->GetZoneScript())
- zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
+ zoneScript->ProcessEvent(target, effectInfo->MiscValue);
else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
- instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
+ instanceScript->ProcessEvent(target, effectInfo->MiscValue);
- m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
+ m_caster->GetMap()->ScriptsStart(sEventScripts, effectInfo->MiscValue, m_caster, target);
}
void Spell::EffectPowerBurn(SpellEffIndex effIndex)
@@ -1182,10 +1215,10 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (effectInfo->MiscValue < 0 || effectInfo->MiscValue >= int8(MAX_POWERS))
return;
- Powers powerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers powerType = Powers(effectInfo->MiscValue);
if (!unitTarget || !unitTarget->IsAlive() || unitTarget->getPowerType() != powerType || damage < 0)
return;
@@ -1201,7 +1234,7 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex)
int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
// NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
- float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ float dmgMultiplier = effectInfo->CalcValueMultiplier(m_originalCaster, this);
// add log data before multiplication (need power amount, not damage)
ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, powerType, newDamage, 0.0f);
@@ -1271,7 +1304,7 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
int32 tickheal = targetAura->GetAmount();
if (Unit* auraCaster = targetAura->GetCaster())
- tickheal = auraCaster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT);
+ tickheal = auraCaster->SpellHealingBonusDone(unitTarget, targetAura->GetSpellInfo(), tickheal, DOT, effectInfo);
//int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
//It is said that talent bonus should not be included
@@ -1294,11 +1327,15 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
}
// Death Pact - return pct of max health to caster
else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000)
- addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL);
+ addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effectInfo);
else
- addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
+ {
+ addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effectInfo);
+ uint32 bonus = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effectInfo);
+ damage = bonus + uint32(bonus * variance);
+ }
- addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
+ addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL, effectInfo);
// Remove Grievious bite if fully healed
if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth()))
@@ -1320,8 +1357,8 @@ void Spell::EffectHealPct(SpellEffIndex /*effIndex*/)
if (!m_originalCaster)
return;
- uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL);
- heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
+ uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, unitTarget->CountPctFromMaxHealth(damage), HEAL, effectInfo);
+ heal = unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL, effectInfo);
m_healing += heal;
}
@@ -1338,12 +1375,13 @@ void Spell::EffectHealMechanical(SpellEffIndex /*effIndex*/)
if (!m_originalCaster)
return;
- uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL);
+ uint32 heal = m_originalCaster->SpellHealingBonusDone(unitTarget, m_spellInfo, uint32(damage), HEAL, effectInfo);
+ heal += uint32(heal * variance);
- m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL);
+ m_healing += unitTarget->SpellHealingBonusTaken(m_originalCaster, m_spellInfo, heal, HEAL, effectInfo);
}
-void Spell::EffectHealthLeech(SpellEffIndex effIndex)
+void Spell::EffectHealthLeech(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -1351,12 +1389,13 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex)
if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
return;
- damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
- damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
+ uint32 bonus = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE, effectInfo);
+ damage = bonus + uint32(bonus * variance);
+ damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE, effectInfo);
TC_LOG_DEBUG("spells", "HealthLeech :%i", damage);
- float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
+ float healMultiplier = effectInfo->CalcValueMultiplier(m_originalCaster, this);
m_damage += damage;
// get max possible damage, don't count overkill for heal
@@ -1364,8 +1403,8 @@ void Spell::EffectHealthLeech(SpellEffIndex effIndex)
if (m_caster->IsAlive())
{
- healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL);
- healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL);
+ healthGain = m_caster->SpellHealingBonusDone(m_caster, m_spellInfo, healthGain, HEAL, effectInfo);
+ healthGain = m_caster->SpellHealingBonusTaken(m_caster, m_spellInfo, healthGain, HEAL, effectInfo);
m_caster->HealBySpell(m_caster, m_spellInfo, uint32(healthGain));
}
@@ -1491,8 +1530,8 @@ void Spell::EffectCreateItem(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
- ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
+ DoCreateItem(effIndex, effectInfo->ItemType);
+ ExecuteLogEffectCreateItem(effIndex, effectInfo->ItemType);
}
void Spell::EffectCreateItem2(SpellEffIndex effIndex)
@@ -1505,7 +1544,7 @@ void Spell::EffectCreateItem2(SpellEffIndex effIndex)
Player* player = unitTarget->ToPlayer();
- uint32 item_id = m_spellInfo->Effects[effIndex].ItemType;
+ uint32 item_id = effectInfo->ItemType;
if (item_id)
DoCreateItem(effIndex, item_id);
@@ -1553,7 +1592,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
if (!m_spellAura)
{
Unit* caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
+ float radius = effectInfo->CalcRadius(caster);
// Caster not in world, might be spell triggered from aura removal
if (!caster->IsInWorld())
@@ -1578,7 +1617,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
m_spellAura->_ApplyEffectForTargets(effIndex);
}
-void Spell::EffectEnergize(SpellEffIndex effIndex)
+void Spell::EffectEnergize(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -1588,10 +1627,10 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
if (!unitTarget->IsAlive())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (effectInfo->MiscValue < 0 || effectInfo->MiscValue >= int8(MAX_POWERS))
return;
- Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers power = Powers(effectInfo->MiscValue);
if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER))
return;
@@ -1687,7 +1726,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
}
}
-void Spell::EffectEnergizePct(SpellEffIndex effIndex)
+void Spell::EffectEnergizePct(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -1697,10 +1736,10 @@ void Spell::EffectEnergizePct(SpellEffIndex effIndex)
if (!unitTarget->IsAlive())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
+ if (effectInfo->MiscValue < 0 || effectInfo->MiscValue >= int8(MAX_POWERS))
return;
- Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
+ Powers power = Powers(effectInfo->MiscValue);
if (unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->getPowerType() != power && !(m_spellInfo->AttributesEx7 & SPELL_ATTR7_CAN_RESTORE_SECONDARY_POWER))
return;
@@ -1887,7 +1926,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex)
ExecuteLogEffectOpenLock(effIndex, gameObjTarget ? (Object*)gameObjTarget : (Object*)itemTarget);
}
-void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
+void Spell::EffectSummonChangeItem(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -1905,7 +1944,7 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
if (m_CastItem->GetOwnerGUID() != player->GetGUID())
return;
- uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
+ uint32 newitemid = effectInfo->ItemType;
if (!newitemid)
return;
@@ -2022,14 +2061,14 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 entry = effectInfo->MiscValue;
if (!entry)
return;
- SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(effectInfo->MiscValueB);
if (!properties)
{
- TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u", m_spellInfo->Effects[effIndex].MiscValueB);
+ TC_LOG_ERROR("spells", "EffectSummonType: Unhandled summon type %u", effectInfo->MiscValueB);
return;
}
@@ -2130,7 +2169,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
}
default:
{
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = effectInfo->CalcRadius();
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
@@ -2175,8 +2214,8 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
uint32 spellId = VEHICLE_SPELL_RIDE_HARDCODED;
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].CalcValue());
- if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(effectInfo->CalcValue());
+ if (spellInfo && spellInfo->HasAura(m_originalCaster->GetMap()->GetDifficulty(), SPELL_AURA_CONTROL_VEHICLE))
spellId = spellInfo->Id;
// Hard coded enter vehicle spell
@@ -2214,13 +2253,13 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex)
Player* player = unitTarget->ToPlayer();
- uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
+ uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : effectInfo->TriggerSpell;
player->LearnSpell(spellToLearn, false);
TC_LOG_DEBUG("spells", "Spell: %s has learned spell %u from %s", player->GetGUID().ToString().c_str(), spellToLearn, m_caster->GetGUID().ToString().c_str());
}
-void Spell::EffectDispel(SpellEffIndex effIndex)
+void Spell::EffectDispel(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2229,7 +2268,7 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
return;
// Create dispel mask by dispel type
- uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 dispel_type = effectInfo->MiscValue;
uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
DispelChargesList dispel_list;
@@ -2316,12 +2355,15 @@ void Spell::EffectDispel(SpellEffIndex effIndex)
// Devour Magic
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC)
{
- int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue(m_caster);
- m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
- // Glyph of Felhunter
- if (Unit* owner = m_caster->GetOwner())
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_1))
+ {
+ int32 heal_amount = effect->CalcValue(m_caster);
+ m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true);
+ // Glyph of Felhunter
+ if (Unit* owner = m_caster->GetOwner())
if (owner->GetAura(56249))
owner->CastCustomSpell(owner, 19658, &heal_amount, NULL, NULL, true);
+ }
}
}
@@ -2376,7 +2418,7 @@ void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/)
m_caster->ToPlayer()->SendLoot(unitTarget->GetGUID(), LOOT_PICKPOCKETING);
}
-void Spell::EffectAddFarsight(SpellEffIndex effIndex)
+void Spell::EffectAddFarsight(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -2384,7 +2426,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
if (m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = effectInfo->CalcRadius();
int32 duration = m_spellInfo->GetDuration();
// Caster not in world, might be spell triggered from aura removal
if (!m_caster->IsInWorld())
@@ -2412,7 +2454,7 @@ void Spell::EffectUntrainTalents(SpellEffIndex /*effIndex*/)
unitTarget->ToPlayer()->SendTalentWipeConfirm(m_caster->GetGUID());
}
-void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex)
+void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2423,7 +2465,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex)
if (unitTarget->IsInFlight())
return;
- float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
+ float dis = effectInfo->CalcRadius(m_caster);
float fx, fy, fz;
m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectSize(), dis);
@@ -2431,7 +2473,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffIndex effIndex)
unitTarget->NearTeleportTo(fx, fy, fz, -m_caster->GetOrientation(), unitTarget == m_caster);
}
-void Spell::EffectLearnSkill(SpellEffIndex effIndex)
+void Spell::EffectLearnSkill(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2442,7 +2484,7 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
if (damage < 0)
return;
- uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 skillid = effectInfo->MiscValue;
SkillRaceClassInfoEntry const* rcEntry = GetSkillRaceClassInfo(skillid, unitTarget->getRace(), unitTarget->getClass());
if (!rcEntry)
return;
@@ -2452,10 +2494,10 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
return;
uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
- unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]);
+ unitTarget->ToPlayer()->SetSkill(skillid, effectInfo->CalcValue(), std::max<uint16>(skillval, 1), tier->Value[damage - 1]);
}
-void Spell::EffectPlayMovie(SpellEffIndex effIndex)
+void Spell::EffectPlayMovie(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2463,7 +2505,7 @@ void Spell::EffectPlayMovie(SpellEffIndex effIndex)
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 movieId = GetSpellInfo()->Effects[effIndex].MiscValue;
+ uint32 movieId = effectInfo->MiscValue;
if (!sMovieStore.LookupEntry(movieId))
return;
@@ -2502,7 +2544,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
player->DestroyItemCount(itemTarget, count, true);
unitTarget = player;
// and add a scroll
- DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
+ DoCreateItem(effIndex, effectInfo->ItemType);
itemTarget = NULL;
m_targets.SetItemTarget(NULL);
}
@@ -2512,7 +2554,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
if (!(m_CastItem && m_CastItem->GetTemplate()->Flags[0] & ITEM_PROTO_FLAG_TRIGGERED_CAST))
player->UpdateCraftSkill(m_spellInfo->Id);
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = effectInfo->MiscValue;
if (!enchant_id)
return;
@@ -2546,7 +2588,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
}
}
-void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
+void Spell::EffectEnchantItemPrismatic(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2558,7 +2600,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
if (!player)
return;
- uint32 enchantId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchantId = effectInfo->MiscValue;
if (!enchantId)
return;
@@ -2622,7 +2664,7 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
if (!itemTarget)
return;
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = effectInfo->MiscValue;
if (!enchant_id)
{
@@ -2757,7 +2799,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
owner = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
}
- uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 petentry = effectInfo->MiscValue;
if (!owner)
{
@@ -2843,7 +2885,7 @@ void Spell::EffectLearnPetSpell(SpellEffIndex effIndex)
if (!pet)
return;
- SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
+ SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(effectInfo->TriggerSpell);
if (!learn_spellproto)
return;
@@ -2887,7 +2929,7 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
unitTarget->ToCreature()->AI()->AttackStart(m_caster);
}
-void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
+void Spell::EffectWeaponDmg(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
return;
@@ -2898,9 +2940,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// multiple weapon dmg effect workaround
// execute only the last weapon damage
// and handle all effects at once
- for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[j].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -2988,48 +3032,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Blood Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
{
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
- AddPct(totalDamagePercentMod, bonusPct);
- break;
- }
- // Death Strike
- if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
- {
- // Glyph of Death Strike
- // 2% more damage per 5 runic power, up to a maximum of 40%
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(59336, EFFECT_0))
- if (uint32 runic = std::min<uint32>(uint32(m_caster->GetPower(POWER_RUNIC_POWER) / 2.5f), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(m_caster)))
- AddPct(totalDamagePercentMod, runic);
- break;
- }
- // Obliterate (12.5% more damage per disease)
- if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
- {
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), false) / 2.0f;
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
- AddPct(totalDamagePercentMod, bonusPct);
- break;
- }
- // Blood-Caked Strike - Blood-Caked Blade
- if (m_spellInfo->SpellIconID == 1736)
- {
- AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) * 50.0f);
- break;
- }
- // Heart Strike
- if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
- {
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID());
- // Death Knight T8 Melee 4P Bonus
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
- AddPct(bonusPct, aurEff->GetAmount());
-
- AddPct(totalDamagePercentMod, bonusPct);
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_2))
+ {
+ float bonusPct = effect->CalcValue(m_caster) * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
+ AddPct(bonusPct, aurEff->GetAmount());
+ AddPct(totalDamagePercentMod, bonusPct);
+ }
break;
}
break;
@@ -3038,20 +3048,22 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
bool normalized = false;
float weaponDamagePercentMod = 1.0f;
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
- switch (m_spellInfo->Effects[j].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
- fixed_bonus += CalculateDamage(j, unitTarget);
+ fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
break;
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
- fixed_bonus += CalculateDamage(j, unitTarget);
+ fixed_bonus += CalculateDamage(effect->EffectIndex, unitTarget);
normalized = true;
break;
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
- ApplyPct(weaponDamagePercentMod, CalculateDamage(j, unitTarget));
+ ApplyPct(weaponDamagePercentMod, CalculateDamage(effect->EffectIndex, unitTarget));
break;
default:
break; // not weapon damage effect, just skip
@@ -3083,11 +3095,13 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
int32 weaponDamage = m_caster->CalculateDamage(m_attackType, normalized, true);
// Sequence is important
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : GetEffects())
{
+ if (!effect)
+ continue;
// We assume that a spell have at most one fixed_bonus
// and at most one weaponDamagePercentMod
- switch (m_spellInfo->Effects[j].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_WEAPON_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:
@@ -3189,7 +3203,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 gameobject_id = effectInfo->MiscValue;
GameObject* pGameObj = new GameObject;
@@ -3321,7 +3335,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 55693: // Remove Collapsing Cave Aura
if (!unitTarget)
return;
- unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].CalcValue());
+ unitTarget->RemoveAurasDueToSpell(effectInfo->CalcValue());
break;
// Bending Shinbone
case 8856:
@@ -3455,7 +3469,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
case 45151:
{
//Workaround for Range ... should be global for every ScriptEffect
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = effectInfo->CalcRadius();
if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER && unitTarget->GetDistance(m_caster) >= radius && !unitTarget->HasAura(46394) && unitTarget != m_caster)
unitTarget->CastSpell(unitTarget, 46394, true);
@@ -3567,7 +3581,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
return;
float x, y, z;
- float radius = m_spellInfo->Effects[effIndex].CalcRadius();
+ float radius = effectInfo->CalcRadius();
for (uint8 i = 0; i < 15; ++i)
{
m_caster->GetRandomPoint(*destTarget, radius, x, y, z);
@@ -3613,8 +3627,9 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex != 0)
return;
- uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
- uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
+ // Effects for 58418 and 58420 are all DIFFICULTY_NONE so always valid
+ uint32 spellID = GetEffect(EFFECT_0)->CalcValue();
+ uint32 questID = GetEffect(EFFECT_1)->CalcValue();
if (unitTarget->ToPlayer()->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE)
unitTarget->CastSpell(unitTarget, spellID, true);
@@ -3664,7 +3679,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
{
/// @todo a hack, range = 11, should after some time cast, otherwise too far
m_caster->CastSpell(parent, 62496, true);
- unitTarget->CastSpell(parent, m_spellInfo->Effects[EFFECT_0].CalcValue());
+ unitTarget->CastSpell(parent, GetEffect(EFFECT_0)->CalcValue()); // DIFFICULTY_NONE, so effect always valid
}
}
}
@@ -3856,7 +3871,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
//CREATE DUEL FLAG OBJECT
GameObject* pGameObj = new GameObject;
- uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 gameobject_id = effectInfo->MiscValue;
Map* map = m_caster->GetMap();
if (!pGameObj->Create(sObjectMgr->GetGenerator<HighGuid::GameObject>()->Generate(), gameobject_id,
@@ -3981,12 +3996,12 @@ void Spell::EffectActivateObject(SpellEffIndex /*effIndex*/)
ScriptInfo activateCommand;
activateCommand.command = SCRIPT_COMMAND_ACTIVATE_OBJECT;
- // int32 unk = m_spellInfo->Effects[effIndex].MiscValue; // This is set for EffectActivateObject spells; needs research
+ // int32 unk = effectInfo->MiscValue; // This is set for EffectActivateObject spells; needs research
gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, 0, m_caster, gameObjTarget);
}
-void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
+void Spell::EffectApplyGlyph(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -4020,7 +4035,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
}
// apply new one
- if (uint32 newGlyph = m_spellInfo->Effects[effIndex].MiscValue)
+ if (uint32 newGlyph = effectInfo->MiscValue)
{
if (GlyphPropertiesEntry const* newGlyphProperties = sGlyphPropertiesStore.LookupEntry(newGlyph))
{
@@ -4059,7 +4074,7 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
}
}
-void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex)
+void Spell::EffectEnchantHeldItem(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4078,9 +4093,9 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex effIndex)
if (!item->IsEquipped())
return;
- if (m_spellInfo->Effects[effIndex].MiscValue)
+ if (effectInfo->MiscValue)
{
- uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 enchant_id = effectInfo->MiscValue;
int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
if (!duration)
duration = damage;//+1; //Base points after ..
@@ -4174,7 +4189,7 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex)
player->DestroyItemCount(foodItem, count, true);
/// @todo fix crash when a spell has two effects, both pointed at the same item target
- m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, NULL, NULL, true);
+ m_caster->CastCustomSpell(pet, effectInfo->TriggerSpell, &benefit, NULL, NULL, true);
}
void Spell::EffectDismissPet(SpellEffIndex effIndex)
@@ -4196,8 +4211,8 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 go_id = m_spellInfo->Effects[effIndex].MiscValue;
- uint8 slot = m_spellInfo->Effects[effIndex].Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
+ uint32 go_id = effectInfo->MiscValue;
+ uint8 slot = effectInfo->Effect - SPELL_EFFECT_SUMMON_OBJECT_SLOT1;
ObjectGuid guid = m_caster->m_ObjectSlot[slot];
if (!guid.IsEmpty())
{
@@ -4320,7 +4335,7 @@ void Spell::EffectLeap(SpellEffIndex /*effIndex*/)
unitTarget->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), unitTarget == m_caster);
}
-void Spell::EffectReputation(SpellEffIndex effIndex)
+void Spell::EffectReputation(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4332,7 +4347,7 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
int32 repChange = damage;
- uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 factionId = effectInfo->MiscValue;
FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
if (!factionEntry)
@@ -4343,7 +4358,7 @@ void Spell::EffectReputation(SpellEffIndex effIndex)
player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
}
-void Spell::EffectQuestComplete(SpellEffIndex effIndex)
+void Spell::EffectQuestComplete(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4352,7 +4367,7 @@ void Spell::EffectQuestComplete(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 questId = effectInfo->MiscValue;
if (questId)
{
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
@@ -4377,7 +4392,7 @@ void Spell::EffectForceDeselect(SpellEffIndex /*effIndex*/)
m_caster->SendMessageToSet(&data, true);
}
-void Spell::EffectSelfResurrect(SpellEffIndex effIndex)
+void Spell::EffectSelfResurrect(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -4396,7 +4411,7 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex)
if (damage < 0)
{
health = uint32(-damage);
- mana = m_spellInfo->Effects[effIndex].MiscValue;
+ mana = effectInfo->MiscValue;
}
// percent case
else
@@ -4488,7 +4503,7 @@ void Spell::EffectChargeDest(SpellEffIndex /*effIndex*/)
}
}
-void Spell::EffectKnockBack(SpellEffIndex effIndex)
+void Spell::EffectKnockBack(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4509,13 +4524,13 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)
unitTarget->InterruptNonMeleeSpells(true);
float ratio = 0.1f;
- float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
+ float speedxy = float(effectInfo->MiscValue) * ratio;
float speedz = float(damage) * ratio;
if (speedxy < 0.1f && speedz < 0.1f)
return;
float x, y;
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
+ if (effectInfo->Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
{
if (m_targets.HasDst())
destTarget->GetPosition(x, y);
@@ -4530,7 +4545,7 @@ void Spell::EffectKnockBack(SpellEffIndex effIndex)
unitTarget->KnockbackFrom(x, y, speedxy, speedz);
}
-void Spell::EffectLeapBack(SpellEffIndex effIndex)
+void Spell::EffectLeapBack(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_LAUNCH_TARGET)
return;
@@ -4538,13 +4553,13 @@ void Spell::EffectLeapBack(SpellEffIndex effIndex)
if (!unitTarget)
return;
- float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue)/10;
- float speedz = float(damage/10);
+ float speedxy = float(effectInfo->MiscValue) / 10;
+ float speedz = float(damage / 10);
//1891: Disengage
m_caster->JumpTo(speedxy, speedz, m_spellInfo->SpellIconID != 1891);
}
-void Spell::EffectQuestClear(SpellEffIndex effIndex)
+void Spell::EffectQuestClear(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4553,7 +4568,7 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex)
return;
Player* player = unitTarget->ToPlayer();
- uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 quest_id = effectInfo->MiscValue;
Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
@@ -4587,7 +4602,7 @@ void Spell::EffectQuestClear(SpellEffIndex effIndex)
player->RemoveRewardedQuest(quest_id);
}
-void Spell::EffectSendTaxi(SpellEffIndex effIndex)
+void Spell::EffectSendTaxi(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4595,10 +4610,10 @@ void Spell::EffectSendTaxi(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
+ unitTarget->ToPlayer()->ActivateTaxiPathTo(effectInfo->MiscValue, m_spellInfo->Id);
}
-void Spell::EffectPullTowards(SpellEffIndex effIndex)
+void Spell::EffectPullTowards(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4607,7 +4622,7 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
return;
Position pos;
- if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
+ if (effectInfo->Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
{
if (m_targets.HasDst())
pos.Relocate(*destTarget);
@@ -4619,13 +4634,13 @@ void Spell::EffectPullTowards(SpellEffIndex effIndex)
pos.Relocate(m_caster);
}
- float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f;
+ float speedXY = float(effectInfo->MiscValue) * 0.1f;
float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
}
-void Spell::EffectDispelMechanic(SpellEffIndex effIndex)
+void Spell::EffectDispelMechanic(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4633,7 +4648,7 @@ void Spell::EffectDispelMechanic(SpellEffIndex effIndex)
if (!unitTarget)
return;
- uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 mechanic = effectInfo->MiscValue;
DispelList dispel_list;
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
@@ -4752,7 +4767,7 @@ void Spell::EffectDurabilityDamage(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 slot = effectInfo->MiscValue;
// -1 means all player equipped items and -2 all items
if (slot < 0)
@@ -4773,7 +4788,7 @@ void Spell::EffectDurabilityDamage(SpellEffIndex effIndex)
}
}
-void Spell::EffectDurabilityDamagePCT(SpellEffIndex effIndex)
+void Spell::EffectDurabilityDamagePCT(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -4781,7 +4796,7 @@ void Spell::EffectDurabilityDamagePCT(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 slot = effectInfo->MiscValue;
// FIXME: some spells effects have value -1/-2
// Possibly its mean -1 all player equipped items and -2 all items
@@ -4818,7 +4833,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
- uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 name_id = effectInfo->MiscValue;
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
@@ -4833,9 +4848,9 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex)
if (m_targets.HasDst())
destTarget->GetPosition(fx, fy, fz);
//FIXME: this can be better check for most objects but still hack
- else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
+ else if (effectInfo->HasRadius() && m_spellInfo->Speed == 0)
{
- float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
+ float dis = effectInfo->CalcRadius(m_originalCaster);
m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
}
else
@@ -5044,7 +5059,7 @@ void Spell::EffectSkinPlayerCorpse(SpellEffIndex /*effIndex*/)
target->RemovedInsignia(player);
}
-void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
+void Spell::EffectStealBeneficialBuff(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5057,7 +5072,7 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
DispelChargesList steal_list;
// Create dispel mask by dispel type
- uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
+ uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(effectInfo->MiscValue));
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
@@ -5149,7 +5164,7 @@ void Spell::EffectStealBeneficialBuff(SpellEffIndex effIndex)
m_caster->SendMessageToSet(&dataSuccess, true);
}
-void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex)
+void Spell::EffectKillCreditPersonal(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5157,10 +5172,10 @@ void Spell::EffectKillCreditPersonal(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
+ unitTarget->ToPlayer()->KilledMonsterCredit(effectInfo->MiscValue);
}
-void Spell::EffectKillCredit(SpellEffIndex effIndex)
+void Spell::EffectKillCredit(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5168,7 +5183,7 @@ void Spell::EffectKillCredit(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
+ int32 creatureEntry = effectInfo->MiscValue;
if (!creatureEntry)
{
if (m_spellInfo->Id == 42793) // Burn Body
@@ -5179,7 +5194,7 @@ void Spell::EffectKillCredit(SpellEffIndex effIndex)
unitTarget->ToPlayer()->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
}
-void Spell::EffectQuestFail(SpellEffIndex effIndex)
+void Spell::EffectQuestFail(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5187,10 +5202,10 @@ void Spell::EffectQuestFail(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
+ unitTarget->ToPlayer()->FailQuest(effectInfo->MiscValue);
}
-void Spell::EffectQuestStart(SpellEffIndex effIndex)
+void Spell::EffectQuestStart(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5202,7 +5217,7 @@ void Spell::EffectQuestStart(SpellEffIndex effIndex)
if (!player)
return;
- if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(effectInfo->MiscValue))
{
if (!player->CanTakeQuest(quest, false))
return;
@@ -5234,10 +5249,10 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
if (count == 0) count = 1;
for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
{
- if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
+ if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(effectInfo->MiscValue))
{
if (m_spellInfo->Id == 45529)
- if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
+ if (player->GetBaseRune(j) != RuneType(effectInfo->MiscValueB))
continue;
player->SetRuneCooldown(j, 0);
--count;
@@ -5250,7 +5265,7 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
for (uint32 l = 0; l + 1 < MAX_RUNES && count > 0; ++l)
{
// Check if both runes are on cd as that is the only time when this needs to come into effect
- if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)) && (player->GetRuneCooldown(l+1) && player->GetCurrentRune(l+1) == RuneType(m_spellInfo->Effects[effIndex].MiscValueB)))
+ if ((player->GetRuneCooldown(l) && player->GetCurrentRune(l) == RuneType(effectInfo->MiscValueB)) && (player->GetRuneCooldown(l + 1) && player->GetCurrentRune(l + 1) == RuneType(effectInfo->MiscValueB)))
{
// Should always update the rune with the lowest cd
if (l + 1 < MAX_RUNES && player->GetRuneCooldown(l) >= player->GetRuneCooldown(l+1))
@@ -5280,7 +5295,7 @@ void Spell::EffectActivateRune(SpellEffIndex effIndex)
}
}
-void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
+void Spell::EffectCreateTamedPet(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5288,7 +5303,7 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || !unitTarget->GetPetGUID().IsEmpty() || unitTarget->getClass() != CLASS_HUNTER)
return;
- uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 creatureEntry = effectInfo->MiscValue;
Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
if (!pet)
return;
@@ -5313,14 +5328,14 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
}
}
-void Spell::EffectDiscoverTaxi(SpellEffIndex effIndex)
+void Spell::EffectDiscoverTaxi(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 nodeid = effectInfo->MiscValue;
if (sTaxiNodesStore.LookupEntry(nodeid))
unitTarget->ToPlayer()->GetSession()->SendDiscoverNewTaxiNode(nodeid);
}
@@ -5373,7 +5388,7 @@ void Spell::EffectGameObjectRepair(SpellEffIndex /*effIndex*/)
gameObjTarget->ModifyHealth(damage, m_caster);
}
-void Spell::EffectGameObjectSetDestructionState(SpellEffIndex effIndex)
+void Spell::EffectGameObjectSetDestructionState(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5382,7 +5397,7 @@ void Spell::EffectGameObjectSetDestructionState(SpellEffIndex effIndex)
return;
Player* player = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
- gameObjTarget->SetDestructibleState(GameObjectDestructibleState(m_spellInfo->Effects[effIndex].MiscValue), player, true);
+ gameObjTarget->SetDestructibleState(GameObjectDestructibleState(effectInfo->MiscValue), player, true);
}
void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numGuardians)
@@ -5464,7 +5479,7 @@ void Spell::EffectRenamePet(SpellEffIndex /*effIndex*/)
unitTarget->SetByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED);
}
-void Spell::EffectPlayMusic(SpellEffIndex effIndex)
+void Spell::EffectPlayMusic(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5472,7 +5487,7 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 soundid = effectInfo->MiscValue;
if (!sSoundEntriesStore.LookupEntry(soundid))
{
@@ -5508,7 +5523,7 @@ void Spell::EffectActivateSpec(SpellEffIndex /*effIndex*/)
unitTarget->ToPlayer()->ActivateTalentGroup(damage-1); // damage is 1 or 2, spec is 0 or 1
}
-void Spell::EffectPlaySound(SpellEffIndex effIndex)
+void Spell::EffectPlaySound(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5529,7 +5544,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
break;
}
- uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
+ uint32 soundId = effectInfo->MiscValue;
if (!sSoundEntriesStore.LookupEntry(soundId))
{
@@ -5540,7 +5555,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
player->PlayDirectSound(soundId, player);
}
-void Spell::EffectRemoveAura(SpellEffIndex effIndex)
+void Spell::EffectRemoveAura(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5548,7 +5563,7 @@ void Spell::EffectRemoveAura(SpellEffIndex effIndex)
if (!unitTarget)
return;
// there may be need of specifying casterguid of removed auras
- unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
+ unitTarget->RemoveAurasDueToSpell(effectInfo->TriggerSpell);
}
void Spell::EffectDamageFromMaxHealthPCT(SpellEffIndex /*effIndex*/)
@@ -5562,7 +5577,7 @@ void Spell::EffectDamageFromMaxHealthPCT(SpellEffIndex /*effIndex*/)
m_damage += unitTarget->CountPctFromMaxHealth(damage);
}
-void Spell::EffectGiveCurrency(SpellEffIndex effIndex)
+void Spell::EffectGiveCurrency(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5570,10 +5585,10 @@ void Spell::EffectGiveCurrency(SpellEffIndex effIndex)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- unitTarget->ToPlayer()->ModifyCurrency(m_spellInfo->Effects[effIndex].MiscValue, damage);
+ unitTarget->ToPlayer()->ModifyCurrency(effectInfo->MiscValue, damage);
}
-void Spell::EffectCastButtons(SpellEffIndex effIndex)
+void Spell::EffectCastButtons(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -5582,8 +5597,8 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex)
return;
Player* p_caster = m_caster->ToPlayer();
- uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
- uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
+ uint32 button_id = effectInfo->MiscValue + 132;
+ uint32 n_buttons = effectInfo->MiscValueB;
for (; n_buttons; --n_buttons, ++button_id)
{
@@ -5628,25 +5643,27 @@ void Spell::EffectRechargeManaGem(SpellEffIndex /*effIndex*/)
if (!player)
return;
-
- uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
-
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
- if (!pProto)
+ if (SpellEffectInfo const* effect = GetEffect(EFFECT_0))
{
- player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
- return;
- }
+ uint32 item_id = effect->ItemType;
- if (Item* pItem = player->GetItemByEntry(item_id))
- {
- for (int x = 0; x < pProto->Effects.size(); ++x)
- pItem->SetSpellCharges(x, pProto->Effects[x].Charges);
- pItem->SetState(ITEM_CHANGED, player);
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
+ if (!pProto)
+ {
+ player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
+ return;
+ }
+
+ if (Item* pItem = player->GetItemByEntry(item_id))
+ {
+ for (int x = 0; x < pProto->Effects.size(); ++x)
+ pItem->SetSpellCharges(x, pProto->Effects[x].Charges);
+ pItem->SetState(ITEM_CHANGED, player);
+ }
}
}
-void Spell::EffectBind(SpellEffIndex effIndex)
+void Spell::EffectBind(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5659,8 +5676,8 @@ void Spell::EffectBind(SpellEffIndex effIndex)
WorldLocation homeLoc;
uint32 areaId = player->GetAreaId();
- if (m_spellInfo->Effects[effIndex].MiscValue)
- areaId = m_spellInfo->Effects[effIndex].MiscValue;
+ if (effectInfo->MiscValue)
+ areaId = effectInfo->MiscValue;
if (m_targets.HasDst())
homeLoc.WorldRelocate(*destTarget);
@@ -5668,27 +5685,19 @@ void Spell::EffectBind(SpellEffIndex effIndex)
homeLoc = player->GetWorldLocation();
player->SetHomebind(homeLoc, areaId);
-
- // binding
- WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
- data << float(homeLoc.GetPositionX());
- data << float(homeLoc.GetPositionY());
- data << float(homeLoc.GetPositionZ());
- data << uint32(homeLoc.GetMapId());
- data << uint32(areaId);
- player->SendDirectMessage(&data);
+ player->SendBindPointUpdate();
TC_LOG_DEBUG("spells", "EffectBind: New homebind X: %f, Y: %f, Z: %f, MapId: %u, AreaId: %u",
homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
// zone update
- data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
+ WorldPacket data(SMSG_PLAYERBOUND, 8 + 4);
data << m_caster->GetGUID();
data << uint32(areaId);
player->SendDirectMessage(&data);
}
-void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex)
+void Spell::EffectSummonRaFFriend(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -5696,10 +5705,10 @@ void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex)
if (m_caster->GetTypeId() != TYPEID_PLAYER || !unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- m_caster->CastSpell(unitTarget, m_spellInfo->Effects[effIndex].TriggerSpell, true);
+ m_caster->CastSpell(unitTarget, effectInfo->TriggerSpell, true);
}
-void Spell::EffectUnlockGuildVaultTab(SpellEffIndex effIndex)
+void Spell::EffectUnlockGuildVaultTab(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -5707,7 +5716,7 @@ void Spell::EffectUnlockGuildVaultTab(SpellEffIndex effIndex)
// Safety checks done in Spell::CheckCast
Player* caster = m_caster->ToPlayer();
if (Guild* guild = caster->GetGuild())
- guild->HandleBuyBankTab(caster->GetSession(), m_spellInfo->Effects[effIndex].BasePoints - 1); // Bank tabs start at zero internally
+ guild->HandleBuyBankTab(caster->GetSession(), effectInfo->BasePoints - 1); // Bank tabs start at zero internally
}
void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
@@ -5731,8 +5740,8 @@ void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
uint32 health = target->CountPctFromMaxHealth(damage);
uint32 mana = CalculatePct(target->GetMaxPower(POWER_MANA), damage);
uint32 resurrectAura = 0;
- if (sSpellMgr->GetSpellInfo(GetSpellInfo()->Effects[effIndex].TriggerSpell))
- resurrectAura = GetSpellInfo()->Effects[effIndex].TriggerSpell;
+ if (sSpellMgr->GetSpellInfo(effectInfo->TriggerSpell))
+ resurrectAura = effectInfo->TriggerSpell;
if (resurrectAura && target->HasAura(resurrectAura))
return;
@@ -5742,7 +5751,7 @@ void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
SendResurrectRequest(target);
}
-void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex)
+void Spell::EffectCreateAreaTrigger(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
@@ -5754,7 +5763,7 @@ void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex)
pos = destTarget->GetPosition();
// trigger entry/miscvalue relation is currently unknown, for now use MiscValue as trigger entry
- uint32 triggerEntry = GetSpellInfo()->Effects[effIndex].MiscValue;
+ uint32 triggerEntry = effectInfo->MiscValue;
AreaTrigger * areaTrigger = new AreaTrigger;
if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GetGenerator<HighGuid::AreaTrigger>()->Generate(), triggerEntry, GetCaster(), GetSpellInfo(), pos))
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index cc88cc41e5a..da3135f6001 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -341,10 +341,8 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_
SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* _effect)
{
- SpellScalingEntry const* scaling = spellInfo->GetSpellScaling();
-
_spellInfo = spellInfo;
- _effIndex = _effect ? _effect->EffectIndex : effIndex;
+ EffectIndex = _effect ? _effect->EffectIndex : effIndex;
Effect = _effect ? _effect->Effect : 0;
ApplyAuraName = _effect ? _effect->EffectAura : 0;
ApplyAuraPeriod = _effect ? _effect->EffectAuraPeriod : 0;
@@ -358,6 +356,7 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con
MiscValue = _effect ? _effect->EffectMiscValue : 0;
MiscValueB = _effect ? _effect->EffectMiscValueB : 0;
Mechanic = Mechanics(_effect ? _effect->EffectMechanic : 0);
+ PositionFacing = _effect ? _effect->EffectPosFacing : 0.0f;
TargetA = SpellImplicitTargetInfo(_effect ? _effect->ImplicitTarget[0] : 0);
TargetB = SpellImplicitTargetInfo(_effect ? _effect->ImplicitTarget[1] : 0);
RadiusEntry = _effect && _effect->EffectRadiusIndex ? sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex) : NULL;
@@ -366,11 +365,15 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo con
ItemType = _effect ? _effect->EffectItemType : 0;
TriggerSpell = _effect ? _effect->EffectTriggerSpell : 0;
SpellClassMask = _effect ? _effect->EffectSpellClassMask : flag128();
+ BonusCoefficientFromAP = _effect ? _effect->BonusCoefficientFromAP : 0.0f;
ImplicitTargetConditions = NULL;
- // TODO: 6.x these values are no longer in dbc
- ScalingMultiplier = /*scaling ? scaling->Multiplier[_effIndex] :*/ 0.0f;
- DeltaScalingMultiplier = /*scaling ? scaling->RandomMultiplier[_effIndex] :*/ 0.0f;
- ComboScalingMultiplier = /*scaling ? scaling->OtherMultiplier[_effIndex] :*/ 0.0f;
+
+ uint32 _effectScalingId = _effect ? sSpellEffectScallingByEffectId.find(_effect->ID) != sSpellEffectScallingByEffectId.end() ? sSpellEffectScallingByEffectId[_effect->ID] : 0 : 0;
+ SpellEffectScalingEntry const* _effectScalingEntry = sSpellEffectScalingStore.LookupEntry(_effectScalingId);
+
+ Scaling.Coefficient = _effectScalingEntry ? _effectScalingEntry->Coefficient : 0.0f;
+ Scaling.Variance = _effectScalingEntry ? _effectScalingEntry->Variance : 0.0f;
+ Scaling.ResourceCoefficient = _effectScalingEntry ? _effectScalingEntry->ResourceCoefficient : 0.0f;
}
bool SpellEffectInfo::IsEffect() const
@@ -378,7 +381,7 @@ bool SpellEffectInfo::IsEffect() const
return Effect != 0;
}
-bool SpellEffectInfo::IsEffect(SpellEffects effectName) const
+bool SpellEffectInfo::IsEffect(SpellEffectName effectName) const
{
return Effect == uint32(effectName);
}
@@ -429,42 +432,71 @@ bool SpellEffectInfo::IsUnitOwnedAuraEffect() const
return IsAreaAuraEffect() || Effect == SPELL_EFFECT_APPLY_AURA;
}
-int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const* target) const
+int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/) const
{
float basePointsPerLevel = RealPointsPerLevel;
int32 basePoints = bp ? *bp : BasePoints;
float comboDamage = PointsPerResource;
// base amount modification based on spell lvl vs caster lvl
- if (ScalingMultiplier != 0.0f)
+ if (Scaling.Coefficient != 0.0f)
{
- if (caster)
+ int32 level = _spellInfo->SpellLevel;
+ if (target && _spellInfo->IsPositiveEffect(EffectIndex) && (Effect == SPELL_EFFECT_APPLY_AURA))
+ level = target->getLevel();
+ else if (caster)
+ level = caster->getLevel();
+
+ if (!(_spellInfo->AttributesEx11 & SPELL_ATTR11_UNK2) && _spellInfo->AttributesEx10 & SPELL_ATTR10_UNK12)
+ level = _spellInfo->BaseLevel;
+
+ if (_spellInfo->Scaling.MaxScalingLevel && _spellInfo->Scaling.MaxScalingLevel > level)
+ level = _spellInfo->Scaling.MaxScalingLevel;
+
+ float value = 0.0f;
+ if (level > 0)
{
- int32 level = caster->getLevel();
- if (target && _spellInfo->IsPositiveEffect(_effIndex) && (Effect == SPELL_EFFECT_APPLY_AURA))
- level = target->getLevel();
+ if (!_spellInfo->Scaling.Class)
+ return 0;
- if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.LookupEntry((_spellInfo->ScalingClass != -1 ? _spellInfo->ScalingClass - 1 : MAX_CLASSES - 1) * 100 + level - 1))
+ if (!_spellInfo->Scaling.ScalesFromItemLevel)
{
- float multiplier = gtScaling->value;
- if (_spellInfo->CastTimeMax > 0 && _spellInfo->CastTimeMaxLevel > level)
- multiplier *= float(_spellInfo->CastTimeMin + (level - 1) * (_spellInfo->CastTimeMax - _spellInfo->CastTimeMin) / (_spellInfo->CastTimeMaxLevel - 1)) / float(_spellInfo->CastTimeMax);
- if (_spellInfo->CoefLevelBase > level)
- multiplier *= (1.0f - _spellInfo->CoefBase) * (float)(level - 1) / (float)(_spellInfo->CoefLevelBase - 1) + _spellInfo->CoefBase;
-
- float preciseBasePoints = ScalingMultiplier * multiplier;
- if (DeltaScalingMultiplier)
+ if (!(_spellInfo->AttributesEx11 & SPELL_ATTR11_UNK2))
{
- float delta = fabs(DeltaScalingMultiplier * ScalingMultiplier * multiplier * 0.5f);
- preciseBasePoints += frand(-delta, delta);
+ if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.EvaluateTable(level - 1, (_spellInfo->Scaling.Class > 0 ? _spellInfo->Scaling.Class - 1 : MAX_CLASSES - 1)))
+ value = gtScaling->value;
}
+ else
+ value = GetRandomPropertyPoints(level, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
+ }
+ else
+ value = GetRandomPropertyPoints(_spellInfo->Scaling.ScalesFromItemLevel, ITEM_QUALITY_RARE, INVTYPE_CHEST, 0);
- basePoints = int32(preciseBasePoints);
+ if (level < _spellInfo->Scaling.CastTimeMaxLevel && _spellInfo->Scaling.CastTimeMax)
+ value *= float(_spellInfo->Scaling.CastTimeMin + (level - 1) * (_spellInfo->Scaling.CastTimeMax - _spellInfo->Scaling.CastTimeMin) / (_spellInfo->Scaling.CastTimeMaxLevel - 1)) / float(_spellInfo->Scaling.CastTimeMax);
- if (ComboScalingMultiplier)
- comboDamage = ComboScalingMultiplier * multiplier;
- }
+ if (level < _spellInfo->Scaling.NerfMaxLevel)
+ value *= ((((1.0 - _spellInfo->Scaling.NerfFactor) * (level - 1)) / (_spellInfo->Scaling.NerfMaxLevel - 1)) + _spellInfo->Scaling.NerfFactor);
+ }
+
+ value *= Scaling.Coefficient;
+ if (value != 0.0f && value < 1.0f)
+ value = 1.0f;
+
+ if (Scaling.Variance)
+ {
+ float delta = fabs(Scaling.Variance * 0.5f);
+ float valueVariance = frand(-delta, delta);
+ value += value * valueVariance;
+
+ if (variance)
+ *variance = valueVariance;
}
+
+ basePoints = int32(value);
+
+ if (Scaling.ResourceCoefficient)
+ comboDamage = Scaling.ResourceCoefficient * value;
}
else
{
@@ -508,22 +540,9 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
if (uint8 comboPoints = caster->m_movedPlayer->GetComboPoints())
value += comboDamage * comboPoints;
- value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, value);
+ value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
// amount multiplication based on caster's level
-/* REVIEW - MERGE <<<<<<< HEAD
- if (!_spellInfo->GetSpellScaling() && !basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&
- Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
- Effect != SPELL_EFFECT_KNOCK_BACK &&
- Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS &&
- ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS &&
- ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK &&
- ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED &&
- ApplyAuraName != SPELL_AURA_MOD_DECREASE_SPEED)
- //there are many more: slow speed, -healing pct
- value *= 0.25f * exp(caster->getLevel() * (70 - _spellInfo->SpellLevel) / 1000.0f);
- //value = int32(value * (int32)getLevel() / (int32)(_spellInfo->spellLevel ? _spellInfo->spellLevel : 1));
-======= */
if (!caster->IsControlledByPlayer() &&
_spellInfo->SpellLevel && _spellInfo->SpellLevel != caster->getLevel() &&
!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION))
@@ -568,13 +587,12 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
if (canEffectScale)
{
- GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(_spellInfo->SpellLevel - 1);
- GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
+ GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.EvaluateTable(_spellInfo->SpellLevel - 1, 0);
+ GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.EvaluateTable(caster->getLevel() - 1, 0);
if (spellScaler && casterScaler)
value *= casterScaler->ratio / spellScaler->ratio;
}
}
-// REVIEW - MERGE >>>>>>> master
}
return int32(value);
@@ -862,14 +880,30 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 182 SPELL_EFFECT_182
};
-SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects)
+SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects)
{
Id = spellEntry->ID;
+ // SpellDifficultyEntry
+ for (SpellEffectEntryMap::const_iterator itr = effects.begin(); itr != effects.end(); ++itr)
+ {
+ SpellEffectEntryVector effects = itr->second;
+ _effects[itr->first].resize(effects.size());
+
+ for (uint32 i = effects.size(); i > 0; --i)
+ {
+ SpellEffectEntry const* effect = effects[i - 1];
+ if (!effect)
+ continue;
+
+ _effects[itr->first][effect->EffectIndex] = new SpellEffectInfo(spellEntry, this, effect->EffectIndex, effect);
+ }
+ }
+
SpellName = spellEntry->Name_lang;
- //Rank = spellEntry->Rank;
+ Rank = nullptr;
RuneCostID = spellEntry->RuneCostID;
- //SpellDifficultyId = spellEntry->DifficultyID;
+ SpellDifficultyId = 0;
SpellScalingId = spellEntry->ScalingID;
SpellAuraOptionsId = spellEntry->AuraOptionsID;
SpellAuraRestrictionsId = spellEntry->AuraRestrictionsID;
@@ -880,7 +914,6 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effe
SpellEquippedItemsId = spellEntry->EquippedItemsID;
SpellInterruptsId = spellEntry->InterruptsID;
SpellLevelsId = spellEntry->LevelsID;
- //SpellPowerId = spellEntry->PowerID;
SpellReagentsId = spellEntry->ReagentsID;
SpellShapeshiftId = spellEntry->ShapeshiftID;
SpellTargetRestrictionsId = spellEntry->TargetRestrictionsID;
@@ -916,18 +949,16 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effe
SpellIconID = _misc ? _misc->SpellIconID : 0;
ActiveIconID = _misc ? _misc->ActiveIconID : 0;
- // SpellDifficultyEntry
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- Effects[i] = SpellEffectInfo(spellEntry, this, i, effects[i]);
-
// SpellScalingEntry
SpellScalingEntry const* _scaling = GetSpellScaling();
- CastTimeMin = _scaling ? _scaling->CastTimeMin : 0;
- CastTimeMax = _scaling ?_scaling->CastTimeMax : 0;
- CastTimeMaxLevel = _scaling ? _scaling->CastTimeMaxLevel : 0;
- ScalingClass = _scaling ? _scaling->ScalingClass : 0;
- CoefBase = _scaling ? _scaling->NerfFactor : 0;
- CoefLevelBase = _scaling ? _scaling->NerfMaxLevel : 0;
+ Scaling.CastTimeMin = _scaling ? _scaling->CastTimeMin : 0;
+ Scaling.CastTimeMax = _scaling ?_scaling->CastTimeMax : 0;
+ Scaling.CastTimeMaxLevel = _scaling ? _scaling->CastTimeMaxLevel : 0;
+ Scaling.Class = _scaling ? _scaling->ScalingClass : 0;
+ Scaling.NerfFactor = _scaling ? _scaling->NerfFactor : 0;
+ Scaling.NerfMaxLevel = _scaling ? _scaling->NerfMaxLevel : 0;
+ Scaling.MaxScalingLevel = _scaling ? _scaling->MaxScalingLevel : 0;
+ Scaling.ScalesFromItemLevel = _scaling ? _scaling->ScalesFromItemLevel : 0;
// SpellAuraOptionsEntry
SpellAuraOptionsEntry const* _options = GetSpellAuraOptions();
@@ -1040,58 +1071,99 @@ uint32 SpellInfo::GetCategory() const
return CategoryEntry ? CategoryEntry->ID : 0;
}
-bool SpellInfo::HasEffect(SpellEffects effect) const
+bool SpellInfo::HasEffect(uint32 difficulty, SpellEffectName effect) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsEffect(effect))
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* eff : effects)
+ {
+ if (eff && eff->IsEffect(effect))
return true;
+ }
return false;
}
-bool SpellInfo::HasAura(AuraType aura) const
+bool SpellInfo::HasEffect(SpellEffectName effect) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsAura(aura))
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* eff : itr->second)
+ {
+ if (eff && eff->IsEffect(effect))
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SpellInfo::HasAura(uint32 difficulty, AuraType aura) const
+{
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
+ {
+ if (effect && effect->IsAura(aura))
return true;
+ }
return false;
}
-bool SpellInfo::HasAreaAuraEffect() const
+bool SpellInfo::HasAreaAuraEffect(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsAreaAuraEffect())
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
+ {
+ if (effect && effect->IsAreaAuraEffect())
return true;
+ }
+ return false;
+}
+
+bool SpellInfo::HasAreaAuraEffect() const
+{
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->IsAreaAuraEffect())
+ return true;
+ }
+ }
return false;
}
bool SpellInfo::IsExplicitDiscovery() const
{
- return ((Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM
- || Effects[0].Effect == SPELL_EFFECT_CREATE_ITEM_2)
- && Effects[1].Effect == SPELL_EFFECT_SCRIPT_EFFECT)
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ SpellEffectInfo const* effect1 = GetEffect(DIFFICULTY_NONE, EFFECT_1);
+
+ return ((effect0 && (effect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM || effect0->Effect == SPELL_EFFECT_CREATE_ITEM_2))
+ && effect1 && effect1->Effect == SPELL_EFFECT_SCRIPT_EFFECT)
|| Id == 64323;
}
bool SpellInfo::IsLootCrafting() const
{
- return (Effects[0].Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ return effect0 && (effect0->Effect == SPELL_EFFECT_CREATE_RANDOM_ITEM ||
// different random cards from Inscription (121==Virtuoso Inking Set category) r without explicit item
- (Effects[0].Effect == SPELL_EFFECT_CREATE_ITEM_2 &&
- ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || Effects[0].ItemType == 0)));
+ (effect0->Effect == SPELL_EFFECT_CREATE_ITEM_2 &&
+ ((TotemCategory[0] != 0 || (Totem[0] != 0 && SpellIconID == 1)) || effect0->ItemType == 0)));
}
bool SpellInfo::IsQuestTame() const
{
- return Effects[0].Effect == SPELL_EFFECT_THREAT && Effects[1].Effect == SPELL_EFFECT_APPLY_AURA && Effects[1].ApplyAuraName == SPELL_AURA_DUMMY;
+ SpellEffectInfo const* effect0 = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ SpellEffectInfo const* effect1 = GetEffect(DIFFICULTY_NONE, EFFECT_1);
+ return effect0 && effect1 && effect0->Effect == SPELL_EFFECT_THREAT && effect1->Effect == SPELL_EFFECT_APPLY_AURA && effect1->ApplyAuraName == SPELL_AURA_DUMMY;
}
-bool SpellInfo::IsProfessionOrRiding() const
+bool SpellInfo::IsProfessionOrRiding(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
{
- if (Effects[i].Effect == SPELL_EFFECT_SKILL)
+ if ((effect && effect->Effect == SPELL_EFFECT_SKILL))
{
- uint32 skill = Effects[i].MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsProfessionOrRidingSkill(skill))
return true;
@@ -1100,13 +1172,14 @@ bool SpellInfo::IsProfessionOrRiding() const
return false;
}
-bool SpellInfo::IsProfession() const
+bool SpellInfo::IsProfession(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
{
- if (Effects[i].Effect == SPELL_EFFECT_SKILL)
+ if (effect && effect->Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = Effects[i].MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsProfessionSkill(skill))
return true;
@@ -1115,13 +1188,14 @@ bool SpellInfo::IsProfession() const
return false;
}
-bool SpellInfo::IsPrimaryProfession() const
+bool SpellInfo::IsPrimaryProfession(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for(SpellEffectInfo const* effect : effects)
{
- if (Effects[i].Effect == SPELL_EFFECT_SKILL)
+ if (effect && effect->Effect == SPELL_EFFECT_SKILL)
{
- uint32 skill = Effects[i].MiscValue;
+ uint32 skill = effect->MiscValue;
if (IsPrimaryProfessionSkill(skill))
return true;
@@ -1130,9 +1204,9 @@ bool SpellInfo::IsPrimaryProfession() const
return false;
}
-bool SpellInfo::IsPrimaryProfessionFirstRank() const
+bool SpellInfo::IsPrimaryProfessionFirstRank(uint32 difficulty) const
{
- return IsPrimaryProfession() && GetRank() == 1;
+ return IsPrimaryProfession(difficulty) && GetRank() == 1;
}
bool SpellInfo::IsAbilityLearnedWithProfession() const
@@ -1163,20 +1237,26 @@ bool SpellInfo::IsAbilityOfSkillType(uint32 skillType) const
return false;
}
-bool SpellInfo::IsAffectingArea() const
+bool SpellInfo::IsAffectingArea(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsEffect() && (Effects[i].IsTargetingArea() || Effects[i].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || Effects[i].IsAreaAuraEffect()))
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
+ {
+ if (effect && effect->IsEffect() && (effect->IsTargetingArea() || effect->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || effect->IsAreaAuraEffect()))
return true;
+ }
return false;
}
// checks if spell targets are selected from area, doesn't include spell effects in check (like area wide auras for example)
-bool SpellInfo::IsTargetingArea() const
+bool SpellInfo::IsTargetingArea(uint32 difficulty) const
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsEffect() && Effects[i].IsTargetingArea())
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
+ {
+ if (effect && effect->IsEffect() && effect->IsTargetingArea())
return true;
+ }
return false;
}
@@ -1185,7 +1265,7 @@ bool SpellInfo::NeedsExplicitUnitTarget() const
return (GetExplicitTargetMask() & TARGET_FLAG_UNIT_MASK) != 0;
}
-bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const
+bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const
{
if (NeedsExplicitUnitTarget())
return true;
@@ -1205,12 +1285,16 @@ bool SpellInfo::NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) con
if (triggeringSpell->IsChanneled())
{
uint32 mask = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ for (SpellEffectInfo const* effect : effects)
{
- if (Effects[i].TargetA.GetTarget() != TARGET_UNIT_CASTER && Effects[i].TargetA.GetTarget() != TARGET_DEST_CASTER
- && Effects[i].TargetB.GetTarget() != TARGET_UNIT_CASTER && Effects[i].TargetB.GetTarget() != TARGET_DEST_CASTER)
+ if (!effect)
+ continue;
+
+ if (effect->TargetA.GetTarget() != TARGET_UNIT_CASTER && effect->TargetA.GetTarget() != TARGET_DEST_CASTER
+ && effect->TargetB.GetTarget() != TARGET_UNIT_CASTER && effect->TargetB.GetTarget() != TARGET_DEST_CASTER)
{
- mask |= Effects[i].GetProvidedTargetMask();
+ mask |= effect->GetProvidedTargetMask();
}
}
@@ -1248,19 +1332,23 @@ bool SpellInfo::IsStackableWithRanks() const
return false;
// All stance spells. if any better way, change it.
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(DIFFICULTY_NONE);
+ for (SpellEffectInfo const* effect : effects)
{
+ if (!effect)
+ continue;
+
switch (SpellFamilyName)
{
case SPELLFAMILY_PALADIN:
// Paladin aura Spell
- if (Effects[i].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID)
return false;
break;
case SPELLFAMILY_DRUID:
// Druid form Spell
- if (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA &&
- Effects[i].ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect->Effect == SPELL_EFFECT_APPLY_AURA &&
+ effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
return false;
break;
}
@@ -1268,9 +1356,9 @@ bool SpellInfo::IsStackableWithRanks() const
return true;
}
-bool SpellInfo::IsPassiveStackableWithRanks() const
+bool SpellInfo::IsPassiveStackableWithRanks(uint32 difficulty) const
{
- return IsPassive() && !HasEffect(SPELL_EFFECT_APPLY_AURA);
+ return IsPassive() && !HasEffect(difficulty, SPELL_EFFECT_APPLY_AURA);
}
bool SpellInfo::IsMultiSlotAura() const
@@ -1650,12 +1738,12 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
// aura limitations
if (player)
{
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(player->GetMap()->GetDifficulty()))
{
- if (!Effects[i].IsAura())
+ if (!effect || !effect->IsAura())
continue;
- switch (Effects[i].ApplyAuraName)
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_FLY:
{
@@ -1665,7 +1753,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
}
case SPELL_AURA_MOUNTED:
{
- if (Effects[i].MiscValueB && !player->GetMountCapability(Effects[i].MiscValueB))
+ if (effect->MiscValueB && !player->GetMountCapability(effect->MiscValueB))
return SPELL_FAILED_NOT_HERE;
break;
}
@@ -1814,14 +1902,14 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
return SPELL_FAILED_TARGET_AURASTATE;
}
- if (TargetAuraSpell && !unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(TargetAuraSpell, caster)))
+ if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
return SPELL_FAILED_TARGET_AURASTATE;
- if (ExcludeTargetAuraSpell && unitTarget->HasAura(sSpellMgr->GetSpellIdForDifficulty(ExcludeTargetAuraSpell, caster)))
+ if (ExcludeTargetAuraSpell && unitTarget->HasAura(ExcludeTargetAuraSpell))
return SPELL_FAILED_TARGET_AURASTATE;
if (unitTarget->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION))
- if (HasEffect(SPELL_EFFECT_SELF_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT) || HasEffect(SPELL_EFFECT_RESURRECT_NEW))
+ if (HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_SELF_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT) || HasEffect(caster->GetMap()->GetDifficulty(), SPELL_EFFECT_RESURRECT_NEW))
return SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED;
return SPELL_CAST_OK;
@@ -1872,18 +1960,18 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
if (vehicle)
{
uint16 checkMask = 0;
- for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
{
- if (Effects[effIndex].ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
+ if (effect && effect->ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
{
- SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(Effects[effIndex].MiscValue);
+ SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(effect->MiscValue);
if (shapeShiftFromEntry && (shapeShiftFromEntry->Flags & 1) == 0) // unk flag
checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
break;
}
}
- if (HasAura(SPELL_AURA_MOUNTED))
+ if (HasAura(caster->GetMap()->GetDifficulty(), SPELL_AURA_MOUNTED))
checkMask |= VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL;
if (!checkMask)
@@ -1897,12 +1985,12 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
// Can only summon uncontrolled minions/guardians when on controlled vehicle
if (vehicleSeat->Flags & (VEHICLE_SEAT_FLAG_CAN_CONTROL | VEHICLE_SEAT_FLAG_UNK2))
{
- for (uint32 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(caster->GetMap()->GetDifficulty()))
{
- if (Effects[i].Effect != SPELL_EFFECT_SUMMON)
+ if (!effect || effect->Effect != SPELL_EFFECT_SUMMON)
continue;
- SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(Effects[i].MiscValueB);
+ SummonPropertiesEntry const* props = sSummonPropertiesStore.LookupEntry(effect->MiscValueB);
if (props && props->Category != SUMMON_CATEGORY_WILD)
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
}
@@ -1942,19 +2030,30 @@ uint32 SpellInfo::GetAllEffectsMechanicMask() const
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsEffect() && Effects[i].Mechanic)
- mask |= 1 << Effects[i].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->IsEffect() && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
-uint32 SpellInfo::GetEffectMechanicMask(uint8 effIndex) const
+uint32 SpellInfo::GetEffectMechanicMask(uint32 effIndex) const
{
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic)
- mask |= 1 << Effects[effIndex].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->EffectIndex == effIndex && effect->IsEffect() && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
@@ -1963,28 +2062,34 @@ uint32 SpellInfo::GetSpellMechanicMaskByEffectMask(uint32 effectMask) const
uint32 mask = 0;
if (Mechanic)
mask |= 1 << Mechanic;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if ((effectMask & (1 << i)) && Effects[i].Mechanic)
- mask |= 1 << Effects[i].Mechanic;
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
+ {
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && (effectMask & (1 << effect->EffectIndex)) && effect->Mechanic)
+ mask |= 1 << effect->Mechanic;
+ }
+ }
return mask;
}
-Mechanics SpellInfo::GetEffectMechanic(uint8 effIndex) const
+Mechanics SpellInfo::GetEffectMechanic(uint32 effIndex, uint32 difficulty) const
{
- if (Effects[effIndex].IsEffect() && Effects[effIndex].Mechanic)
- return Mechanics(Effects[effIndex].Mechanic);
+ SpellEffectInfo const* effect = GetEffect(difficulty, effIndex);
+ if (effect && effect->IsEffect() && effect->Mechanic)
+ return Mechanics(effect->Mechanic);
if (Mechanic)
return Mechanics(Mechanic);
return MECHANIC_NONE;
}
-bool SpellInfo::HasAnyEffectMechanic() const
+/*bool SpellInfo::HasAnyEffectMechanic() const
{
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (Effects[i].Mechanic)
return true;
return false;
-}
+}*/
uint32 SpellInfo::GetDispelMask() const
{
@@ -2005,7 +2110,7 @@ uint32 SpellInfo::GetExplicitTargetMask() const
return ExplicitTargetMask;
}
-AuraStateType SpellInfo::GetAuraState() const
+AuraStateType SpellInfo::GetAuraState(uint32 difficulty) const
{
// Seals
if (GetSpellSpecific() == SPELL_SPECIFIC_SEAL)
@@ -2048,10 +2153,10 @@ AuraStateType SpellInfo::GetAuraState() const
return AURA_STATE_BLEEDING;
if (GetSchoolMask() & SPELL_SCHOOL_MASK_FROST)
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (Effects[i].IsAura() && (Effects[i].ApplyAuraName == SPELL_AURA_MOD_STUN
- || Effects[i].ApplyAuraName == SPELL_AURA_MOD_ROOT))
- return AURA_STATE_FROZEN;
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(difficulty))
+ if (effect && effect->IsAura() && (effect->ApplyAuraName == SPELL_AURA_MOD_STUN
+ || effect->ApplyAuraName == SPELL_AURA_MOD_ROOT))
+ return AURA_STATE_FROZEN;
switch (Id)
{
@@ -2076,24 +2181,27 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
{
bool food = false;
bool drink = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (!Effects[i].IsAura())
- continue;
- switch (Effects[i].ApplyAuraName)
+ for (SpellEffectInfo const* effect : itr->second)
{
- // Food
+ if (!effect || !effect->IsAura())
+ continue;
+ switch (effect->ApplyAuraName)
+ {
+ // Food
case SPELL_AURA_MOD_REGEN:
case SPELL_AURA_OBS_MOD_HEALTH:
food = true;
break;
- // Drink
+ // Drink
case SPELL_AURA_MOD_POWER_REGEN:
case SPELL_AURA_OBS_MOD_POWER:
drink = true;
break;
default:
break;
+ }
}
}
@@ -2133,8 +2241,8 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (SpellFamilyFlags[0] & 0x400)
return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
-
- if ((SpellFamilyFlags[0] & 0x1000000) && Effects[0].ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
+ SpellEffectInfo const* effect = GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ if (effect && (SpellFamilyFlags[0] & 0x1000000) && effect->ApplyAuraName == SPELL_AURA_MOD_CONFUSE)
return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
@@ -2220,12 +2328,14 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
break;
}
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA)
+ for (SpellEffectInfo const* effect : itr->second)
{
- switch (Effects[i].ApplyAuraName)
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
{
+ switch (effect->ApplyAuraName)
+ {
case SPELL_AURA_MOD_CHARM:
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
@@ -2238,10 +2348,10 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
return SPELL_SPECIFIC_TRACKER;
+ }
}
}
}
-
return SPELL_SPECIFIC_NORMAL;
}
@@ -2290,11 +2400,11 @@ uint32 SpellInfo::CalcCastTime(uint8 level, Spell* spell /*= NULL*/) const
level = spell->GetCaster()->getLevel();
// not all spells have cast time index and this is all is pasiive abilities
- if (level && CastTimeMax > 0)
+ if (level && Scaling.CastTimeMax > 0)
{
- castTime = CastTimeMax;
- if (CastTimeMaxLevel > level)
- castTime = CastTimeMin + int32(level - 1) * (CastTimeMax - CastTimeMin) / (CastTimeMaxLevel - 1);
+ castTime = Scaling.CastTimeMax;
+ if (Scaling.CastTimeMaxLevel > level)
+ castTime = Scaling.CastTimeMin + int32(level - 1) * (Scaling.CastTimeMax - Scaling.CastTimeMin) / (Scaling.CastTimeMaxLevel - 1);
}
else if (CastTimeEntry)
castTime = CastTimeEntry->CastTime;
@@ -2311,7 +2421,7 @@ uint32 SpellInfo::CalcCastTime(uint8 level, Spell* spell /*= NULL*/) const
return (castTime > 0) ? uint32(castTime) : 0;
}
-uint32 SpellInfo::GetMaxTicks() const
+uint32 SpellInfo::GetMaxTicks(uint32 difficulty) const
{
int32 DotDuration = GetDuration();
if (DotDuration == 0)
@@ -2321,16 +2431,16 @@ uint32 SpellInfo::GetMaxTicks() const
if (DotDuration > 30000)
DotDuration = 30000;
- for (uint8 x = 0; x < MAX_SPELL_EFFECTS; x++)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(difficulty))
{
- if (Effects[x].Effect == SPELL_EFFECT_APPLY_AURA)
- switch (Effects[x].ApplyAuraName)
+ if (effect && effect->Effect == SPELL_EFFECT_APPLY_AURA)
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
case SPELL_AURA_PERIODIC_LEECH:
- if (Effects[x].ApplyAuraPeriod != 0)
- return DotDuration / Effects[x].ApplyAuraPeriod;
+ if (effect->ApplyAuraPeriod != 0)
+ return DotDuration / effect->ApplyAuraPeriod;
break;
}
}
@@ -2426,8 +2536,8 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
{
if (Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
{
- GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(SpellLevel - 1);
- GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
+ GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.EvaluateTable(SpellLevel - 1, 0);
+ GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.EvaluateTable(caster->getLevel() - 1, 0);
if (spellScaler && casterScaler)
powerCost *= casterScaler->ratio / spellScaler->ratio;
}
@@ -2492,13 +2602,13 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
return this;
bool needRankSelection = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (IsPositiveEffect(i) &&
- (Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
- Effects[i].Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
- Effects[i].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
- !Effects[i].ScalingMultiplier)
+ if (effect && IsPositiveEffect(effect->Effect) &&
+ (effect->Effect == SPELL_EFFECT_APPLY_AURA ||
+ effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY ||
+ effect->Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
+ !effect->Scaling.Coefficient)
{
needRankSelection = true;
break;
@@ -2550,32 +2660,35 @@ void SpellInfo::_InitializeExplicitTargetMask()
bool dstSet = false;
uint32 targetMask = Targets;
// prepare target mask using effect target entries
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (!Effects[i].IsEffect())
- continue;
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (!effect || !effect->IsEffect())
+ continue;
- targetMask |= Effects[i].TargetA.GetExplicitTargetMask(srcSet, dstSet);
- targetMask |= Effects[i].TargetB.GetExplicitTargetMask(srcSet, dstSet);
+ targetMask |= effect->TargetA.GetExplicitTargetMask(srcSet, dstSet);
+ targetMask |= effect->TargetB.GetExplicitTargetMask(srcSet, dstSet);
- // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
- if (Effects[i].GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
- continue;
+ // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided
+ if (effect->GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT)
+ continue;
- // extend explicit target mask only if valid targets for effect could not be provided by target types
- uint32 effectTargetMask = Effects[i].GetMissingTargetMask(srcSet, dstSet, targetMask);
+ // extend explicit target mask only if valid targets for effect could not be provided by target types
+ uint32 effectTargetMask = effect->GetMissingTargetMask(srcSet, dstSet, targetMask);
- // don't add explicit object/dest flags when spell has no max range
- if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
- effectTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_DEST_LOCATION);
+ // don't add explicit object/dest flags when spell has no max range
+ if (GetMaxRange(true) == 0.0f && GetMaxRange(false) == 0.0f)
+ effectTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_DEST_LOCATION);
- targetMask |= effectTargetMask;
+ targetMask |= effectTargetMask;
+ }
}
ExplicitTargetMask = targetMask;
}
-bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
+bool SpellInfo::_IsPositiveEffect(uint32 effIndex, bool deep) const
{
// not found a single positive spell with this attribute
if (Attributes & SPELL_ATTR0_NEGATIVE_1)
@@ -2640,40 +2753,50 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
}
// Special case: effects which determine positivity of whole spell
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- if (Effects[i].IsAura() && Effects[i].ApplyAuraName == SPELL_AURA_MOD_STEALTH)
- return true;
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (effect && effect->IsAura() && effect->ApplyAuraName == SPELL_AURA_MOD_STEALTH)
+ return true;
+ }
}
- switch (Effects[effIndex].Effect)
+ for (SpellEffectInfoMap::const_iterator itr = _effects.begin(); itr != _effects.end(); ++itr)
{
- case SPELL_EFFECT_DUMMY:
- // some explicitly required dummy effect sets
- switch (Id)
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ if (!effect || effect->EffectIndex != effIndex)
+ continue;
+
+ switch (effect->Effect)
{
+ case SPELL_EFFECT_DUMMY:
+ // some explicitly required dummy effect sets
+ switch (Id)
+ {
case 28441:
return false; // AB Effect 000
default:
break;
- }
- break;
- // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
- case SPELL_EFFECT_HEAL:
- case SPELL_EFFECT_LEARN_SPELL:
- case SPELL_EFFECT_SKILL_STEP:
- case SPELL_EFFECT_HEAL_PCT:
- case SPELL_EFFECT_ENERGIZE_PCT:
- return true;
- case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
- return false;
+ }
+ break;
+ // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
+ case SPELL_EFFECT_HEAL:
+ case SPELL_EFFECT_LEARN_SPELL:
+ case SPELL_EFFECT_SKILL_STEP:
+ case SPELL_EFFECT_HEAL_PCT:
+ case SPELL_EFFECT_ENERGIZE_PCT:
+ return true;
+ case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
+ return false;
- // non-positive aura use
- case SPELL_EFFECT_APPLY_AURA:
- case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
- {
- switch (Effects[effIndex].ApplyAuraName)
+ // non-positive aura use
+ case SPELL_EFFECT_APPLY_AURA:
+ case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
+ switch (effect->ApplyAuraName)
+ {
case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative)
case SPELL_AURA_MOD_STAT:
case SPELL_AURA_MOD_SKILL:
@@ -2681,16 +2804,16 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_MOD_HEALING_PCT:
case SPELL_AURA_MOD_HEALING_DONE:
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE:
- if (Effects[effIndex].CalcValue() < 0)
+ if (effect->CalcValue() < 0)
return false;
break;
case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
return false;
break;
case SPELL_AURA_MOD_CRIT_PCT:
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
return true; // some expected positive spells have SPELL_ATTR1_NEGATIVE
break;
case SPELL_AURA_ADD_TARGET_TRIGGER:
@@ -2699,17 +2822,20 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
if (!deep)
{
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(Effects[effIndex].TriggerSpell))
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell))
{
// negative targets of main spell return early
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfoMap::const_iterator it = spellTriggeredProto->_effects.begin(); it != spellTriggeredProto->_effects.end(); ++it)
{
- if (!spellTriggeredProto->Effects[i].Effect)
- continue;
- // if non-positive trigger cast targeted to positive target this main cast is non-positive
- // this will place this spell auras as debuffs
- if (_IsPositiveTarget(spellTriggeredProto->Effects[i].TargetA.GetTarget(), spellTriggeredProto->Effects[i].TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(i, true))
- return false;
+ for (SpellEffectInfo const* eff : itr->second)
+ {
+ if (!eff || !eff->Effect)
+ continue;
+ // if non-positive trigger cast targeted to positive target this main cast is non-positive
+ // this will place this spell auras as debuffs
+ if (_IsPositiveTarget(eff->TargetA.GetTarget(), eff->TargetB.GetTarget()) && !spellTriggeredProto->_IsPositiveEffect(eff->EffectIndex, true))
+ return false;
+ }
}
}
}
@@ -2717,9 +2843,23 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
// many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
break;
case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment.
- if (effIndex == 0 && Effects[1].Effect == 0 && Effects[2].Effect == 0)
+ {
+ bool more = false;
+ for (SpellEffectInfoMap::const_iterator i = _effects.begin(); i != _effects.end(); ++i)
+ {
+ for (SpellEffectInfo const* eff : i->second)
+ {
+ if (eff && eff->EffectIndex != 0)
+ {
+ more = true;
+ break;
+ }
+ }
+ }
+ if (effIndex == 0 && !more)
return false; // but all single stun aura spells is negative
break;
+ }
case SPELL_AURA_MOD_PACIFY_SILENCE:
if (Id == 24740) // Wisp Costume
return true;
@@ -2734,12 +2874,12 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
return false;
case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
// part of negative spell if cast at self (prevent cancel)
- if (Effects[effIndex].TargetA.GetTarget() == TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
return false;
break;
case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also
// part of positive spell if cast at self
- if (Effects[effIndex].TargetA.GetTarget() != TARGET_UNIT_CASTER)
+ if (effect->TargetA.GetTarget() != TARGET_UNIT_CASTER)
return false;
// but not this if this first effect (didn't find better check)
if (Attributes & SPELL_ATTR0_NEGATIVE_1 && effIndex == 0)
@@ -2748,7 +2888,7 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_MECHANIC_IMMUNITY:
{
// non-positive immunities
- switch (Effects[effIndex].MiscValue)
+ switch (effect->MiscValue)
{
case MECHANIC_BANDAGE:
case MECHANIC_SHIELD:
@@ -2764,10 +2904,10 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case SPELL_AURA_ADD_PCT_MODIFIER:
{
// non-positive mods
- switch (Effects[effIndex].MiscValue)
+ switch (effect->MiscValue)
{
case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
- if (Effects[effIndex].CalcValue() > 0)
+ if (effect->CalcValue() > 0)
{
if (!deep)
{
@@ -2793,25 +2933,26 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
}
default:
break;
+ }
+ break;
+ }
+ default:
+ break;
}
- break;
- }
- default:
- break;
- }
-
- // non-positive targets
- if (!_IsPositiveTarget(Effects[effIndex].TargetA.GetTarget(), Effects[effIndex].TargetB.GetTarget()))
- return false;
- // negative spell if triggered spell is negative
- if (!deep && !Effects[effIndex].ApplyAuraName && Effects[effIndex].TriggerSpell)
- {
- if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(Effects[effIndex].TriggerSpell))
- if (!spellTriggeredProto->_IsPositiveSpell())
+ // non-positive targets
+ if (!_IsPositiveTarget(effect->TargetA.GetTarget(), effect->TargetB.GetTarget()))
return false;
- }
+ // negative spell if triggered spell is negative
+ if (!deep && !effect->ApplyAuraName && effect->TriggerSpell)
+ {
+ if (SpellInfo const* spellTriggeredProto = sSpellMgr->GetSpellInfo(effect->TriggerSpell))
+ if (!spellTriggeredProto->_IsPositiveSpell())
+ return false;
+ }
+ }
+ }
// ok, positive
return true;
}
@@ -2870,7 +3011,10 @@ SpellLevelsEntry const* SpellInfo::GetSpellLevels() const
SpellPowerEntry const* SpellInfo::GetSpellPower() const
{
- return SpellPowerId ? sSpellPowerStore.LookupEntry(SpellPowerId) : NULL;
+ auto itr = sSpellPowerBySpellIDStore.find(Id);
+ if (itr != sSpellPowerBySpellIDStore.end())
+ return itr->second;
+ return NULL;
}
SpellReagentsEntry const* SpellInfo::GetSpellReagents() const
@@ -2931,16 +3075,72 @@ SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const
void SpellInfo::_UnloadImplicitTargetConditionLists()
{
// find the same instances of ConditionList and delete them.
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (uint32 d = 0; d < DIFFICULTY_MAX; ++d)
{
- ConditionList* cur = Effects[i].ImplicitTargetConditions;
- if (!cur)
- continue;
- for (uint8 j = i; j < MAX_SPELL_EFFECTS; ++j)
+ for (uint32 i = 0; i < _effects.size(); ++i)
+ {
+ if (SpellEffectInfo const* effect = GetEffect(d, i))
+ {
+ ConditionList* cur = effect->ImplicitTargetConditions;
+ if (!cur)
+ continue;
+ for (uint8 j = i; j < _effects.size(); ++j)
+ {
+ if (SpellEffectInfo const* eff = GetEffect(d, j))
+ {
+ if (eff->ImplicitTargetConditions == cur)
+ const_cast<SpellEffectInfo*>(eff)->ImplicitTargetConditions = NULL;
+ }
+ }
+ delete cur;
+ }
+ }
+ }
+}
+
+SpellEffectInfoVector SpellInfo::GetEffectsForDifficulty(uint32 difficulty) const
+{
+ // 6.x todo: add first highest difficulty effect, resize list to max element, add lower diff effects without overwriting any higher diffed ones
+
+ SpellEffectInfoVector effList;
+
+ // DIFFICULTY_NONE effects are the default effects, always active if current difficulty's effects don't overwrite
+ SpellEffectInfoMap::const_iterator itr = _effects.find(DIFFICULTY_NONE);
+ if (itr != _effects.end())
+ effList = itr->second;
+
+ // downscale difficulty if original was not found
+ // DIFFICULTY_NONE is already in our list
+ for (; difficulty > DIFFICULTY_NONE; --difficulty)
+ {
+ SpellEffectInfoMap::const_iterator itr = _effects.find(difficulty);
+ if (itr != _effects.end())
{
- if (Effects[j].ImplicitTargetConditions == cur)
- Effects[j].ImplicitTargetConditions = NULL;
+ for (SpellEffectInfo const* effect : itr->second)
+ {
+ // overwrite any existing effect from DIFFICULTY_NONE
+ if (effect)
+ {
+ if (effect->EffectIndex >= effList.size())
+ effList.resize(effect->EffectIndex + 1);
+
+ effList[effect->EffectIndex] = effect;
+ }
+ }
+ // if we found any effect in our difficulty then stop searching
+ break;
}
- delete cur;
}
+ if (effList.empty())
+ TC_LOG_ERROR("spells", "GetEffectsForDifficulty did not find any effects for spell %u in difficulty %u", Id, difficulty);
+ return effList;
+}
+
+SpellEffectInfo const* SpellInfo::GetEffect(uint32 difficulty, uint32 index) const
+{
+ SpellEffectInfoVector effects = GetEffectsForDifficulty(difficulty);
+ if (index >= effects.size())
+ return nullptr;
+
+ return effects[index];
}
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 1fad30dd23b..0f655580b6d 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -65,6 +65,11 @@ enum SpellCastTargetFlags
TARGET_FLAG_DEST_TARGET = 0x00040000, // sometimes appears with DEST_TARGET spells (may appear or not for a given spell)
TARGET_FLAG_EXTRA_TARGETS = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far
TARGET_FLAG_UNIT_PASSENGER = 0x00100000, // guessed, used to validate target (if vehicle passenger)
+ TARGET_FLAG_UNK400000 = 0X00400000,
+ TARGET_FLAG_UNK1000000 = 0X01000000,
+ TARGET_FLAG_UNK4000000 = 0X04000000,
+ TARGET_FLAG_UNK10000000 = 0X10000000,
+ TARGET_FLAG_UNK40000000 = 0X40000000,
TARGET_FLAG_UNIT_MASK = TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY
| TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER,
@@ -230,8 +235,8 @@ private:
class SpellEffectInfo
{
SpellInfo const* _spellInfo;
- uint8 _effIndex;
public:
+ uint32 EffectIndex;
uint32 Effect;
uint32 ApplyAuraName;
uint32 ApplyAuraPeriod;
@@ -245,6 +250,7 @@ public:
int32 MiscValue;
int32 MiscValueB;
Mechanics Mechanic;
+ float PositionFacing;
SpellImplicitTargetInfo TargetA;
SpellImplicitTargetInfo TargetB;
SpellRadiusEntry const* RadiusEntry;
@@ -253,20 +259,24 @@ public:
uint32 ItemType;
uint32 TriggerSpell;
flag128 SpellClassMask;
+ float BonusCoefficientFromAP;
std::list<Condition*>* ImplicitTargetConditions;
// SpellScalingEntry
- float ScalingMultiplier;
- float DeltaScalingMultiplier;
- float ComboScalingMultiplier;
+ struct ScalingInfo
+ {
+ float Coefficient;
+ float Variance;
+ float ResourceCoefficient;
+ } Scaling;
- SpellEffectInfo() : _spellInfo(NULL), _effIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), DieSides(0),
+ SpellEffectInfo() : _spellInfo(NULL), EffectIndex(0), Effect(0), ApplyAuraName(0), ApplyAuraPeriod(0), DieSides(0),
RealPointsPerLevel(0), BasePoints(0), PointsPerResource(0), Amplitude(0), ChainAmplitude(0),
- BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(NULL), ChainTargets(0),
- ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) {}
+ BonusCoefficient(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), PositionFacing(0),
+ RadiusEntry(NULL), ChainTargets(0), ItemType(0), TriggerSpell(0), BonusCoefficientFromAP(0.0f), ImplicitTargetConditions(NULL) { }
SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect);
bool IsEffect() const;
- bool IsEffect(SpellEffects effectName) const;
+ bool IsEffect(SpellEffectName effectName) const;
bool IsAura() const;
bool IsAura(AuraType aura) const;
bool IsTargetingArea() const;
@@ -275,7 +285,7 @@ public:
bool IsFarDestTargetEffect() const;
bool IsUnitOwnedAuraEffect() const;
- int32 CalcValue(Unit const* caster = NULL, int32 const* basePoints = NULL, Unit const* target = NULL) const;
+ int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr) const;
int32 CalcBaseValue(int32 value) const;
float CalcValueMultiplier(Unit* caster, Spell* spell = NULL) const;
float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const;
@@ -299,6 +309,14 @@ private:
static StaticData _data[TOTAL_SPELL_EFFECTS];
};
+typedef std::vector<SpellEffectInfo const*> SpellEffectInfoVector;
+typedef std::unordered_map<uint32, SpellEffectInfoVector> SpellEffectInfoMap;
+
+typedef std::vector<SpellEffectEntry const*> SpellEffectEntryVector;
+typedef std::unordered_map<uint32, SpellEffectEntryVector> SpellEffectEntryMap;
+
+typedef std::vector<AuraEffect*> AuraEffectVector;
+
class SpellInfo
{
public:
@@ -390,20 +408,24 @@ public:
uint32 SpellEquippedItemsId;
uint32 SpellInterruptsId;
uint32 SpellLevelsId;
- uint32 SpellPowerId;
uint32 SpellReagentsId;
uint32 SpellShapeshiftId;
uint32 SpellTargetRestrictionsId;
uint32 SpellTotemsId;
uint32 SpellMiscId;
// SpellScalingEntry
- int32 CastTimeMin;
- int32 CastTimeMax;
- int32 CastTimeMaxLevel;
- int32 ScalingClass;
- float CoefBase;
- int32 CoefLevelBase;
- SpellEffectInfo Effects[MAX_SPELL_EFFECTS];
+ struct ScalingInfo
+ {
+ int32 CastTimeMin;
+ int32 CastTimeMax;
+ uint32 CastTimeMaxLevel;
+ int32 Class;
+ float NerfFactor;
+ uint32 NerfMaxLevel;
+ uint32 MaxScalingLevel;
+ uint32 ScalesFromItemLevel;
+ } Scaling;
+
uint32 ExplicitTargetMask;
SpellChainNode const* ChainEntry;
@@ -425,33 +447,35 @@ public:
SpellTotemsEntry const* GetSpellTotems() const;
SpellMiscEntry const* GetSpellMisc() const;
- SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects);
+ SpellInfo(SpellEntry const* spellEntry, SpellEffectEntryMap effects);
~SpellInfo();
uint32 GetCategory() const;
- bool HasEffect(SpellEffects effect) const;
- bool HasAura(AuraType aura) const;
+ bool HasEffect(uint32 difficulty, SpellEffectName effect) const;
+ bool HasEffect(SpellEffectName effect) const;
+ bool HasAura(uint32 difficulty, AuraType aura) const;
+ bool HasAreaAuraEffect(uint32 difficulty) const;
bool HasAreaAuraEffect() const;
bool IsExplicitDiscovery() const;
bool IsLootCrafting() const;
bool IsQuestTame() const;
- bool IsProfessionOrRiding() const;
- bool IsProfession() const;
- bool IsPrimaryProfession() const;
- bool IsPrimaryProfessionFirstRank() const;
+ bool IsProfessionOrRiding(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsProfession(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsPrimaryProfession(uint32 difficulty = DIFFICULTY_NONE) const;
+ bool IsPrimaryProfessionFirstRank(uint32 difficulty = DIFFICULTY_NONE) const;
bool IsAbilityLearnedWithProfession() const;
bool IsAbilityOfSkillType(uint32 skillType) const;
- bool IsAffectingArea() const;
- bool IsTargetingArea() const;
+ bool IsAffectingArea(uint32 difficulty) const;
+ bool IsTargetingArea(uint32 difficulty) const;
bool NeedsExplicitUnitTarget() const;
- bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell) const;
+ bool NeedsToBeTriggeredByCaster(SpellInfo const* triggeringSpell, uint32 difficulty) const;
bool IsPassive() const;
bool IsAutocastable() const;
bool IsStackableWithRanks() const;
- bool IsPassiveStackableWithRanks() const;
+ bool IsPassiveStackableWithRanks(uint32 difficulty) const;
bool IsMultiSlotAura() const;
bool IsStackableOnOneSlotWithDifferentCasters() const;
bool IsCooldownStartedOnEvent() const;
@@ -486,15 +510,15 @@ public:
SpellSchoolMask GetSchoolMask() const;
uint32 GetAllEffectsMechanicMask() const;
- uint32 GetEffectMechanicMask(uint8 effIndex) const;
+ uint32 GetEffectMechanicMask(uint32 effIndex) const;
uint32 GetSpellMechanicMaskByEffectMask(uint32 effectMask) const;
- Mechanics GetEffectMechanic(uint8 effIndex) const;
- bool HasAnyEffectMechanic() const;
+ Mechanics GetEffectMechanic(uint32 effIndex, uint32 difficulty) const;
+ //bool HasAnyEffectMechanic() const;
uint32 GetDispelMask() const;
static uint32 GetDispelMask(DispelType type);
uint32 GetExplicitTargetMask() const;
- AuraStateType GetAuraState() const;
+ AuraStateType GetAuraState(uint32 difficulty) const;
SpellSpecificType GetSpellSpecific() const;
float GetMinRange(bool positive = false) const;
@@ -503,7 +527,7 @@ public:
int32 GetDuration() const;
int32 GetMaxDuration() const;
- uint32 GetMaxTicks() const;
+ uint32 GetMaxTicks(uint32 difficulty) const;
uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
uint32 GetRecoveryTime() const;
@@ -523,12 +547,19 @@ public:
// loading helpers
void _InitializeExplicitTargetMask();
- bool _IsPositiveEffect(uint8 effIndex, bool deep) const;
+ bool _IsPositiveEffect(uint32 effIndex, bool deep) const;
bool _IsPositiveSpell() const;
static bool _IsPositiveTarget(uint32 targetA, uint32 targetB);
// unloading helpers
void _UnloadImplicitTargetConditionLists();
+
+ SpellEffectInfoVector GetEffectsForDifficulty(uint32 difficulty) const;
+ SpellEffectInfo const* GetEffect(uint32 difficulty, uint32 index) const;
+ SpellEffectInfo const* GetEffect(uint32 index) const { return GetEffect(DIFFICULTY_NONE, index); }
+ SpellEffectInfo const* GetEffect(WorldObject* obj, uint32 index) const { return GetEffect(obj->GetMap()->GetDifficulty(), index); }
+
+ SpellEffectInfoMap _effects;
};
#endif // _SPELLINFO_H
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 3b7ab7abe30..544abc9ca87 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -59,9 +59,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto,
if (spellproto->IsPositive())
return DIMINISHING_NONE;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect: spellproto->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellproto->Effects[i].ApplyAuraName == SPELL_AURA_MOD_TAUNT)
+ if (effect && effect->ApplyAuraName == SPELL_AURA_MOD_TAUNT)
return DIMINISHING_TAUNT;
}
@@ -370,9 +370,12 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
bool needCheckReagents = false;
// check effects
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- switch (spellInfo->Effects[i].Effect)
+ if (!effect)
+ continue;
+
+ switch (effect->Effect)
{
case 0:
continue;
@@ -381,7 +384,7 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
case SPELL_EFFECT_CREATE_ITEM:
case SPELL_EFFECT_CREATE_ITEM_2:
{
- if (spellInfo->Effects[i].ItemType == 0)
+ if (effect->ItemType == 0)
{
// skip auto-loot crafting spells, its not need explicit item info (but have special fake items sometime)
if (!spellInfo->IsLootCrafting())
@@ -398,14 +401,14 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
}
// also possible IsLootCrafting case but fake item must exist anyway
- else if (!sObjectMgr->GetItemTemplate(spellInfo->Effects[i].ItemType))
+ else if (!sObjectMgr->GetItemTemplate(effect->ItemType))
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
+ ChatHandler(player->GetSession()).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
else
- TC_LOG_ERROR("sql.sql", "Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Effects[i].ItemType);
+ TC_LOG_ERROR("sql.sql", "Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, effect->ItemType);
}
return false;
}
@@ -415,15 +418,15 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
}
case SPELL_EFFECT_LEARN_SPELL:
{
- SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell);
+ SpellInfo const* spellInfo2 = sSpellMgr->GetSpellInfo(effect->TriggerSpell);
if (!IsSpellValid(spellInfo2, player, msg))
{
if (msg)
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell);
+ ChatHandler(player->GetSession()).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
else
- TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellInfo->Effects[i].TriggerSpell);
+ TC_LOG_ERROR("sql.sql", "Spell %u learn to invalid spell %u, and then...", spellInfo->Id, effect->TriggerSpell);
}
return false;
}
@@ -453,81 +456,6 @@ bool SpellMgr::IsSpellValid(SpellInfo const* spellInfo, Player* player, bool msg
return true;
}
-uint32 SpellMgr::GetSpellDifficultyId(uint32 spellId) const
-{
- SpellDifficultySearcherMap::const_iterator i = mSpellDifficultySearcherMap.find(spellId);
- return i == mSpellDifficultySearcherMap.end() ? 0 : i->second;
-}
-
-void SpellMgr::SetSpellDifficultyId(uint32 spellId, uint32 id)
-{
- if (uint32 i = GetSpellDifficultyId(spellId))
- TC_LOG_ERROR("spells", "SpellMgr::SetSpellDifficultyId: Spell %u has already spellDifficultyId %u. Will override with spellDifficultyId %u.", spellId, i, id);
- mSpellDifficultySearcherMap[spellId] = id;
-}
-
-// TODO: 6.x adapt to new spell diff system
-uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) const
-{
- /*if (!GetSpellInfo(spellId))
- return spellId;
-
- if (!caster || !caster->GetMap() || !caster->GetMap()->IsDungeon())
- return spellId;
-
- uint32 mode = uint32(caster->GetMap()->GetSpawnMode());
- if (mode >= MAX_DIFFICULTY)
- {
- TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: Incorrect Difficulty for spell %u.", spellId);
- return spellId; //return source spell
- }
-
- uint32 difficultyId = GetSpellDifficultyId(spellId);
- if (!difficultyId)
- return spellId; //return source spell, it has only REGULAR_DIFFICULTY
-
- SpellDifficultyEntry const* difficultyEntry = sSpellDifficultyStore.LookupEntry(difficultyId);
- if (!difficultyEntry)
- {
- TC_LOG_ERROR("spells", "SpellMgr::GetSpellIdForDifficulty: SpellDifficultyEntry not found for spell %u. This should never happen.", spellId);
- return spellId; //return source spell
- }
-
- if (difficultyEntry->SpellID[mode] <= 0 && mode > DUNGEON_DIFFICULTY_HEROIC)
- {
- TC_LOG_DEBUG("spells", "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is NULL, using mode %u", spellId, mode, mode - 2);
- mode -= 2;
- }
-
- if (difficultyEntry->SpellID[mode] <= 0)
- {
- TC_LOG_ERROR("sql.sql", "SpellMgr::GetSpellIdForDifficulty: spell %u mode %u spell is 0. Check spelldifficulty_dbc!", spellId, mode);
- return spellId;
- }
-
- TC_LOG_DEBUG("spells", "SpellMgr::GetSpellIdForDifficulty: spellid for spell %u in mode %u is %d", spellId, mode, difficultyEntry->SpellID[mode]);
- return uint32(difficultyEntry->SpellID[mode]);
- */
- return 0;
-}
-
-SpellInfo const* SpellMgr::GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const
-{
- if (!spell)
- return NULL;
-
- uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster);
- SpellInfo const* newSpell = GetSpellInfo(newSpellId);
- if (!newSpell)
- {
- TC_LOG_DEBUG("spells", "SpellMgr::GetSpellForDifficultyFromSpell: spell %u not found. Check spelldifficulty_dbc!", newSpellId);
- return spell;
- }
-
- TC_LOG_DEBUG("spells", "SpellMgr::GetSpellForDifficultyFromSpell: Spell id for instance mode is %u (original %u)", newSpell->Id, spell->Id);
- return newSpell;
-}
-
SpellChainNode const* SpellMgr::GetSpellChainNode(uint32 spell_id) const
{
SpellChainMap::const_iterator itr = mSpellChains.find(spell_id);
@@ -1021,22 +949,6 @@ bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcE
return true;
}
-SpellBonusEntry const* SpellMgr::GetSpellBonusData(uint32 spellId) const
-{
- // Lookup data
- SpellBonusMap::const_iterator itr = mSpellBonusMap.find(spellId);
- if (itr != mSpellBonusMap.end())
- return &itr->second;
- // Not found, try lookup for 1 spell rank if exist
- if (uint32 rank_1 = GetFirstSpellInChain(spellId))
- {
- SpellBonusMap::const_iterator itr2 = mSpellBonusMap.find(rank_1);
- if (itr2 != mSpellBonusMap.end())
- return &itr2->second;
- }
- return NULL;
-}
-
SpellThreatEntry const* SpellMgr::GetSpellThreatEntry(uint32 spellID) const
{
SpellThreatMap::const_iterator itr = mSpellThreatMap.find(spellID);
@@ -1479,13 +1391,13 @@ void SpellMgr::LoadSpellLearnSkills()
if (!entry)
continue;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : entry->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (entry->Effects[i].Effect == SPELL_EFFECT_SKILL)
+ if (effect && effect->Effect == SPELL_EFFECT_SKILL)
{
SpellLearnSkillNode dbc_node;
- dbc_node.skill = entry->Effects[i].MiscValue;
- dbc_node.step = entry->Effects[i].CalcValue();
+ dbc_node.skill = effect->MiscValue;
+ dbc_node.step = effect->CalcValue();
if (dbc_node.skill != SKILL_RIDING)
dbc_node.value = 1;
else
@@ -1562,12 +1474,12 @@ void SpellMgr::LoadSpellLearnSpells()
if (!entry)
continue;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ for (SpellEffectInfo const* effect : entry->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (entry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
+ if (effect && effect->Effect == SPELL_EFFECT_LEARN_SPELL)
{
SpellLearnSpellNode dbc_node;
- dbc_node.spell = entry->Effects[i].TriggerSpell;
+ dbc_node.spell = effect->TriggerSpell;
dbc_node.active = true; // all dbc based learned spells is active (show in spell book or hide by client itself)
// ignore learning not existed spells (broken/outdated/or generic learnig spell 483
@@ -1577,7 +1489,7 @@ void SpellMgr::LoadSpellLearnSpells()
// talent or passive spells or skill-step spells auto-cast and not need dependent learning,
// pet teaching spells must not be dependent learning (cast)
// other required explicit dependent learning
- dbc_node.autoLearned = entry->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentBySpellID(spell) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
+ dbc_node.autoLearned = effect->TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentBySpellID(spell) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spell);
@@ -1672,8 +1584,8 @@ void SpellMgr::LoadSpellTargetPositions()
mSpellTargetPositions.clear(); // need for reload case
- // 0 1 2 3 4 5 6
- QueryResult result = WorldDatabase.Query("SELECT id, effIndex, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position");
+ // 0 1 2 3 4 5
+ QueryResult result = WorldDatabase.Query("SELECT ID, EffectIndex, MapID, PositionX, PositionY, PositionZ FROM spell_target_position");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 spell target coordinates. DB table `spell_target_position` is empty.");
@@ -1694,29 +1606,47 @@ void SpellMgr::LoadSpellTargetPositions()
st.target_X = fields[3].GetFloat();
st.target_Y = fields[4].GetFloat();
st.target_Z = fields[5].GetFloat();
- st.target_Orientation = fields[6].GetFloat();
MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
if (!mapEntry)
{
- TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) target map (ID: %u) does not exist in `Map.dbc`.", Spell_ID, effIndex, st.target_mapId);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u, EffectIndex: %u) is using a non-existant MapID (ID: %u).", Spell_ID, effIndex, st.target_mapId);
continue;
}
- if (st.target_X==0 && st.target_Y==0 && st.target_Z==0)
+ if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
{
- TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) target coordinates not provided.", Spell_ID, effIndex);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u, EffectIndex: %u): target coordinates not provided.", Spell_ID, effIndex);
continue;
}
SpellInfo const* spellInfo = GetSpellInfo(Spell_ID);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Spell (Id: %u) listed in `spell_target_position` does not exist.", Spell_ID);
+ TC_LOG_ERROR("sql.sql", "Spell (ID: %u) listed in `spell_target_position` does not exist.", Spell_ID);
continue;
}
- if (spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_DEST_DB || spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_DEST_DB)
+ SpellEffectInfo const* effect = spellInfo->GetEffect(effIndex);
+ if (!effect)
+ {
+ TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have an effect at index %u.", Spell_ID, effIndex, effIndex);
+ continue;
+ }
+
+ // target facing is in degrees for 6484 & 9268... (blizz sucks)
+ if (effect->PositionFacing > 2 * M_PI)
+ st.target_Orientation = effect->PositionFacing * M_PI / 180;
+ else
+ st.target_Orientation = effect->PositionFacing;
+
+ if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB)
+ {
+ TC_LOG_ERROR("sql.sql", "Spell (Id: %u, effIndex: %u) listed in `spell_target_position` does not have TARGET_DEST_DB as target at index %u.", Spell_ID, effIndex, effIndex);
+ continue;
+ }
+
+ if (effect->TargetA.GetTarget() == TARGET_DEST_DB || effect->TargetB.GetTarget() == TARGET_DEST_DB)
{
std::pair<uint32, SpellEffIndex> key = std::make_pair(Spell_ID, effIndex);
mSpellTargetPositions[key] = st;
@@ -2121,45 +2051,6 @@ void SpellMgr::LoadSpellProcs()
TC_LOG_INFO("server.loading", ">> Loaded %u spell proc conditions and data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void SpellMgr::LoadSpellBonusess()
-{
- uint32 oldMSTime = getMSTime();
-
- mSpellBonusMap.clear(); // need for reload case
-
- // 0 1 2 3 4
- QueryResult result = WorldDatabase.Query("SELECT entry, direct_bonus, dot_bonus, ap_bonus, ap_dot_bonus FROM spell_bonus_data");
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 spell bonus data. DB table `spell_bonus_data` is empty.");
- return;
- }
-
- uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
- uint32 entry = fields[0].GetUInt32();
-
- SpellInfo const* spell = GetSpellInfo(entry);
- if (!spell)
- {
- TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_bonus_data` does not exist", entry);
- continue;
- }
-
- SpellBonusEntry& sbe = mSpellBonusMap[entry];
- sbe.direct_damage = fields[1].GetFloat();
- sbe.dot_damage = fields[2].GetFloat();
- sbe.ap_bonus = fields[3].GetFloat();
- sbe.ap_dot_bonus = fields[4].GetFloat();
-
- ++count;
- } while (result->NextRow());
-
- TC_LOG_INFO("server.loading", ">> Loaded %u extra spell bonus data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
-}
-
void SpellMgr::LoadSpellThreats()
{
uint32 oldMSTime = getMSTime();
@@ -2255,9 +2146,16 @@ void SpellMgr::LoadSpellPetAuras()
TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_pet_auras` does not exist", spell);
continue;
}
- if (spellInfo->Effects[eff].Effect != SPELL_EFFECT_DUMMY &&
- (spellInfo->Effects[eff].Effect != SPELL_EFFECT_APPLY_AURA ||
- spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_DUMMY))
+ SpellEffectInfo const* effect = spellInfo->GetEffect(eff);
+ if (!effect)
+ {
+ TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have effect at index %u", spell, uint32(eff));
+ continue;
+ }
+
+ if (effect->Effect != SPELL_EFFECT_DUMMY &&
+ (effect->Effect != SPELL_EFFECT_APPLY_AURA ||
+ effect->ApplyAuraName != SPELL_AURA_DUMMY))
{
TC_LOG_ERROR("spells", "Spell %u listed in `spell_pet_auras` does not have dummy aura or dummy effect", spell);
continue;
@@ -2270,7 +2168,7 @@ void SpellMgr::LoadSpellPetAuras()
continue;
}
- PetAura pa(pet, aura, spellInfo->Effects[eff].TargetA.GetTarget() == TARGET_UNIT_PET, spellInfo->Effects[eff].CalcValue());
+ PetAura pa(pet, aura, effect->TargetA.GetTarget() == TARGET_UNIT_PET, effect->CalcValue());
mSpellPetAuraMap[(spell<<8) + eff] = pa;
}
@@ -2302,11 +2200,11 @@ void SpellMgr::LoadEnchantCustomAttr()
if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_PRESERVE_ENCHANT_IN_ARENA) || !(spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT))
continue;
- for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[j].Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
+ if (effect && effect->Effect == SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY)
{
- uint32 enchId = spellInfo->Effects[j].MiscValue;
+ uint32 enchId = effect->MiscValue;
SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchId);
if (!ench)
continue;
@@ -2393,10 +2291,10 @@ void SpellMgr::LoadSpellLinked()
}
if (effect >= 0)
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* eff : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellInfo->Effects[j].CalcValue() == abs(effect))
- TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), j);
+ if (eff && eff->CalcValue() == abs(effect))
+ TC_LOG_ERROR("sql.sql", "Spell %u Effect: %u listed in `spell_linked_spell` has same bp%u like effect (possible hack)", abs(trigger), abs(effect), eff->EffectIndex);
}
spellInfo = GetSpellInfo(abs(effect));
@@ -2570,11 +2468,11 @@ void SpellMgr::LoadPetDefaultSpells()
if (!spellEntry)
continue;
- for (uint8 k = 0; k < MAX_SPELL_EFFECTS; ++k)
+ for (SpellEffectInfo const* effect : spellEntry->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- if (spellEntry->Effects[k].Effect == SPELL_EFFECT_SUMMON || spellEntry->Effects[k].Effect == SPELL_EFFECT_SUMMON_PET)
+ if (effect && (effect->Effect == SPELL_EFFECT_SUMMON || effect->Effect == SPELL_EFFECT_SUMMON_PET))
{
- uint32 creature_id = spellEntry->Effects[k].MiscValue;
+ uint32 creature_id = effect->MiscValue;
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
if (!cInfo)
continue;
@@ -2791,18 +2689,7 @@ void SpellMgr::LoadSpellAreas()
TC_LOG_INFO("server.loading", ">> Loaded %u spell area requirements in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-// Temporary structure to hold spell effect entries for faster loading
-struct SpellEffectArray
-{
- SpellEffectArray()
- {
- effects[0] = NULL;
- effects[1] = NULL;
- effects[2] = NULL;
- }
-
- SpellEffectEntry const* effects[MAX_SPELL_EFFECTS];
-};
+typedef std::vector<SpellEffectEntry const*> SpellEffectVector;
void SpellMgr::LoadSpellInfoStore()
{
@@ -2811,25 +2698,30 @@ void SpellMgr::LoadSpellInfoStore()
UnloadSpellInfoStore();
mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL);
- std::map<uint32, SpellEffectArray> effectsBySpell;
+ std::unordered_map<uint32, SpellEffectEntryMap> effectsBySpell;
for (uint32 i = 0; i < sSpellEffectStore.GetNumRows(); ++i)
{
SpellEffectEntry const* effect = sSpellEffectStore.LookupEntry(i);
if (!effect)
continue;
-
- // TODO: 6.x implement dynamic spell effect storage and remove MAX_SPELL_EFFECTS
- // This is a temporary fix to avoid crash when loading spells
+
if (effect->EffectIndex >= MAX_SPELL_EFFECTS)
+ {
+ TC_LOG_ERROR("server.loading", "Spell %u has invalid EffectIndex %u, max is %u, skipped", i, effect->EffectIndex, uint32(MAX_SPELL_EFFECTS));
continue;
+ }
- effectsBySpell[effect->SpellID].effects[effect->EffectIndex] = effect;
+ SpellEffectEntryVector& effectsForDifficulty = effectsBySpell[effect->SpellID][effect->DifficultyID];
+ if (effectsForDifficulty.size() <= effect->EffectIndex)
+ effectsForDifficulty.resize(effect->EffectIndex + 1);
+
+ effectsForDifficulty[effect->EffectIndex] = effect;
}
for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i))
- mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i].effects);
+ mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i]);
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
@@ -2891,9 +2783,12 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
if (!spellInfo)
continue;
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- switch (spellInfo->Effects[j].ApplyAuraName)
+ if (!effect)
+ continue;
+
+ switch (effect->ApplyAuraName)
{
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CONFUSE:
@@ -2917,7 +2812,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
break;
}
- switch (spellInfo->Effects[j].Effect)
+ switch (effect->Effect)
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
case SPELL_EFFECT_WEAPON_DAMAGE:
@@ -2955,7 +2850,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
// only enchanting profession enchantments procs can stack
if (IsPartOfSkillLine(SKILL_ENCHANTING, i))
{
- uint32 enchantId = spellInfo->Effects[j].MiscValue;
+ uint32 enchantId = effect->MiscValue;
SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(enchantId);
if (!enchant)
break;
@@ -2972,7 +2867,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes()
// if proced directly from enchantment, not via proc aura
// NOTE: Enchant Weapon - Blade Ward also has proc aura spell and is proced directly
// however its not expected to stack so this check is good
- if (procInfo->HasAura(SPELL_AURA_PROC_TRIGGER_SPELL))
+ if (procInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_PROC_TRIGGER_SPELL))
continue;
procInfo->AttributesCu |= SPELL_ATTR0_CU_ENCHANT_PROC;
@@ -3028,9 +2923,11 @@ void SpellMgr::LoadSpellInfoCorrections()
if (!spellInfo)
continue;
- for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ for (SpellEffectInfo const* effect : spellInfo->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- switch (spellInfo->Effects[j].Effect)
+ if (!effect)
+ continue;
+ switch (effect->Effect)
{
case SPELL_EFFECT_CHARGE:
case SPELL_EFFECT_CHARGE_DEST:
@@ -3049,43 +2946,43 @@ void SpellMgr::LoadSpellInfoCorrections()
switch (spellInfo->Id)
{
case 42436: // Drink! (Brewfest)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
case 52611: // Summon Skeletons
case 52612: // Summon Skeletons
- spellInfo->Effects[EFFECT_0].MiscValueB = 64;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MiscValueB = 64;
break;
case 40244: // Simon Game Visual
case 40245: // Simon Game Visual
case 40246: // Simon Game Visual
case 40247: // Simon Game Visual
case 42835: // Spout, remove damage effect, only anim is needed
- spellInfo->Effects[EFFECT_0].Effect = 0;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = 0;
break;
case 30657: // Quake
- spellInfo->Effects[EFFECT_0].TriggerSpell = 30571;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 30571;
break;
case 30541: // Blaze (needs conditions entry)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
break;
case 63665: // Charge (Argent Tournament emote on riders)
case 31298: // Sleep (needs target selection script)
case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed)
case 68933: // Wrath of Air Totem rank 2 (Aura)
case 29200: // Purify Helboar Meat
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
break;
case 31344: // Howl of Azgalor
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yards instead of 50000?!
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yards instead of 50000?!
break;
case 42818: // Headless Horseman - Wisp Flight Port
case 42821: // Headless Horseman - Wisp Flight Missile
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(6); // 100 yards
break;
case 36350: // They Must Burn Bomb Aura (self)
- spellInfo->Effects[EFFECT_0].TriggerSpell = 36325; // They Must Burn Bomb Drop (DND)
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 36325; // They Must Burn Bomb Drop (DND)
break;
case 49838: // Stop Time
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO;
@@ -3094,11 +2991,11 @@ void SpellMgr::LoadSpellInfoCorrections()
case 62136: // Energize Cores
case 54069: // Energize Cores
case 56251: // Energize Cores
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
break;
case 50785: // Energize Cores
case 59372: // Energize Cores
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
break;
case 63320: // Glyph of Life Tap
case 53228: // Rapid Killing (Rank 1)
@@ -3111,8 +3008,8 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 59725: // Improved Spell Reflection - aoe aura
// Target entry seems to be wrong for this spell :/
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS_2);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS_2);
break;
case 31347: // Doom
case 36327: // Shoot Arcane Explosion Arrow
@@ -3184,7 +3081,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 33711: // Murmur's Touch
case 38794: // Murmur's Touch
spellInfo->MaxAffectedTargets = 1;
- spellInfo->Effects[EFFECT_0].TriggerSpell = 33760;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TriggerSpell = 33760;
break;
case 17941: // Shadow Trance
case 22008: // Netherwind Focus
@@ -3199,7 +3096,7 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->ProcCharges = 1;
break;
case 44544: // Fingers of Frost
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(685904631, 1151048, 0, 0);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(685904631, 1151048, 0, 0);
break;
case 74396: // Fingers of Frost visual buff
spellInfo->ProcCharges = 2;
@@ -3214,16 +3111,16 @@ void SpellMgr::LoadSpellInfoCorrections()
case 47204: // Everlasting Affliction (4)
case 47205: // Everlasting Affliction (5)
// add corruption to affected spells
- spellInfo->Effects[EFFECT_1].SpellClassMask[0] |= 2;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->SpellClassMask[0] |= 2;
break;
case 37408: // Oscillation Field
spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
break;
case 51852: // The Eye of Acherus (no spawn in phase 2 in db)
- spellInfo->Effects[EFFECT_0].MiscValue |= 1;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MiscValue |= 1;
break;
case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
- spellInfo->Effects[EFFECT_0].ApplyAuraPeriod = 3000;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraPeriod = 3000;
break;
// Master Shapeshifter: missing stance data for forms other than bear - bear version has correct data
// To prevent aura staying on target after talent unlearned
@@ -3239,23 +3136,23 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 51466: // Elemental Oath (Rank 1)
case 51470: // Elemental Oath (Rank 2)
- spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_APPLY_AURA;
- spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
- spellInfo->Effects[EFFECT_1].MiscValue = SPELLMOD_EFFECT2;
- spellInfo->Effects[EFFECT_1].SpellClassMask = flag128(0x00000000, 0x00004000, 0x00000000, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = SPELL_EFFECT_APPLY_AURA;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->MiscValue = SPELLMOD_EFFECT2;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->SpellClassMask = flag128(0x00000000, 0x00004000, 0x00000000, 0x00000000);
break;
case 47569: // Improved Shadowform (Rank 1)
// with this spell atrribute aura can be stacked several times
spellInfo->Attributes &= ~SPELL_ATTR0_NOT_SHAPESHIFT;
break;
case 64904: // Hymn of Hope
- spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->ApplyAuraName = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
break;
case 30421: // Nether Portal - Perseverence
- spellInfo->Effects[EFFECT_2].BasePoints += 30000;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->BasePoints += 30000;
break;
case 41913: // Parasitic Shadowfiend Passive
- spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY; // proc debuff, and summon infinite fiends
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraName = SPELL_AURA_DUMMY; // proc debuff, and summon infinite fiends
break;
case 27892: // To Anchor 1
case 27928: // To Anchor 1
@@ -3269,8 +3166,8 @@ void SpellMgr::LoadSpellInfoCorrections()
// this is the only known exception, probably just wrong data
case 29214: // Wrath of the Plaguebringer
case 54836: // Wrath of the Plaguebringer
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
- spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
break;
case 63675: // Improved Devouring Plague
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
@@ -3284,47 +3181,47 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 53241: // Marked for Death (Rank 1)
case 53243: // Marked for Death (Rank 2)
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(0x00067801, 0x10820001, 0x00000801, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(0x00067801, 0x10820001, 0x00000801, 0x00000000);
break;
case 5176: // Wrath
case 2912: // Starfire
- case 78674: // Starsurge
- spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_DUMMY;
- spellInfo->Effects[EFFECT_1].TargetA = TARGET_UNIT_CASTER;
+ //case 78674: // Starsurge 6.x effect 1 is no more
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = SPELL_EFFECT_DUMMY;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->TargetA = TARGET_UNIT_CASTER;
break;
case 70728: // Exploit Weakness (needs target selection script)
case 70840: // Devious Minds (needs target selection script)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_PET);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_PET);
break;
case 70893: // Culling The Herd (needs target selection script)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_MASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_MASTER);
break;
case 54800: // Sigil of the Frozen Conscience - change class mask to custom extended flags of Icy Touch
// this is done because another spell also uses the same SpellFamilyFlags as Icy Touch
// SpellFamilyFlags[0] & 0x00000040 in SPELLFAMILY_DEATHKNIGHT is currently unused (3.3.5a)
// this needs research on modifier applying rules, does not seem to be in Attributes fields
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(0x00000040, 0x00000000, 0x00000000, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(0x00000040, 0x00000000, 0x00000000, 0x00000000);
break;
case 64949: // Idol of the Flourishing Life
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(0x00000000, 0x02000000, 0x00000000, 0x00000000);
- spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(0x00000000, 0x02000000, 0x00000000, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
break;
case 34231: // Libram of the Lightbringer
case 60792: // Libram of Tolerance
case 64956: // Libram of the Resolute
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(0x80000000, 0x00000000, 0x00000000, 0x00000000);
- spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(0x80000000, 0x00000000, 0x00000000, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
break;
case 28851: // Libram of Light
case 28853: // Libram of Divinity
case 32403: // Blessed Book of Nagrand
- spellInfo->Effects[EFFECT_0].SpellClassMask = flag128(0x40000000, 0x00000000, 0x00000000, 0x00000000);
- spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask = flag128(0x40000000, 0x00000000, 0x00000000, 0x00000000);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->ApplyAuraName = SPELL_AURA_ADD_FLAT_MODIFIER;
break;
case 45602: // Ride Carpet
- spellInfo->Effects[EFFECT_0].BasePoints = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->BasePoints = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
break;
case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
@@ -3339,7 +3236,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 56606: // Ride Jokkum
case 61791: // Ride Vehicle (Yogg-Saron)
/// @todo: remove this when basepoints of all Ride Vehicle auras are calculated correctly
- spellInfo->Effects[EFFECT_0].BasePoints = 1;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->BasePoints = 1;
break;
case 59630: // Black Magic
spellInfo->Attributes |= SPELL_ATTR0_PASSIVE;
@@ -3350,12 +3247,12 @@ void SpellMgr::LoadSpellInfoCorrections()
case 51798: // Brewfest - Relay Race - Intro - Quest Complete
case 47134: // Quest Complete
//! HACK: This spell break quest complete for alliance and on retail not used °_O
- spellInfo->Effects[EFFECT_0].Effect = 0;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = 0;
break;
// ULDUAR SPELLS
//
case 62374: // Pursued (Flame Leviathan)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 63342: // Focused Eyebeam Summon Trigger (Kologarn)
spellInfo->MaxAffectedTargets = 1;
@@ -3377,7 +3274,7 @@ void SpellMgr::LoadSpellInfoCorrections()
// then EFFECT_1, etc - instead of applying each effect on target1, then target2, etc.
// The above situation causes the visual for this spell to be bugged, so we remove the instakill
// effect and implement a script hack for that.
- spellInfo->Effects[EFFECT_1].Effect = 0;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = 0;
break;
case 64386: // Terrifying Screech (Auriaya)
case 64389: // Sentinel Blast (Auriaya)
@@ -3391,7 +3288,7 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
break;
case 63414: // Spinning Up (Mimiron)
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
spellInfo->ChannelInterruptFlags = 0;
break;
case 63036: // Rocket Strike (Mimiron)
@@ -3411,7 +3308,7 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->MaxAffectedTargets = 3;
break;
case 62293: // Cosmic Smash (Algalon the Observer)
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_DEST_CASTER);
break;
case 62311: // Cosmic Smash (Algalon the Observer)
case 64596: // Cosmic Smash (Algalon the Observer)
@@ -3426,7 +3323,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 64031: // Scrapyard Teleport
case 64032: // Formation Grounds Teleport
case 65042: // Prison of Yogg-Saron Teleport
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
// ENDOF ULDUAR SPELLS
//
@@ -3444,14 +3341,14 @@ void SpellMgr::LoadSpellInfoCorrections()
//
case 72435: // Defiling Horror
case 72452: // Defiling Horror
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_60_YARDS); // 60yd
break;
case 72830: // Achievement Check
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 72900: // Start Halls of Reflection Quest AE
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
// ENDOF HALLS OF REFLECTION SPELLS
//
@@ -3467,7 +3364,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 70859: // Upper Spire Teleport
case 70860: // Frozen Throne Teleport
case 70861: // Sindragosa's Lair Teleport
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
case 69075: // Bone Storm (Lord Marrowgar)
case 70834: // Bone Storm (Lord Marrowgar)
@@ -3477,7 +3374,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 71160: // Plague Stench (Stinky)
case 71161: // Plague Stench (Stinky)
case 71123: // Decimate (Stinky & Precious)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
break;
case 71169: // Shadow's Fate
spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
@@ -3489,59 +3386,59 @@ void SpellMgr::LoadSpellInfoCorrections()
case 73844: // Award Reputation - Boss Kill
case 73845: // Award Reputation - Boss Kill
case 73846: // Award Reputation - Boss Kill
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 72378: // Blood Nova (Deathbringer Saurfang)
case 73058: // Blood Nova (Deathbringer Saurfang)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
break;
case 72769: // Scent of Blood (Deathbringer Saurfang)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
// no break
case 72771: // Scent of Blood (Deathbringer Saurfang)
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS);
break;
case 72723: // Resistant Skin (Deathbringer Saurfang adds)
// this spell initially granted Shadow damage immunity, however it was removed but the data was left in client
- spellInfo->Effects[EFFECT_2].Effect = 0;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->Effect = 0;
break;
case 70460: // Coldflame Jets (Traps after Saurfang)
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(1); // 10 seconds
break;
case 71412: // Green Ooze Summon (Professor Putricide)
case 71415: // Orange Ooze Summon (Professor Putricide)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
case 71159: // Awaken Plagued Zombies
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
break;
case 70530: // Volatile Ooze Beam Protection (Professor Putricide)
- spellInfo->Effects[EFFECT_0].Effect = SPELL_EFFECT_APPLY_AURA; // for an unknown reason this was SPELL_EFFECT_APPLY_AREA_AURA_RAID
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = SPELL_EFFECT_APPLY_AURA; // for an unknown reason this was SPELL_EFFECT_APPLY_AREA_AURA_RAID
break;
// THIS IS HERE BECAUSE COOLDOWN ON CREATURE PROCS IS NOT IMPLEMENTED
case 71604: // Mutated Strength (Professor Putricide)
case 72673: // Mutated Strength (Professor Putricide)
case 72674: // Mutated Strength (Professor Putricide)
case 72675: // Mutated Strength (Professor Putricide)
- spellInfo->Effects[EFFECT_1].Effect = 0;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->Effect = 0;
break;
case 72454: // Mutated Plague (Professor Putricide)
case 72464: // Mutated Plague (Professor Putricide)
case 72506: // Mutated Plague (Professor Putricide)
case 72507: // Mutated Plague (Professor Putricide)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 70911: // Unbound Plague (Professor Putricide) (needs target selection script)
case 72854: // Unbound Plague (Professor Putricide) (needs target selection script)
case 72855: // Unbound Plague (Professor Putricide) (needs target selection script)
case 72856: // Unbound Plague (Professor Putricide) (needs target selection script)
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ENEMY);
break;
case 71518: // Unholy Infusion Quest Credit (Professor Putricide)
case 72934: // Blood Infusion Quest Credit (Blood-Queen Lana'thel)
case 72289: // Frost Infusion Quest Credit (Sindragosa)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // another missing radius
break;
case 71708: // Empowered Flare (Blood Prince Council)
case 72785: // Empowered Flare (Blood Prince Council)
@@ -3565,18 +3462,18 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
case 72015: // Frostbolt Volley (only heroic)
case 72016: // Frostbolt Volley (only heroic)
- spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_40_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_40_YARDS);
break;
case 70936: // Summon Suppressor (needs target selection script)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetB = SpellImplicitTargetInfo();
break;
case 72706: // Achievement Check (Valithria Dreamwalker)
case 71357: // Order Whelp
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
case 70598: // Sindragosa's Fury
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_DEST_DEST);
break;
case 69846: // Frost Bomb
spellInfo->Speed = 0.0f; // This spell's summon happens instantly
@@ -3594,12 +3491,12 @@ void SpellMgr::LoadSpellInfoCorrections()
case 73708: // Defile
case 73709: // Defile
case 73710: // Defile
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
case 69030: // Val'kyr Target Search
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
case 69198: // Raging Spirit Visual
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13); // 50000yd
@@ -3608,9 +3505,9 @@ void SpellMgr::LoadSpellInfoCorrections()
case 74295: // Harvest Souls
case 74296: // Harvest Souls
case 74297: // Harvest Souls
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
- spellInfo->Effects[EFFECT_2].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_2))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 73655: // Harvest Soul
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
@@ -3622,34 +3519,34 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(28); // 5 seconds
break;
case 73529: // Shadow Trap
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS); // 10yd
break;
case 74282: // Shadow Trap (searcher)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_3_YARDS); // 3yd
break;
case 72595: // Restore Soul
case 73650: // Restore Soul
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
case 74086: // Destroy Soul
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
case 74302: // Summon Spirit Bomb
case 74342: // Summon Spirit Bomb
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
spellInfo->MaxAffectedTargets = 1;
break;
case 74341: // Summon Spirit Bomb
case 74343: // Summon Spirit Bomb
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
spellInfo->MaxAffectedTargets = 3;
break;
case 73579: // Summon Spirit Bomb
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
break;
case 72350: // Fury of Frostmourne
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 75127: // Kill Frostmourne Players
case 72351: // Fury of Frostmourne
@@ -3657,31 +3554,31 @@ void SpellMgr::LoadSpellInfoCorrections()
case 72429: // Mass Resurrection
case 73159: // Play Movie
case 73582: // Trigger Vile Spirit (Inside, Heroic)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 72376: // Raise Dead
spellInfo->MaxAffectedTargets = 3;
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_50000_YARDS); // 50000yd
break;
case 71809: // Jump
spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(3); // 20yd
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS); // 25yd
break;
case 72405: // Broken Frostmourne
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_200_YARDS); // 200yd
break;
// ENDOF ICECROWN CITADEL SPELLS
//
// RUBY SANCTUM SPELLS
//
case 74799: // Soul Consumption
- spellInfo->Effects[EFFECT_1].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_1))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_12_YARDS);
break;
case 74769: // Twilight Cutter
case 77844: // Twilight Cutter
case 77845: // Twilight Cutter
case 77846: // Twilight Cutter
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_100_YARDS); // 100yd
break;
case 75509: // Twilight Mending
spellInfo->AttributesEx6 |= SPELL_ATTR6_CAN_TARGET_INVISIBLE;
@@ -3726,7 +3623,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 76606: // Disable Beacon Beams L
case 76608: // Disable Beacon Beams R
// Little hack, Increase the radius so it can hit the Cave In Stalkers in the platform.
- spellInfo->Effects[EFFECT_0].MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_45_YARDS);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->MaxRadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_45_YARDS);
break;
case 75323: // Reverberating Hymn
// Aura is refreshed at 3 seconds, and the tick should happen at the fourth.
@@ -3755,7 +3652,7 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->MaxAffectedTargets = 1;
break;
case 75697: // Evolution
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENTRY);
break;
// ISLE OF CONQUEST SPELLS
//
@@ -3773,7 +3670,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case SPELLFAMILY_PALADIN:
// Seals of the Pure should affect Seal of Righteousness
if (spellInfo->SpellIconID == 25 && spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
- spellInfo->Effects[EFFECT_0].SpellClassMask[1] |= 0x20000000;
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->SpellClassMask[1] |= 0x20000000;
break;
case SPELLFAMILY_DEATHKNIGHT:
// Icy Touch - extend FamilyFlags (unused value) for Sigil of the Frozen Conscience to use
@@ -3790,3 +3687,42 @@ void SpellMgr::LoadSpellInfoCorrections()
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo corrections in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
+
+void SpellMgr::LoadPetFamilySpellsStore()
+{
+ for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j)
+ {
+ SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j);
+ if (!skillLine)
+ continue;
+
+ SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->SpellID);
+ if (!spellInfo)
+ continue;
+
+ SpellLevelsEntry const* levels = sSpellLevelsStore.LookupEntry(spellInfo->LevelsID);
+ if (spellInfo->LevelsID && (!levels || levels->SpellLevel))
+ continue;
+
+ if (SpellMiscEntry const* spellMisc = sSpellMiscStore.LookupEntry(spellInfo->MiscID))
+ {
+ if (spellMisc->Attributes & SPELL_ATTR0_PASSIVE)
+ {
+ for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i)
+ {
+ CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i);
+ if (!cFamily)
+ continue;
+
+ if (skillLine->SkillLine != cFamily->SkillLine[0] && skillLine->SkillLine != cFamily->SkillLine[1])
+ continue;
+
+ if (skillLine->AquireMethod != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN)
+ continue;
+
+ sPetFamilySpellsStore[i].insert(spellInfo->ID);
+ }
+ }
+ }
+ }
+}
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 053935a53cb..3acd13b3a0e 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -313,16 +313,6 @@ struct SpellEnchantProcEntry
typedef std::unordered_map<uint32, SpellEnchantProcEntry> SpellEnchantProcEventMap;
-struct SpellBonusEntry
-{
- float direct_damage;
- float dot_damage;
- float ap_bonus;
- float ap_dot_bonus;
-};
-
-typedef std::unordered_map<uint32, SpellBonusEntry> SpellBonusMap;
-
enum SpellGroup
{
SPELL_GROUP_NONE = 0,
@@ -617,12 +607,6 @@ class SpellMgr
// Spell correctness for client using
static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true);
- // Spell difficulty
- uint32 GetSpellDifficultyId(uint32 spellId) const;
- void SetSpellDifficultyId(uint32 spellId, uint32 id);
- uint32 GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) const;
- SpellInfo const* GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const;
-
// Spell Ranks table
SpellChainNode const* GetSpellChainNode(uint32 spell_id) const;
uint32 GetFirstSpellInChain(uint32 spell_id) const;
@@ -668,9 +652,6 @@ class SpellMgr
SpellProcEntry const* GetSpellProcEntry(uint32 spellId) const;
bool CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) const;
- // Spell bonus data table
- SpellBonusEntry const* GetSpellBonusData(uint32 spellId) const;
-
// Spell threat table
SpellThreatEntry const* GetSpellThreatEntry(uint32 spellID) const;
@@ -705,6 +686,8 @@ class SpellMgr
}
uint32 GetSpellInfoStoreSize() const { return mSpellInfoMap.size(); }
+ void LoadPetFamilySpellsStore();
+
private:
SpellInfo* _GetSpellInfo(uint32 spellId) { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; }
@@ -723,7 +706,6 @@ class SpellMgr
void LoadSpellGroupStackRules();
void LoadSpellProcEvents();
void LoadSpellProcs();
- void LoadSpellBonusess();
void LoadSpellThreats();
void LoadSkillLineAbilityMap();
void LoadSpellPetAuras();
@@ -752,7 +734,6 @@ class SpellMgr
SpellGroupStackMap mSpellGroupStack;
SpellProcEventMap mSpellProcEventMap;
SpellProcMap mSpellProcMap;
- SpellBonusMap mSpellBonusMap;
SpellThreatMap mSpellThreatMap;
SpellPetAuraMap mSpellPetAuraMap;
SpellLinkedMap mSpellLinkedMap;
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index 8ab3a72b47e..1d5eab259aa 100644
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -110,11 +110,14 @@ std::string _SpellScript::EffectHook::EffIndexToString()
bool _SpellScript::EffectNameCheck::Check(SpellInfo const* spellEntry, uint8 effIndex)
{
- if (!spellEntry->Effects[effIndex].Effect && !effName)
+ SpellEffectInfo const* effect = spellEntry->GetEffect(effIndex);
+ if (!effect)
+ return false;
+ if (!effect->Effect && !effName)
return true;
- if (!spellEntry->Effects[effIndex].Effect)
+ if (!effect->Effect)
return false;
- return (effName == SPELL_EFFECT_ANY) || (spellEntry->Effects[effIndex].Effect == effName);
+ return (effName == SPELL_EFFECT_ANY) || (effect->Effect == effName);
}
std::string _SpellScript::EffectNameCheck::ToString()
@@ -132,11 +135,14 @@ std::string _SpellScript::EffectNameCheck::ToString()
bool _SpellScript::EffectAuraNameCheck::Check(SpellInfo const* spellEntry, uint8 effIndex)
{
- if (!spellEntry->Effects[effIndex].ApplyAuraName && !effAurName)
+ SpellEffectInfo const* effect = spellEntry->GetEffect(effIndex);
+ if (!effect)
+ return false;
+ if (!effect->ApplyAuraName && !effAurName)
return true;
- if (!spellEntry->Effects[effIndex].ApplyAuraName)
+ if (!effect->ApplyAuraName)
return false;
- return (effAurName == SPELL_AURA_ANY) || (spellEntry->Effects[effIndex].ApplyAuraName == effAurName);
+ return (effAurName == SPELL_AURA_ANY) || (effect->ApplyAuraName == effAurName);
}
std::string _SpellScript::EffectAuraNameCheck::ToString()
@@ -218,8 +224,12 @@ bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 eff
if (!targetType)
return false;
- if (spellEntry->Effects[effIndex].TargetA.GetTarget() != targetType &&
- spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType)
+ SpellEffectInfo const* effect = spellEntry->GetEffect(effIndex);
+ if (!effect)
+ return false;
+
+ if (effect->TargetA.GetTarget() != targetType &&
+ effect->TargetB.GetTarget() != targetType)
return false;
SpellImplicitTargetInfo targetInfo(targetType);
@@ -635,6 +645,11 @@ SpellValue const* SpellScript::GetSpellValue()
return m_spell->m_spellValue;
}
+SpellEffectInfo const* SpellScript::GetEffectInfo(SpellEffIndex effIndex) const
+{
+ return m_spell->GetEffect(effIndex);
+}
+
bool AuraScript::_Validate(SpellInfo const* entry)
{
for (std::list<CheckAreaTargetHandler>::iterator itr = DoCheckAreaTarget.begin(); itr != DoCheckAreaTarget.end(); ++itr)
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 653ae9ab5e9..ba25a056ee8 100644
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -342,6 +342,7 @@ class SpellScript : public _SpellScript
Unit* GetOriginalCaster();
SpellInfo const* GetSpellInfo();
SpellValue const* GetSpellValue();
+ SpellEffectInfo const* GetEffectInfo(SpellEffIndex) const;
// methods useable after spell is prepared
// accessors to the explicit targets of the spell
diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h
index 72f80bb07a3..a4834d555d3 100644
--- a/src/server/game/Texts/ChatTextBuilder.h
+++ b/src/server/game/Texts/ChatTextBuilder.h
@@ -20,6 +20,7 @@
#include "Chat.h"
#include "ObjectMgr.h"
+#include "Packets/ChatPackets.h"
namespace Trinity
{
@@ -32,13 +33,9 @@ namespace Trinity
void operator()(WorldPacket& data, LocaleConstant locale)
{
BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId);
- ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale);
- }
-
- size_t operator()(WorldPacket* data, LocaleConstant locale) const
- {
- BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId);
- return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale);
+ data = *packet.Write();
}
private:
@@ -57,7 +54,9 @@ namespace Trinity
void operator()(WorldPacket& data, LocaleConstant locale)
{
- ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgType, _language, _source, _target, _text, 0, "", locale);
+ data = *packet.Write();
}
private:
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index 77819b87ec0..992942cefeb 100644
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -24,6 +24,7 @@
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CreatureTextMgr.h"
+#include "ChatPackets.h"
class CreatureTextBuilder
{
@@ -31,11 +32,12 @@ class CreatureTextBuilder
CreatureTextBuilder(WorldObject const* obj, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target)
: _source(obj), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
- size_t operator()(WorldPacket* data, LocaleConstant locale) const
+ void operator()(WorldPacket& data, LocaleConstant locale) const
{
std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale);
-
- return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _source, _target, text, 0, "", locale);
+ data = *packet.Write();
}
private:
@@ -54,11 +56,12 @@ class PlayerTextBuilder
PlayerTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, uint32 language, WorldObject const* target)
: _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
- size_t operator()(WorldPacket* data, LocaleConstant locale) const
+ void operator()(WorldPacket& data, LocaleConstant locale) const
{
std::string const& text = sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale);
-
- return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _talker, _target, text, 0, "", locale);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, _msgType, Language(_language), _talker, _target, text, 0, "", locale);
+ data = *packet.Write();
}
private:
diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h
index 06efadb1dc7..647d8249e68 100644
--- a/src/server/game/Texts/CreatureTextMgr.h
+++ b/src/server/game/Texts/CreatureTextMgr.h
@@ -24,6 +24,7 @@
#include "SharedDefines.h"
#include "Opcodes.h"
#include "Group.h"
+#include "Packets/ChatPackets.h"
enum CreatureTextRange
{
@@ -133,50 +134,38 @@ class CreatureTextLocalizer
~CreatureTextLocalizer()
{
for (size_t i = 0; i < _packetCache.size(); ++i)
- {
- if (_packetCache[i])
- delete _packetCache[i]->first;
delete _packetCache[i];
- }
}
void operator()(Player* player)
{
LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
- WorldPacket* messageTemplate;
- size_t whisperGUIDpos;
+ WorldPackets::Chat::Chat* messageTemplate;
// create if not cached yet
if (!_packetCache[loc_idx])
{
- messageTemplate = new WorldPacket();
- whisperGUIDpos = _builder(messageTemplate, loc_idx);
- ASSERT(messageTemplate->GetOpcode() != NULL_OPCODE);
- _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos);
+ messageTemplate = new WorldPackets::Chat::Chat();
+ _packetCache[loc_idx] = messageTemplate;
}
else
- {
- messageTemplate = _packetCache[loc_idx]->first;
- whisperGUIDpos = _packetCache[loc_idx]->second;
- }
+ messageTemplate = _packetCache[loc_idx];
- WorldPacket data(*messageTemplate);
switch (_msgType)
{
case CHAT_MSG_MONSTER_WHISPER:
case CHAT_MSG_RAID_BOSS_WHISPER:
- // TODO: Fix this. GUIDs are now always written packed and can have different packed lengths
- //data.put<uint64>(whisperGUIDpos, player->GetGUID().GetRawValue());
+ messageTemplate->TargetGUID = player->GetGUID();
break;
default:
break;
}
- player->SendDirectMessage(&data);
+ player->SendDirectMessage(messageTemplate->Write());
}
private:
- std::vector<std::pair<WorldPacket*, size_t>* > _packetCache;
+ std::vector<WorldPackets::Chat::Chat*> _packetCache;
Builder const& _builder;
ChatMsg _msgType;
};
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index 6f42d41c694..43d4374c544 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -519,10 +519,10 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s
if (!changenth(line, 2, chraccount)) // characters.account update
ROLLBACK(DUMP_FILE_BROKEN);
- race = uint8(atol(getnth(line, 4).c_str()));
- playerClass = uint8(atol(getnth(line, 5).c_str()));
- gender = uint8(atol(getnth(line, 6).c_str()));
- level = uint8(atol(getnth(line, 7).c_str()));
+ race = uint8(atoul(getnth(line, 4).c_str()));
+ playerClass = uint8(atoul(getnth(line, 5).c_str()));
+ gender = uint8(atoul(getnth(line, 6).c_str()));
+ level = uint8(atoul(getnth(line, 7).c_str()));
if (name.empty())
{
// check if the original name already exists
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 098181c76a1..53a2ee814a7 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -46,6 +46,7 @@
#include "LFGMgr.h"
#include "MapManager.h"
#include "Memory.h"
+#include "MiscPackets.h"
#include "MMapFactory.h"
#include "ObjectMgr.h"
#include "OutdoorPvPMgr.h"
@@ -64,6 +65,7 @@
#include "WaypointMovementGenerator.h"
#include "WeatherMgr.h"
#include "WorldSession.h"
+#include "ChatPackets.h"
#include <boost/algorithm/string.hpp>
@@ -1411,6 +1413,8 @@ void World::SetInitialWorldSettings()
LoadDBCStores(m_dataPath);
LoadDB2Stores(m_dataPath);
+ sSpellMgr->LoadPetFamilySpellsStore();
+
TC_LOG_INFO("server.loading", "Loading SpellInfo store...");
sSpellMgr->LoadSpellInfoStore();
@@ -1487,9 +1491,6 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Spell Proc conditions and data...");
sSpellMgr->LoadSpellProcs();
- TC_LOG_INFO("server.loading", "Loading Spell Bonus Data...");
- sSpellMgr->LoadSpellBonusess();
-
TC_LOG_INFO("server.loading", "Loading Aggro Spells Definitions...");
sSpellMgr->LoadSpellThreats();
@@ -2287,7 +2288,9 @@ namespace Trinity
while (char* line = lineFromMessage(pos))
{
WorldPacket* data = new WorldPacket();
- ChatHandler::BuildChatPacket(*data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ *data = *packet.Write();
data_list.push_back(data);
}
}
@@ -2345,16 +2348,15 @@ void World::SendGMText(uint32 string_id, ...)
/// DEPRECATED, only for debug purpose. Send a System Message to all players (except self if mentioned)
void World::SendGlobalText(const char* text, WorldSession* self)
{
- WorldPacket data;
-
// need copy to prevent corruption by strtok call in LineFromMessage original string
char* buf = strdup(text);
char* pos = buf;
while (char* line = ChatHandler::LineFromMessage(pos))
{
- ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
- SendGlobalMessage(&data, self);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line);
+ SendGlobalMessage(packet.Write(), self);
}
free(buf);
@@ -2386,9 +2388,9 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket const* packet, WorldSession
/// Send a System Message to all players in the zone (except self if mentioned)
void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team)
{
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text);
- SendZoneMessage(zone, &data, self, team);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text);
+ SendZoneMessage(zone, packet.Write(), self, team);
}
/// Kick (and save) all players
@@ -3305,9 +3307,9 @@ void World::UpdateCharacterInfo(ObjectGuid const& guid, std::string const& name,
if (race != RACE_NONE)
itr->second.Race = race;
- WorldPacket data(SMSG_INVALIDATE_PLAYER, 8);
- data << guid;
- SendGlobalMessage(&data);
+ WorldPackets::Misc::InvalidatePlayer data;
+ data.Guid = guid;
+ SendGlobalMessage(data.Write());
}
void World::UpdateCharacterInfoLevel(ObjectGuid const& guid, uint8 level)
diff --git a/src/server/ipc/Commands.cpp b/src/server/ipc/Commands.cpp
index 8e494fc34b9..61b448d3d01 100644
--- a/src/server/ipc/Commands.cpp
+++ b/src/server/ipc/Commands.cpp
@@ -49,14 +49,14 @@ zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandl
return msg;
}
-zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header)
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader const& header)
{
msg << header.Channel;
msg << header.Command;
return msg;
}
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm)
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm)
{
msg << realm.Region;
msg << realm.Battlegroup;
@@ -64,14 +64,14 @@ zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm)
return msg;
}
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header)
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header const& header)
{
msg << header.Ipc;
msg << header.Realm;
return msg;
}
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle)
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle const& toonHandle)
{
msg << toonHandle.AccountId;
msg << toonHandle.GameAccountId;
diff --git a/src/server/ipc/Commands.h b/src/server/ipc/Commands.h
index 05309a45022..e34f939bae4 100644
--- a/src/server/ipc/Commands.h
+++ b/src/server/ipc/Commands.h
@@ -75,9 +75,9 @@ zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::RealmHandle& realm);
zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::Header& header);
zmqpp::message& operator>>(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
-zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader& header);
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle& realm);
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header& header);
-zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle& toonHandle);
+zmqpp::message& operator<<(zmqpp::message& msg, IPCHeader const& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::RealmHandle const& realm);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::Header const& header);
+zmqpp::message& operator<<(zmqpp::message& msg, Battlenet::ToonHandle const& toonHandle);
#endif // _COMMANDS_H
diff --git a/src/server/ipc/ZMQTask.h b/src/server/ipc/ZMQTask.h
index 24251893aaa..1141f740f76 100644
--- a/src/server/ipc/ZMQTask.h
+++ b/src/server/ipc/ZMQTask.h
@@ -45,8 +45,8 @@ protected:
zmqpp::poller* _poller;
- zmqpp::socket* _inproc;
- std::thread* _thread;
+ zmqpp::socket* _inproc = nullptr;
+ std::thread* _thread = nullptr;
};
#endif // __ZMQTASK_H
diff --git a/src/server/ipc/ZmqMux.cpp b/src/server/ipc/ZmqMux.cpp
index 2b62eaaf1eb..0f87106a948 100644
--- a/src/server/ipc/ZmqMux.cpp
+++ b/src/server/ipc/ZmqMux.cpp
@@ -18,15 +18,15 @@
#include "ZmqMux.h"
#include "ZmqContext.h"
-ZmqMux::ZmqMux(std::string from_uri, std::string to_uri):
- _fromAddress(from_uri)
+ZmqMux::ZmqMux(std::string const& fromUri, std::string const& toUri):
+ _fromAddress(fromUri)
{
- printf("Opening muxer thread from %s to %s\n", from_uri.c_str(), to_uri.c_str());
+ printf("Opening muxer thread from %s to %s\n", fromUri.c_str(), toUri.c_str());
_from = sIpcContext->CreateNewSocket(zmqpp::socket_type::pull);
_to = sIpcContext->CreateNewSocket(zmqpp::socket_type::push);
- _from->bind(from_uri);
- _to->connect(to_uri);
+ _from->bind(fromUri);
+ _to->connect(toUri);
}
ZmqMux::~ZmqMux()
diff --git a/src/server/ipc/ZmqMux.h b/src/server/ipc/ZmqMux.h
index 07336330253..c6ec26596c1 100644
--- a/src/server/ipc/ZmqMux.h
+++ b/src/server/ipc/ZmqMux.h
@@ -29,7 +29,7 @@
class ZmqMux : public ZMQTask
{
public:
- ZmqMux(std::string from, std::string to);
+ ZmqMux(std::string const& from, std::string const& to);
~ZmqMux();
bool Send(zmqpp::message*, bool dont_block = false);
void Run() override;
diff --git a/src/server/ipc/ZmqWorker.cpp b/src/server/ipc/ZmqWorker.cpp
index f205ea831b5..a3db41efe18 100644
--- a/src/server/ipc/ZmqWorker.cpp
+++ b/src/server/ipc/ZmqWorker.cpp
@@ -18,8 +18,8 @@
#include "ZmqWorker.h"
#include "ZmqContext.h"
-ZmqWorker::ZmqWorker(std::string task_uri, std::string res_uri) :
- _taskUri(task_uri), _resultsUri(res_uri)
+ZmqWorker::ZmqWorker(std::string const& taskUri, std::string const& resUri) :
+ _taskUri(taskUri), _resultsUri(resUri)
{
}
@@ -27,7 +27,6 @@ ZmqWorker::~ZmqWorker()
{
delete _taskQueue;
delete _results;
- delete _inproc;
}
void ZmqWorker::HandleOpen()
diff --git a/src/server/ipc/ZmqWorker.h b/src/server/ipc/ZmqWorker.h
index b3e221e9129..7f9b0cd1382 100644
--- a/src/server/ipc/ZmqWorker.h
+++ b/src/server/ipc/ZmqWorker.h
@@ -24,19 +24,19 @@
class ZmqWorker : public ZMQTask
{
public:
- ZmqWorker(std::string task_uri, std::string res_uri);
+ ZmqWorker(std::string const& taskUri, std::string const& resUri);
~ZmqWorker();
void Run() override;
protected:
void HandleOpen() override;
void HandleClose() override;
- zmqpp::socket* _results;
+ zmqpp::socket* _results = nullptr;
private:
void PerformWork();
virtual void Dispatch(zmqpp::message const&) = 0;
- zmqpp::socket* _taskQueue;
+ zmqpp::socket* _taskQueue = nullptr;
std::string _taskUri;
std::string _resultsUri;
};
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 0c37b1491c3..22a8fcb67f0 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -481,15 +481,15 @@ public:
char const* msg = "testtest";
uint8 type = atoi(args);
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan");
- handler->GetSession()->SendPacket(&data);
+ WorldPackets::Chat::Chat packet;
+ ChatHandler::BuildChatPacket(&packet, ChatMsg(type), LANG_UNIVERSAL, handler->GetSession()->GetPlayer(), handler->GetSession()->GetPlayer(), msg, 0, "chan");
+ handler->GetSession()->SendPacket(packet.Write());
return true;
}
static bool HandleDebugSendQuestPartyMsgCommand(ChatHandler* handler, char const* args)
{
- uint32 msg = atol((char*)args);
+ uint32 msg = atoul(args);
handler->GetSession()->GetPlayer()->SendPushToPartyResponse(handler->GetSession()->GetPlayer(), msg);
return true;
}
@@ -508,7 +508,7 @@ public:
static bool HandleDebugSendQuestInvalidMsgCommand(ChatHandler* handler, char const* args)
{
- QuestFailedReason msg = static_cast<QuestFailedReason>(atol((char*)args));
+ QuestFailedReason msg = static_cast<QuestFailedReason>(atoul(args));
handler->GetSession()->GetPlayer()->SendCanTakeQuestResponse(msg);
return true;
}
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 20ce825ad5e..d802d5a496d 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -118,7 +118,7 @@ public:
if (!id)
return false;
- uint32 objectId = atol(id);
+ uint32 objectId = atoul(id);
if (!objectId)
return false;
@@ -241,7 +241,7 @@ public:
if (!id)
return false;
- uint32 objectId = atol(id);
+ uint32 objectId = atoul(id);
if (objectId)
result = WorldDatabase.PQuery("SELECT guid, id, position_x, position_y, position_z, orientation, map, phaseMask, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE map = '%i' AND id = '%u' ORDER BY order_ ASC LIMIT 1",
diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp
index 2cf97403595..e571f30b74e 100644
--- a/src/server/scripts/Commands/cs_learn.cpp
+++ b/src/server/scripts/Commands/cs_learn.cpp
@@ -204,7 +204,7 @@ public:
// learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
player->LearnSpellHighestRank(talentInfo->SpellID);
- player->AddTalent(talentInfo->SpellID, player->GetActiveTalentGroup());
+ player->AddTalent(talentInfo->SpellID, player->GetActiveTalentGroup(), true);
}
handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 46929e3967c..7721fed3fba 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -65,7 +65,7 @@ public:
if (!id)
return false;
- uint32 creatureId = atol(id);
+ uint32 creatureId = atoul(id);
if (!creatureId)
{
handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
@@ -82,7 +82,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
@@ -133,11 +133,11 @@ public:
if (!*args)
return false;
- char* id = handler->extractKeyFromLink((char*)args, "Hitem");
+ char const* id = handler->extractKeyFromLink((char*)args, "Hitem");
if (!id)
return false;
- uint32 itemId = atol(id);
+ uint32 itemId = atoul(id);
if (!itemId)
{
handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
@@ -154,7 +154,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
@@ -354,7 +354,7 @@ public:
if (!id)
return false;
- uint32 gameObjectId = atol(id);
+ uint32 gameObjectId = atoul(id);
if (!gameObjectId)
{
handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
@@ -371,7 +371,7 @@ public:
}
char* countStr = strtok(NULL, " ");
- uint32 count = countStr ? atol(countStr) : 10;
+ uint32 count = countStr ? atoul(countStr) : 10;
if (count == 0)
return false;
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index 39644e5c08f..47f20c622bf 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -808,9 +808,11 @@ public:
}
bool known = target && target->HasSpell(id);
- bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
- SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
+ SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
+ bool learn = effect ? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
+
+ SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
bool talent = (GetTalentBySpellID(id) != nullptr);
bool passive = spellInfo->IsPassive();
@@ -878,9 +880,11 @@ public:
}
bool known = target && target->HasSpell(id);
- bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
- SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
+ SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
+ bool learn = effect? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
+
+ SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
bool talent = (GetTalentBySpellID(id) != nullptr);
bool passive = spellInfo->IsPassive();
@@ -1065,39 +1069,44 @@ public:
// Search in CharTitles.dbc
for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
{
- CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
- if (titleInfo)
+ if (CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id))
{
- std::string name = target->getGender() == GENDER_MALE ? titleInfo->NameMale_lang : titleInfo->NameFemale_lang;
+ for (uint8 gender = GENDER_MALE; gender <= GENDER_FEMALE; ++gender)
+ {
+ if (target && target->getGender() != gender)
+ continue;
- if (name.empty())
- continue;
+ std::string name = gender == GENDER_MALE ? titleInfo->NameMale_lang : titleInfo->NameFemale_lang;
- if (!Utf8FitTo(name, wNamePart))
- continue;
+ if (name.empty())
+ continue;
- if (maxResults && counter == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ if (!Utf8FitTo(name, wNamePart))
+ continue;
+
+ if (maxResults && counter == maxResults)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : "";
+ char const* knownStr = target && target->HasTitle(titleInfo) ? handler->GetTrinityString(LANG_KNOWN) : "";
- char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->MaskID
- ? handler->GetTrinityString(LANG_ACTIVE)
- : "";
+ char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->MaskID
+ ? handler->GetTrinityString(LANG_ACTIVE)
+ : "";
- char titleNameStr[80];
- snprintf(titleNameStr, 80, name.c_str(), targetName);
+ char titleNameStr[80];
+ snprintf(titleNameStr, 80, name.c_str(), targetName);
- // send title in "id (idx:idx) - [namedlink locale]" format
- if (handler->GetSession())
- handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->MaskID, id, titleNameStr, "", knownStr, activeStr);
- else
- handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->MaskID, titleNameStr, "", knownStr, activeStr);
+ // send title in "id (idx:idx) - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->MaskID, id, titleNameStr, "", knownStr, activeStr);
+ else
+ handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->MaskID, titleNameStr, "", knownStr, activeStr);
- ++counter;
+ ++counter;
+ }
}
}
if (counter == 0) // if counter == 0 then we found nth
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index 715487eff99..664c8f3d216 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -74,7 +74,7 @@ public:
Player* player = handler->GetSession()->GetPlayer();
Channel* channcel = NULL;
- if (ChannelMgr* cMgr = ChannelMgr::forTeam(player->GetTeam()))
+ if (ChannelMgr* cMgr = ChannelMgr::ForTeam(player->GetTeam()))
channcel = cMgr->GetChannel(channelStr, player);
if (strcmp(argStr, "on") == 0)
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index e868811b113..52b8b859c21 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -96,6 +96,7 @@ public:
{ "unstuck", rbac::RBAC_PERM_COMMAND_UNSTUCK, true, &HandleUnstuckCommand, "", NULL },
{ "wchange", rbac::RBAC_PERM_COMMAND_WCHANGE, false, &HandleChangeWeather, "", NULL },
{ "mailbox", rbac::RBAC_PERM_COMMAND_MAILBOX, false, &HandleMailBoxCommand, "", NULL },
+ { "auras ", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleAurasCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -1135,7 +1136,7 @@ public:
char const* id = handler->extractKeyFromLink((char*)args, "Hitem");
if (!id)
return false;
- itemId = uint32(atol(id));
+ itemId = atoul(id);
}
char const* ccount = strtok(NULL, " ");
@@ -1217,7 +1218,7 @@ public:
if (!id)
return false;
- uint32 itemSetId = atol(id);
+ uint32 itemSetId = atoul(id);
// prevent generation all items with itemset field value '0'
if (itemSetId == 0)
@@ -1358,7 +1359,7 @@ public:
return false;
}
- int32 level = uint32(atol(levelStr));
+ int32 level = atol(levelStr);
Player* target = handler->getSelectedPlayer();
if (!target)
@@ -1380,7 +1381,7 @@ public:
// If our target does not yet have the skill they are trying to add to them, the chosen level also becomes
// the max level of the new profession.
- uint16 max = maxPureSkill ? atol(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
+ uint16 max = maxPureSkill ? atoul(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
if (level <= 0 || level > max || max <= 0)
return false;
@@ -1779,7 +1780,7 @@ public:
uint32 totalmail = uint32(fields[1].GetUInt64());
// ... we have to convert it from Char to int. We can use totalmail as it is
- rmailint = atol(readmail.c_str());
+ rmailint = atoul(readmail.c_str());
// Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given
if (totalmail >= 1)
@@ -2248,7 +2249,7 @@ public:
SpellSchoolMask schoolmask = SpellSchoolMask(1 << school);
- if (Unit::IsDamageReducedByArmor(schoolmask))
+ if (handler->GetSession()->GetPlayer()->IsDamageReducedByArmor(schoolmask))
damage = handler->GetSession()->GetPlayer()->CalcArmorReducedDamage(target, damage, NULL, BASE_ATTACK);
char* spellStr = strtok((char*)NULL, " ");
@@ -2279,7 +2280,10 @@ public:
if (!spellid || !sSpellMgr->GetSpellInfo(spellid))
return false;
- handler->GetSession()->GetPlayer()->SpellNonMeleeDamageLog(target, spellid, damage);
+ SpellNonMeleeDamage damageInfo(handler->GetSession()->GetPlayer(), target, spellid, sSpellMgr->GetSpellInfo(spellid)->SchoolMask);
+ handler->GetSession()->GetPlayer()->DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
+ target->SendSpellNonMeleeDamageLog(&damageInfo);
+ target->DealSpellDamage(&damageInfo, true);
return true;
}
@@ -2597,6 +2601,44 @@ public:
handler->GetSession()->SendShowMailBox(player->GetGUID());
return true;
}
+
+ static bool HandleAurasCommand(ChatHandler* handler, char const* args)
+ {
+ Unit* target = handler->GetSession()->GetPlayer()->GetSelectedUnit();
+
+ if (!target)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ Unit::AuraApplicationMap const& uAuras = target->GetAppliedAuras();
+ handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
+ for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
+ {
+ AuraApplication const* aurApp = itr->second;
+ Aura const* aura = aurApp->GetBase();
+ char const* name = aura->GetSpellInfo()->SpellName;
+
+ bool self = target->GetGUID() == aura->GetCasterGUID();
+ if (self)
+ handler->PSendSysMessage("%u: %s (self)", aura->GetId(), name);
+ else
+ {
+ if (Unit* u = aura->GetCaster())
+ {
+ if (u->GetTypeId() == TYPEID_PLAYER)
+ handler->PSendSysMessage("%u: %s (player: %s)", aura->GetId(), name, u->GetName().c_str());
+ else if (u->GetTypeId() == TYPEID_UNIT)
+ handler->PSendSysMessage("%u: %s (creature: %s)", aura->GetId(), name, u->GetName().c_str());
+ }
+ else
+ handler->PSendSysMessage("%u: %s)", aura->GetId(), name);
+ }
+ }
+ return true;
+ }
};
void AddSC_misc_commandscript()
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 7d42609a2a0..aadf97e9b0c 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -1004,7 +1004,7 @@ public:
if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c'))
moneyToAdd = MoneyStringToMoney(std::string(args));
else
- moneyToAdd = atol(args);
+ moneyToAdd = atoll(args);
uint64 targetMoney = target->GetMoney();
@@ -1344,7 +1344,7 @@ public:
}
// Set gender
- target->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender);
+ target->SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, gender);
target->SetByteValue(PLAYER_BYTES_3, 0, gender);
// Change display ID
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 9d64ba60bc4..3e841f45f59 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -332,15 +332,15 @@ public:
char* fmaxcount = strtok(NULL, " "); //add maxcount, default: 0
uint32 maxcount = 0;
if (fmaxcount)
- maxcount = atol(fmaxcount);
+ maxcount = atoul(fmaxcount);
char* fincrtime = strtok(NULL, " "); //add incrtime, default: 0
uint32 incrtime = 0;
if (fincrtime)
- incrtime = atol(fincrtime);
+ incrtime = atoul(fincrtime);
char* fextendedcost = strtok(NULL, " "); //add ExtendedCost, default: 0
- uint32 extendedcost = fextendedcost ? atol(fextendedcost) : 0;
+ uint32 extendedcost = fextendedcost ? atoul(fextendedcost) : 0;
Creature* vendor = handler->getSelectedCreature();
if (!vendor)
{
@@ -570,7 +570,7 @@ public:
handler->SetSentErrorMessage(true);
return false;
}
- uint32 itemId = atol(pitem);
+ uint32 itemId = atoul(pitem);
const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp
index b5186bdb948..8138a755f87 100644
--- a/src/server/scripts/Commands/cs_quest.cpp
+++ b/src/server/scripts/Commands/cs_quest.cpp
@@ -67,7 +67,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -112,7 +112,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -165,7 +165,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
@@ -269,7 +269,7 @@ public:
if (!cId)
return false;
- uint32 entry = atol(cId);
+ uint32 entry = atoul(cId);
Quest const* quest = sObjectMgr->GetQuestTemplate(entry);
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index fa6adcc8eb0..a25c6bbcb59 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -137,7 +137,6 @@ public:
{ "smart_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS, true, &HandleReloadSmartScripts, "", NULL },
{ "spell_required", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED, true, &HandleReloadSpellRequiredCommand, "", NULL },
{ "spell_area", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_AREA, true, &HandleReloadSpellAreaCommand, "", NULL },
- { "spell_bonus_data", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_BONUS_DATA, true, &HandleReloadSpellBonusesCommand, "", NULL },
{ "spell_group", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP, true, &HandleReloadSpellGroupsCommand, "", NULL },
{ "spell_learn_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL, true, &HandleReloadSpellLearnSpellCommand, "", NULL },
{ "spell_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSpellCommand, "", NULL },
@@ -279,7 +278,6 @@ public:
HandleReloadSpellLinkedSpellCommand(handler, "a");
HandleReloadSpellProcEventCommand(handler, "a");
HandleReloadSpellProcsCommand(handler, "a");
- HandleReloadSpellBonusesCommand(handler, "a");
HandleReloadSpellTargetPositionCommand(handler, "a");
HandleReloadSpellThreatsCommand(handler, "a");
HandleReloadSpellGroupStackRulesCommand(handler, "a");
@@ -819,14 +817,6 @@ public:
return true;
}
- static bool HandleReloadSpellBonusesCommand(ChatHandler* handler, const char* /*args*/)
- {
- TC_LOG_INFO("misc", "Re-Loading Spell Bonus Data...");
- sSpellMgr->LoadSpellBonusess();
- handler->SendGlobalGMSysMessage("DB table `spell_bonus_data` (spell damage/healing coefficients) reloaded.");
- return true;
- }
-
static bool HandleReloadSpellTargetPositionCommand(ChatHandler* handler, const char* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Spell target coordinates...");
@@ -954,7 +944,7 @@ public:
sObjectMgr->LoadGraveyardZones();
- handler->SendGlobalGMSysMessage("DB table `game_graveyard_zone` reloaded.");
+ handler->SendGlobalGMSysMessage("DB table `graveyard_zone` reloaded.");
return true;
}
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index 01a0094bfc7..1c3bff77593 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -100,8 +100,7 @@ public:
player->SetShapeshiftForm(FORM_NONE);
player->setFactionForRace(player->getRace());
-
- player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24)));
+ player->SetUInt32Value(UNIT_FIELD_DISPLAY_POWER, powerType);
// reset only if player not in some form;
if (player->GetShapeshiftForm() == FORM_NONE)
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp
index 62d12a94c54..80ddecf8914 100644
--- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp
@@ -81,10 +81,7 @@ class boss_alizabal : public CreatureScript
struct boss_alizabalAI : public BossAI
{
- boss_alizabalAI(Creature* creature) : BossAI(creature, DATA_ALIZABAL)
- {
- _intro = false;
- }
+ boss_alizabalAI(Creature* creature) : BossAI(creature, DATA_ALIZABAL) { }
void Reset() override
{
@@ -251,10 +248,9 @@ class boss_alizabal : public CreatureScript
}
private:
- bool _intro;
- bool _hate;
- bool _skewer;
-
+ bool _intro = false;
+ bool _hate = false;
+ bool _skewer = false;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp
index 9c203ac2395..5805509cc9b 100644
--- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp
@@ -267,7 +267,7 @@ class spell_occuthar_eyes_of_occuthar : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
+ if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->CalcValue()))
return false;
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
index 008803f9a52..26a6b89dee9 100644
--- a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
@@ -157,12 +157,6 @@ class spell_argaloth_meteor_slash : public SpellScriptLoader
{
PrepareSpellScript(spell_argaloth_meteor_slash_SpellScript);
- bool Load() override
- {
- _targetCount = 0;
- return true;
- }
-
void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = targets.size();
@@ -183,7 +177,7 @@ class spell_argaloth_meteor_slash : public SpellScriptLoader
}
private:
- uint32 _targetCount;
+ uint32 _targetCount = 0;
};
SpellScript* GetSpellScript() const override
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp
index f736aa6ffbc..97d43ab163c 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.cpp
@@ -357,7 +357,7 @@ class npc_twilight_sadist : public CreatureScript
void Reset() override
{
_combatPhase = false;
- if(!me->GetWaypointPath())
+ if (!me->GetWaypointPath())
_events.ScheduleEvent(EVENT_INFLICT_PAIN_TS, urand(6000, 18000));
}
@@ -422,7 +422,7 @@ class npc_twilight_sadist : public CreatureScript
private:
EventMap _events;
InstanceScript* _instance;
- bool _combatPhase;
+ bool _combatPhase = false;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp
index 3f2e8f8b243..e97583c3575 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockCaverns/boss_corla.cpp
@@ -114,7 +114,7 @@ class boss_corla : public CreatureScript
}
private:
- bool combatPhase;
+ bool combatPhase = false;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
index 4cb0b61365d..9c4865a8d84 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_shade_of_aran.cpp
@@ -485,23 +485,23 @@ public:
void SpellHit(Unit* /*pAttacker*/, const SpellInfo* Spell) override
{
//We only care about interrupt effects and only if they are durring a spell currently being cast
- if ((Spell->Effects[0].Effect != SPELL_EFFECT_INTERRUPT_CAST &&
- Spell->Effects[1].Effect != SPELL_EFFECT_INTERRUPT_CAST &&
- Spell->Effects[2].Effect != SPELL_EFFECT_INTERRUPT_CAST) || !me->IsNonMeleeSpellCast(false))
- return;
-
- //Interrupt effect
- me->InterruptNonMeleeSpells(false);
+ for (SpellEffectInfo const* effect : Spell->GetEffectsForDifficulty(me->GetMap()->GetDifficulty()))
+ if (effect && effect->Effect == SPELL_EFFECT_INTERRUPT_CAST && me->IsNonMeleeSpellCast(false))
+ {
+ //Interrupt effect
+ me->InterruptNonMeleeSpells(false);
- //Normally we would set the cooldown equal to the spell duration
- //but we do not have access to the DurationStore
+ //Normally we would set the cooldown equal to the spell duration
+ //but we do not have access to the DurationStore
- switch (CurrentNormalSpell)
- {
- case SPELL_ARCMISSLE: ArcaneCooldown = 5000; break;
- case SPELL_FIREBALL: FireCooldown = 5000; break;
- case SPELL_FROSTBOLT: FrostCooldown = 5000; break;
- }
+ switch (CurrentNormalSpell)
+ {
+ case SPELL_ARCMISSLE: ArcaneCooldown = 5000; break;
+ case SPELL_FIREBALL: FireCooldown = 5000; break;
+ case SPELL_FROSTBOLT: FrostCooldown = 5000; break;
+ }
+ return;
+ }
}
};
};
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp
index 6cd14598a58..6758808c5d9 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.cpp
@@ -164,8 +164,10 @@ public:
{
if (Player* player = i->GetSource())
{
- if (spell && spell->Effects[0].MiscValue)
- player->KilledMonsterCredit(spell->Effects[0].MiscValue);
+ if (spell)
+ if (SpellEffectInfo const* effect = spell->GetEffect(EFFECT_0))
+ if (effect->MiscValue)
+ player->KilledMonsterCredit(effect->MiscValue);
}
}
}
diff --git a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp
index 69c188a61dc..e5a42096a04 100644
--- a/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp
+++ b/src/server/scripts/EasternKingdoms/Scholomance/boss_darkmaster_gandling.cpp
@@ -314,7 +314,7 @@ class spell_shadow_portal_rooms : public SpellScriptLoader
int8 phase_to_set = 0;
int32 gate_to_close = 0;
- switch (GetSpellInfo()->Effects[effIndex].MiscValue)
+ switch (GetSpellInfo()->GetEffect(effIndex)->MiscValue)
{
case SPELL_EVENT_HALLOFSECRETS:
pos_to_summon = 0; // Not yet spawned
diff --git a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
index 99b710afb1e..cf0228f5192 100644
--- a/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
+++ b/src/server/scripts/EasternKingdoms/SunwellPlateau/boss_muru.cpp
@@ -412,9 +412,14 @@ public:
void SpellHit(Unit* /*caster*/, const SpellInfo* Spell) override
{
- for (uint8 i = 0; i < 3; ++i)
- if (Spell->Effects[i].Effect == 38)
+ for (SpellEffectInfo const* effect : Spell->GetEffectsForDifficulty(DIFFICULTY_NONE))
+ {
+ if (effect && effect->Effect == 38)
+ {
me->DisappearAndDie();
+ return;
+ }
+ }
}
void UpdateAI(uint32 diff) override
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
index dd1152a02a5..ac557bcad97 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
@@ -141,6 +141,7 @@ class npc_voljin_zulaman : public CreatureScript
case EVENT_INTRO_MOVEPOINT_3:
Talk(SAY_INTRO_2);
_events.ScheduleEvent(EVENT_BANGING_THE_GONG, 3000);
+ break;
case EVENT_BANGING_THE_GONG:
DoCast(me, SPELL_BANGING_THE_GONG);
if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetGuidData(DATA_STRANGE_GONG)))
@@ -208,7 +209,7 @@ class npc_voljin_zulaman : public CreatureScript
private:
InstanceScript* _instance;
EventMap _events;
- uint8 _gongCount;
+ uint8 _gongCount = 0;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index 992b20d2580..e0416b56397 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -25,10 +25,9 @@ EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "hyjal.h"
-#include "SpellAuras.h"
-#include "hyjal_trash.h"
+#include "SpellScript.h"
#include "Player.h"
+#include "hyjal.h"
enum Texts
{
@@ -39,42 +38,59 @@ enum Texts
SAY_ENRAGE = 5,
SAY_DEATH = 6,
SAY_SOUL_CHARGE = 7,
+ // YELL_ARCHIMONDE_INTRO = 8
};
enum Spells
{
- SPELL_DENOUEMENT_WISP = 32124,
- SPELL_ANCIENT_SPARK = 39349,
- SPELL_PROTECTION_OF_ELUNE = 38528,
-
- SPELL_DRAIN_WORLD_TREE = 39140,
- SPELL_DRAIN_WORLD_TREE_2 = 39141,
-
- SPELL_FINGER_OF_DEATH = 31984,
- SPELL_HAND_OF_DEATH = 35354,
- SPELL_AIR_BURST = 32014,
- SPELL_GRIP_OF_THE_LEGION = 31972,
- SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
- SPELL_DOOMFIRE_SPAWN = 32074,
- SPELL_DOOMFIRE = 31945,
- SPELL_SOUL_CHARGE_YELLOW = 32045,
- SPELL_SOUL_CHARGE_GREEN = 32051,
- SPELL_SOUL_CHARGE_RED = 32052,
- SPELL_UNLEASH_SOUL_YELLOW = 32054,
- SPELL_UNLEASH_SOUL_GREEN = 32057,
- SPELL_UNLEASH_SOUL_RED = 32053,
- SPELL_FEAR = 31970,
+ SPELL_DENOUEMENT_WISP = 32124,
+ SPELL_ANCIENT_SPARK = 39349,
+ SPELL_PROTECTION_OF_ELUNE = 38528,
+
+ SPELL_DRAIN_WORLD_TREE = 39140,
+ SPELL_DRAIN_WORLD_TREE_TRIGGERED = 39141,
+
+ SPELL_FINGER_OF_DEATH = 31984,
+ SPELL_HAND_OF_DEATH = 35354,
+ SPELL_AIR_BURST = 32014,
+ SPELL_GRIP_OF_THE_LEGION = 31972,
+ SPELL_DOOMFIRE_STRIKE = 31903, // summons two creatures
+ SPELL_DOOMFIRE_SPAWN = 32074,
+ SPELL_DOOMFIRE = 31945,
+ SPELL_SOUL_CHARGE_YELLOW = 32045,
+ SPELL_SOUL_CHARGE_GREEN = 32051,
+ SPELL_SOUL_CHARGE_RED = 32052,
+ SPELL_UNLEASH_SOUL_YELLOW = 32054,
+ SPELL_UNLEASH_SOUL_GREEN = 32057,
+ SPELL_UNLEASH_SOUL_RED = 32053,
+ SPELL_FEAR = 31970
+};
+
+enum Events
+{
+ EVENT_HAND_OF_DEATH = 1, // Raid wiper
+ EVENT_UNLEASH_SOUL_CHARGE,
+ EVENT_FINGER_OF_DEATH,
+ EVENT_GRIP_OF_THE_LEGION,
+ EVENT_FEAR,
+ EVENT_AIR_BURST,
+ EVENT_DOOMFIRE,
+ EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
+ EVENT_SUMMON_WHISP
};
enum Summons
{
- CREATURE_DOOMFIRE = 18095,
- CREATURE_DOOMFIRE_SPIRIT = 18104,
- CREATURE_ANCIENT_WISP = 17946,
- CREATURE_CHANNEL_TARGET = 22418,
+ NPC_DOOMFIRE = 18095,
+ NPC_DOOMFIRE_SPIRIT = 18104,
+ NPC_ANCIENT_WISP = 17946
};
-Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
+enum Actions
+{
+ ACTION_ENRAGE,
+ ACTION_CHANNEL_WORLD_TREE
+};
class npc_ancient_wisp : public CreatureScript
{
@@ -200,7 +216,6 @@ public:
}
void MoveInLineOfSight(Unit* who) override
-
{
//will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
//when UpdateAI needs it, it will be forced to select randomPoint
@@ -249,409 +264,309 @@ class boss_archimonde : public CreatureScript
public:
boss_archimonde() : CreatureScript("boss_archimonde") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_archimondeAI>(creature);
- }
-
- struct boss_archimondeAI : public hyjal_trashAI
+ struct boss_archimondeAI : public BossAI
{
- boss_archimondeAI(Creature* creature) : hyjal_trashAI(creature)
+ boss_archimondeAI(Creature* creature) : BossAI(creature, DATA_ARCHIMONDE)
{
Initialize();
- instance = creature->GetInstanceScript();
}
void Initialize()
{
DoomfireSpiritGUID.Clear();
- damageTaken = 0;
- WorldTreeGUID.Clear();
-
- DrainNordrassilTimer = 0;
- FearTimer = 42000;
- AirBurstTimer = 30000;
- GripOfTheLegionTimer = urand(5000, 25000);
- DoomfireTimer = 20000;
- SoulChargeTimer = urand(2000, 30000);
+
SoulChargeCount = 0;
- MeleeRangeCheckTimer = 15000;
- HandOfDeathTimer = 2000;
WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
- EnrageTimer = 600000; // 10 minutes
- CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
- SummonWispTimer = 0;
+ _unleashSpell = 0;
+ _chargeSpell = 0;
Enraged = false;
- BelowTenPercent = false;
HasProtected = false;
- IsChanneling = false;
}
- InstanceScript* instance;
-
- ObjectGuid DoomfireSpiritGUID;
- ObjectGuid WorldTreeGUID;
-
- uint32 DrainNordrassilTimer;
- uint32 FearTimer;
- uint32 AirBurstTimer;
- uint32 GripOfTheLegionTimer;
- uint32 DoomfireTimer;
- uint32 SoulChargeTimer;
- uint8 SoulChargeCount;
- uint32 MeleeRangeCheckTimer;
- uint32 HandOfDeathTimer;
- uint32 SummonWispTimer;
- uint8 WispCount;
- uint32 EnrageTimer;
- uint32 CheckDistanceTimer;
-
- bool Enraged;
- bool BelowTenPercent;
- bool HasProtected;
- bool IsChanneling;
+ void InitializeAI() override
+ {
+ BossAI::InitializeAI();
+ DoAction(ACTION_CHANNEL_WORLD_TREE);
+ }
void Reset() override
{
- instance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
-
Initialize();
+ _Reset();
+ me->RemoveAllAuras(); // Reset Soul Charge auras.
}
void EnterCombat(Unit* /*who*/) override
{
- me->InterruptSpell(CURRENT_CHANNELED_SPELL);
Talk(SAY_AGGRO);
- DoZoneInCombat();
-
- instance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
- }
-
- void KilledUnit(Unit* victim) override
- {
- Talk(SAY_SLAY);
-
- if (victim && victim->GetTypeId() == TYPEID_PLAYER)
- GainSoulCharge(victim->ToPlayer());
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_FEAR, 42000);
+ events.ScheduleEvent(EVENT_AIR_BURST, 30000);
+ events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000));
+ events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 15000);
+ events.ScheduleEvent(EVENT_HAND_OF_DEATH, 600000);
+ events.ScheduleEvent(EVENT_DISTANCE_CHECK, 30000);
}
- void GainSoulCharge(Player* victim)
+ void ExecuteEvent(uint32 eventId) override
{
- switch (victim->getClass())
+ switch (eventId)
{
- case CLASS_PRIEST:
- case CLASS_PALADIN:
- case CLASS_WARLOCK:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
+ case EVENT_HAND_OF_DEATH:
+ DoCastAOE(SPELL_HAND_OF_DEATH);
+ events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2000);
+ break;
+ case EVENT_UNLEASH_SOUL_CHARGE:
+ _chargeSpell = 0;
+ _unleashSpell = 0;
+ me->InterruptNonMeleeSpells(false);
+ switch (urand(0, 2))
+ {
+ case 0:
+ _chargeSpell = SPELL_SOUL_CHARGE_RED;
+ _unleashSpell = SPELL_UNLEASH_SOUL_RED;
+ break;
+ case 1:
+ _chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
+ _unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
+ break;
+ case 2:
+ _chargeSpell = SPELL_SOUL_CHARGE_GREEN;
+ _unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
+ break;
+ }
+
+ if (me->HasAura(_chargeSpell))
+ {
+ me->RemoveAuraFromStack(_chargeSpell);
+ DoCastVictim(_unleashSpell);
+ SoulChargeCount--;
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ }
+ break;
+ case EVENT_FINGER_OF_DEATH:
+ if (!SelectTarget(SELECT_TARGET_RANDOM, 0, 5.0f)) // Checks if there are no targets in melee range
+ {
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 1000);
+ }
+ else
+ events.ScheduleEvent(EVENT_FINGER_OF_DEATH, 5000);
break;
- case CLASS_MAGE:
- case CLASS_ROGUE:
- case CLASS_WARRIOR:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
+ case EVENT_GRIP_OF_THE_LEGION:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_GRIP_OF_THE_LEGION);
+ events.ScheduleEvent(EVENT_GRIP_OF_THE_LEGION, urand(5000, 25000));
break;
- case CLASS_DRUID:
- case CLASS_SHAMAN:
- case CLASS_HUNTER:
- victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
+ case EVENT_AIR_BURST:
+ Talk(SAY_AIR_BURST);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ DoCast(target, SPELL_AIR_BURST); //not on tank
+ events.ScheduleEvent(EVENT_AIR_BURST, urand(25000, 40000));
+ break;
+ case EVENT_FEAR:
+ DoCastAOE(SPELL_FEAR);
+ events.ScheduleEvent(EVENT_FEAR, 42000);
+ break;
+ case EVENT_DOOMFIRE:
+ Talk(SAY_DOOMFIRE);
+ if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1))
+ SummonDoomfire(temp);
+ else
+ SummonDoomfire(me->GetVictim());
+ events.ScheduleEvent(EVENT_DOOMFIRE, 20000);
+ break;
+ case EVENT_DISTANCE_CHECK:
+ if (Creature* channelTrigger = instance->GetCreature(DATA_CHANNEL_TARGET))
+ if (me->IsWithinDistInMap(channelTrigger, 75.0f))
+ DoAction(ACTION_ENRAGE);
+ events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5000);
+ break;
+ case EVENT_SUMMON_WHISP:
+ DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
+ ++WispCount;
+ if (WispCount >= 30)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
+ break;
+ default:
break;
}
-
- SoulChargeTimer = urand(2000, 30000);
- ++SoulChargeCount;
- }
-
- void JustDied(Unit* killer) override
- {
- hyjal_trashAI::JustDied(killer);
- Talk(SAY_DEATH);
-
- instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
}
- bool CanUseFingerOfDeath()
+ void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
{
- // First we check if our current victim is in melee range or not.
- Unit* victim = me->GetVictim();
- if (victim && me->IsWithinDistInMap(victim, me->GetAttackDistance(victim)))
- return false;
-
- ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList();
- if (threatlist.empty())
- return false;
-
- std::list<Unit*> targets;
- ThreatContainer::StorageType::const_iterator itr = threatlist.begin();
- for (; itr != threatlist.end(); ++itr)
+ if (me->HealthBelowPctDamaged(10, damage))
{
- Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
- if (unit && unit->IsAlive())
- targets.push_back(unit);
- }
+ if (!Enraged)
+ DoAction(ACTION_ENRAGE);
- if (targets.empty())
- return false;
+ if (!HasProtected)
+ {
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
- targets.sort(Trinity::ObjectDistanceOrderPred(me));
- Unit* target = targets.front();
- if (target)
- {
- if (!me->IsWithinDistInMap(target, me->GetAttackDistance(target)))
- return true; // Cast Finger of Death
- else // This target is closest, he is our new tank
- me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim()));
+ // All members of raid must get this buff
+ DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true);
+ HasProtected = true;
+ events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500);
+ }
}
-
- return false;
}
- void JustSummoned(Creature* summoned) override
+ void KilledUnit(Unit* victim) override
{
- if (summoned->GetEntry() == CREATURE_ANCIENT_WISP)
- summoned->AI()->AttackStart(me);
- else
- {
- summoned->setFaction(me->getFaction());
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
- {
- DoomfireSpiritGUID = summoned->GetGUID();
- }
+ Talk(SAY_SLAY);
- if (summoned->GetEntry() == CREATURE_DOOMFIRE)
+ if (victim->GetTypeId() == TYPEID_PLAYER)
{
- summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
- summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
-
- if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
+ switch (victim->getClass())
{
- summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
- DoomfireSpiritGUID.Clear();
+ case CLASS_PRIEST:
+ case CLASS_PALADIN:
+ case CLASS_WARLOCK:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
+ break;
+ case CLASS_MAGE:
+ case CLASS_ROGUE:
+ case CLASS_WARRIOR:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
+ break;
+ case CLASS_DRUID:
+ case CLASS_SHAMAN:
+ case CLASS_HUNTER:
+ victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
+ break;
}
+
+ events.ScheduleEvent(EVENT_UNLEASH_SOUL_CHARGE, urand(2000, 30000));
+ ++SoulChargeCount;
}
}
- //this is code doing close to what the summoning spell would do (spell 31903)
- void SummonDoomfire(Unit* target)
+ void JustReachedHome() override
{
- me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
- target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
-
- me->SummonCreature(CREATURE_DOOMFIRE,
- target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
- TEMPSUMMON_TIMED_DESPAWN, 27000);
+ DoAction(ACTION_CHANNEL_WORLD_TREE);
}
- void UnleashSoulCharge()
+ void JustDied(Unit* /*killer*/) override
{
- me->InterruptNonMeleeSpells(false);
-
- bool HasCast = false;
- uint32 chargeSpell = 0;
- uint32 unleashSpell = 0;
+ Talk(SAY_DEATH);
+ _JustDied();
+ // @todo: remove this when instance script gets updated, kept for compatibility only
+ instance->SetData(DATA_ARCHIMONDE, DONE);
+ }
- switch (urand(0, 2))
+ void JustSummoned(Creature* summoned) override
+ {
+ switch (summoned->GetEntry())
{
- case 0:
- chargeSpell = SPELL_SOUL_CHARGE_RED;
- unleashSpell = SPELL_UNLEASH_SOUL_RED;
- break;
- case 1:
- chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
- unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
+ case NPC_ANCIENT_WISP:
+ summoned->AI()->AttackStart(me);
break;
- case 2:
- chargeSpell = SPELL_SOUL_CHARGE_GREEN;
- unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
+ case NPC_DOOMFIRE_SPIRIT:
+ DoomfireSpiritGUID = summoned->GetGUID();
break;
- }
+ case NPC_DOOMFIRE:
+ summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
+ summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
- if (me->HasAura(chargeSpell))
- {
- me->RemoveAuraFromStack(chargeSpell);
- DoCastVictim(unleashSpell);
- HasCast = true;
- SoulChargeCount--;
+ if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
+ {
+ summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
+ DoomfireSpiritGUID.Clear();
+ }
+ break;
+ default:
+ break;
}
-
- if (HasCast)
- SoulChargeTimer = urand(2000, 30000);
}
- void UpdateAI(uint32 diff) override
+ void DoAction(int32 actionId) override
{
- if (!me->IsInCombat())
+ switch (actionId)
{
- // Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
- if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35)))
- {
- me->SetVisible(false);
- me->setFaction(35);
- }
- else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35)))
- {
- me->setFaction(1720);
- me->SetVisible(true);
- }
-
- if (DrainNordrassilTimer <= diff)
- {
- if (!IsChanneling)
- {
- Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
-
- if (temp)
- WorldTreeGUID = temp->GetGUID();
-
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- {
- Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Nordrassil->SetDisplayId(11686);
- DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
- IsChanneling = true;
- }
- }
-
- if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
- {
- Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
- DrainNordrassilTimer = 1000;
- }
- } else DrainNordrassilTimer -= diff;
+ case ACTION_ENRAGE:
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
+ Enraged = true;
+ Talk(SAY_ENRAGE);
+ break;
+ case ACTION_CHANNEL_WORLD_TREE:
+ DoCastAOE(SPELL_DRAIN_WORLD_TREE, true);
+ break;
+ default:
+ break;
}
+ }
- if (!UpdateVictim())
+ //this is code doing close to what the summoning spell would do (spell 31903)
+ void SummonDoomfire(Unit* target)
+ {
+ if (!target)
return;
- if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged)
- BelowTenPercent = true;
-
- if (!Enraged)
- {
- if (EnrageTimer <= diff)
- {
- if (HealthAbovePct(10))
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
- Enraged = true;
- Talk(SAY_ENRAGE);
- }
- } else EnrageTimer -= diff;
+ me->SummonCreature(NPC_DOOMFIRE_SPIRIT,
+ target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
- if (CheckDistanceTimer <= diff)
- {
- // To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
- Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
- if (Check)
- {
- Check->SetVisible(false);
-
- if (me->IsWithinDistInMap(Check, 75))
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
- Enraged = true;
- Talk(SAY_ENRAGE);
- }
- }
- CheckDistanceTimer = 5000;
- } else CheckDistanceTimer -= diff;
- }
+ me->SummonCreature(NPC_DOOMFIRE,
+ target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
+ TEMPSUMMON_TIMED_DESPAWN, 27000);
+ }
- if (BelowTenPercent)
- {
- if (!HasProtected)
- {
- me->GetMotionMaster()->Clear(false);
- me->GetMotionMaster()->MoveIdle();
+ private:
+ ObjectGuid DoomfireSpiritGUID;
+ uint8 SoulChargeCount;
+ uint8 WispCount;
+ uint32 _chargeSpell;
+ uint32 _unleashSpell;
+ bool Enraged;
+ bool HasProtected;
+ };
- //all members of raid must get this buff
- DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true);
- HasProtected = true;
- Enraged = true;
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_archimondeAI>(creature);
+ }
+};
- if (SummonWispTimer <= diff)
- {
- DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- SummonWispTimer = 1500;
- ++WispCount;
- } else SummonWispTimer -= diff;
+// 39142 - Drain World Tree Dummy
+class spell_archimonde_drain_world_tree_dummy : public SpellScriptLoader
+{
+ public:
+ spell_archimonde_drain_world_tree_dummy() : SpellScriptLoader("spell_archimonde_drain_world_tree_dummy") { }
- if (WispCount >= 30)
- me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
+ class spell_archimonde_drain_world_tree_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_archimonde_drain_world_tree_dummy_SpellScript);
- if (Enraged)
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- if (HandOfDeathTimer <= diff)
- {
- DoCastVictim(SPELL_HAND_OF_DEATH);
- HandOfDeathTimer = 2000;
- } else HandOfDeathTimer -= diff;
- return; // Don't do anything after this point.
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRAIN_WORLD_TREE_TRIGGERED))
+ return false;
+ return true;
}
- if (SoulChargeCount)
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
- if (SoulChargeTimer <= diff)
- UnleashSoulCharge();
- else SoulChargeTimer -= diff;
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(GetCaster(), SPELL_DRAIN_WORLD_TREE_TRIGGERED, true);
}
- if (GripOfTheLegionTimer <= diff)
- {
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
- GripOfTheLegionTimer = urand(5000, 25000);
- } else GripOfTheLegionTimer -= diff;
-
- if (AirBurstTimer <= diff)
- {
- Talk(SAY_AIR_BURST);
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
- AirBurstTimer = urand(25000, 40000);
- } else AirBurstTimer -= diff;
-
- if (FearTimer <= diff)
- {
- DoCastVictim(SPELL_FEAR);
- FearTimer = 42000;
- } else FearTimer -= diff;
-
- if (DoomfireTimer <= diff)
+ void Register() override
{
- Talk(SAY_DOOMFIRE);
- Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
- if (!temp)
- temp = me->GetVictim();
-
- //replace with spell cast 31903 once implicitTarget 73 implemented
- SummonDoomfire(temp);
-
- //supposedly three doomfire can be up at the same time
- DoomfireTimer = 20000;
- } else DoomfireTimer -= diff;
-
- if (MeleeRangeCheckTimer <= diff)
- {
- if (CanUseFingerOfDeath())
- {
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
- MeleeRangeCheckTimer = 1000;
- }
-
- MeleeRangeCheckTimer = 5000;
- } else MeleeRangeCheckTimer -= diff;
+ OnEffectHitTarget += SpellEffectFn(spell_archimonde_drain_world_tree_dummy_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
- DoMeleeAttackIfReady();
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_archimonde_drain_world_tree_dummy_SpellScript();
}
- void WaypointReached(uint32 /*waypointId*/) override { }
- };
};
void AddSC_boss_archimonde()
@@ -660,4 +575,5 @@ void AddSC_boss_archimonde()
new npc_doomfire();
new npc_doomfire_targetting();
new npc_ancient_wisp();
+ new spell_archimonde_drain_world_tree_dummy();
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
index c5f4d4ae679..54a763573ed 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
@@ -44,7 +44,8 @@ enum DataTypes
DATA_HORDE_RETREAT = 17,
DATA_RAIDDAMAGE = 18,
DATA_RESET_RAIDDAMAGE = 19,
- TYPE_RETREAT = 20
+ TYPE_RETREAT = 20,
+ DATA_CHANNEL_TARGET = 21
};
enum WorldStateIds
@@ -77,7 +78,8 @@ enum CreaturesIds
KAZROGAL = 17888,
AZGALOR = 17842,
ARCHIMONDE = 17968,
- NPC_WORLD_TRIGGER_TINY = 21987
+ NPC_WORLD_TRIGGER_TINY = 21987,
+ NPC_CHANNEL_TARGET = 22418
};
enum GameobjectIds
@@ -89,5 +91,6 @@ enum GameobjectIds
GO_ROARING_FLAME = 182592
};
-#endif
+#define MINRAIDDAMAGE 700000 // minimal damage before trash can drop loot and reputation, resets if faction leader dies
+#endif
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 56b79b6b3e1..0394b8535e5 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -26,7 +26,6 @@ enum Spells
SPELL_METEOR = 33814, //infernal visual
SPELL_IMMOLATION = 37059,
SPELL_FLAME_BUFFET = 31724,
- NPC_TRIGGER = 21987, //World Trigger (Tiny)
MODEL_INVIS = 11686, //invisible model
SPELL_DISEASE_CLOUD = 31607,
SPELL_KNOCKDOWN = 31610,
@@ -465,10 +464,7 @@ public:
}
if (!meteor)
{
- float x, y, z;
- me->GetPosition(x, y, z);
- Creature* trigger = me->SummonCreature(NPC_TRIGGER, x + 8, y + 8, z + 25 + rand32() % 10, me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 1000);
- if (trigger)
+ if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_TINY, me->GetPositionWithOffset({ 8.0f, 8.0f, frand(25.0f, 35.0f), 0.0f }), TEMPSUMMON_TIMED_DESPAWN, 1000))
{
trigger->SetVisible(false);
trigger->setFaction(me->getFaction());
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
index 18122ba2b0c..62f82ebcee1 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.h
@@ -21,8 +21,6 @@
#include "hyjal.h"
#include "ScriptedEscortAI.h"
-#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
-
struct hyjal_trashAI : public npc_escortAI
{
hyjal_trashAI(Creature* creature);
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
index 176c24f6707..99b8515c6e8 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
@@ -26,11 +26,7 @@ EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "ScriptedCreature.h"
-#include "hyjal_trash.h"
-#include "Player.h"
-#include "WorldPacket.h"
-#include "Chat.h"
-#include "WorldSession.h"
+#include "hyjal.h"
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
@@ -40,8 +36,16 @@ EndScriptData */
4 - Archimonde event
*/
-#define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."
-#define YELL_EFFORTS_NAME "Archimonde"
+enum Yells
+{
+ YELL_ARCHIMONDE_INTRO = 8
+};
+
+ObjectData const creatureData[] =
+{
+ { NPC_CHANNEL_TARGET, DATA_CHANNEL_TARGET },
+ { 0, 0 } // END
+};
class instance_hyjal : public InstanceMapScript
{
@@ -58,6 +62,7 @@ public:
instance_mount_hyjal_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
+ LoadObjectData(creatureData, nullptr);
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
RaidDamage = 0;
@@ -105,15 +110,35 @@ public:
{
switch (creature->GetEntry())
{
- case RAGE_WINTERCHILL: RageWinterchill = creature->GetGUID(); break;
- case ANETHERON: Anetheron = creature->GetGUID(); break;
- case KAZROGAL: Kazrogal = creature->GetGUID(); break;
- case AZGALOR: Azgalor = creature->GetGUID(); break;
- case ARCHIMONDE: Archimonde = creature->GetGUID(); break;
- case JAINA: JainaProudmoore = creature->GetGUID(); break;
- case THRALL: Thrall = creature->GetGUID(); break;
- case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break;
+ case RAGE_WINTERCHILL:
+ RageWinterchill = creature->GetGUID();
+ break;
+ case ANETHERON:
+ Anetheron = creature->GetGUID();
+ break;
+ case KAZROGAL:
+ Kazrogal = creature->GetGUID();
+ break;
+ case AZGALOR:
+ Azgalor = creature->GetGUID();
+ break;
+ case ARCHIMONDE:
+ Archimonde = creature->GetGUID();
+ if (GetData(DATA_AZGALOREVENT) != DONE)
+ creature->SetVisible(false);
+ break;
+ case JAINA:
+ JainaProudmoore = creature->GetGUID();
+ break;
+ case THRALL:
+ Thrall = creature->GetGUID();
+ break;
+ case TYRANDE:
+ TyrandeWhisperwind = creature->GetGUID();
+ break;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
ObjectGuid GetGuidData(uint32 identifier) const override
@@ -147,40 +172,18 @@ public:
m_auiEncounter[2] = data;
break;
case DATA_AZGALOREVENT:
+ m_auiEncounter[3] = data;
+ if (data == DONE)
{
- m_auiEncounter[3] = data;
- if (data == DONE)
+ instance->LoadGrid(5581.49f, -3445.63f);
+ if (Creature* archimonde = instance->GetCreature(Archimonde))
{
- if (ArchiYell)
- break;
+ archimonde->SetVisible(true);
- ArchiYell = true;
-
- Creature* creature = instance->GetCreature(Azgalor);
- if (creature)
+ if (!ArchiYell)
{
- Creature* unit = creature->SummonCreature(NPC_WORLD_TRIGGER_TINY, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
-
- Map* map = creature->GetMap();
- if (map->IsDungeon() && unit)
- {
- unit->SetVisible(false);
- Map::PlayerList const &PlayerList = map->GetPlayers();
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (Player* player = i->GetSource())
- {
- WorldPacket packet;
-
- ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, player, YELL_EFFORTS);
- player->SendDirectMessage(&packet);
- player->PlayDirectSound(10986, player);
- }
- }
- }
+ ArchiYell = true;
+ archimonde->AI()->Talk(YELL_ARCHIMONDE_INTRO);
}
}
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
index b84d24d66d3..794496382c2 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
@@ -292,6 +292,7 @@ public:
break;
}
player->CLOSE_GOSSIP_MENU();
+ ai->SetDespawnAtFar(false);
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
return true;
}
diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp
index 9b8b435e93c..386f80c0c64 100644
--- a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp
+++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp
@@ -484,7 +484,7 @@ class npc_egg_pile : public CreatureScript
private:
EventMap _events;
- uint32 _callHatchlingSpell;
+ uint32 _callHatchlingSpell = 0;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
index 84a267543c5..15fbef8a08b 100644
--- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
@@ -537,7 +537,7 @@ public:
/// TODO: Remove this once we find a general rule for WorldObject::MovePosition (this spell shouldn't take the Z change into consideration)
Unit* caster = GetCaster();
float angle = float(rand_norm()) * static_cast<float>(2 * M_PI);
- uint32 dist = caster->GetObjectSize() + GetSpellInfo()->Effects[effIndex].CalcRadius(GetCaster()) * (float)rand_norm();
+ uint32 dist = caster->GetObjectSize() + GetSpellInfo()->GetEffect(effIndex)->CalcRadius(GetCaster()) * (float)rand_norm();
float x = caster->GetPositionX() + dist * std::cos(angle);
float y = caster->GetPositionY() + dist * std::sin(angle);
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
index 47a40dd56ef..38b587eacf7 100644
--- a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
@@ -80,7 +80,17 @@ public:
struct boss_temple_guardian_anhuurAI : public BossAI
{
- boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, DATA_TEMPLE_GUARDIAN_ANHUUR) { }
+ boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, DATA_TEMPLE_GUARDIAN_ANHUUR)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ _phase = PHASE_FIRST_SHIELD;
+ _oldPhase = PHASE_FIRST_SHIELD;
+ _beacons = 0;
+ }
void CleanStalkers()
{
@@ -95,9 +105,7 @@ public:
void Reset() override
{
- _phase = PHASE_FIRST_SHIELD;
- _oldPhase = PHASE_FIRST_SHIELD;
- _beacons = 0;
+ Initialize();
_Reset();
CleanStalkers();
me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
@@ -378,7 +386,7 @@ public:
{
CustomSpellValues values;
values.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
- caster->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, values, GetTarget());
+ caster->CastCustomSpell(GetSpellInfo()->GetEffect(caster, EFFECT_0)->TriggerSpell, values, GetTarget());
}
}
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
index 4377344fb26..30a0e2441fb 100644
--- a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
@@ -65,6 +65,7 @@ class instance_halls_of_origination : public InstanceMapScript
{
case GO_ANHUURS_BRIDGE:
AnhuursBridgeGUID = go->GetGUID();
+ // no break
case GO_DOODAD_ULDUM_ELEVATOR_COL01:
case GO_VAULT_OF_LIGHTS_DOOR:
case GO_DOODAD_ULDUM_LIGHTMACHINE_01:
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
index 189cc842d9b..919f8b43ce3 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
@@ -106,7 +106,7 @@ public:
//THIS GOB IS A TRAP - What shall i do? =(
//Cast it spell? Copyed Heigan method
floorEruption->SendCustomAnim(floorEruption->GetGoAnimProgress());
- floorEruption->CastSpell(NULL, Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId
+ floorEruption->CastSpell(NULL, Difficulty(instance->GetSpawnMode()) == DIFFICULTY_10_N ? 17731 : 69294); //pFloorEruption->GetGOInfo()->trap.spellId
//Get all immediatly nearby floors
std::list<GameObject*> nearFloorList;
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index e0b03d54f69..533d78a68f5 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -518,7 +518,7 @@ class spell_ooze_zap : public SpellScriptLoader
SpellCastResult CheckRequirement()
{
- if (!GetCaster()->HasAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
+ if (!GetCaster()->HasAura(GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()))
return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW; // This is actually correct
if (!GetExplTargetUnit())
@@ -603,7 +603,7 @@ class spell_energize_aoe : public SpellScriptLoader
{
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
- if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)
+ if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()) == QUEST_STATUS_INCOMPLETE)
++itr;
else
targets.erase(itr++);
diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp
index e4d5925c950..9f02e14220e 100644
--- a/src/server/scripts/Kalimdor/zone_felwood.cpp
+++ b/src/server/scripts/Kalimdor/zone_felwood.cpp
@@ -51,7 +51,7 @@ public:
void Reset() override
{
- lasher_clicked = false;
+ lasherClicked = false;
}
void OnSpellClick(Unit* clicker, bool& result) override
@@ -74,7 +74,7 @@ public:
me->CastSpell(me, SPELL_STAND);
me->GetMotionMaster()->MoveRandom(8.0f);
events.ScheduleEvent(EVENT_CHECK_OOC, 20000);
- lasher_clicked = true;
+ lasherClicked = true;
if (Player* player = clicker->ToPlayer())
player->KilledMonsterCredit(NPC_WHISPERWIND_LASHER);
@@ -82,7 +82,7 @@ public:
void UpdateAI(uint32 diff) override
{
- if (!lasher_clicked)
+ if (!lasherClicked)
return;
events.Update(diff);
@@ -104,7 +104,7 @@ public:
private:
EventMap events;
- bool lasher_clicked;
+ bool lasherClicked = false;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
index 01baf54eef7..1cf0cc56242 100644
--- a/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_corborus.cpp
@@ -241,7 +241,7 @@ class boss_corborus : public CreatureScript
private:
EncounterState stateIntro;
- uint32 countTrashingCharge;
+ uint32 countTrashingCharge = 0;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp
index 0535ac64a9f..08d56f2fa50 100644
--- a/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp
+++ b/src/server/scripts/Maelstrom/Stonecore/boss_high_priestess_azil.cpp
@@ -132,13 +132,11 @@ class boss_high_priestess_azil : public CreatureScript
struct boss_high_priestess_azilAI : public BossAI
{
- boss_high_priestess_azilAI(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_AZIL), vehicle(creature->GetVehicleKit())
+ boss_high_priestess_azilAI(Creature* creature) : BossAI(creature, DATA_HIGH_PRIESTESS_AZIL)
{
- ASSERT(vehicle);
+ ASSERT(creature->GetVehicleKit());
}
- Vehicle* vehicle;
-
void Reset() override
{
_Reset();
@@ -276,7 +274,7 @@ class boss_high_priestess_azil : public CreatureScript
me->GetMotionMaster()->MovePoint(POINT_ABOVE_PLATFORM, AbovePlatformPos);
break;
case EVENT_EARTH_FURY_CHECK_SEAT0:
- if (!vehicle->GetPassenger(0))
+ if (!me->GetVehicleKit()->GetPassenger(0))
DoCast(SPELL_SEISMIC_SHARD_PREPARE);
events.ScheduleEvent(EVENT_EARTH_FURY_LAUNCH_SHARD, 1800);
break;
@@ -318,7 +316,7 @@ class boss_high_priestess_azil : public CreatureScript
}
private:
- uint8 countSeismicShard;
+ uint8 countSeismicShard = 3;
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
index dc2fdb62d19..abfb82284d3 100644
--- a/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
+++ b/src/server/scripts/Maelstrom/Stonecore/stonecore.cpp
@@ -213,7 +213,7 @@ class npc_sc_millhouse_manastorm : public CreatureScript
events.Update(diff);
// Impending Doom is exception because it needs to be interrupted.
- if (me->HasUnitState(UNIT_STATE_CASTING) && !me->GetCurrentSpell(SPELL_IMPENDING_DOOM))
+ if (me->HasUnitState(UNIT_STATE_CASTING) && me->GetCurrentSpell(CURRENT_GENERIC_SPELL)->GetSpellInfo()->Id != SPELL_IMPENDING_DOOM_CHANNEL)
return;
while (uint32 eventId = events.ExecuteEvent())
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp
index 592d69c5c76..5b88cfb332b 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp
@@ -142,7 +142,7 @@ public:
// clone
player->CastSpell(summon, SPELL_CLONE_PLAYER, true);
// phase the summon
- summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true);
+ summon->SetInPhase(spellInfo->GetEffect(EFFECT_0)->MiscValueB, true, true);
}
}
++insanityHandled;
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
index c826b8fc9ef..f1d029e53e2 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp
@@ -151,7 +151,7 @@ class boss_baltharus_the_warborn : public CreatureScript
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_10_N)
{
if (me->HealthBelowPctDamaged(50, damage) && _cloneCount == 1)
DoAction(ACTION_CLONE);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index ee77671d83e..16cbcee562e 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -1499,8 +1499,8 @@ class spell_halion_damage_aoe_summon : public SpellScriptLoader
{
PreventHitDefaultEffect(effIndex);
Unit* caster = GetCaster();
- uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
- SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetSpellInfo()->Effects[effIndex].MiscValueB));
+ uint32 entry = uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValue);
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValueB));
uint32 duration = uint32(GetSpellInfo()->GetDuration());
Position pos = caster->GetPosition();
@@ -1607,8 +1607,8 @@ class spell_halion_clear_debuffs : public SpellScriptLoader
void HandleScript(SpellEffIndex effIndex)
{
- if (GetHitUnit()->HasAura(GetSpellInfo()->Effects[effIndex].CalcValue()))
- GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->Effects[effIndex].CalcValue());
+ if (GetHitUnit()->HasAura(GetSpellInfo()->GetEffect(effIndex)->CalcValue()))
+ GetHitUnit()->RemoveAurasDueToSpell(GetSpellInfo()->GetEffect(effIndex)->CalcValue());
}
void Register() override
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index 69dc25892c1..aa80295d83c 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -837,10 +837,9 @@ class spell_impale : public SpellScriptLoader
void HandleDamageCalc(SpellEffIndex /*effIndex*/)
{
Unit* target = GetHitUnit();
- uint32 permafrost = sSpellMgr->GetSpellIdForDifficulty(SPELL_PERMAFROST, target);
// make sure Impale doesnt do damage if we are standing on permafrost
- if (target && target->HasAura(permafrost))
+ if (target && target->HasAura(SPELL_PERMAFROST))
SetHitDamage(0);
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
index 2b541e4b972..b79e093a3e0 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
@@ -384,7 +384,7 @@ class boss_toc_champion_controller : public CreatureScript
vOtherEntries.push_back(playerTeam == ALLIANCE ? NPC_HORDE_WARRIOR : NPC_ALLIANCE_WARRIOR);
uint8 healersSubtracted = 2;
- if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
+ if (_instance->instance->GetSpawnMode() == DIFFICULTY_25_N || _instance->instance->GetSpawnMode() == DIFFICULTY_25_HC)
healersSubtracted = 1;
for (uint8 i = 0; i < healersSubtracted; ++i)
{
@@ -421,7 +421,7 @@ class boss_toc_champion_controller : public CreatureScript
vHealersEntries.erase(vHealersEntries.begin() + pos);
}
- if (_instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_NORMAL || _instance->instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
+ if (_instance->instance->GetSpawnMode() == DIFFICULTY_10_N || _instance->instance->GetSpawnMode() == DIFFICULTY_10_HC)
for (uint8 i = 0; i < 4; ++i)
vOtherEntries.erase(vOtherEntries.begin() + urand(0, vOtherEntries.size() - 1));
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
index 7e8653c4a55..25dc59acc34 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_lord_jaraxxus.cpp
@@ -494,7 +494,7 @@ class spell_mistress_kiss : public SpellScriptLoader
bool Load() override
{
if (GetCaster())
- if (sSpellMgr->GetSpellIdForDifficulty(SPELL_MISTRESS_KISS_DAMAGE_SILENCE, GetCaster()))
+ if (sSpellMgr->GetSpellInfo(SPELL_MISTRESS_KISS_DAMAGE_SILENCE))
return true;
return false;
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
index dec2f44745d..07eec388ca2 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp
@@ -706,11 +706,11 @@ class spell_powering_up : public SpellScriptLoader
bool Load() override
{
- spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster());
+ spellId = SPELL_SURGE_OF_SPEED;
if (!sSpellMgr->GetSpellInfo(spellId))
return false;
- poweringUp = sSpellMgr->GetSpellIdForDifficulty(SPELL_POWERING_UP, GetCaster());
+ poweringUp = SPELL_POWERING_UP;
if (!sSpellMgr->GetSpellInfo(poweringUp))
return false;
@@ -769,7 +769,7 @@ class spell_valkyr_essences : public SpellScriptLoader
bool Load() override
{
- spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_SURGE_OF_SPEED, GetCaster());
+ spellId = SPELL_SURGE_OF_SPEED;
if (!sSpellMgr->GetSpellInfo(spellId))
return false;
return true;
@@ -781,57 +781,54 @@ class spell_valkyr_essences : public SpellScriptLoader
{
if (dmgInfo.GetSpellInfo())
{
- if (uint32 poweringUp = sSpellMgr->GetSpellIdForDifficulty(SPELL_POWERING_UP, owner))
- {
- if (urand(0, 99) < 5)
- GetTarget()->CastSpell(GetTarget(), spellId, true);
+ if (urand(0, 99) < 5)
+ GetTarget()->CastSpell(GetTarget(), spellId, true);
- // Twin Vortex part
- uint32 lightVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHT_VORTEX_DAMAGE, owner);
- uint32 darkVortex = sSpellMgr->GetSpellIdForDifficulty(SPELL_DARK_VORTEX_DAMAGE, owner);
- int32 stacksCount = dmgInfo.GetSpellInfo()->Effects[EFFECT_0].CalcValue() / 1000 - 1;
+ // Twin Vortex part
+ uint32 lightVortex = SPELL_LIGHT_VORTEX_DAMAGE;
+ uint32 darkVortex = SPELL_DARK_VORTEX_DAMAGE;
+ int32 stacksCount = dmgInfo.GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue() / 1000 - 1;
- if (lightVortex && darkVortex && stacksCount)
+ if (lightVortex && darkVortex && stacksCount)
+ {
+ if (dmgInfo.GetSpellInfo()->Id == darkVortex || dmgInfo.GetSpellInfo()->Id == lightVortex)
{
- if (dmgInfo.GetSpellInfo()->Id == darkVortex || dmgInfo.GetSpellInfo()->Id == lightVortex)
+ Aura* pAura = owner->GetAura(SPELL_POWERING_UP);
+ if (pAura)
+ {
+ pAura->ModStackAmount(stacksCount);
+ owner->CastSpell(owner, SPELL_POWERING_UP, true);
+ }
+ else
{
- Aura* pAura = owner->GetAura(poweringUp);
- if (pAura)
- {
- pAura->ModStackAmount(stacksCount);
- owner->CastSpell(owner, poweringUp, true);
- }
- else
- {
- owner->CastSpell(owner, poweringUp, true);
- if (Aura* pTemp = owner->GetAura(poweringUp))
- pTemp->ModStackAmount(stacksCount);
- }
+ owner->CastSpell(owner, SPELL_POWERING_UP, true);
+ if (Aura* pTemp = owner->GetAura(SPELL_POWERING_UP))
+ pTemp->ModStackAmount(stacksCount);
}
}
+ }
- // Picking floating balls
- uint32 unleashedDark = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNLEASHED_DARK, owner);
- uint32 unleashedLight = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNLEASHED_LIGHT, owner);
+ // Picking floating balls
+ uint32 unleashedDark = SPELL_UNLEASHED_DARK;
+ uint32 unleashedLight = SPELL_UNLEASHED_LIGHT;
- if (unleashedDark && unleashedLight)
+ if (unleashedDark && unleashedLight)
+ {
+ if (dmgInfo.GetSpellInfo()->Id == unleashedDark || dmgInfo.GetSpellInfo()->Id == unleashedLight)
{
- if (dmgInfo.GetSpellInfo()->Id == unleashedDark || dmgInfo.GetSpellInfo()->Id == unleashedLight)
+ // need to do the things in this order, else players might have 100 charges of Powering Up without anything happening
+ Aura* pAura = owner->GetAura(SPELL_POWERING_UP);
+ if (pAura)
+ {
+ // 2 lines together add the correct amount of buff stacks
+ pAura->ModStackAmount(stacksCount);
+ owner->CastSpell(owner, SPELL_POWERING_UP, true);
+ }
+ else
{
- // need to do the things in this order, else players might have 100 charges of Powering Up without anything happening
- Aura* pAura = owner->GetAura(poweringUp);
- if (pAura)
- {
- // 2 lines together add the correct amount of buff stacks
- pAura->ModStackAmount(stacksCount);
- owner->CastSpell(owner, poweringUp, true);
- }
- else
- {
- owner->CastSpell(owner, poweringUp, true);
- if (Aura* pTemp = owner->GetAura(poweringUp))
- pTemp->ModStackAmount(stacksCount);
- }
+ owner->CastSpell(owner, SPELL_POWERING_UP, true);
+ if (Aura* pTemp = owner->GetAura(SPELL_POWERING_UP))
+ pTemp->ModStackAmount(stacksCount);
}
}
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
index cb7e58cfe16..91da9ebd9be 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/instance_trial_of_the_crusader.cpp
@@ -274,7 +274,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
{
EventStage = 6000;
uint32 tributeChest = 0;
- if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
+ if (instance->GetSpawnMode() == DIFFICULTY_10_HC)
{
if (TrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_10H_99;
@@ -291,7 +291,7 @@ class instance_trial_of_the_crusader : public InstanceMapScript
}
}
}
- else if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
+ else if (instance->GetSpawnMode() == DIFFICULTY_25_HC)
{
if (TrialCounter >= 50)
tributeChest = GO_TRIBUTE_CHEST_25H_99;
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp
index b91ca893955..f24ca7dd583 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp
@@ -309,7 +309,7 @@ class spell_trollgore_invader_taunt : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
+ if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->CalcValue()))
return false;
return true;
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
index a014be4369e..ebad98de91a 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/boss_falric.cpp
@@ -89,7 +89,7 @@ class boss_falric : public CreatureScript
|| (_hopelessnessCount < 3 && me->HealthBelowPctDamaged(10, damage)))
{
if (_hopelessnessCount)
- me->RemoveOwnedAura(sSpellMgr->GetSpellIdForDifficulty(HopelessnessHelper[_hopelessnessCount - 1], me));
+ me->RemoveOwnedAura(HopelessnessHelper[_hopelessnessCount - 1]);
DoCast(me, HopelessnessHelper[_hopelessnessCount]);
++_hopelessnessCount;
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
index eeb05f44a71..c99ebddae37 100644
--- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp
@@ -2390,7 +2390,7 @@ class spell_hor_evasion : public SpellScriptLoader
return;
float angle = pos.GetAngle(&home);
- float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ float dist = GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(GetCaster());
target->MovePosition(pos, dist, angle);
dest.Relocate(pos);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index 6053ff295a9..d289d494d62 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -553,8 +553,7 @@ class spell_blood_queen_vampiric_bite : public SpellScriptLoader
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(SPELL_FRENZIED_BLOODTHIRST, GetCaster());
- GetCaster()->RemoveAura(spellId, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
+ GetCaster()->RemoveAura(SPELL_FRENZIED_BLOODTHIRST, ObjectGuid::Empty, 0, AURA_REMOVE_BY_ENEMY_SPELL);
GetCaster()->CastSpell(GetCaster(), SPELL_ESSENCE_OF_THE_BLOOD_QUEEN_PLR, TRIGGERED_FULL_MASK);
// Shadowmourne questline
@@ -807,7 +806,7 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg : public SpellScriptLoader
void PeriodicTick(AuraEffect const* aurEff)
{
SpellInfo const* damageSpell = sSpellMgr->EnsureSpellInfo(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE);
- int32 damage = damageSpell->Effects[EFFECT_0].CalcValue();
+ int32 damage = damageSpell->GetEffect(EFFECT_0)->CalcValue();
float multiplier = 0.3375f + 0.1f * uint32(aurEff->GetTickNumber()/10); // do not convert to 0.01f - we need tick number/10 as INT (damage increases every 10 ticks)
damage = int32(damage * multiplier);
GetTarget()->CastCustomSpell(SPELL_PACT_OF_THE_DARKFALLEN_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
index b1f6a4a5e83..008a89030a7 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_festergut.cpp
@@ -377,11 +377,7 @@ class spell_festergut_pungent_blight : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
- // Get Inhaled Blight id for our difficulty
- uint32 blightId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), GetCaster());
-
- // ...and remove it
- GetCaster()->RemoveAurasDueToSpell(blightId);
+ GetCaster()->RemoveAurasDueToSpell(uint32(GetEffectValue()));
GetCaster()->ToCreature()->AI()->Talk(EMOTE_PUNGENT_BLIGHT);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
index 416c27b7353..080880608d6 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_icecrown_gunship_battle.cpp
@@ -1847,7 +1847,7 @@ class spell_igb_rocket_pack : public SpellScriptLoader
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
SpellInfo const* damageInfo = sSpellMgr->EnsureSpellInfo(SPELL_ROCKET_PACK_DAMAGE);
- GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->Effects[EFFECT_0].CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod()), NULL, TRIGGERED_FULL_MASK);
+ GetTarget()->CastCustomSpell(SPELL_ROCKET_PACK_DAMAGE, SPELLVALUE_BASE_POINT0, 2 * (damageInfo->GetEffect(EFFECT_0)->CalcValue() + aurEff->GetTickNumber() * aurEff->GetPeriod()), NULL, TRIGGERED_FULL_MASK);
GetTarget()->CastSpell(NULL, SPELL_ROCKET_BURST, TRIGGERED_FULL_MASK);
}
@@ -1977,7 +1977,7 @@ class spell_igb_periodic_trigger_with_power_cost : public SpellScriptLoader
void HandlePeriodicTick(AuraEffect const* /*aurEff*/)
{
PreventDefaultAction();
- GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST));
+ GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->GetEffect(EFFECT_0)->TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST));
}
void Register() override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index 3e78865c924..834b0aeb5e1 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -288,7 +288,7 @@ class boss_lady_deathwhisper : public CreatureScript
events.ScheduleEvent(EVENT_P1_SUMMON_WAVE, 5000, 0, PHASE_ONE);
events.ScheduleEvent(EVENT_P1_SHADOW_BOLT, urand(5500, 6000), 0, PHASE_ONE);
events.ScheduleEvent(EVENT_P1_EMPOWER_CULTIST, urand(20000, 30000), 0, PHASE_ONE);
- if (GetDifficulty() != RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() != DIFFICULTY_10_N)
events.ScheduleEvent(EVENT_DOMINATE_MIND_H, 27000);
Talk(SAY_AGGRO);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 2e360e19b75..3a66d3e1363 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -576,7 +576,7 @@ class spell_marrowgar_coldflame_damage : public SpellScriptLoader
if (target->HasAura(SPELL_IMPALED))
return false;
- if (target->GetExactDist2d(GetOwner()) > GetSpellInfo()->Effects[EFFECT_0].CalcRadius())
+ if (target->GetExactDist2d(GetOwner()) > GetSpellInfo()->GetEffect(target, EFFECT_0)->CalcRadius())
return false;
if (Aura* aur = target->GetAura(GetId()))
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 8f5ca0b4322..d0bf573ba19 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -395,14 +395,14 @@ class boss_professor_putricide : public CreatureScript
{
SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_CREATE_CONCOCTION);
DoCast(me, SPELL_CREATE_CONCOCTION);
- events.ScheduleEvent(EVENT_PHASE_TRANSITION, sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime() + 100);
+ events.ScheduleEvent(EVENT_PHASE_TRANSITION, spell->CalcCastTime() + 100);
break;
}
case PHASE_COMBAT_3:
{
SpellInfo const* spell = sSpellMgr->GetSpellInfo(SPELL_GUZZLE_POTIONS);
DoCast(me, SPELL_GUZZLE_POTIONS);
- events.ScheduleEvent(EVENT_PHASE_TRANSITION, sSpellMgr->GetSpellForDifficultyFromSpell(spell, me)->CalcCastTime() + 100);
+ events.ScheduleEvent(EVENT_PHASE_TRANSITION, spell->CalcCastTime() + 100);
break;
}
default:
@@ -725,7 +725,7 @@ class npc_putricide_oozeAI : public ScriptedAI
void SpellHitTarget(Unit* /*target*/, SpellInfo const* spell) override
{
- if (!_newTargetSelectTimer && spell->Id == sSpellMgr->GetSpellIdForDifficulty(_hitTargetSpellId, me))
+ if (!_newTargetSelectTimer && spell->Id == _hitTargetSpellId)
_newTargetSelectTimer = 1000;
}
@@ -1031,7 +1031,7 @@ class spell_putricide_unstable_experiment : public SpellScriptLoader
break;
}
- GetCaster()->CastSpell(target, uint32(GetSpellInfo()->Effects[stage].CalcValue()), true, NULL, NULL, GetCaster()->GetGUID());
+ GetCaster()->CastSpell(target, uint32(GetSpellInfo()->GetEffect(stage)->CalcValue()), true, NULL, NULL, GetCaster()->GetGUID());
}
void Register() override
@@ -1057,11 +1057,10 @@ class spell_putricide_ooze_eruption_searcher : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- uint32 adhesiveId = sSpellMgr->GetSpellIdForDifficulty(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster());
- if (GetHitUnit()->HasAura(adhesiveId))
+ if (GetHitUnit()->HasAura(SPELL_VOLATILE_OOZE_ADHESIVE))
{
GetCaster()->CastSpell(GetHitUnit(), SPELL_OOZE_ERUPTION, true);
- GetHitUnit()->RemoveAurasDueToSpell(adhesiveId, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL);
+ GetHitUnit()->RemoveAurasDueToSpell(SPELL_VOLATILE_OOZE_ADHESIVE, GetCaster()->GetGUID(), 0, AURA_REMOVE_BY_ENEMY_SPELL);
}
}
@@ -1089,12 +1088,12 @@ class spell_putricide_choking_gas_bomb : public SpellScriptLoader
void HandleScript(SpellEffIndex /*effIndex*/)
{
uint32 skipIndex = urand(0, 2);
- for (uint32 i = 0; i < 3; ++i)
+ for (SpellEffectInfo const* effect : GetSpellInfo()->GetEffectsForDifficulty(GetCaster()->GetMap()->GetDifficulty()))
{
- if (i == skipIndex)
+ if (!effect || effect->EffectIndex == skipIndex)
continue;
- uint32 spellId = uint32(GetSpellInfo()->Effects[i].CalcValue());
+ uint32 spellId = uint32(effect->CalcValue());
GetCaster()->CastSpell(GetCaster(), spellId, true, NULL, NULL, GetCaster()->GetGUID());
}
}
@@ -1141,7 +1140,7 @@ class spell_putricide_unbound_plague : public SpellScriptLoader
}
- targets.remove_if(Trinity::UnitAuraCheck(true, sSpellMgr->GetSpellIdForDifficulty(SPELL_UNBOUND_PLAGUE, GetCaster())));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_UNBOUND_PLAGUE));
Trinity::Containers::RandomResizeList(targets, 1);
}
@@ -1154,15 +1153,13 @@ class spell_putricide_unbound_plague : public SpellScriptLoader
if (!instance)
return;
- uint32 plagueId = sSpellMgr->GetSpellIdForDifficulty(SPELL_UNBOUND_PLAGUE, GetCaster());
-
- if (!GetHitUnit()->HasAura(plagueId))
+ if (!GetHitUnit()->HasAura(SPELL_UNBOUND_PLAGUE))
{
if (Creature* professor = ObjectAccessor::GetCreature(*GetCaster(), instance->GetGuidData(DATA_PROFESSOR_PUTRICIDE)))
{
- if (Aura* oldPlague = GetCaster()->GetAura(plagueId, professor->GetGUID()))
+ if (Aura* oldPlague = GetCaster()->GetAura(SPELL_UNBOUND_PLAGUE, professor->GetGUID()))
{
- if (Aura* newPlague = professor->AddAura(plagueId, GetHitUnit()))
+ if (Aura* newPlague = professor->AddAura(SPELL_UNBOUND_PLAGUE, GetHitUnit()))
{
newPlague->SetMaxDuration(oldPlague->GetMaxDuration());
newPlague->SetDuration(oldPlague->GetDuration());
@@ -1258,11 +1255,10 @@ class spell_putricide_mutated_plague : public SpellScriptLoader
if (!caster)
return;
- uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
+ uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell;
SpellInfo const* spell = sSpellMgr->GetSpellInfo(triggerSpell);
- spell = sSpellMgr->GetSpellForDifficultyFromSpell(spell, caster);
- int32 damage = spell->Effects[EFFECT_0].CalcValue(caster);
+ int32 damage = spell->GetEffect(EFFECT_0)->CalcValue(caster);
float multiplier = 2.0f;
if (GetTarget()->GetMap()->GetSpawnMode() & 1)
multiplier = 3.0f;
@@ -1275,13 +1271,13 @@ class spell_putricide_mutated_plague : public SpellScriptLoader
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- uint32 healSpell = uint32(GetSpellInfo()->Effects[EFFECT_0].CalcValue());
+ uint32 healSpell = uint32(GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue());
SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(healSpell);
if (!healSpellInfo)
return;
- int32 heal = healSpellInfo->Effects[0].CalcValue() * GetStackAmount();
+ int32 heal = healSpellInfo->GetEffect(EFFECT_0)->CalcValue() * GetStackAmount();
GetTarget()->CastCustomSpell(healSpell, SPELLVALUE_BASE_POINT0, heal, GetTarget(), true, NULL, NULL, GetCasterGUID());
}
@@ -1445,8 +1441,8 @@ class spell_putricide_mutated_transformation : public SpellScriptLoader
return;
}
- uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
- SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetSpellInfo()->Effects[effIndex].MiscValueB));
+ uint32 entry = uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValue);
+ SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValueB));
uint32 duration = uint32(GetSpellInfo()->GetDuration());
Position pos = caster->GetPosition();
@@ -1543,8 +1539,7 @@ class spell_putricide_clear_aura_effect_value : public SpellScriptLoader
void HandleScript(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
- uint32 auraId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), GetCaster());
- GetHitUnit()->RemoveAurasDueToSpell(auraId);
+ GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue());
}
void Register() override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index d5c07fb6942..ee948789bc4 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -745,7 +745,7 @@ class spell_rotface_unstable_ooze_explosion : public SpellScriptLoader
if (!GetExplTargetDest())
return;
- uint32 triggered_spell_id = GetSpellInfo()->Effects[effIndex].TriggerSpell;
+ uint32 triggered_spell_id = GetSpellInfo()->GetEffect(effIndex)->TriggerSpell;
float x, y, z;
GetExplTargetDest()->GetPosition(x, y, z);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 8e659a746ed..ab19ffe7fed 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -409,10 +409,9 @@ class boss_sindragosa : public CreatureScript
void SpellHitTarget(Unit* target, SpellInfo const* spell) override
{
- if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(70127, me))
- if (spellId == spell->Id)
- if (Aura const* mysticBuffet = target->GetAura(spell->Id))
- _mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount());
+ if (spell->Id == 70127)
+ if (Aura const* mysticBuffet = target->GetAura(spell->Id))
+ _mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount());
}
@@ -1546,7 +1545,7 @@ class spell_frostwarden_handler_focus_fire : public SpellScriptLoader
PreventDefaultAction();
if (Unit* caster = GetCaster())
{
- caster->AddThreat(GetTarget(), -float(GetSpellInfo()->Effects[EFFECT_1].CalcValue()));
+ caster->AddThreat(GetTarget(), -float(GetSpellInfo()->GetEffect(caster, EFFECT_1)->CalcValue()));
caster->GetAI()->SetData(DATA_WHELP_MARKER, 0);
}
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 03c26ba2e09..caba9ff5262 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -2437,7 +2437,7 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader
dest->RelocateOffset(offset);
GetHitDest()->RelocateOffset(offset);
// spirit bombs get higher
- if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB)
+ if (GetSpellInfo()->GetEffect(effIndex)->MiscValue == NPC_SPIRIT_BOMB)
{
dest->RelocateOffset(offset);
GetHitDest()->RelocateOffset(offset);
@@ -2641,7 +2641,7 @@ class spell_the_lich_king_vile_spirits : public SpellScriptLoader
void OnPeriodic(AuraEffect const* aurEff)
{
if (_is25Man || ((aurEff->GetTickNumber() - 1) % 5))
- GetTarget()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, NULL, aurEff, GetCasterGUID());
+ GetTarget()->CastSpell((Unit*)NULL, aurEff->GetSpellEffectInfo()->TriggerSpell, true, NULL, aurEff, GetCasterGUID());
}
void Register() override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index 49e24f54b02..eebf5a2c2ea 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -1227,7 +1227,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
if (!GetHitUnit())
return;
- GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING));
+ GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->GetEffect(effIndex)->TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING));
}
void Register() override
@@ -1306,7 +1306,7 @@ class spell_dreamwalker_summon_suppresser_effect : public SpellScriptLoader
if (!GetHitUnit())
return;
- GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING));
+ GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->GetEffect(effIndex)->TriggerSpell, true, NULL, NULL, GetCaster()->GetInstanceScript()->GetGuidData(DATA_VALITHRIA_LICH_KING));
}
void Register() override
@@ -1442,7 +1442,7 @@ class spell_dreamwalker_twisted_nightmares : public SpellScriptLoader
// return;
if (InstanceScript* instance = GetHitUnit()->GetInstanceScript())
- GetHitUnit()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[effIndex].TriggerSpell, true, NULL, NULL, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER));
+ GetHitUnit()->CastSpell((Unit*)NULL, GetSpellInfo()->GetEffect(effIndex)->TriggerSpell, true, NULL, NULL, instance->GetGuidData(DATA_VALITHRIA_DREAMWALKER));
}
void Register() override
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index abe178a874d..ab7606f5e6f 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1799,7 +1799,7 @@ class spell_icc_sprit_alarm : public SpellScriptLoader
{
PreventHitDefaultEffect(effIndex);
uint32 trapId = 0;
- switch (GetSpellInfo()->Effects[effIndex].MiscValue)
+ switch (GetSpellInfo()->GetEffect(effIndex)->MiscValue)
{
case EVENT_AWAKEN_WARD_1:
trapId = GO_SPIRIT_ALARM_1;
@@ -1838,7 +1838,7 @@ class spell_icc_sprit_alarm : public SpellScriptLoader
void Register() override
{
- OnEffectHit += SpellEffectFn(spell_icc_sprit_alarm_SpellScript::HandleEvent, EFFECT_2, SPELL_EFFECT_SEND_EVENT);
+ OnEffectHit += SpellEffectFn(spell_icc_sprit_alarm_SpellScript::HandleEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
}
};
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
index 35402771494..90b252a47ce 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
@@ -80,7 +80,7 @@ public:
Initialize();
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_25_N)
{
Position pos;
@@ -121,7 +121,7 @@ public:
events.ScheduleEvent(EVENT_LOCUST, 90000);
events.ScheduleEvent(EVENT_BERSERK, 600000);
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_10_N)
events.ScheduleEvent(EVENT_SPAWN_GUARDIAN_NORMAL, urand(15000, 20000));
}
@@ -160,7 +160,7 @@ public:
case EVENT_IMPALE:
//Cast Impale on a random target
//Do NOT cast it when we are afflicted by locust swarm
- if (!me->HasAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_LOCUST_SWARM, me)))
+ if (!me->HasAura(SPELL_LOCUST_SWARM))
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_IMPALE);
events.ScheduleEvent(EVENT_IMPALE, urand(10000, 20000));
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
index dcb004cc3a0..568df379f15 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
@@ -192,7 +192,7 @@ class npc_faerlina_add : public CreatureScript
void Reset() override
{
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) {
+ if (GetDifficulty() == DIFFICULTY_10_N) {
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_BIND, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true);
}
@@ -200,7 +200,7 @@ class npc_faerlina_add : public CreatureScript
void JustDied(Unit* /*killer*/) override
{
- if (_instance && GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (_instance && GetDifficulty() == DIFFICULTY_10_N)
if (Creature* faerlina = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FAERLINA)))
DoCast(faerlina, SPELL_WIDOWS_EMBRACE);
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index 39381f38d67..a70d354b966 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -259,7 +259,7 @@ class boss_gothik : public CreatureScript
void DoGothikSummon(uint32 entry)
{
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_25_N)
{
switch (entry)
{
@@ -421,9 +421,9 @@ class boss_gothik : public CreatureScript
case EVENT_SUMMON:
if (waves[waveCount].entry)
{
- if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
+ if ((waves[waveCount].mode == 2) && (GetDifficulty() == DIFFICULTY_25_N))
DoGothikSummon(waves[waveCount].entry);
- else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
+ else if ((waves[waveCount].mode == 0) && (GetDifficulty() == DIFFICULTY_10_N))
DoGothikSummon(waves[waveCount].entry);
else if (waves[waveCount].mode == 1)
DoGothikSummon(waves[waveCount].entry);
@@ -443,9 +443,9 @@ class boss_gothik : public CreatureScript
if (waves[waveCount].mode == 1)
events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
- else if ((waves[waveCount].mode == 2) && (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL))
+ else if ((waves[waveCount].mode == 2) && (GetDifficulty() == DIFFICULTY_25_N))
events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
- else if ((waves[waveCount].mode == 0) && (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL))
+ else if ((waves[waveCount].mode == 0) && (GetDifficulty() == DIFFICULTY_10_N))
events.ScheduleEvent(EVENT_SUMMON, waves[waveCount].time);
else
events.ScheduleEvent(EVENT_SUMMON, 0);
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
index 929c52a986c..ba54b5150e4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_grobbulus.cpp
@@ -194,7 +194,7 @@ class spell_grobbulus_poison_cloud : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell))
+ if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->TriggerSpell))
return false;
return true;
}
@@ -203,7 +203,7 @@ class spell_grobbulus_poison_cloud : public SpellScriptLoader
{
PreventDefaultAction();
- uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
+ uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell;
int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3);
GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_RADIUS_MOD, mod, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 87466b6bf41..8c927dcb0ac 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -30,26 +30,23 @@ EndScriptData */
#include "naxxramas.h"
#include "Player.h"
-enum Yells
+enum Texts
{
- //when shappiron dies. dialog between kel and lich king (in this order)
- SAY_SAPP_DIALOG1 = 0, //not used
- SAY_SAPP_DIALOG2_LICH = 1, //not used
- SAY_SAPP_DIALOG3 = 2, //not used
- SAY_SAPP_DIALOG4_LICH = 3, //not used
- SAY_SAPP_DIALOG5 = 4, //not used
- SAY_CAT_DIED = 5, //when cat dies, not used
- //when each of the 4 wing bosses dies
- SAY_TAUNT = 6,
SAY_AGGRO = 7,
SAY_SLAY = 8,
SAY_DEATH = 9,
SAY_CHAIN = 10,
SAY_FROST_BLAST = 11,
SAY_REQUEST_AID = 12, //start of phase 3
- SAY_ANSWER_REQUEST = 13, //lich king answer
+ EMOTE_PHASE_TWO = 13,
SAY_SUMMON_MINIONS = 14, //start of phase 1
- SAY_SPECIAL = 15
+ SAY_SPECIAL = 15,
+
+ // The Lich King
+ SAY_ANSWER_REQUEST = 3,
+
+ // Old World Trigger
+ SAY_GUARDIAN_SPAWNED = 0
};
enum Events
@@ -70,7 +67,10 @@ enum Events
EVENT_TRIGGER,
EVENT_PHASE,
- EVENT_MORTAL_WOUND
+ EVENT_MORTAL_WOUND,
+
+ EVENT_ANSWER_REQUEST,
+ EVENT_SUMMON_GUARDIANS
};
enum Spells
@@ -123,6 +123,13 @@ enum Spells
SPELL_MORTAL_WOUND = 28467
};
+enum Phases
+{
+ PHASE_ONE = 1, // Players move in the circle and Kel'Thuzad spawns his minions.
+ PHASE_TWO = 2, // Starts on a timer.
+ PHASE_THREE = 3 // At 45% health.
+};
+
enum Creatures
{
NPC_WASTE = 16427, // Soldiers of the Frozen Wastes
@@ -270,15 +277,11 @@ public:
void Initialize()
{
nGuardiansOfIcecrownCount = 0;
- uiGuardiansOfIcecrownTimer = 5000; // 5 seconds for summoning each Guardian of Icecrown in phase 3
- Phase = 0;
nAbomination = 0;
nWeaver = 0;
}
- uint32 Phase;
- uint32 uiGuardiansOfIcecrownTimer;
uint32 uiFaction;
uint8 nGuardiansOfIcecrownCount;
@@ -345,7 +348,6 @@ public:
void EnterCombat(Unit* /*who*/) override
{
me->setFaction(uiFaction);
-
_EnterCombat();
for (uint8 i = 0; i <= 3; ++i)
{
@@ -354,10 +356,10 @@ public:
}
DoCast(me, SPELL_KELTHUZAD_CHANNEL, false);
Talk(SAY_SUMMON_MINIONS);
- Phase = 1;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->SetFloatValue(UNIT_FIELD_COMBATREACH, 4);
me->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, 4);
+ events.SetPhase(PHASE_ONE);
events.ScheduleEvent(EVENT_TRIGGER, 5000);
events.ScheduleEvent(EVENT_WASTE, 15000);
events.ScheduleEvent(EVENT_ABOMIN, 30000);
@@ -365,6 +367,23 @@ public:
events.ScheduleEvent(EVENT_PHASE, 228000);
}
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (events.IsInPhase(PHASE_TWO) && me->HealthBelowPctDamaged(45, damage))
+ {
+ Talk(SAY_REQUEST_AID);
+ events.SetPhase(PHASE_THREE);
+ events.ScheduleEvent(EVENT_ANSWER_REQUEST, 4000);
+
+ for (uint8 i = 0; i <= 3; ++i)
+ {
+ if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
+ if (portal->getLootState() == GO_READY)
+ portal->UseDoorOrButton();
+ }
+ }
+ }
+
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -372,7 +391,7 @@ public:
events.Update(diff);
- if (Phase == 1)
+ if (events.IsInPhase(PHASE_ONE))
{
while (uint32 eventId = events.ExecuteEvent())
{
@@ -405,6 +424,7 @@ public:
case EVENT_PHASE:
events.Reset();
Talk(SAY_AGGRO);
+ Talk(EMOTE_PHASE_TWO);
spawns.DespawnAll();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_SELECTABLE);
me->CastStop();
@@ -415,9 +435,9 @@ public:
events.ScheduleEvent(EVENT_DETONATE, urand(30000, 40000));
events.ScheduleEvent(EVENT_FISSURE, urand(10000, 30000));
events.ScheduleEvent(EVENT_BLAST, urand(60000, 120000));
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_CHAIN, urand(30000, 60000));
- Phase = 2;
+ events.SetPhase(PHASE_TWO);
break;
default:
break;
@@ -426,38 +446,6 @@ public:
}
else
{
- //start phase 3 when we are 45% health
- if (Phase != 3)
- {
- if (HealthBelowPct(45))
- {
- Phase = 3;
- Talk(SAY_REQUEST_AID);
- //here Lich King should respond to KelThuzad but I don't know which Creature to make talk
- //so for now just make Kelthuzad says it.
- Talk(SAY_ANSWER_REQUEST);
-
- for (uint8 i = 0; i <= 3; ++i)
- {
- if (GameObject* portal = ObjectAccessor::GetGameObject(*me, instance->GetGuidData(DATA_KELTHUZAD_PORTAL01 + i)))
- if (portal->getLootState() == GO_READY)
- portal->UseDoorOrButton();
- }
- }
- }
- else if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
- {
- if (uiGuardiansOfIcecrownTimer <= diff)
- {
- /// @todo Add missing text
- if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
- guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
- ++nGuardiansOfIcecrownCount;
- uiGuardiansOfIcecrownTimer = 5000;
- }
- else uiGuardiansOfIcecrownTimer -= diff;
- }
-
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
@@ -609,6 +597,18 @@ public:
Talk(SAY_FROST_BLAST);
events.Repeat(30000, 90000);
break;
+ case EVENT_ANSWER_REQUEST:
+ if (Creature* lichKing = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_LICH_KING)))
+ lichKing->AI()->Talk(SAY_ANSWER_REQUEST);
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
+ case EVENT_SUMMON_GUARDIANS:
+ if (Creature* guardian = DoSummon(NPC_ICECROWN, Pos[RAND(2, 5, 8, 11)]))
+ guardian->SetFloatValue(UNIT_FIELD_COMBATREACH, 2);
+ ++nGuardiansOfIcecrownCount;
+ if (nGuardiansOfIcecrownCount < RAID_MODE(2, 4))
+ events.ScheduleEvent(EVENT_SUMMON_GUARDIANS, 5000);
+ break;
default:
break;
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
index fc376a5439f..cc7e38173c8 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_maexxna.cpp
@@ -112,7 +112,7 @@ public:
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
{
- target->RemoveAura(sSpellMgr->GetSpellIdForDifficulty(SPELL_WEB_SPRAY, me));
+ target->RemoveAura(SPELL_WEB_SPRAY);
uint8 pos = rand32() % MAX_POS_WRAP;
target->GetMotionMaster()->MoveJump(PosWrap[pos].GetPositionX(), PosWrap[pos].GetPositionY(), PosWrap[pos].GetPositionZ(), 20, 20);
if (Creature* wrap = DoSummon(NPC_WEB_WRAP, PosWrap[pos], 0, TEMPSUMMON_CORPSE_DESPAWN))
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
index 0e07ff027f6..be4c8583377 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
@@ -106,7 +106,7 @@ public:
events.ScheduleEvent(EVENT_BALCONY, 110000);
events.ScheduleEvent(EVENT_CURSE, 10000 + rand32() % 15000);
events.ScheduleEvent(EVENT_WARRIOR, 30000);
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_BLINK, urand(20000, 40000));
}
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index b66bc07f2c8..ce478cd0664 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -115,6 +115,7 @@ class instance_naxxramas : public InstanceMapScript
minHorsemenDiedTime = 0;
maxHorsemenDiedTime = 0;
AbominationCount = 0;
+ CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT;
playerDied = 0;
}
@@ -156,6 +157,9 @@ class instance_naxxramas : public InstanceMapScript
case NPC_KEL_THUZAD:
KelthuzadGUID = creature->GetGUID();
break;
+ case NPC_LICH_KING:
+ LichKingGUID = creature->GetGUID();
+ break;
default:
break;
}
@@ -201,6 +205,9 @@ class instance_naxxramas : public InstanceMapScript
case GO_KELTHUZAD_TRIGGER:
KelthuzadTriggerGUID = go->GetGUID();
break;
+ case GO_ROOM_KELTHUZAD:
+ KelthuzadDoorGUID = go->GetGUID();
+ break;
default:
break;
}
@@ -242,6 +249,15 @@ class instance_naxxramas : public InstanceMapScript
playerDied = 1;
SaveToDB();
}
+
+ if (Creature* creature = unit->ToCreature())
+ if (creature->GetEntry() == NPC_BIGGLESWORTH)
+ {
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_KELTHUZAD_CAT_DIED);
+ }
}
void SetData(uint32 id, uint32 value) override
@@ -327,6 +343,8 @@ class instance_naxxramas : public InstanceMapScript
return PortalsGUID[3];
case DATA_KELTHUZAD_TRIGGER:
return KelthuzadTriggerGUID;
+ case DATA_LICH_KING:
+ return LichKingGUID;
}
return ObjectGuid::Empty;
@@ -337,18 +355,131 @@ class instance_naxxramas : public InstanceMapScript
if (!InstanceScript::SetBossState(id, state))
return false;
- if (id == BOSS_HORSEMEN && state == DONE)
+ switch (id)
{
- if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
- {
- horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
- horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- }
+ case BOSS_MAEXXNA:
+ case BOSS_LOATHEB:
+ case BOSS_THADDIUS:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ break;
+ case BOSS_GOTHIK:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ, 10000);
+ break;
+ case BOSS_HORSEMEN:
+ if (state == DONE)
+ {
+ if (GameObject* horsemenChest = instance->GetGameObject(HorsemenChestGUID))
+ {
+ horsemenChest->SetRespawnTime(horsemenChest->GetRespawnDelay());
+ horsemenChest->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ events.ScheduleEvent(EVENT_KELTHUZAD_WING_TAUNT, 6000);
+ }
+ break;
+ case BOSS_SAPPHIRON:
+ if (state == DONE)
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD, 6000);
+ break;
+ default:
+ break;
}
return true;
}
+ void Update(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK, 5000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_BLAUMEUX2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_BLAUMEUX2:
+ if (Creature* blaumeux = instance->GetCreature(LadyGUID))
+ blaumeux->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_ZELIEK2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_ZELIEK2:
+ if (Creature* zeliek = instance->GetCreature(SirGUID))
+ zeliek->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_KORTHAZZ2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_KORTHAZZ2:
+ if (Creature* korthazz = instance->GetCreature(ThaneGUID))
+ korthazz->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ events.ScheduleEvent(EVENT_DIALOGUE_GOTHIK_RIVENDARE2, 6000);
+ break;
+ case EVENT_DIALOGUE_GOTHIK_RIVENDARE2:
+ if (Creature* rivendare = instance->GetCreature(BaronGUID))
+ rivendare->AI()->Talk(SAY_DIALOGUE_GOTHIK_HORSEMAN2);
+ break;
+ case EVENT_KELTHUZAD_WING_TAUNT:
+ // Loads Kel'Thuzad's grid. We need this as he must be active in order for his texts to work.
+ instance->LoadGrid(3749.67f, -5114.06f);
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(CurrentWingTaunt);
+ ++CurrentWingTaunt;
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD);
+ HandleGameObject(KelthuzadDoorGUID, false);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2, 16000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_LICHKING2, 9000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_LICHKING2:
+ if (Creature* lichKing = instance->GetCreature(LichKingGUID))
+ lichKing->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_LICH_KING2);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3, 12000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3);
+ events.ScheduleEvent(EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4, 6000);
+ break;
+ case EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4:
+ if (Creature* kelthuzad = instance->GetCreature(KelthuzadGUID))
+ kelthuzad->AI()->Talk(SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4);
+ HandleGameObject(KelthuzadDoorGUID, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void HeiganErupt(uint32 section)
{
for (uint32 i = 0; i < 4; ++i)
@@ -387,11 +518,11 @@ class instance_naxxramas : public InstanceMapScript
switch (criteria_id)
{
case 7600: // Criteria for achievement 2176: And They Would All Go Down Together 15sec of each other 10-man
- if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_10MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
+ if (Difficulty(instance->GetSpawnMode()) == DIFFICULTY_10_N && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
return true;
return false;
case 7601: // Criteria for achievement 2177: And They Would All Go Down Together 15sec of each other 25-man
- if (Difficulty(instance->GetSpawnMode()) == RAID_DIFFICULTY_25MAN_NORMAL && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
+ if (Difficulty(instance->GetSpawnMode()) == DIFFICULTY_25_N && (maxHorsemenDiedTime - minHorsemenDiedTime) < 15)
return true;
return false;
// Difficulty checks are done on DB.
@@ -450,10 +581,15 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid KelthuzadGUID;
ObjectGuid KelthuzadTriggerGUID;
ObjectGuid PortalsGUID[4];
+ ObjectGuid KelthuzadDoorGUID;
+ ObjectGuid LichKingGUID;
uint8 AbominationCount;
+ uint8 CurrentWingTaunt;
/* The Immortal / The Undying */
uint32 playerDied;
+
+ EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 8325271a403..eb77980f3ba 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -71,6 +71,7 @@ enum Data64
DATA_KELTHUZAD_PORTAL03,
DATA_KELTHUZAD_PORTAL04,
DATA_KELTHUZAD_TRIGGER,
+ DATA_LICH_KING
};
enum CreaturesIds
@@ -89,7 +90,10 @@ enum CreaturesIds
NPC_CRYPT_GUARD = 16573,
NPC_NAXXRAMAS_FOLLOWER = 16505,
NPC_FOLLOWER_WORSHIPPER = 16506,
- NPC_DK_UNDERSTUDY = 16803
+ NPC_DK_UNDERSTUDY = 16803,
+ NPC_BIGGLESWORTH = 16998,
+ NPC_LICH_KING = 16980,
+ NPC_OLD_WORLD_TRIGGER = 15384
};
enum GameObjectsIds
@@ -142,6 +146,50 @@ enum SpellIds
SPELL_SLIME = 28801
};
+enum InstanceEvents
+{
+ // Dialogue that happens after Gothik's death.
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ = 1,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE,
+ EVENT_DIALOGUE_GOTHIK_BLAUMEUX2,
+ EVENT_DIALOGUE_GOTHIK_ZELIEK2,
+ EVENT_DIALOGUE_GOTHIK_KORTHAZZ2,
+ EVENT_DIALOGUE_GOTHIK_RIVENDARE2,
+
+ // Dialogue that happens after each wing.
+ EVENT_KELTHUZAD_WING_TAUNT,
+
+ // Dialogue that happens after Sapphiron's death.
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD2,
+ EVENT_DIALOGUE_SAPPHIRON_LICHKING2,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD3,
+ EVENT_DIALOGUE_SAPPHIRON_KELTHUZAD4
+};
+
+enum InstanceTexts
+{
+ // The Four Horsemen
+ SAY_DIALOGUE_GOTHIK_HORSEMAN = 5,
+ SAY_DIALOGUE_GOTHIK_HORSEMAN2 = 6,
+
+ // Kel'Thuzad
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD = 0,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD2 = 2,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD3 = 4,
+ SAY_DIALOGUE_SAPPHIRON_KELTHUZAD4 = 20,
+
+ SAY_KELTHUZAD_CAT_DIED = 5,
+ SAY_KELTHUZAD_FIRST_WING_TAUNT = 16,
+
+ // Lich King
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING = 1,
+ SAY_DIALOGUE_SAPPHIRON_LICH_KING2 = 2
+};
+
/*
template<class AI>
CreatureAI* GetNaxxramasAI(Creature* creature)
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 813e51ad23c..b4f27710e03 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -406,7 +406,7 @@ public:
{
_summonDeaths = value;
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_10_N)
{
if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_10MAN)
{
@@ -414,7 +414,7 @@ public:
DoAction(ACTION_HANDLE_P_THREE_INTRO);
}
}
- else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ else if (GetDifficulty() == DIFFICULTY_25_N)
{
if (_summonDeaths == MAX_SUMMONS_PHASE_TWO_25MAN)
{
@@ -862,7 +862,7 @@ public:
if (_arcaneReinforcements)
{
- for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 5); rangeDisks++)
+ for (uint8 rangeDisks = 0; rangeDisks < (GetDifficulty() == DIFFICULTY_10_N ? 4 : 5); rangeDisks++)
{
Creature* casterDiskSummon = me->SummonCreature(NPC_HOVER_DISK_CASTER, RangeHoverDisksSpawnPositions[rangeDisks]);
@@ -878,7 +878,7 @@ public:
_arcaneReinforcements = false;
- if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_DELAYED_REINFORCEMENTS, 1*IN_MILLISECONDS, 0, PHASE_TWO);
}
break;
@@ -958,7 +958,7 @@ public:
SetPhase(PHASE_THREE, true);
break;
case EVENT_SURGE_OF_POWER_P_THREE:
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_10_N)
{
if (Unit* tempSurgeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, SPELL_RIDE_RED_DRAGON_BUDDY))
{
@@ -975,7 +975,7 @@ public:
}
}
}
- else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ else if (GetDifficulty() == DIFFICULTY_25_N)
{
memset(_surgeTargetGUID, 0, sizeof(_surgeTargetGUID));
DoCastAOE(SPELL_SURGE_OF_POWER_WARNING_SELECTOR_25, true);
@@ -1007,10 +1007,10 @@ public:
Talk(SAY_DEATH);
if (Creature* alexstraszaGiftBoxBunny = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_GIFT_BOX_BUNNY_GUID)))
{
- if (GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (GetDifficulty() == DIFFICULTY_10_N)
alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_10, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(),
HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0);
- else if (GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ else if (GetDifficulty() == DIFFICULTY_25_N)
alexstraszaGiftBoxBunny->SummonGameObject(GO_HEART_OF_MAGIC_25, HeartOfMagicSpawnPos.GetPositionX(), HeartOfMagicSpawnPos.GetPositionY(),
HeartOfMagicSpawnPos.GetPositionZ(), HeartOfMagicSpawnPos.GetOrientation(), 0.0f, 0.0f, 0.0f, 1.0f, 0);
}
@@ -1786,10 +1786,10 @@ class spell_malygos_arcane_storm : public SpellScriptLoader
{
// Resize list only to objects that are vehicles.
IsCreatureVehicleCheck check(true);
- Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10));
+ Trinity::Containers::RandomResizeList(targets, check, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10));
}
else
- Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? 4 : 10));
+ Trinity::Containers::RandomResizeList(targets, (malygos->GetMap()->GetDifficulty() == DIFFICULTY_10_N ? 4 : 10));
}
void HandleVisual(SpellEffIndex /*effIndex*/)
@@ -1948,7 +1948,7 @@ class spell_arcane_overload : public SpellScriptLoader
{
Creature* arcaneOverload = GetCaster()->ToCreature();
targets.remove_if(ExactDistanceCheck(arcaneOverload,
- GetSpellInfo()->Effects[EFFECT_0].CalcRadius(arcaneOverload) * arcaneOverload->GetObjectScale()));
+ GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(arcaneOverload) * arcaneOverload->GetObjectScale()));
}
void Register() override
@@ -2475,9 +2475,9 @@ class spell_alexstrasza_gift_beam_visual : public SpellScriptLoader
{
if (Creature* target = GetTarget()->ToCreature())
{
- if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (target->GetMap()->GetDifficulty() == DIFFICULTY_10_N)
_alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_10, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
- else if (target->GetMap()->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ else if (target->GetMap()->GetDifficulty() == DIFFICULTY_25_N)
_alexstraszaGift = target->SummonGameObject(GO_ALEXSTRASZA_S_GIFT_25, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0);
}
}
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
index 90decfbf46e..b689df3c977 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp
@@ -92,14 +92,14 @@ public:
platformGUID = go->GetGUID();
break;
case GO_FOCUSING_IRIS_10:
- if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (instance->GetDifficulty() == DIFFICULTY_10_N)
{
irisGUID = go->GetGUID();
focusingIrisPosition = go->GetPosition();
}
break;
case GO_FOCUSING_IRIS_25:
- if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (instance->GetDifficulty() == DIFFICULTY_25_N)
{
irisGUID = go->GetGUID();
focusingIrisPosition = go->GetPosition();
@@ -110,11 +110,11 @@ public:
exitPortalPosition = go->GetPosition();
break;
case GO_HEART_OF_MAGIC_10:
- if (instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL)
+ if (instance->GetDifficulty() == DIFFICULTY_10_N)
heartOfMagicGUID = go->GetGUID();
break;
case GO_HEART_OF_MAGIC_25:
- if (instance->GetDifficulty() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (instance->GetDifficulty() == DIFFICULTY_25_N)
heartOfMagicGUID = go->GetGUID();
break;
}
@@ -240,7 +240,7 @@ public:
PowerSparksHandling();
break;
case DATA_RESPAWN_IRIS:
- SpawnGameObject(instance->GetDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition);
+ SpawnGameObject(instance->GetDifficulty() == DIFFICULTY_10_N ? GO_FOCUSING_IRIS_10 : GO_FOCUSING_IRIS_25, focusingIrisPosition);
break;
}
}
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index 3f882e0b99e..b0c4be44ee8 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -418,7 +418,7 @@ class spell_oculus_ride_ruby_emerald_amber_drake_que : public SpellScriptLoader
// caster of the triggered spell is wrong for an unknown reason, handle it here correctly
PreventDefaultAction();
if (Unit* caster = GetCaster())
- GetTarget()->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true);
+ GetTarget()->CastSpell(caster, aurEff->GetSpellEffectInfo()->TriggerSpell, true);
}
void Register() override
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index fc29369c28f..86a19d16efb 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -28,7 +28,7 @@ EndScriptData */
#include "SpellScript.h"
#include "halls_of_lightning.h"
-enum Yells
+enum Texts
{
SAY_INTRO_1 = 0,
SAY_INTRO_2 = 1,
@@ -51,6 +51,21 @@ enum Spells
SPELL_PULSING_SHOCKWAVE_AURA = 59414
};
+enum Events
+{
+ EVENT_ARC_LIGHTNING = 1,
+ EVENT_LIGHTNING_NOVA,
+ EVENT_RESUME_PULSING_SHOCKWAVE,
+ EVENT_INTRO_DIALOGUE
+};
+
+enum Phases
+{
+ // Phases are used to allow executing the intro event while UpdateVictim() returns false and convenience.
+ PHASE_INTRO = 1,
+ PHASE_NORMAL
+};
+
enum Misc
{
ACHIEV_TIMELY_DEATH_START_EVENT = 20384
@@ -65,57 +80,41 @@ class boss_loken : public CreatureScript
public:
boss_loken() : CreatureScript("boss_loken") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_lokenAI>(creature);
- }
-
- struct boss_lokenAI : public ScriptedAI
+ struct boss_lokenAI : public BossAI
{
- boss_lokenAI(Creature* creature) : ScriptedAI(creature)
+ boss_lokenAI(Creature* creature) : BossAI(creature, DATA_LOKEN)
{
Initialize();
- instance = creature->GetInstanceScript();
+ _isIntroDone = false;
}
void Initialize()
{
- m_uiArcLightning_Timer = 15000;
- m_uiLightningNova_Timer = 20000;
- m_uiResumePulsingShockwave_Timer = 1000;
-
- m_uiHealthAmountModifier = 1;
+ _healthAmountModifier = 1;
}
- InstanceScript* instance;
-
- uint32 m_uiArcLightning_Timer;
- uint32 m_uiLightningNova_Timer;
- uint32 m_uiResumePulsingShockwave_Timer;
-
- uint32 m_uiHealthAmountModifier;
-
void Reset() override
{
Initialize();
-
- instance->SetBossState(DATA_LOKEN, NOT_STARTED);
+ _Reset();
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void EnterCombat(Unit* /*who*/) override
{
+ _EnterCombat();
Talk(SAY_AGGRO);
-
- instance->SetBossState(DATA_LOKEN, IN_PROGRESS);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, 15000);
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 20000);
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, 1000);
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMELY_DEATH_START_EVENT);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
-
- instance->SetBossState(DATA_LOKEN, DONE);
+ _JustDied();
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA);
}
@@ -125,66 +124,89 @@ public:
Talk(SAY_SLAY);
}
- void UpdateAI(uint32 uiDiff) override
+ void MoveInLineOfSight(Unit* who) override
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- if (m_uiResumePulsingShockwave_Timer)
+ if (!_isIntroDone && me->IsValidAttackTarget(who) && me->IsWithinDistInMap(who, 40.0f))
{
- if (m_uiResumePulsingShockwave_Timer <= uiDiff)
- {
- DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
- me->ClearUnitState(UNIT_STATE_CASTING); // this flag breaks movement
-
- DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
- m_uiResumePulsingShockwave_Timer = 0;
- }
- else
- m_uiResumePulsingShockwave_Timer -= uiDiff;
+ _isIntroDone = true;
+ Talk(SAY_INTRO_1);
+ events.ScheduleEvent(EVENT_INTRO_DIALOGUE, 20000, 0, PHASE_INTRO);
}
+ BossAI::MoveInLineOfSight(who);
+ }
- if (m_uiArcLightning_Timer <= uiDiff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARC_LIGHTNING);
+ void UpdateAI(uint32 diff) override
+ {
+ if (events.IsInPhase(PHASE_NORMAL) && !UpdateVictim())
+ return;
- m_uiArcLightning_Timer = urand(15000, 16000);
- }
- else
- m_uiArcLightning_Timer -= uiDiff;
+ events.Update(diff);
- if (m_uiLightningNova_Timer <= uiDiff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- Talk(SAY_NOVA);
- Talk(EMOTE_NOVA);
- DoCast(me, SPELL_LIGHTNING_NOVA);
-
- me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_PULSING_SHOCKWAVE, me));
- m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
- m_uiLightningNova_Timer = urand(20000, 21000);
+ switch (eventId)
+ {
+ case EVENT_ARC_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_ARC_LIGHTNING);
+ events.ScheduleEvent(EVENT_ARC_LIGHTNING, urand(15000, 16000));
+ break;
+ case EVENT_LIGHTNING_NOVA:
+ Talk(SAY_NOVA);
+ Talk(EMOTE_NOVA);
+ DoCastAOE(SPELL_LIGHTNING_NOVA);
+ me->RemoveAurasDueToSpell(SPELL_PULSING_SHOCKWAVE);
+ events.ScheduleEvent(EVENT_RESUME_PULSING_SHOCKWAVE, DUNGEON_MODE(5000, 4000)); // Pause Pulsing Shockwave aura
+ events.ScheduleEvent(EVENT_LIGHTNING_NOVA, urand(20000, 21000));
+ break;
+ case EVENT_RESUME_PULSING_SHOCKWAVE:
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
+ me->ClearUnitState(UNIT_STATE_CASTING); // This flag breaks movement.
+ DoCast(me, SPELL_PULSING_SHOCKWAVE, true);
+ break;
+ case EVENT_INTRO_DIALOGUE:
+ Talk(SAY_INTRO_2);
+ events.SetPhase(PHASE_NORMAL);
+ break;
+ default:
+ break;
+ }
}
- else
- m_uiLightningNova_Timer -= uiDiff;
- // Health check
- if (HealthBelowPct(100 - 25 * m_uiHealthAmountModifier))
+ DoMeleeAttackIfReady();
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
+ {
+ if (me->HealthBelowPctDamaged(100 - 25 * _healthAmountModifier, damage))
{
- switch (m_uiHealthAmountModifier)
+ switch (_healthAmountModifier)
{
- case 1: Talk(SAY_75HEALTH); break;
- case 2: Talk(SAY_50HEALTH); break;
- case 3: Talk(SAY_25HEALTH); break;
+ case 1:
+ Talk(SAY_75HEALTH);
+ break;
+ case 2:
+ Talk(SAY_50HEALTH);
+ break;
+ case 3:
+ Talk(SAY_25HEALTH);
+ break;
+ default:
+ break;
}
-
- ++m_uiHealthAmountModifier;
+ ++_healthAmountModifier;
}
-
- DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 _healthAmountModifier;
+ bool _isIntroDone;
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_lokenAI>(creature);
+ }
};
class spell_loken_pulsing_shockwave : public SpellScriptLoader
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index d63d5e87923..3a707e7fa70 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -428,7 +428,7 @@ public:
void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) override
{
// This is the dummy effect of the spells
- if (pSpell->Id == sSpellMgr->GetSpellIdForDifficulty(SPELL_SHATTER, me))
+ if (pSpell->Id == SPELL_SHATTER)
if (me->GetEntry() == NPC_BRITTLE_GOLEM)
me->DespawnOrUnsummon();
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
index 07cdfa3353c..d911bf07439 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
@@ -182,7 +182,7 @@ class spell_krystallus_shatter_effect : public SpellScriptLoader
if (!GetHitUnit())
return;
- float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ float radius = GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(GetCaster());
if (!radius)
return;
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
index bb7a8592e04..41da9ec09ea 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
@@ -615,7 +615,7 @@ class boss_stormcaller_brundir : public CreatureScript
break;
case EVENT_GROUND:
//me->SetLevitate(false);
- me->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(SPELL_LIGHTNING_TENDRILS, me));
+ me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS);
me->RemoveAurasDueToSpell(SPELL_LIGHTNING_TENDRILS_VISUAL);
DoStartMovement(me->GetVictim());
events.CancelEvent(EVENT_GROUND);
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 40c189a8da2..b6ac62257d0 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -1793,7 +1793,7 @@ class spell_vehicle_throw_passenger : public SpellScriptLoader
}
}
}
- if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->Effects[effIndex].CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
+ if (target && target->IsWithinDist2d(targets.GetDstPos(), GetSpellInfo()->GetEffect(effIndex)->CalcRadius() * 2)) // now we use *2 because the location of the seat is not correct
passenger->EnterVehicle(target, 0);
else
{
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
index 93fee8d1964..5952c9f8501 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_freya.cpp
@@ -1583,7 +1583,7 @@ class spell_freya_iron_roots : public SpellScriptLoader
void HandleSummon(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
- uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
+ uint32 entry = uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValue);
Position pos = GetCaster()->GetPosition();
// Not good at all, but this prevents having roots in a different position then player
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
index 419052baddc..5ac0024c032 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
@@ -454,11 +454,11 @@ class spell_ulduar_cancel_stone_grip : public SpellScriptLoader
switch (target->GetMap()->GetDifficulty())
{
- case RAID_DIFFICULTY_10MAN_NORMAL:
- target->RemoveAura(GetSpellInfo()->Effects[EFFECT_0].CalcValue());
+ case DIFFICULTY_10_N:
+ target->RemoveAura(GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue());
break;
- case RAID_DIFFICULTY_25MAN_NORMAL:
- target->RemoveAura(GetSpellInfo()->Effects[EFFECT_1].CalcValue());
+ case DIFFICULTY_25_N:
+ target->RemoveAura(GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue());
break;
default:
break;
@@ -534,7 +534,7 @@ class spell_ulduar_stone_grip_absorb : public SpellScriptLoader
if (!GetOwner()->ToCreature())
return;
- uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? 33809 : 33942);
+ uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DIFFICULTY_NORMAL ? 33809 : 33942);
Creature* rubbleStalker = GetOwner()->FindNearestCreature(rubbleStalkerEntry, 200.0f, true);
if (rubbleStalker)
rubbleStalker->CastSpell(rubbleStalker, SPELL_STONE_GRIP_CANCEL, true);
@@ -643,7 +643,7 @@ class spell_kologarn_summon_focused_eyebeam : public SpellScriptLoader
void HandleForceCast(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
- GetCaster()->CastSpell(GetCaster(), GetSpellInfo()->Effects[effIndex].TriggerSpell, true);
+ GetCaster()->CastSpell(GetCaster(), GetSpellInfo()->GetEffect(effIndex)->TriggerSpell, true);
}
void Register() override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
index cad6b045120..947b1ce9b86 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_razorscale.cpp
@@ -237,7 +237,7 @@ class boss_razorscale_controller : public CreatureScript
{
case ACTION_HARPOON_BUILD:
events.ScheduleEvent(EVENT_BUILD_HARPOON_1, 50000);
- if (me->GetMap()->GetSpawnMode() == RAID_DIFFICULTY_25MAN_NORMAL)
+ if (me->GetMap()->GetSpawnMode() == DIFFICULTY_25_N)
events.ScheduleEvent(EVENT_BUILD_HARPOON_3, 90000);
break;
case ACTION_PLACE_BROKEN_HARPOON:
@@ -1075,7 +1075,7 @@ class spell_razorscale_devouring_flame : public SpellScriptLoader
{
PreventHitDefaultEffect(effIndex);
Unit* caster = GetCaster();
- uint32 entry = uint32(GetSpellInfo()->Effects[effIndex].MiscValue);
+ uint32 entry = uint32(GetSpellInfo()->GetEffect(effIndex)->MiscValue);
WorldLocation const* summonLocation = GetExplTargetDest();
if (!caster || !summonLocation)
return;
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
index 53fbf8f0cf7..1f55abf8a11 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/instance_sethekk_halls.cpp
@@ -21,8 +21,14 @@
DoorData const doorData[] =
{
- { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_IKISS_DOOR, DATA_TALON_KING_IKISS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+};
+
+ObjectData const gameObjectData[] =
+{
+ { GO_TALON_KING_COFFER, DATA_TALON_KING_COFFER },
+ { 0, 0 } // END
};
class instance_sethekk_halls : public InstanceMapScript
@@ -37,6 +43,7 @@ class instance_sethekk_halls : public InstanceMapScript
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
+ LoadObjectData(nullptr, gameObjectData);
}
void OnCreatureCreate(Creature* creature) override
@@ -50,16 +57,27 @@ class instance_sethekk_halls : public InstanceMapScript
}
}
- void OnGameObjectCreate(GameObject* go) override
+ bool SetBossState(uint32 type, EncounterState state) override
{
- if (go->GetEntry() == GO_IKISS_DOOR)
- AddDoor(go, true);
- }
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
- void OnGameObjectRemove(GameObject* go) override
- {
- if (go->GetEntry() == GO_IKISS_DOOR)
- AddDoor(go, false);
+ switch (type)
+ {
+ case DATA_TALON_KING_IKISS:
+ if (state == DONE)
+ {
+ /// @workaround: GO_FLAG_INTERACT_COND remains on the gob, but it is not handled correctly in this case
+ /// gameobject should have GO_DYNFLAG_LO_ACTIVATE too, which makes gobs interactable with GO_FLAG_INTERACT_COND
+ /// so just removed GO_FLAG_INTERACT_COND
+ if (GameObject* coffer = GetGameObject(DATA_TALON_KING_COFFER))
+ coffer->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND | GO_FLAG_NOT_SELECTABLE);
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
}
};
diff --git a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
index 4b6bfab46cb..8cf01fb4635 100644
--- a/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
+++ b/src/server/scripts/Outland/Auchindoun/SethekkHalls/sethekk_halls.h
@@ -28,7 +28,10 @@ enum DataTypes
// Encounter States/Boss GUIDs
DATA_DARKWEAVER_SYTH = 0,
DATA_TALON_KING_IKISS = 1,
- DATA_ANZU = 2
+ DATA_ANZU = 2,
+
+ // Additional Data
+ DATA_TALON_KING_COFFER = 3
};
enum CreatureIds
@@ -39,7 +42,8 @@ enum CreatureIds
enum GameObjectIds
{
- GO_IKISS_DOOR = 177203
+ GO_IKISS_DOOR = 177203,
+ GO_TALON_KING_COFFER = 187372
};
template<class AI>
diff --git a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
index d49a23c85dd..1e55eb37007 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_reliquary_of_souls.cpp
@@ -572,8 +572,8 @@ public:
void SpellHit(Unit* /*caster*/, const SpellInfo* spell) override
{
if (me->GetCurrentSpell(CURRENT_GENERIC_SPELL))
- for (uint8 i = 0; i < 3; ++i)
- if (spell->Effects[i].Effect == SPELL_EFFECT_INTERRUPT_CAST)
+ for (SpellEffectInfo const* effect : spell->GetEffectsForDifficulty(me->GetMap()->GetDifficulty()))
+ if (effect->Effect == SPELL_EFFECT_INTERRUPT_CAST)
if (me->GetCurrentSpell(CURRENT_GENERIC_SPELL)->m_spellInfo->Id == SPELL_SOUL_SHOCK
|| me->GetCurrentSpell(CURRENT_GENERIC_SPELL)->m_spellInfo->Id == SPELL_DEADEN)
me->InterruptSpell(CURRENT_GENERIC_SPELL, false);
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
index f0884e83baa..794d3a490f6 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/instance_steam_vault.cpp
@@ -31,21 +31,25 @@ class go_main_chambers_access_panel : public GameObjectScript
return false;
if (go->GetEntry() == GO_ACCESS_PANEL_HYDRO && (instance->GetBossState(DATA_HYDROMANCER_THESPIA) == DONE || instance->GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL))
- {
instance->SetBossState(DATA_HYDROMANCER_THESPIA, SPECIAL);
- go->SetGoState(GO_STATE_ACTIVE);
- }
if (go->GetEntry() == GO_ACCESS_PANEL_MEK && (instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == DONE || instance->GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL))
- {
instance->SetBossState(DATA_MEKGINEER_STEAMRIGGER, SPECIAL);
- go->SetGoState(GO_STATE_ACTIVE);
- }
+
+ go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ go->SetGoState(GO_STATE_ACTIVE);
return true;
}
};
+ObjectData const gameObjectData[] =
+{
+ { GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDRO },
+ { GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEK },
+ { 0, 0 } // END
+};
+
class instance_steam_vault : public InstanceMapScript
{
public:
@@ -57,6 +61,7 @@ class instance_steam_vault : public InstanceMapScript
{
SetHeaders(DataHeader);
SetBossNumber(EncounterCount);
+ LoadObjectData(nullptr, gameObjectData);
DistillerState = 0;
}
@@ -89,6 +94,8 @@ class instance_steam_vault : public InstanceMapScript
default:
break;
}
+
+ InstanceScript::OnGameObjectCreate(go);
}
ObjectGuid GetGuidData(uint32 type) const override
@@ -128,6 +135,9 @@ class instance_steam_vault : public InstanceMapScript
switch (type)
{
case DATA_HYDROMANCER_THESPIA:
+ if (state == DONE)
+ if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_HYDRO))
+ panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (state == SPECIAL)
{
if (GetBossState(DATA_MEKGINEER_STEAMRIGGER) == SPECIAL)
@@ -137,6 +147,9 @@ class instance_steam_vault : public InstanceMapScript
}
break;
case DATA_MEKGINEER_STEAMRIGGER:
+ if (state == DONE)
+ if (GameObject* panel = GetGameObject(DATA_ACCESS_PANEL_MEK))
+ panel->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (state == SPECIAL)
{
if (GetBossState(DATA_HYDROMANCER_THESPIA) == SPECIAL)
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
index 58f71b047ef..d18d0406dea 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
+++ b/src/server/scripts/Outland/CoilfangReservoir/SteamVault/steam_vault.h
@@ -28,7 +28,11 @@ enum DataTypes
DATA_HYDROMANCER_THESPIA = 0,
DATA_MEKGINEER_STEAMRIGGER = 1,
DATA_WARLORD_KALITHRESH = 2,
- DATA_DISTILLER = 3
+ DATA_DISTILLER = 3,
+
+ // Additional Data
+ DATA_ACCESS_PANEL_HYDRO = 4,
+ DATA_ACCESS_PANEL_MEK = 5
};
enum CreatureIds
diff --git a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
index 2cee741cbf3..a3404e048ce 100644
--- a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
+++ b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
@@ -317,7 +317,7 @@ class spell_gruul_shatter_effect : public SpellScriptLoader
if (!GetHitUnit())
return;
- float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ float radius = GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(GetCaster());
if (!radius)
return;
diff --git a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp
index a0673d4aced..c0a7f85cb63 100644
--- a/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/BloodFurnace/boss_broggok.cpp
@@ -154,7 +154,7 @@ class spell_broggok_poison_cloud : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell))
+ if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->TriggerSpell))
return false;
return true;
}
@@ -163,7 +163,7 @@ class spell_broggok_poison_cloud : public SpellScriptLoader
{
PreventDefaultAction();
- uint32 triggerSpell = GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
+ uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell;
int32 mod = int32(((float(aurEff->GetTickNumber()) / aurEff->GetTotalTicks()) * 0.9f + 0.1f) * 10000 * 2 / 3);
GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_RADIUS_MOD, mod, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
index cd433000e8e..7e30ae1a931 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
@@ -542,7 +542,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
return;
Unit* target = GetUnitOwner();
- target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_1].CalcValue(), false);
+ target->CastSpell(target, GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue(), false);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 0ff7d116a88..cc96b27cb0a 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -89,7 +89,7 @@ class spell_dk_anti_magic_shell_raid : public SpellScriptLoader
bool Load() override
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
+ absorbPct = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue(GetCaster());
return true;
}
@@ -138,8 +138,8 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader
uint32 absorbPct, hpPct;
bool Load() override
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
- hpPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster());
+ absorbPct = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue(GetCaster());
+ hpPct = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue(GetCaster());
return true;
}
@@ -203,7 +203,7 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader
bool Load() override
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
+ absorbPct = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue(GetCaster());
return true;
}
@@ -217,7 +217,7 @@ class spell_dk_anti_magic_zone : public SpellScriptLoader
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
SpellInfo const* talentSpell = sSpellMgr->EnsureSpellInfo(SPELL_DK_ANTI_MAGIC_SHELL_TALENT);
- amount = talentSpell->Effects[EFFECT_0].CalcValue(GetCaster());
+ amount = talentSpell->GetEffect(EFFECT_0)->CalcValue(GetCaster());
if (Player* player = GetCaster()->ToPlayer())
amount += int32(2 * player->GetTotalAttackPowerValue(BASE_ATTACK));
}
@@ -628,7 +628,7 @@ class spell_dk_death_strike : public SpellScriptLoader
if (AuraEffect* enabler = GetCaster()->GetAuraEffect(SPELL_DK_DEATH_STRIKE_ENABLER, EFFECT_0, GetCaster()->GetGUID()))
{
// Call CalculateAmount() to constantly fire the AuraEffect's HandleCalcAmount method
- int32 heal = CalculatePct(enabler->CalculateAmount(GetCaster()), GetSpellInfo()->Effects[EFFECT_0].ChainAmplitude);
+ int32 heal = CalculatePct(enabler->CalculateAmount(GetCaster()), GetSpellInfo()->GetEffect(EFFECT_0)->ChainAmplitude);
if (AuraEffect const* aurEff = GetCaster()->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_DEATH_STRIKE, EFFECT_2))
heal = AddPct(heal, aurEff->GetAmount());
@@ -1045,7 +1045,7 @@ class spell_dk_pestilence : public SpellScriptLoader
{
aurEffNew->SetCritChance(critChance); // Blood Plague can crit if caster has T9.
aurEffNew->SetDonePct(donePct);
- aurEffNew->SetDamage(caster->SpellDamageBonusDone(hitUnit, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
+ aurEffNew->SetDamage(caster->SpellDamageBonusDone(hitUnit, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT, aurEffNew->GetSpellEffectInfo()) * donePct);
}
}
}
@@ -1064,7 +1064,7 @@ class spell_dk_pestilence : public SpellScriptLoader
if (AuraEffect* aurEffNew = aurNew->GetEffect(EFFECT_0))
{
aurEffNew->SetDonePct(donePct);
- aurEffNew->SetDamage(caster->SpellDamageBonusDone(hitUnit, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT) * donePct);
+ aurEffNew->SetDamage(caster->SpellDamageBonusDone(hitUnit, aurEffNew->GetSpellInfo(), std::max(aurEffNew->GetAmount(), 0), DOT, aurEffNew->GetSpellEffectInfo()) * donePct);
}
}
}
@@ -1231,12 +1231,13 @@ class spell_dk_raise_dead : public SpellScriptLoader
private:
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].CalcValue())
- || !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_2].CalcValue())
+ // 6.x effects changed
+ /*if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_1)->CalcValue())
+ || !sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_2)->CalcValue())
|| !sSpellMgr->GetSpellInfo(SPELL_DK_RAISE_DEAD_USE_REAGENT)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_MASTER_OF_GHOULS))
- return false;
- return true;
+ return false;*/
+ return false;
}
bool Load() override
@@ -1314,10 +1315,10 @@ class spell_dk_raise_dead : public SpellScriptLoader
// Do we have talent Master of Ghouls?
if (GetCaster()->HasAura(SPELL_DK_MASTER_OF_GHOULS))
// summon as pet
- return GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ return GetSpellInfo()->GetEffect(EFFECT_2)->CalcValue();
// or guardian
- return GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ return GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue();
}
void HandleRaiseDead(SpellEffIndex /*effIndex*/)
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 184e12cdccb..c38d6b07124 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -148,8 +148,6 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
{
PrepareSpellScript(spell_dru_eclipse_energize_SpellScript);
- int32 energizeAmount;
-
bool Load() override
{
if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
@@ -158,8 +156,6 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
if (GetCaster()->ToPlayer()->getClass() != CLASS_DRUID)
return false;
- energizeAmount = 0;
-
return true;
}
@@ -175,7 +171,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
{
case SPELL_DRUID_WRATH:
{
- energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -13
+ int32 energizeAmount = -GetEffectValue(); // -13
// If we are set to fill the lunar side or we've just logged in with 0 power..
if ((!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER))
|| caster->GetPower(POWER_ECLIPSE) == 0)
@@ -192,7 +188,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
}
case SPELL_DRUID_STARFIRE:
{
- energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 20
+ int32 energizeAmount = GetEffectValue(); // 20
// If we are set to fill the solar side or we've just logged in with 0 power..
if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
|| caster->GetPower(POWER_ECLIPSE) == 0)
@@ -213,7 +209,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
|| caster->GetPower(POWER_ECLIPSE) == 0)
{
- energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 15
+ int32 energizeAmount = GetEffectValue(); // 15
caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true);
// If the energize was due to 0 power, cast the eclipse marker aura
@@ -222,7 +218,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
}
else if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER))
{
- energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -15
+ int32 energizeAmount = -GetEffectValue(); // -15
caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true);
}
// The energizing effect brought us out of the lunar eclipse, remove the aura
@@ -430,7 +426,7 @@ class spell_dru_idol_lifebloom : public SpellScriptLoader
spellMod->op = SPELLMOD_DOT;
spellMod->type = SPELLMOD_FLAT;
spellMod->spellId = GetId();
- spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
+ spellMod->mask = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->SpellClassMask;
}
spellMod->value = aurEff->GetAmount() / 7;
}
@@ -536,8 +532,8 @@ class spell_dru_lifebloom : public SpellScriptLoader
int32 healAmount = aurEff->GetAmount();
if (Unit* caster = GetCaster())
{
- healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack);
- healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack);
+ healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, aurEff->GetSpellEffectInfo(), stack);
+ healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, aurEff->GetSpellEffectInfo(), stack);
GetTarget()->CastCustomSpell(GetTarget(), SPELL_DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
@@ -560,8 +556,8 @@ class spell_dru_lifebloom : public SpellScriptLoader
int32 healAmount = aurEff->GetAmount();
if (Unit* caster = GetCaster())
{
- healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
- healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
+ healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, aurEff->GetSpellEffectInfo(), dispelInfo->GetRemovedCharges());
+ healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, aurEff->GetSpellEffectInfo(), dispelInfo->GetRemovedCharges());
target->CastCustomSpell(target, SPELL_DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID());
// restore mana
@@ -757,7 +753,7 @@ class spell_dru_savage_defense : public SpellScriptLoader
bool Load() override
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
+ absorbPct = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue(GetCaster());
return true;
}
@@ -1191,7 +1187,7 @@ class spell_dru_wild_growth : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (spellInfo->Effects[EFFECT_2].IsEffect() || spellInfo->Effects[EFFECT_2].CalcValue() <= 0)
+ if (spellInfo->GetEffect(EFFECT_2)->IsEffect() || spellInfo->GetEffect(EFFECT_2)->CalcValue() <= 0)
return false;
return true;
}
@@ -1200,7 +1196,7 @@ class spell_dru_wild_growth : public SpellScriptLoader
{
targets.remove_if(RaidCheck(GetCaster()));
- uint32 const maxTargets = uint32(GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster()));
+ uint32 const maxTargets = uint32(GetSpellInfo()->GetEffect(EFFECT_2)->CalcValue(GetCaster()));
if (targets.size() > maxTargets)
{
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index badb19c12c3..87619460ee7 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -59,7 +59,7 @@ class spell_gen_absorb0_hitlimit1 : public SpellScriptLoader
bool Load() override
{
// Max absorb stored in 1 dummy effect
- limit = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ limit = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue();
return true;
}
@@ -207,9 +207,9 @@ class spell_gen_alchemist_stone : public SpellScriptLoader
uint32 spellId = 0;
int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 0.4f);
- if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_HEAL))
+ if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_HEAL))
spellId = ALECHEMIST_STONE_HEAL;
- else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_ENERGIZE))
+ else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_ENERGIZE))
spellId = ALECHEMIST_STONE_MANA;
if (!spellId)
@@ -1180,13 +1180,14 @@ class spell_gen_defend : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) override
{
- if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3))
- return false;
- return true;
+ // 6.x effects changed
+ //if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1))
+ // return false;
+ //if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2))
+ // return false;
+ //if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3))
+ // return false;
+ return false;
}
void RefreshVisualShields(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
@@ -1222,23 +1223,24 @@ class spell_gen_defend : public SpellScriptLoader
{
SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
+ // 6.x effects removed
+
// Defend spells cast by NPCs (add visuals)
- if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
+ /*if (spell->GetEffect(EFFECT_0)->ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
- }
-
+ }*/
// Remove Defend spell from player when he dismounts
- if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
+ //if (spell->GetEffect(EFFECT_2)->ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
+ // OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
// Defend spells cast by players (add/remove visuals)
- if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
+ /*if (spell->GetEffect(EFFECT_1)->ApplyAuraName == SPELL_AURA_DUMMY)
{
AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
- }
+ }*/
}
};
@@ -1264,7 +1266,7 @@ class spell_gen_despawn_self : public SpellScriptLoader
void HandleDummy(SpellEffIndex effIndex)
{
- if (GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->Effects[effIndex].Effect == SPELL_EFFECT_SCRIPT_EFFECT)
+ if (GetSpellInfo()->GetEffect(effIndex)->Effect == SPELL_EFFECT_DUMMY || GetSpellInfo()->GetEffect(effIndex)->Effect == SPELL_EFFECT_SCRIPT_EFFECT)
GetCaster()->ToCreature()->DespawnOrUnsummon();
}
@@ -1945,10 +1947,10 @@ class spell_gen_mounted_charge: public SpellScriptLoader
{
SpellInfo const* spell = sSpellMgr->EnsureSpellInfo(m_scriptSpellId);
- if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT))
+ if (spell->HasEffect(DIFFICULTY_NONE, SPELL_EFFECT_SCRIPT_EFFECT))
OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
- if (spell->Effects[EFFECT_0].Effect == SPELL_EFFECT_CHARGE)
+ if (spell->GetEffect(EFFECT_0)->Effect == SPELL_EFFECT_CHARGE)
OnEffectHitTarget += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleChargeEffect, EFFECT_0, SPELL_EFFECT_CHARGE);
}
};
@@ -2426,8 +2428,8 @@ class spell_gen_oracle_wolvar_reputation : public SpellScriptLoader
void HandleDummy(SpellEffIndex effIndex)
{
Player* player = GetCaster()->ToPlayer();
- uint32 factionId = GetSpellInfo()->Effects[effIndex].CalcValue();
- int32 repChange = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ uint32 factionId = GetSpellInfo()->GetEffect(effIndex)->CalcValue();
+ int32 repChange = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue();
FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
if (!factionEntry)
@@ -3845,7 +3847,7 @@ public:
void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
{
- if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell))
+ if (GetCaster()->HasAura(SPELL_MIXOLOGY) && GetCaster()->HasSpell(GetSpellInfo()->GetEffect(EFFECT_0)->TriggerSpell))
{
switch (GetId())
{
diff --git a/src/server/scripts/Spells/spell_holiday.cpp b/src/server/scripts/Spells/spell_holiday.cpp
index 5c84f3045f8..a5eec35d95b 100644
--- a/src/server/scripts/Spells/spell_holiday.cpp
+++ b/src/server/scripts/Spells/spell_holiday.cpp
@@ -691,7 +691,7 @@ class spell_brewfest_relay_race_intro_force_player_to_throw : public SpellScript
PreventHitDefaultEffect(effIndex);
// All this spells trigger a spell that requires reagents; if the
// triggered spell is cast as "triggered", reagents are not consumed
- GetHitUnit()->CastSpell((Unit*)NULL, GetSpellInfo()->Effects[effIndex].TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST));
+ GetHitUnit()->CastSpell((Unit*)NULL, GetSpellInfo()->GetEffect(effIndex)->TriggerSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_POWER_AND_REAGENT_COST));
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index f8ef7862c35..9f7f0dc4a5b 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -231,42 +231,6 @@ class spell_hun_disengage : public SpellScriptLoader
}
};
-// 82926 - Fire!
-class spell_hun_fire : public SpellScriptLoader
-{
- public:
- spell_hun_fire() : SpellScriptLoader("spell_hun_fire") { }
-
- class spell_hun_fire_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_hun_fire_AuraScript);
-
- void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
- {
- if (!spellMod)
- {
- spellMod = new SpellModifier(GetAura());
- spellMod->op = SPELLMOD_CASTING_TIME;
- spellMod->type = SPELLMOD_PCT;
- spellMod->spellId = GetId();
- spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
- }
-
- spellMod->value = -aurEff->GetAmount();
- }
-
- void Register() override
- {
- DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_hun_fire_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_hun_fire_AuraScript();
- }
-};
-
// -19572 - Improved Mend Pet
class spell_hun_improved_mend_pet : public SpellScriptLoader
{
@@ -308,42 +272,6 @@ class spell_hun_improved_mend_pet : public SpellScriptLoader
}
};
-// -19464 Improved Serpent Sting
-class spell_hun_improved_serpent_sting : public SpellScriptLoader
-{
- public:
- spell_hun_improved_serpent_sting() : SpellScriptLoader("spell_hun_improved_serpent_sting") { }
-
- class spell_hun_improved_serpent_sting_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_hun_improved_serpent_sting_AuraScript);
-
- void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
- {
- if (!spellMod)
- {
- spellMod = new SpellModifier(GetAura());
- spellMod->op = SpellModOp(aurEff->GetMiscValue());
- spellMod->type = SPELLMOD_PCT;
- spellMod->spellId = GetId();
- spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
- }
-
- spellMod->value = aurEff->GetAmount();
- }
-
- void Register() override
- {
- DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_hun_improved_serpent_sting_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_hun_improved_serpent_sting_AuraScript();
- }
-};
-
// 53412 - Invigoration
class spell_hun_invigoration : public SpellScriptLoader
{
@@ -430,7 +358,7 @@ class spell_hun_masters_call : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) ||
- !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
+ !sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->CalcValue()))
return false;
return true;
}
@@ -1087,9 +1015,7 @@ void AddSC_hunter_spell_scripts()
new spell_hun_chimera_shot();
new spell_hun_cobra_shot();
new spell_hun_disengage();
- new spell_hun_fire();
new spell_hun_improved_mend_pet();
- new spell_hun_improved_serpent_sting();
new spell_hun_invigoration();
new spell_hun_last_stand_pet();
new spell_hun_masters_call();
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index 17c72ba5561..baf7ff48cb5 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -221,7 +221,7 @@ class spell_mage_blast_wave : public SpellScriptLoader
}
private:
- uint32 _targetCount;
+ uint32 _targetCount = 0;
};
SpellScript* GetSpellScript() const override
@@ -497,7 +497,7 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader
void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
{
- Unit* target = GetTarget();
+ /*Unit* target = GetTarget();
if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_MAGE_FROST_WARDING_R1, EFFECT_0))
{
int32 chance = talentAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue(); // SPELL_EFFECT_DUMMY with NO_TARGET
@@ -510,7 +510,7 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader
absorbAmount = 0;
PreventDefaultAction();
}
- }
+ }*/
}
void Register() override
@@ -738,7 +738,7 @@ class spell_mage_living_bomb : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo)
{
- if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_1].CalcValue())))
+ if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->GetEffect(EFFECT_1)->CalcValue())))
return false;
return true;
}
@@ -780,7 +780,7 @@ class spell_mage_ice_barrier : public SpellScriptLoader
{
canBeRecalculated = false;
if (Unit* caster = GetCaster())
- amount += int32(0.87f * caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()));
+ amount += int32(4.95f * caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()));
}
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
@@ -836,7 +836,7 @@ class spell_mage_ignite : public SpellScriptLoader
SpellInfo const* igniteDot = sSpellMgr->EnsureSpellInfo(SPELL_MAGE_IGNITE);
int32 pct = 8 * GetSpellInfo()->GetRank();
- int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks());
+ int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks(DIFFICULTY_NONE));
amount += eventInfo.GetProcTarget()->GetRemainingPeriodicAmount(eventInfo.GetActor()->GetGUID(), SPELL_MAGE_IGNITE, SPELL_AURA_PERIODIC_DAMAGE);
GetTarget()->CastCustomSpell(SPELL_MAGE_IGNITE, SPELLVALUE_BASE_POINT0, amount, eventInfo.GetProcTarget(), true, NULL, aurEff);
}
@@ -1078,12 +1078,6 @@ class spell_mage_polymorph : public SpellScriptLoader
return true;
}
- bool Load() override
- {
- _caster = NULL;
- return true;
- }
-
bool DoCheck(ProcEventInfo& eventInfo)
{
_caster = GetCaster();
@@ -1111,7 +1105,7 @@ class spell_mage_polymorph : public SpellScriptLoader
}
private:
- Unit* _caster;
+ Unit* _caster = nullptr;
};
AuraScript* GetAuraScript() const override
@@ -1254,7 +1248,7 @@ class spell_mage_ring_of_frost : public SpellScriptLoader
void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
std::list<Creature*> MinionList;
- GetTarget()->GetAllMinionsByEntry(MinionList, GetSpellInfo()->Effects[EFFECT_0].MiscValue);
+ GetTarget()->GetAllMinionsByEntry(MinionList, GetSpellInfo()->GetEffect(EFFECT_0)->MiscValue);
// Get the last summoned RoF, save it and despawn older ones
for (std::list<Creature*>::iterator itr = MinionList.begin(); itr != MinionList.end(); itr++)
@@ -1313,7 +1307,7 @@ class spell_mage_ring_of_frost_freeze : public SpellScriptLoader
void FilterTargets(std::list<WorldObject*>& targets)
{
- float outRadius = sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)->Effects[EFFECT_0].CalcRadius();
+ float outRadius = sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)->GetEffect(EFFECT_0)->CalcRadius();
float inRadius = 4.7f;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
@@ -1456,7 +1450,7 @@ class spell_mage_water_elemental_freeze : public SpellScriptLoader
}
private:
- bool _didHit;
+ bool _didHit = false;
};
SpellScript* GetSpellScript() const
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 1dab620a9c7..f4afee89d6f 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -401,62 +401,6 @@ class spell_pal_blessing_of_faith : public SpellScriptLoader
}
};
-// 64205 - Divine Sacrifice
-class spell_pal_divine_sacrifice : public SpellScriptLoader
-{
- public:
- spell_pal_divine_sacrifice() : SpellScriptLoader("spell_pal_divine_sacrifice") { }
-
- class spell_pal_divine_sacrifice_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_pal_divine_sacrifice_AuraScript);
-
- uint32 groupSize, minHpPct;
- int32 remainingAmount;
-
- bool Load() override
- {
-
- if (Unit* caster = GetCaster())
- {
- if (caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (caster->ToPlayer()->GetGroup())
- groupSize = caster->ToPlayer()->GetGroup()->GetMembersCount();
- else
- groupSize = 1;
- }
- else
- return false;
-
- remainingAmount = (caster->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster)) * groupSize);
- minHpPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster);
- return true;
- }
- return false;
- }
-
- void Split(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & splitAmount)
- {
- remainingAmount -= splitAmount;
- // break when absorbed everything it could, or if the casters hp drops below 20%
- if (Unit* caster = GetCaster())
- if (remainingAmount <= 0 || (caster->GetHealthPct() < minHpPct))
- caster->RemoveAura(SPELL_PALADIN_DIVINE_SACRIFICE);
- }
-
- void Register() override
- {
- OnEffectSplit += AuraEffectSplitFn(spell_pal_divine_sacrifice_AuraScript::Split, EFFECT_0);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_pal_divine_sacrifice_AuraScript();
- }
-};
-
// 53385 - Divine Storm
class spell_pal_divine_storm : public SpellScriptLoader
{
@@ -485,7 +429,7 @@ class spell_pal_divine_storm : public SpellScriptLoader
bool Load() override
{
- healPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster());
+ healPct = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue(GetCaster());
return true;
}
@@ -1279,7 +1223,6 @@ void AddSC_paladin_spell_scripts()
new spell_pal_avenging_wrath();
new spell_pal_beacon_of_light();
new spell_pal_blessing_of_faith();
- new spell_pal_divine_sacrifice();
new spell_pal_divine_storm();
new spell_pal_divine_storm_dummy();
new spell_pal_exorcism_and_holy_wrath_damage();
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
index 9fd55ae057e..042f1c321ee 100644
--- a/src/server/scripts/Spells/spell_pet.cpp
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -915,7 +915,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
- AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue());
+ AddPct(mod, spellInfo->GetEffect(EFFECT_0)->CalcValue());
}
ownerBonus = owner->GetStat(STAT_STAMINA)*mod;
@@ -958,7 +958,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
- mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ mod += CalculatePct(1.0f, spellInfo->GetEffect(EFFECT_1)->CalcValue());
}
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
@@ -988,7 +988,7 @@ public:
if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
{
SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
- mod += CalculatePct(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ mod += CalculatePct(1.0f, spellInfo->GetEffect(EFFECT_1)->CalcValue());
}
bonusDamage = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod;
@@ -1450,7 +1450,7 @@ public:
amount = -90;
// Night of the dead
else if (Aura* aur = owner->GetAuraOfRankedSpell(SPELL_NIGHT_OF_THE_DEAD))
- amount = aur->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ amount = aur->GetSpellInfo()->GetEffect(EFFECT_2)->CalcValue();
}
}
}
@@ -1502,7 +1502,7 @@ public:
// Ravenous Dead. Check just if owner has Ravenous Dead since it's effect is not an aura
if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0))
- mod += aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()/100; // Ravenous Dead edits the original scale
+ mod += aurEff->GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()/100; // Ravenous Dead edits the original scale
// Glyph of the Ghoul
if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL, 0))
@@ -1547,7 +1547,7 @@ public:
aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0);
if (aurEff)
{
- mod += CalculatePct(mod, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale
+ mod += CalculatePct(mod, aurEff->GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue()); // Ravenous Dead edits the original scale
}
// Glyph of the Ghoul
aurEff = owner->GetAuraEffect(58686, 0);
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 8ec5450072f..77386808136 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -369,7 +369,7 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
PreventDefaultAction();
SpellInfo const* triggeredSpellInfo = sSpellMgr->EnsureSpellInfo(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL);
- int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks());
+ int32 heal = int32(CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount()) / triggeredSpellInfo->GetMaxTicks(DIFFICULTY_NONE));
GetTarget()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL, SPELLVALUE_BASE_POINT0, heal, eventInfo.GetProcTarget(), true, NULL, aurEff);
}
@@ -402,7 +402,7 @@ class spell_pri_improved_power_word_shield : public SpellScriptLoader
spellMod->op = SpellModOp(aurEff->GetMiscValue());
spellMod->type = SPELLMOD_PCT;
spellMod->spellId = GetId();
- spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
+ spellMod->mask = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->SpellClassMask;
}
spellMod->value = aurEff->GetAmount();
@@ -483,7 +483,7 @@ class spell_pri_guardian_spirit : public SpellScriptLoader
bool Load() override
{
- healPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ healPct = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue();
return true;
}
@@ -752,7 +752,7 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
{
uint32 damage = std::max(aur->GetAmount(), 0);
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aur->SetDamage(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), damage, DOT) * aur->GetDonePct());
+ aur->SetDamage(caster->SpellDamageBonusDone(target, aur->GetSpellInfo(), damage, DOT, aur->GetSpellEffectInfo()) * aur->GetDonePct());
aur->CalculatePeriodic(caster, false, false);
aur->GetBase()->RefreshDuration();
}
@@ -1016,8 +1016,8 @@ class spell_pri_renew : public SpellScriptLoader
// Divine Touch
if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_DIVINE_TOUCH_TALENT, EFFECT_0))
{
- uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), aurEff->GetAmount(), DOT);
- heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
+ uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), aurEff->GetAmount(), DOT, aurEff->GetSpellEffectInfo());
+ heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, aurEff->GetSpellEffectInfo());
int32 basepoints0 = CalculatePct(int32(heal) * aurEff->GetTotalTicks(), empoweredRenewAurEff->GetAmount());
caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_DIVINE_TOUCH, &basepoints0, NULL, NULL, true, NULL, aurEff);
}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 580549a3d99..e9cf81f2e64 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -635,12 +635,12 @@ class spell_q12683_take_sputum_sample : public SpellScriptLoader
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- uint32 reqAuraId = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
+ uint32 reqAuraId = GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue();
Unit* caster = GetCaster();
if (caster->HasAuraEffect(reqAuraId, 0))
{
- uint32 spellId = GetSpellInfo()->Effects[EFFECT_0].CalcValue();
+ uint32 spellId = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue();
caster->CastSpell(caster, spellId, true, NULL);
}
}
@@ -1850,7 +1850,7 @@ class spell_q13086_cannons_target : public SpellScriptLoader
bool Validate(SpellInfo const* spellInfo) override
{
- if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
+ if (!sSpellMgr->GetSpellInfo(spellInfo->GetEffect(EFFECT_0)->CalcValue()))
return false;
return true;
}
@@ -2011,7 +2011,7 @@ class spell_q12308_escape_from_silverbrook_summon_worgen : public SpellScriptLoa
void ModDest(SpellDestination& dest)
{
- float dist = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ float dist = GetSpellInfo()->GetEffect(EFFECT_0)->CalcRadius(GetCaster());
float angle = frand(0.75f, 1.25f) * float(M_PI);
Position pos = GetCaster()->GetNearPosition(dist, angle);
@@ -2151,7 +2151,7 @@ class spell_q12619_emblazon_runeblade : public SpellScriptLoader
{
PreventDefaultAction();
if (Unit* caster = GetCaster())
- caster->CastSpell(caster, GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell, true, NULL, aurEff);
+ caster->CastSpell(caster, GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell, true, NULL, aurEff);
}
void Register() override
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index 9b3b38875af..78ebe0734b5 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -145,7 +145,8 @@ class spell_rog_cheat_death : public SpellScriptLoader
bool Load() override
{
- absorbChance = GetSpellInfo()->Effects[EFFECT_0].CalcValue();
+ // 6.x has basepoint = 0 !
+ absorbChance = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue();
return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER;
}
@@ -491,57 +492,6 @@ class spell_rog_master_of_subtlety : public SpellScriptLoader
}
};
-// 31130 - Nerves of Steel
-class spell_rog_nerves_of_steel : public SpellScriptLoader
-{
- public:
- spell_rog_nerves_of_steel() : SpellScriptLoader("spell_rog_nerves_of_steel") { }
-
- class spell_rog_nerves_of_steel_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_rog_nerves_of_steel_AuraScript);
-
- public:
- spell_rog_nerves_of_steel_AuraScript()
- {
- absorbPct = 0;
- }
-
- private:
- uint32 absorbPct;
-
- bool Load() override
- {
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
- return true;
- }
-
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
- {
- // Set absorbtion amount to unlimited
- amount = -1;
- }
-
- void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
- {
- // reduces all damage taken while stun or fear
- if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_FLEEING) || (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)))
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
- }
-
- void Register() override
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_nerves_of_steel_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_rog_nerves_of_steel_AuraScript::Absorb, EFFECT_0);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_rog_nerves_of_steel_AuraScript();
- }
-};
-
// 58428 - Overkill
class spell_rog_overkill : public SpellScriptLoader
{
@@ -642,51 +592,6 @@ class spell_rog_preparation : public SpellScriptLoader
}
};
-// 51685 - Prey on the Weak
-class spell_rog_prey_on_the_weak : public SpellScriptLoader
-{
- public:
- spell_rog_prey_on_the_weak() : SpellScriptLoader("spell_rog_prey_on_the_weak") { }
-
- class spell_rog_prey_on_the_weak_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_rog_prey_on_the_weak_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_PREY_ON_THE_WEAK))
- return false;
- return true;
- }
-
- void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
- {
- Unit* target = GetTarget();
- Unit* victim = target->GetVictim();
- if (victim && (target->GetHealthPct() > victim->GetHealthPct()))
- {
- if (!target->HasAura(SPELL_ROGUE_PREY_ON_THE_WEAK))
- {
- int32 bp = GetSpellInfo()->Effects[EFFECT_0].CalcValue();
- target->CastCustomSpell(target, SPELL_ROGUE_PREY_ON_THE_WEAK, &bp, nullptr, nullptr, true);
- }
- }
- else
- target->RemoveAurasDueToSpell(SPELL_ROGUE_PREY_ON_THE_WEAK);
- }
-
- void Register() override
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_prey_on_the_weak_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_rog_prey_on_the_weak_AuraScript();
- }
-};
-
// 73651 - Recuperate
class spell_rog_recuperate : public SpellScriptLoader
{
@@ -714,7 +619,7 @@ class spell_rog_recuperate : public SpellScriptLoader
canBeRecalculated = false;
if (Unit* caster = GetCaster())
{
- int32 baseAmount = GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster) * 1000;
+ int32 baseAmount = GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue(caster) * 1000;
// Improved Recuperate
if (AuraEffect const* auraEffect = caster->GetDummyAuraEffect(SPELLFAMILY_ROGUE, ICON_ROGUE_IMPROVED_RECUPERATE, EFFECT_0))
baseAmount += auraEffect->GetAmount();
@@ -1028,10 +933,8 @@ void AddSC_rogue_spell_scripts()
new spell_rog_deadly_poison();
new spell_rog_killing_spree();
new spell_rog_master_of_subtlety();
- new spell_rog_nerves_of_steel();
new spell_rog_overkill();
new spell_rog_preparation();
- new spell_rog_prey_on_the_weak();
new spell_rog_recuperate();
new spell_rog_rupture();
new spell_rog_shiv();
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index 5e8e3a1070f..8e363c6f125 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -236,7 +236,7 @@ class spell_sha_chain_heal : public SpellScriptLoader
if (AuraEffect* aurEff = GetHitUnit()->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, GetCaster()->GetGUID()))
{
riptide = true;
- amount = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ amount = aurEff->GetSpellInfo()->GetEffect(DIFFICULTY_NONE, EFFECT_2)->CalcValue();
// Consume it
GetHitUnit()->RemoveAura(aurEff->GetBase());
}
@@ -284,12 +284,12 @@ class spell_sha_earth_shield : public SpellScriptLoader
return true;
}
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/)
+ void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool & /*canBeRecalculated*/)
{
if (Unit* caster = GetCaster())
{
- amount = caster->SpellHealingBonusDone(GetUnitOwner(), GetSpellInfo(), amount, HEAL);
- amount = GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, HEAL);
+ amount = caster->SpellHealingBonusDone(GetUnitOwner(), GetSpellInfo(), amount, HEAL, aurEff->GetSpellEffectInfo());
+ amount = GetUnitOwner()->SpellHealingBonusTaken(caster, GetSpellInfo(), amount, HEAL, aurEff->GetSpellEffectInfo());
//! WORKAROUND
// If target is affected by healing reduction, modifier is guaranteed to be negative
@@ -561,44 +561,6 @@ class spell_sha_flame_shock : public SpellScriptLoader
}
};
-// 77794 - Focused Insight
-class spell_sha_focused_insight : public SpellScriptLoader
-{
- public:
- spell_sha_focused_insight() : SpellScriptLoader("spell_sha_focused_insight") { }
-
- class spell_sha_focused_insight_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_sha_focused_insight_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_FOCUSED_INSIGHT))
- return false;
- return true;
- }
-
- void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
- {
- PreventDefaultAction();
- int32 basePoints0 = aurEff->GetAmount();
- int32 basePoints1 = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue();
-
- GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_FOCUSED_INSIGHT, &basePoints0, &basePoints1, &basePoints1, true, NULL, aurEff);
- }
-
- void Register() override
- {
- OnEffectProc += AuraEffectProcFn(spell_sha_focused_insight_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_sha_focused_insight_AuraScript();
- }
-};
-
// 55440 - Glyph of Healing Wave
class spell_sha_glyph_of_healing_wave : public SpellScriptLoader
{
@@ -659,26 +621,26 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
return sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL) != nullptr;
}
- void HandleDummy(SpellEffIndex /* effIndex */)
+ void HandleDummy(SpellEffIndex effIndex)
{
int32 damage = GetEffectValue();
SpellInfo const* triggeringSpell = GetTriggeringSpell();
if (Unit* target = GetHitUnit())
- if (Unit* caster = GetCaster())
+ {
+ if (Unit* owner = GetCaster()->GetOwner())
{
- if (Unit* owner = caster->GetOwner())
- {
- if (triggeringSpell)
- damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL));
-
- // Soothing Rains
- if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SOOTHING_RAIN, EFFECT_0))
- AddPct(damage, dummy->GetAmount());
-
- damage = int32(target->SpellHealingBonusTaken(owner, triggeringSpell, damage, HEAL));
- }
- caster->CastCustomSpell(target, SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID());
+ if (triggeringSpell)
+ damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL, triggeringSpell->GetEffect(target, effIndex)));
+
+ // Soothing Rains
+ if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SOOTHING_RAIN, EFFECT_0))
+ AddPct(damage, dummy->GetAmount());
+
+ if (triggeringSpell)
+ damage = int32(target->SpellHealingBonusTaken(owner, triggeringSpell, damage, HEAL, triggeringSpell->GetEffect(target, effIndex)));
}
+ GetCaster()->CastCustomSpell(target, SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID());
+ }
}
void Register() override
@@ -1072,7 +1034,7 @@ class spell_sha_nature_guardian : public SpellScriptLoader
eventInfo.GetProcTarget()->getThreatManager().modifyThreatPercent(GetTarget(), -10);
if (Player* player = GetTarget()->ToPlayer())
- player->AddSpellCooldown(GetSpellInfo()->Id, 0, time(NULL) + aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue());
+ player->AddSpellCooldown(GetSpellInfo()->Id, 0, time(NULL) + aurEff->GetSpellInfo()->GetEffect(EFFECT_1)->CalcValue());
}
void Register() override
@@ -1242,7 +1204,6 @@ void AddSC_shaman_spell_scripts()
new spell_sha_feedback();
new spell_sha_fire_nova();
new spell_sha_flame_shock();
- new spell_sha_focused_insight();
new spell_sha_glyph_of_healing_wave();
new spell_sha_healing_stream_totem();
new spell_sha_heroism();
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 128cddef1c1..5e745f6ab00 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -201,15 +201,16 @@ class spell_warl_conflagrate : public SpellScriptLoader
return true;
}
- void HandleHit(SpellEffIndex /*effIndex*/)
- {
- if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_WARLOCK_IMMOLATE, EFFECT_2, GetCaster()->GetGUID()))
- SetHitDamage(CalculatePct(aurEff->GetAmount(), GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster())));
- }
+ // 6.x dmg formula in tooltip
+ // void HandleHit(SpellEffIndex /*effIndex*/)
+ // {
+ // if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_WARLOCK_IMMOLATE, EFFECT_2, GetCaster()->GetGUID()))
+ // SetHitDamage(CalculatePct(aurEff->GetAmount(), GetSpellInfo()->Effects[EFFECT_1].CalcValue(GetCaster())));
+ // }
void Register() override
{
- OnEffectHitTarget += SpellEffectFn(spell_warl_conflagrate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ //OnEffectHitTarget += SpellEffectFn(spell_warl_conflagrate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
@@ -426,7 +427,7 @@ class spell_warl_demon_soul : public SpellScriptLoader
{
if (targetCreature->IsPet())
{
- CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry());
+ CreatureTemplate const* ci = targetCreature->GetCreatureTemplate();
switch (ci->family)
{
case CREATURE_FAMILY_SUCCUBUS:
@@ -485,8 +486,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader
{
if (targetCreature->IsPet())
{
- CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry());
- ASSERT(ci);
+ CreatureTemplate const* ci = targetCreature->GetCreatureTemplate();
switch (ci->family)
{
case CREATURE_FAMILY_SUCCUBUS:
@@ -536,7 +536,7 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
{
PrepareSpellScript(spell_warl_everlasting_affliction_SpellScript);
- void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ void HandleScriptEffect(SpellEffIndex effIndex)
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
@@ -545,7 +545,7 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
{
uint32 damage = std::max(aurEff->GetAmount(), 0);
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, damage);
- aurEff->SetDamage(caster->SpellDamageBonusDone(target, aurEff->GetSpellInfo(), damage, DOT) * aurEff->GetDonePct());
+ aurEff->SetDamage(caster->SpellDamageBonusDone(target, aurEff->GetSpellInfo(), damage, DOT, GetEffectInfo(effIndex)) * aurEff->GetDonePct());
aurEff->CalculatePeriodic(caster, false, false);
aurEff->GetBase()->RefreshDuration(true);
}
@@ -563,43 +563,6 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
}
};
-// 77799 - Fel Flame - Updated to 4.3.4
-class spell_warl_fel_flame : public SpellScriptLoader
-{
- public:
- spell_warl_fel_flame() : SpellScriptLoader("spell_warl_fel_flame") { }
-
- class spell_warl_fel_flame_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_warl_fel_flame_SpellScript);
-
- void OnHitTarget(SpellEffIndex /*effIndex*/)
- {
- Unit* caster = GetCaster();
- Unit* target = GetHitUnit();
- Aura* aura = target->GetAura(SPELL_WARLOCK_UNSTABLE_AFFLICTION, caster->GetGUID());
- if (!aura)
- aura = target->GetAura(SPELL_WARLOCK_IMMOLATE, caster->GetGUID());
-
- if (!aura)
- return;
-
- int32 newDuration = aura->GetDuration() + GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 1000;
- aura->SetDuration(std::min(newDuration, aura->GetMaxDuration()));
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_warl_fel_flame_SpellScript::OnHitTarget, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_warl_fel_flame_SpellScript;
- }
-};
-
// -47230 - Fel Synergy
class spell_warl_fel_synergy : public SpellScriptLoader
{
@@ -868,7 +831,8 @@ class spell_warl_improved_soul_fire : public SpellScriptLoader
// 1454 - Life Tap
/// Updated 4.3.4
-class spell_warl_life_tap : public SpellScriptLoader
+// 6.x fully changed this
+/*class spell_warl_life_tap : public SpellScriptLoader
{
public:
spell_warl_life_tap() : SpellScriptLoader("spell_warl_life_tap") { }
@@ -882,7 +846,7 @@ class spell_warl_life_tap : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- bool Validate(SpellInfo const* /*spellInfo*/) override
+ bool Validate(SpellInfo const* spellInfo) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE) ||
!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2))
@@ -890,7 +854,7 @@ class spell_warl_life_tap : public SpellScriptLoader
return true;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ void HandleDummy(SpellEffIndex effIndex)
{
Player* caster = GetCaster()->ToPlayer();
if (Unit* target = GetHitUnit())
@@ -935,7 +899,7 @@ class spell_warl_life_tap : public SpellScriptLoader
{
return new spell_warl_life_tap_SpellScript();
}
-};
+};*/
// 687 - Demon Armor
// 28176 - Fel Armor
@@ -1194,22 +1158,18 @@ class spell_warl_soul_swap : public SpellScriptLoader
}
};
+#define SoulSwapOverrideScriptName "spell_warl_soul_swap_override"
+
// 86211 - Soul Swap Override - Also acts as a dot container
class spell_warl_soul_swap_override : public SpellScriptLoader
{
public:
- spell_warl_soul_swap_override() : SpellScriptLoader("spell_warl_soul_swap_override") { }
+ spell_warl_soul_swap_override() : SpellScriptLoader(SoulSwapOverrideScriptName) { }
class spell_warl_soul_swap_override_AuraScript : public AuraScript
{
PrepareAuraScript(spell_warl_soul_swap_override_AuraScript);
- bool Load() override
- {
- _swapCaster = NULL;
- return true;
- }
-
//! Forced to, pure virtual functions must have a body when linking
void Register() override { }
@@ -1221,7 +1181,7 @@ class spell_warl_soul_swap_override : public SpellScriptLoader
private:
std::list<uint32> _dotList;
- Unit* _swapCaster;
+ Unit* _swapCaster = nullptr;
};
AuraScript* GetAuraScript() const override
@@ -1249,14 +1209,16 @@ class spell_warl_soul_swap_dot_marker : public SpellScriptLoader
if (!warlock || !swapVictim)
return;
- flag128 classMask = GetSpellInfo()->Effects[effIndex].SpellClassMask;
+ // effect existance checked in dbc, should not be removed by core at any time, so no need to check for null
+ SpellEffectInfo const* effect = GetSpellInfo()->GetEffect(DIFFICULTY_NONE, EFFECT_0);
+ flag128 classMask = effect->SpellClassMask;
Unit::AuraApplicationMap const& appliedAuras = swapVictim->GetAppliedAuras();
- SoulSwapOverrideAuraScript* swapSpellScript = NULL;
+ SoulSwapOverrideAuraScript* swapSpellScript = nullptr;
if (Aura* swapOverrideAura = warlock->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
- swapSpellScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverrideAura->GetScriptByName("spell_warl_soul_swap_override"));
+ swapSpellScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverrideAura->GetScriptByName(SoulSwapOverrideScriptName));
- if (swapSpellScript == NULL)
+ if (!swapSpellScript)
return;
for (Unit::AuraApplicationMap::const_iterator itr = appliedAuras.begin(); itr != appliedAuras.end(); ++itr)
@@ -1303,9 +1265,9 @@ public:
SpellCastResult CheckCast()
{
Unit* currentTarget = GetExplTargetUnit();
- Unit* swapTarget = NULL;
+ Unit* swapTarget = nullptr;
if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
- if (SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override")))
+ if (SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName(SoulSwapOverrideScriptName)))
swapTarget = swapScript->GetOriginalSwapSource();
// Soul Swap Exhale can't be cast on the same target than Soul Swap
@@ -1321,10 +1283,10 @@ public:
bool hasGlyph = GetCaster()->HasAura(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP);
std::list<uint32> dotList;
- Unit* swapSource = NULL;
+ Unit* swapSource = nullptr;
if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
{
- SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override"));
+ SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName(SoulSwapOverrideScriptName));
if (!swapScript)
return;
dotList = swapScript->GetDotList();
@@ -1452,14 +1414,14 @@ void AddSC_warlock_spell_scripts()
new spell_warl_demonic_empowerment();
new spell_warl_demon_soul();
new spell_warl_everlasting_affliction();
- new spell_warl_fel_flame();
+ //new spell_warl_fel_flame();
new spell_warl_fel_synergy();
new spell_warl_glyph_of_shadowflame();
new spell_warl_haunt();
new spell_warl_health_funnel();
new spell_warl_healthstone_heal();
new spell_warl_improved_soul_fire();
- new spell_warl_life_tap();
+ //new spell_warl_life_tap();
new spell_warl_nether_ward_overrride();
new spell_warl_seduction();
new spell_warl_seed_of_corruption();
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 3b6b68d3fce..d6ff9375544 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -87,15 +87,15 @@ class spell_warr_bloodthirst : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_bloodthirst_SpellScript);
- void HandleDamage(SpellEffIndex /*effIndex*/)
+ void HandleDamage(SpellEffIndex effIndex)
{
int32 damage = GetEffectValue();
ApplyPct(damage, GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK));
if (Unit* target = GetHitUnit())
{
- damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
- damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
+ damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE, GetEffectInfo(effIndex));
+ damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE, GetEffectInfo(effIndex));
}
SetHitDamage(damage);
}
@@ -120,34 +120,6 @@ class spell_warr_bloodthirst : public SpellScriptLoader
};
/// Updated 4.3.4
-class spell_warr_bloodthirst_heal : public SpellScriptLoader
-{
- public:
- spell_warr_bloodthirst_heal() : SpellScriptLoader("spell_warr_bloodthirst_heal") { }
-
- class spell_warr_bloodthirst_heal_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_warr_bloodthirst_heal_SpellScript);
-
- void HandleHeal(SpellEffIndex /*effIndex*/)
- {
- if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_BLOODTHIRST_DAMAGE))
- SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())) / 100);
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_warr_bloodthirst_heal_SpellScript();
- }
-};
-
-/// Updated 4.3.4
class spell_warr_charge : public SpellScriptLoader
{
public:
@@ -216,59 +188,6 @@ class spell_warr_concussion_blow : public SpellScriptLoader
}
};
-// -12162 - Deep Wounds
-class spell_warr_deep_wounds : public SpellScriptLoader
-{
- public:
- spell_warr_deep_wounds() : SpellScriptLoader("spell_warr_deep_wounds") { }
-
- class spell_warr_deep_wounds_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_warr_deep_wounds_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) override
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_1) ||
- !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_2) ||
- !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_RANK_3) ||
- !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC))
- return false;
- return true;
- }
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- int32 damage = GetEffectValue();
- Unit* caster = GetCaster();
- if (Unit* target = GetHitUnit())
- {
- ApplyPct(damage, 16 * GetSpellInfo()->GetRank());
-
- SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC);
- uint32 ticks = uint32(spellInfo->GetDuration()) / spellInfo->Effects[EFFECT_0].ApplyAuraPeriod;
-
- // Add remaining ticks to damage done
- if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, EFFECT_0, caster->GetGUID()))
- damage += aurEff->GetDamage() * int32(ticks - aurEff->GetTickNumber());
-
- damage /= int32(ticks);
-
- caster->CastCustomSpell(target, SPELL_WARRIOR_DEEP_WOUNDS_PERIODIC, &damage, NULL, NULL, true);
- }
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_warr_deep_wounds_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_warr_deep_wounds_SpellScript();
- }
-};
-
/// Updated 4.3.4
class spell_warr_execute : public SpellScriptLoader
{
@@ -281,7 +200,7 @@ class spell_warr_execute : public SpellScriptLoader
void HandleEffect(SpellEffIndex /*effIndex*/)
{
- Unit* caster = GetCaster();
+ /*Unit* caster = GetCaster();
if (GetHitUnit())
{
SpellInfo const* spellInfo = GetSpellInfo();
@@ -302,7 +221,7 @@ class spell_warr_execute : public SpellScriptLoader
/// Formula taken from the DBC: "${$ap*0.874*$m1/100-1} = 20 rage"
int32 moreDamage = int32(rageUsed * (caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.874f * GetEffectValue() / 100.0f - 1) / 200);
SetHitDamage(baseDamage + moreDamage);
- }
+ }*/
}
void Register() override
@@ -317,42 +236,6 @@ class spell_warr_execute : public SpellScriptLoader
}
};
-// 58387 - Glyph of Sunder Armor
-class spell_warr_glyph_of_sunder_armor : public SpellScriptLoader
-{
- public:
- spell_warr_glyph_of_sunder_armor() : SpellScriptLoader("spell_warr_glyph_of_sunder_armor") { }
-
- class spell_warr_glyph_of_sunder_armor_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_warr_glyph_of_sunder_armor_AuraScript);
-
- void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
- {
- if (!spellMod)
- {
- spellMod = new SpellModifier(aurEff->GetBase());
- spellMod->op = SpellModOp(aurEff->GetMiscValue());
- spellMod->type = SPELLMOD_FLAT;
- spellMod->spellId = GetId();
- spellMod->mask = GetSpellInfo()->Effects[aurEff->GetEffIndex()].SpellClassMask;
- }
-
- spellMod->value = aurEff->GetAmount();
- }
-
- void Register() override
- {
- DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_warr_glyph_of_sunder_armor_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_warr_glyph_of_sunder_armor_AuraScript();
- }
-};
-
// 59725 - Improved Spell Reflection
class spell_warr_improved_spell_reflection : public SpellScriptLoader
{
@@ -991,11 +874,11 @@ class spell_warr_vigilance : public SpellScriptLoader
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
- PreventDefaultAction();
+ /*PreventDefaultAction();
int32 damage = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()));
GetTarget()->CastSpell(_procTarget, SPELL_WARRIOR_VIGILANCE_PROC, true, NULL, aurEff);
- _procTarget->CastCustomSpell(_procTarget, SPELL_WARRIOR_VENGEANCE, &damage, &damage, &damage, true, NULL, aurEff);
+ _procTarget->CastCustomSpell(_procTarget, SPELL_WARRIOR_VENGEANCE, &damage, &damage, &damage, true, NULL, aurEff);*/
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
@@ -1058,12 +941,9 @@ class spell_warr_vigilance_trigger : public SpellScriptLoader
void AddSC_warrior_spell_scripts()
{
new spell_warr_bloodthirst();
- new spell_warr_bloodthirst_heal();
new spell_warr_charge();
new spell_warr_concussion_blow();
- new spell_warr_deep_wounds();
new spell_warr_execute();
- new spell_warr_glyph_of_sunder_armor();
new spell_warr_improved_spell_reflection();
new spell_warr_intimidating_shout();
new spell_warr_lambs_to_the_slaughter();
diff --git a/src/server/scripts/World/action_ip_logger.cpp b/src/server/scripts/World/action_ip_logger.cpp
index 9d2aa868234..c82459d0599 100644
--- a/src/server/scripts/World/action_ip_logger.cpp
+++ b/src/server/scripts/World/action_ip_logger.cpp
@@ -16,13 +16,10 @@
*/
#include "ScriptMgr.h"
-#include "Channel.h"
-#include "Guild.h"
-#include "Group.h"
+#include "Player.h"
enum IPLoggingTypes
{
-
// AccountActionIpLogger();
ACCOUNT_LOGIN = 0,
ACCOUNT_FAIL_LOGIN = 1,
diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp
index 17c37c7eba0..3e89041a9e9 100644
--- a/src/server/scripts/World/npc_professions.cpp
+++ b/src/server/scripts/World/npc_professions.cpp
@@ -234,9 +234,12 @@ bool EquippedOk(Player* player, uint32 spellId)
if (!spell)
return false;
- for (uint8 i = 0; i < 3; ++i)
+ for (SpellEffectInfo const* effect : spell->GetEffectsForDifficulty(DIFFICULTY_NONE))
{
- uint32 reqSpell = spell->Effects[i].TriggerSpell;
+ if (!effect)
+ continue;
+
+ uint32 reqSpell = effect->TriggerSpell;
if (!reqSpell)
continue;
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 57c0ddf066e..34699c19648 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -2159,8 +2159,8 @@ public:
const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (spellInfo && spellInfo->Effects[0].Effect == SPELL_EFFECT_SUMMON_OBJECT_WILD)
- return spellInfo->Effects[0].MiscValue;
+ if (spellInfo && spellInfo->GetEffect(EFFECT_0)->Effect == SPELL_EFFECT_SUMMON_OBJECT_WILD)
+ return spellInfo->GetEffect(EFFECT_0)->MiscValue;
return 0;
}
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
index 4e23b4a4770..578bc7aa61f 100644
--- a/src/server/shared/Common.h
+++ b/src/server/shared/Common.h
@@ -79,6 +79,9 @@
inline float finiteAlways(float f) { return std::isfinite(f) ? f : 0.0f; }
+inline unsigned long atoul(char const* str) { return strtoul(str, nullptr, 10); }
+inline unsigned long long atoull(char const* str) { return strtoull(str, nullptr, 10); }
+
#define STRINGIZE(a) #a
enum TimeConstants
@@ -118,7 +121,6 @@ const uint8 TOTAL_LOCALES = 9;
#define DEFAULT_LOCALE LOCALE_enUS
#define MAX_LOCALES 8
-#define MAX_ACCOUNT_TUTORIAL_VALUES 8
extern char const* localeNames[TOTAL_LOCALES];
diff --git a/src/server/shared/Networking/Socket.h b/src/server/shared/Networking/Socket.h
index d3e29ceaaea..5c891d925fa 100644
--- a/src/server/shared/Networking/Socket.h
+++ b/src/server/shared/Networking/Socket.h
@@ -34,7 +34,9 @@
using boost::asio::ip::tcp;
#define READ_BLOCK_SIZE 4096
-#define TC_SOCKET_USE_IOCP BOOST_ASIO_HAS_IOCP
+#ifdef BOOST_ASIO_HAS_IOCP
+#define TC_SOCKET_USE_IOCP
+#endif
template<class T>
class Socket : public std::enable_shared_from_this<T>
diff --git a/src/server/shared/Networking/SocketMgr.h b/src/server/shared/Networking/SocketMgr.h
index 92c16d96882..c004295bc1a 100644
--- a/src/server/shared/Networking/SocketMgr.h
+++ b/src/server/shared/Networking/SocketMgr.h
@@ -47,7 +47,16 @@ public:
return false;
}
- _acceptor = new AsyncAcceptor(service, bindIp, port);
+ try
+ {
+ _acceptor = new AsyncAcceptor(service, bindIp, port);
+ }
+ catch (boost::system::system_error const& err)
+ {
+ TC_LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork (%s:%u): %s", bindIp.c_str(), port, err.what());
+ return false;
+ }
+
_threads = CreateThreads();
ASSERT(_threads);
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index 8a4f7325add..5aaedfb8ffe 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -33,21 +33,21 @@
template<typename T>
struct Optional
{
- Optional() : value(), HasValue(false) { }
+ Optional() : Value(), HasValue(false) { }
- T value;
+ T Value;
bool HasValue;
inline void Set(T const& v)
{
HasValue = true;
- value = v;
+ Value = v;
}
inline void Clear()
{
HasValue = false;
- value = T();
+ Value = T();
}
};
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 71bc9233f87..1aefbfa13de 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -93,7 +93,7 @@ LogsDir = ""
# Default: "127.0.0.1;3306;trinity;trinity;auth" - (LoginDatabaseInfo)
# "127.0.0.1;3306;trinity;trinity;world" - (WorldDatabaseInfo)
# "127.0.0.1;3306;trinity;trinity;characters" - (CharacterDatabaseInfo)
-# "127.0.0.1;3306;trinity;trinity;hotfixes" - (HotfixDatabaseInfo)
+# "127.0.0.1;3306;trinity;trinity;hotfixes" - (HotfixDatabaseInfo)
LoginDatabaseInfo = "127.0.0.1;3306;trinity;trinity;auth"
WorldDatabaseInfo = "127.0.0.1;3306;trinity;trinity;world"
@@ -3034,7 +3034,7 @@ AuctionHouseBot.Buyer.Neutral.Chance.Ratio = 3
###################################################################################################
###################################################################################################
-# LOGGING SYSTEM SETTINGS
+# LOGGING SYSTEM SETTINGS
#
# Appender config values: Given a appender "name"
# Appender.name
@@ -3192,67 +3192,6 @@ Allow.IP.Based.Action.Logging = 0
###################################################################################################
###################################################################################################
-# GUILD LEVELING SETTINGS
-#
-# Guild.LevelingEnabled
-# Description: Controls whether guild can gain levels
-# Default: 1
-#
-
-Guild.LevelingEnabled = 1
-
-#
-# Guild.SaveInterval
-# Description: Time (in minutes) between guild experience saves
-# Default: 15
-#
-
-Guild.SaveInterval = 15
-
-#
-# Guild.MaxLevel
-# Description: Defines max level a guild can reach
-# Default: 25
-#
-
-Guild.MaxLevel = 25
-
-#
-# Guild.UndeletableLevel
-# Description: Guild reaching this level (and higher) cannot be disbanded anymore
-# Default: 4
-#
-
-Guild.UndeletableLevel = 4
-
-#
-# Guild.XPModifier
-# Description: Multiplier for guild experience gained from quests
-# Default: 0.25
-#
-
-Guild.XPModifier = 0.25
-
-#
-# Guild.DailyXPCap
-# Description: Maximum experience points a guild can earn each day
-# Default: 7807500
-#
-
-Guild.DailyXPCap = 7807500
-
-#
-# Guild.WeeklyReputationCap
-# Description: Maximum guild reputation a player can earn every week
-# Default: 4375
-#
-
-Guild.WeeklyReputationCap = 4375
-
-#
-###################################################################################################
-
-###################################################################################################
# CURRENCIES SETTINGS
#
# Currency.ResetInterval