aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp26
-rw-r--r--src/server/game/AI/CoreAI/TotemAI.cpp11
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp16
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp3
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h1
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp2776
-rw-r--r--src/server/game/Achievements/AchievementMgr.h91
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp17
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h2
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp12
-rw-r--r--src/server/game/Battlefield/Battlefield.h6
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.cpp9
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.h1
-rw-r--r--src/server/game/Battlefield/Zones/BattlefieldWG.h2
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.cpp124
-rw-r--r--src/server/game/Battlegrounds/ArenaTeam.h60
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.cpp56
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.h2
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp129
-rw-r--r--src/server/game/Battlegrounds/Battleground.h23
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp811
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.h14
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp13
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp36
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundBFG.h40
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp7
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp36
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundTP.h40
-rw-r--r--src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp4
-rw-r--r--src/server/game/CMakeLists.txt1
-rw-r--r--src/server/game/Calendar/CalendarMgr.cpp8
-rw-r--r--src/server/game/Calendar/CalendarMgr.h3
-rw-r--r--src/server/game/Chat/Channels/ChannelMgr.cpp1
-rw-r--r--src/server/game/Chat/Chat.cpp30
-rw-r--r--src/server/game/Chat/Chat.h5
-rw-r--r--src/server/game/Chat/ChatLink.cpp29
-rw-r--r--src/server/game/Chat/ChatLink.h2
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp56
-rw-r--r--src/server/game/Conditions/ConditionMgr.h3
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp138
-rw-r--r--src/server/game/DataStores/DB2Stores.h35
-rw-r--r--src/server/game/DataStores/DB2Structure.h160
-rw-r--r--src/server/game/DataStores/DB2Utility.cpp171
-rw-r--r--src/server/game/DataStores/DB2Utility.h40
-rw-r--r--src/server/game/DataStores/DB2fmt.h27
-rw-r--r--src/server/game/DataStores/DBCEnums.h213
-rw-r--r--src/server/game/DataStores/DBCStores.cpp620
-rw-r--r--src/server/game/DataStores/DBCStores.h72
-rw-r--r--src/server/game/DataStores/DBCStructure.h1287
-rw-r--r--src/server/game/DataStores/DBCfmt.h186
-rw-r--r--src/server/game/DungeonFinding/LFG.h26
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp87
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.h57
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.cpp12
-rw-r--r--src/server/game/DungeonFinding/LFGQueue.h4
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp2
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp108
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h46
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp20
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp150
-rw-r--r--src/server/game/Entities/Creature/Creature.h33
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp218
-rw-r--r--src/server/game/Entities/Creature/GossipDef.h2
-rw-r--r--src/server/game/Entities/Creature/TemporarySummon.cpp10
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.cpp18
-rw-r--r--src/server/game/Entities/DynamicObject/DynamicObject.h2
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp9
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h3
-rw-r--r--src/server/game/Entities/Item/Item.cpp378
-rw-r--r--src/server/game/Entities/Item/Item.h225
-rw-r--r--src/server/game/Entities/Item/ItemPrototype.h231
-rw-r--r--src/server/game/Entities/Object/Object.cpp503
-rw-r--r--src/server/game/Entities/Object/Object.h92
-rw-r--r--src/server/game/Entities/Object/ObjectDefines.h53
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.cpp97
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateData.h39
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp1388
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFieldFlags.h1
-rw-r--r--src/server/game/Entities/Object/Updates/UpdateFields.h902
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp70
-rw-r--r--src/server/game/Entities/Pet/Pet.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp5266
-rw-r--r--src/server/game/Entities/Player/Player.h757
-rw-r--r--src/server/game/Entities/Player/SocialMgr.cpp1
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp16
-rw-r--r--src/server/game/Entities/Totem/Totem.h9
-rw-r--r--src/server/game/Entities/Transport/Transport.cpp1
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp419
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp3833
-rw-r--r--src/server/game/Entities/Unit/Unit.h274
-rw-r--r--[-rwxr-xr-x]src/server/game/Entities/Vehicle/Vehicle.cpp7
-rw-r--r--src/server/game/Entities/Vehicle/VehicleDefines.h24
-rw-r--r--src/server/game/Events/GameEventMgr.cpp11
-rw-r--r--src/server/game/Events/GameEventMgr.h1
-rw-r--r--src/server/game/Globals/ObjectAccessor.cpp9
-rw-r--r--src/server/game/Globals/ObjectAccessor.h1
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2026
-rw-r--r--src/server/game/Globals/ObjectMgr.h107
-rw-r--r--src/server/game/Grids/GridDefines.h7
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.cpp2
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h35
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiersImpl.h51
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp3
-rw-r--r--src/server/game/Grids/ObjectGridLoader.h1
-rw-r--r--src/server/game/Groups/Group.cpp62
-rw-r--r--src/server/game/Groups/Group.h58
-rw-r--r--src/server/game/Guilds/Guild.cpp1347
-rw-r--r--src/server/game/Guilds/Guild.h253
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.cpp333
-rw-r--r--src/server/game/Guilds/GuildFinderMgr.h274
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp206
-rw-r--r--src/server/game/Guilds/GuildMgr.h15
-rw-r--r--src/server/game/Handlers/ArenaTeamHandler.cpp73
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp176
-rw-r--r--src/server/game/Handlers/AuthHandler.cpp26
-rw-r--r--src/server/game/Handlers/BattleGroundHandler.cpp546
-rw-r--r--src/server/game/Handlers/BattlefieldHandler.cpp273
-rw-r--r--src/server/game/Handlers/CalendarHandler.cpp9
-rw-r--r--src/server/game/Handlers/ChannelHandler.cpp100
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp327
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp504
-rw-r--r--src/server/game/Handlers/GroupHandler.cpp558
-rw-r--r--src/server/game/Handlers/GuildFinderHandler.cpp442
-rw-r--r--src/server/game/Handlers/GuildHandler.cpp657
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp802
-rw-r--r--src/server/game/Handlers/LFGHandler.cpp555
-rw-r--r--src/server/game/Handlers/LootHandler.cpp13
-rw-r--r--src/server/game/Handlers/MailHandler.cpp139
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp450
-rw-r--r--src/server/game/Handlers/MovementHandler.cpp215
-rw-r--r--src/server/game/Handlers/NPCHandler.cpp88
-rw-r--r--src/server/game/Handlers/PetHandler.cpp38
-rw-r--r--src/server/game/Handlers/PetitionsHandler.cpp12
-rw-r--r--src/server/game/Handlers/QueryHandler.cpp16
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp130
-rw-r--r--src/server/game/Handlers/ReferAFriendHandler.cpp3
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp32
-rw-r--r--src/server/game/Handlers/SpellHandler.cpp96
-rw-r--r--src/server/game/Handlers/TaxiHandler.cpp13
-rw-r--r--src/server/game/Handlers/TicketHandler.cpp4
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp229
-rw-r--r--src/server/game/Handlers/VehicleHandler.cpp50
-rw-r--r--src/server/game/Handlers/VoiceChatHandler.cpp4
-rw-r--r--src/server/game/Handlers/VoidStorageHandler.cpp619
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.cpp4
-rw-r--r--src/server/game/Instances/InstanceSaveMgr.h8
-rw-r--r--src/server/game/Instances/InstanceScript.cpp18
-rw-r--r--src/server/game/Instances/InstanceScript.h22
-rw-r--r--src/server/game/Loot/LootMgr.cpp26
-rw-r--r--src/server/game/Mails/Mail.h16
-rw-r--r--src/server/game/Maps/Map.cpp24
-rw-r--r--src/server/game/Maps/Map.h1
-rw-r--r--src/server/game/Maps/MapManager.cpp2
-rw-r--r--src/server/game/Maps/PhaseMgr.cpp403
-rw-r--r--src/server/game/Maps/PhaseMgr.h179
-rw-r--r--src/server/game/Miscellaneous/Formulas.h23
-rw-r--r--src/server/game/Miscellaneous/Language.h22
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h1282
-rw-r--r--src/server/game/Movement/MotionMaster.cpp5
-rw-r--r--[-rwxr-xr-x]src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp17
-rwxr-xr-x[-rw-r--r--]src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp0
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp5
-rw-r--r--src/server/game/Movement/MovementStructures.cpp5451
-rw-r--r--src/server/game/Movement/MovementStructures.h158
-rw-r--r--src/server/game/Movement/PathGenerator.cpp1
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp4
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h102
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp30
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h16
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp127
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.h18
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h2
-rw-r--r--src/server/game/Movement/Spline/MovementUtil.cpp162
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvP.h5
-rw-r--r--src/server/game/Quests/QuestDef.cpp200
-rw-r--r--src/server/game/Quests/QuestDef.h83
-rw-r--r--src/server/game/Reputation/ReputationMgr.cpp3
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp77
-rw-r--r--src/server/game/Scripting/ScriptLoader.h1
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp6
-rw-r--r--src/server/game/Scripting/ScriptMgr.h13
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2950
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2744
-rw-r--r--src/server/game/Server/WorldPacket.cpp106
-rw-r--r--src/server/game/Server/WorldPacket.h (renamed from src/server/shared/Packets/WorldPacket.h)24
-rw-r--r--src/server/game/Server/WorldSession.cpp440
-rw-r--r--src/server/game/Server/WorldSession.h141
-rw-r--r--src/server/game/Server/WorldSocket.cpp128
-rw-r--r--src/server/game/Server/WorldSocket.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h98
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp649
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h10
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp260
-rw-r--r--src/server/game/Spells/Spell.cpp709
-rw-r--r--src/server/game/Spells/Spell.h19
-rw-r--r--src/server/game/Spells/SpellEffects.cpp577
-rw-r--r--src/server/game/Spells/SpellInfo.cpp597
-rw-r--r--src/server/game/Spells/SpellInfo.h67
-rw-r--r--src/server/game/Spells/SpellMgr.cpp347
-rw-r--r--src/server/game/Spells/SpellMgr.h44
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp1
-rw-r--r--src/server/game/Texts/CreatureTextMgr.h2
-rw-r--r--src/server/game/Tickets/TicketMgr.cpp5
-rw-r--r--src/server/game/Tools/PlayerDump.cpp19
-rw-r--r--src/server/game/Tools/PlayerDump.h3
-rw-r--r--src/server/game/Weather/Weather.cpp1
-rw-r--r--src/server/game/Weather/Weather.h2
-rw-r--r--src/server/game/Weather/WeatherMgr.cpp1
-rw-r--r--src/server/game/World/World.cpp300
-rw-r--r--src/server/game/World/World.h61
-rw-r--r--src/server/scripts/CMakeLists.txt2
-rw-r--r--src/server/scripts/Commands/cs_character.cpp4
-rw-r--r--src/server/scripts/Commands/cs_cheat.cpp13
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp75
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp9
-rw-r--r--src/server/scripts/Commands/cs_go.cpp2
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp4
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp1
-rw-r--r--src/server/scripts/Commands/cs_learn.cpp25
-rw-r--r--src/server/scripts/Commands/cs_list.cpp2
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp465
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp23
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp48
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp109
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp21
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp148
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp7
-rw-r--r--src/server/scripts/Commands/cs_titles.cpp6
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp64
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h64
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp270
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp393
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp200
-rw-r--r--src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp164
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/CMakeLists.txt25
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp39
-rw-r--r--src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp392
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp113
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp376
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp914
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp661
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp423
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp601
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp511
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp524
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/zulaman.h87
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp441
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp54
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp180
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp59
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp255
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp285
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp108
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp (renamed from src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp)71
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp813
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp269
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp125
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp557
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp210
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp44
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp109
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp205
-rw-r--r--src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h88
-rw-r--r--src/server/scripts/EasternKingdoms/boss_kruul.cpp163
-rw-r--r--src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp58
-rw-r--r--src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp148
-rw-r--r--src/server/scripts/EasternKingdoms/zone_ghostlands.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/zone_hinterlands.cpp199
-rw-r--r--src/server/scripts/EasternKingdoms/zone_ironforge.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/zone_loch_modan.cpp74
-rw-r--r--src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp145
-rw-r--r--src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp193
-rw-r--r--src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp624
-rw-r--r--src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp130
-rw-r--r--src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp197
-rw-r--r--src/server/scripts/Events/childrens_week.cpp44
-rw-r--r--src/server/scripts/Kalimdor/CMakeLists.txt8
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp4
-rw-r--r--src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp704
-rw-r--r--src/server/scripts/Kalimdor/Firelands/firelands.h74
-rw-r--r--src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp59
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp571
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp346
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp404
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h126
-rw-r--r--src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp282
-rw-r--r--src/server/scripts/Kalimdor/zone_azshara.cpp514
-rw-r--r--src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp4
-rw-r--r--src/server/scripts/Kalimdor/zone_darkshore.cpp372
-rw-r--r--src/server/scripts/Kalimdor/zone_desolace.cpp113
-rw-r--r--src/server/scripts/Kalimdor/zone_durotar.cpp454
-rw-r--r--src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp15
-rw-r--r--src/server/scripts/Kalimdor/zone_felwood.cpp72
-rw-r--r--src/server/scripts/Kalimdor/zone_feralas.cpp232
-rw-r--r--src/server/scripts/Kalimdor/zone_moonglade.cpp535
-rw-r--r--src/server/scripts/Kalimdor/zone_mulgore.cpp136
-rw-r--r--src/server/scripts/Kalimdor/zone_orgrimmar.cpp234
-rw-r--r--src/server/scripts/Kalimdor/zone_silithus.cpp4
-rw-r--r--src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp159
-rw-r--r--src/server/scripts/Kalimdor/zone_tanaris.cpp135
-rw-r--r--src/server/scripts/Kalimdor/zone_the_barrens.cpp11
-rw-r--r--src/server/scripts/Kalimdor/zone_thousand_needles.cpp442
-rw-r--r--src/server/scripts/Kalimdor/zone_thunder_bluff.cpp26
-rw-r--r--src/server/scripts/Kalimdor/zone_ungoro_crater.cpp328
-rw-r--r--src/server/scripts/Maelstrom/CMakeLists.txt14
-rw-r--r--src/server/scripts/Maelstrom/kezan.cpp129
-rw-r--r--src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp4
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp1
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp16
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp64
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp4
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp1
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp1
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp4
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp1
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp51
-rw-r--r--src/server/scripts/Northrend/zone_dalaran.cpp45
-rw-r--r--src/server/scripts/OutdoorPvP/CMakeLists.txt2
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp785
-rw-r--r--src/server/scripts/OutdoorPvP/OutdoorPvPEP.h331
-rw-r--r--src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp1
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp445
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp485
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp609
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp489
-rw-r--r--src/server/scripts/Spells/spell_item.cpp46
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp1020
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp547
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp21
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp455
-rw-r--r--src/server/scripts/Spells/spell_rogue.cpp357
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp644
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp787
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp459
-rw-r--r--src/server/scripts/World/go_scripts.cpp71
-rw-r--r--src/server/scripts/World/item_scripts.cpp12
-rw-r--r--src/server/scripts/World/npc_professions.cpp8
-rw-r--r--src/server/scripts/World/npcs_special.cpp11
-rw-r--r--src/server/shared/Common.h17
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.cpp408
-rw-r--r--src/server/shared/DataStores/DB2FileLoader.h107
-rw-r--r--src/server/shared/DataStores/DB2Store.h233
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.cpp9
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.h15
-rw-r--r--src/server/shared/DataStores/DBCStore.h2
-rw-r--r--src/server/shared/Database/Implementation/CharacterDatabase.cpp96
-rwxr-xr-x[-rw-r--r--]src/server/shared/Database/Implementation/CharacterDatabase.h35
-rw-r--r--src/server/shared/Database/Implementation/WorldDatabase.cpp8
-rw-r--r--src/server/shared/Define.h14
-rw-r--r--src/server/shared/Packets/ByteBuffer.h137
-rw-r--r--src/server/shared/Utilities/Util.cpp6
-rw-r--r--src/server/shared/Utilities/Util.h2
-rw-r--r--src/server/worldserver/CMakeLists.txt2
-rw-r--r--src/server/worldserver/worldserver.conf.dist242
-rw-r--r--src/tools/CMakeLists.txt10
-rw-r--r--src/tools/map_extractor/CMakeLists.txt21
-rw-r--r--src/tools/map_extractor/System.cpp601
-rw-r--r--src/tools/map_extractor/adt.cpp24
-rw-r--r--src/tools/map_extractor/adt.h13
-rw-r--r--src/tools/map_extractor/dbcfile.cpp74
-rw-r--r--src/tools/map_extractor/dbcfile.h211
-rw-r--r--src/tools/map_extractor/loadlib.cpp25
-rw-r--r--src/tools/map_extractor/loadlib/loadlib.h5
-rw-r--r--src/tools/map_extractor/mpq_libmpq.cpp129
-rw-r--r--src/tools/map_extractor/mpq_libmpq04.h108
-rw-r--r--src/tools/map_extractor/wdt.cpp2
-rw-r--r--src/tools/map_extractor/wdt.h2
-rw-r--r--src/tools/mesh_extractor/ContinentBuilder.h1
-rw-r--r--src/tools/mesh_extractor/DBC.cpp1
-rw-r--r--src/tools/vmap4_assembler/CMakeLists.txt5
-rw-r--r--src/tools/vmap4_extractor/CMakeLists.txt23
-rw-r--r--src/tools/vmap4_extractor/adtfile.cpp77
-rw-r--r--src/tools/vmap4_extractor/adtfile.h18
-rw-r--r--src/tools/vmap4_extractor/dbcfile.cpp117
-rw-r--r--src/tools/vmap4_extractor/dbcfile.h242
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp36
-rw-r--r--src/tools/vmap4_extractor/loadlib/loadlib.h77
-rw-r--r--src/tools/vmap4_extractor/model.cpp8
-rw-r--r--src/tools/vmap4_extractor/model.h1
-rw-r--r--src/tools/vmap4_extractor/modelheaders.h7
-rw-r--r--src/tools/vmap4_extractor/mpq_libmpq.cpp129
-rw-r--r--src/tools/vmap4_extractor/mpq_libmpq04.h107
-rw-r--r--src/tools/vmap4_extractor/mpqfile.cpp87
-rw-r--r--src/tools/vmap4_extractor/mpqfile.h81
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp343
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp8
-rw-r--r--src/tools/vmap4_extractor/wdtfile.h2
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp8
-rw-r--r--src/tools/vmap4_extractor/wmo.h2
400 files changed, 48467 insertions, 36091 deletions
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index f8326e0a8ec..f2bc47638e6 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -356,10 +356,13 @@ namespace VMAP
uint32 name_length, displayId;
char buff[500];
- while (!feof(model_list))
+ while (true)
{
- if (fread(&displayId, sizeof(uint32), 1, model_list) != 1
- || fread(&name_length, sizeof(uint32), 1, model_list) != 1
+ if (fread(&displayId, sizeof(uint32), 1, model_list) != 1)
+ if (feof(model_list)) // EOF flag is only set after failed reading attempt
+ break;
+
+ if (fread(&name_length, sizeof(uint32), 1, model_list) != 1
|| name_length >= sizeof(buff)
|| fread(&buff, sizeof(char), name_length, model_list) != name_length)
{
@@ -370,7 +373,7 @@ namespace VMAP
std::string model_name(buff, name_length);
WorldModel_Raw raw_model;
- if ( !raw_model.Read((iSrcDir + "/" + model_name).c_str()) )
+ if (!raw_model.Read((iSrcDir + "/" + model_name).c_str()) )
continue;
spawnedModelFiles.insert(model_name);
@@ -401,13 +404,14 @@ namespace VMAP
fclose(model_list);
fclose(model_list_copy);
}
- // temporary use defines to simplify read/check code (close file and return at fail)
- #define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
- fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }
- #define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
- fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); };
- #define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
- fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
+
+// temporary use defines to simplify read/check code (close file and return at fail)
+#define READ_OR_RETURN(V, S) if (fread((V), (S), 1, rf) != 1) { \
+ fclose(rf); printf("readfail, op = %i\n", readOperation); return(false); }
+#define READ_OR_RETURN_WITH_DELETE(V, S) if (fread((V), (S), 1, rf) != 1) { \
+ fclose(rf); printf("readfail, op = %i\n", readOperation); delete[] V; return(false); };
+#define CMP_OR_RETURN(V, S) if (strcmp((V), (S)) != 0) { \
+ fclose(rf); printf("cmpfail, %s!=%s\n", V, S);return(false); }
bool GroupModel_Raw::Read(FILE* rf)
{
diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp
index 245a47dbe64..27ecc2716f3 100644
--- a/src/server/game/AI/CoreAI/TotemAI.cpp
+++ b/src/server/game/AI/CoreAI/TotemAI.cpp
@@ -95,15 +95,4 @@ void TotemAI::UpdateAI(uint32 /*diff*/)
void TotemAI::AttackStart(Unit* /*victim*/)
{
- // Sentry totem sends ping on attack
- if (me->GetEntry() == SENTRY_TOTEM_ENTRY)
- if (Unit* owner = me->GetOwner())
- if (Player* player = owner->ToPlayer())
- {
- WorldPacket data(MSG_MINIMAP_PING, (8+4+4));
- data << me->GetGUID();
- data << me->GetPositionX();
- data << me->GetPositionY();
- player->SendDirectMessage(&data);
- }
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 36c1d384693..ea9d6c2b9fd 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -234,7 +234,7 @@ SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mec
continue;
//Continue if we don't have the mana to actually cast this spell
- if (tempSpell->ManaCost > me->GetPower(Powers(tempSpell->PowerType)))
+ if (tempSpell->ManaCost > (uint32)me->GetPower(Powers(tempSpell->PowerType)))
continue;
//Check if the spell meets our range requirements
@@ -589,6 +589,20 @@ void BossAI::UpdateAI(uint32 diff)
DoMeleeAttackIfReady();
}
+void BossAI::_DespawnAtEvade()
+{
+ uint32 corpseDelay = me->GetCorpseDelay();
+ uint32 respawnDelay = me->GetRespawnDelay();
+
+ me->SetCorpseDelay(1);
+ me->SetRespawnDelay(29);
+
+ me->DespawnOrUnsummon();
+
+ me->SetCorpseDelay(corpseDelay);
+ me->SetRespawnDelay(respawnDelay);
+}
+
// WorldBossAI - for non-instanced bosses
WorldBossAI::WorldBossAI(Creature* creature) :
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index cee6ba3c379..4d49fcf4449 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -360,6 +360,7 @@ class BossAI : public ScriptedAI
void _EnterCombat();
void _JustDied();
void _JustReachedHome() { me->setActive(false); }
+ void _DespawnAtEvade();
bool CheckInRoom()
{
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index bd51fe0a85b..99ac2ca6f25 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -1390,8 +1390,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
break;
if (e.GetTargetType() == SMART_TARGET_SELF)
- me->SetFacingTo((me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && me->GetTransGUID() ?
- me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
+ me->SetFacingTo((me->GetTransport() ? me->GetTransportHomePosition() : me->GetHomePosition()).GetOrientation());
else if (e.GetTargetType() == SMART_TARGET_POSITION)
me->SetFacingTo(e.target.o);
else if (ObjectList* targets = GetTargets(e, unit))
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index 265df8e2ac4..d47dbeae600 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -23,6 +23,7 @@
#include "CreatureAI.h"
#include "Unit.h"
#include "Spell.h"
+#include "DB2Stores.h"
//#include "SmartScript.h"
//#include "SmartAI.h"
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 7d53f481fe8..dd3ff925335 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -28,6 +28,7 @@
#include "DisableMgr.h"
#include "GameEventMgr.h"
#include "GridNotifiersImpl.h"
+#include "Group.h"
#include "Guild.h"
#include "GuildMgr.h"
#include "InstanceScript.h"
@@ -72,7 +73,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
return false;
}
- switch (criteria->requiredType)
+ switch (criteria->type)
{
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
@@ -101,7 +102,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
default:
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
{
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->requiredType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has data for non-supported criteria type (Entry: %u Type: %u), ignored.", criteria->ID, criteria->type);
return false;
}
break;
@@ -116,21 +117,27 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (!creature.id || !sObjectMgr->GetCreatureTemplate(creature.id))
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_CREATURE (%u) has non-existing creature id in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, creature.id);
+ criteria->ID, criteria->type, dataType, creature.id);
return false;
}
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE:
+ if (!classRace.class_id && !classRace.race_id)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.",
+ criteria->ID, criteria->type, dataType);
+ return false;
+ }
if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, classRace.class_id);
+ criteria->ID, criteria->type, dataType, classRace.class_id);
return false;
}
if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, classRace.race_id);
+ criteria->ID, criteria->type, dataType, classRace.race_id);
return false;
}
return true;
@@ -138,15 +145,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (health.percent < 1 || health.percent > 100)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_PLAYER_LESS_HEALTH (%u) has wrong percent value in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, health.percent);
- return false;
- }
- return true;
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
- if (player_dead.own_team_flag > 1)
- {
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD (%u) has wrong boolean value1 (%u).",
- criteria->ID, criteria->requiredType, dataType, player_dead.own_team_flag);
+ criteria->ID, criteria->type, dataType, health.percent);
return false;
}
return true;
@@ -157,36 +156,28 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (!spellEntry)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type %s (%u) has wrong spell id in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.spell_id);
+ 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)
{
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->requiredType, (dataType == ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA?"ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA":"ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA"), dataType, aura.effect_idx);
+ 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)
{
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->requiredType, (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);
+ 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);
return false;
}
return true;
}
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
- if (!GetAreaEntryByAreaID(area.id))
- {
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA (%u) has wrong area id in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, area.id);
- return false;
- }
- return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
if (value.compType >= COMP_TYPE_MAX)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE (%u) has wrong ComparisionType in value2 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, value.compType);
+ criteria->ID, criteria->type, dataType, value.compType);
return false;
}
return true;
@@ -194,7 +185,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (level.minlevel > STRONG_MAX_LEVEL)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL (%u) has wrong minlevel in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, level.minlevel);
+ criteria->ID, criteria->type, dataType, level.minlevel);
return false;
}
return true;
@@ -202,7 +193,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (gender.gender > GENDER_NONE)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER (%u) has wrong gender in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, gender.gender);
+ criteria->ID, criteria->type, dataType, gender.gender);
return false;
}
return true;
@@ -210,15 +201,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (!ScriptId)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT (%u) does not have ScriptName set, ignored.",
- criteria->ID, criteria->requiredType, dataType);
- return false;
- }
- return true;
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
- if (difficulty.difficulty >= MAX_DIFFICULTY)
- {
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY (%u) has wrong difficulty in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, difficulty.difficulty);
+ criteria->ID, criteria->type, dataType);
return false;
}
return true;
@@ -226,7 +209,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (map_players.maxcount <= 0)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT (%u) has wrong max players count in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, map_players.maxcount);
+ criteria->ID, criteria->type, dataType, map_players.maxcount);
return false;
}
return true;
@@ -234,7 +217,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (team.team != ALLIANCE && team.team != HORDE)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM (%u) has unknown team in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, team.team);
+ criteria->ID, criteria->type, dataType, team.team);
return false;
}
return true;
@@ -242,7 +225,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (drunk.state >= MAX_DRUNKEN)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK (%u) has unknown drunken state in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, drunk.state);
+ criteria->ID, criteria->type, dataType, drunk.state);
return false;
}
return true;
@@ -250,7 +233,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (!sHolidaysStore.LookupEntry(holiday.id))
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY (%u) has unknown holiday in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, holiday.id);
+ criteria->ID, criteria->type, dataType, holiday.id);
return false;
}
return true;
@@ -260,15 +243,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (equipped_item.item_quality >= MAX_ITEM_QUALITY)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_REQUIRE_S_EQUIPED_ITEM (%u) has unknown quality state in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, equipped_item.item_quality);
- return false;
- }
- return true;
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
- if (!sMapStore.LookupEntry(map_id.mapId))
- {
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_requirement` (Entry: %u Type: %u) for requirement ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID (%u) has unknown map id in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, map_id.mapId);
+ criteria->ID, criteria->type, dataType, equipped_item.item_quality);
return false;
}
return true;
@@ -276,29 +251,29 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
if (!classRace.class_id && !classRace.race_id)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) must not have 0 in either value field, ignored.",
- criteria->ID, criteria->requiredType, dataType);
+ criteria->ID, criteria->type, dataType);
return false;
}
if (classRace.class_id && ((1 << (classRace.class_id-1)) & CLASSMASK_ALL_PLAYABLE) == 0)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing class in value1 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, classRace.class_id);
+ criteria->ID, criteria->type, dataType, classRace.class_id);
return false;
}
if (classRace.race_id && ((1 << (classRace.race_id-1)) & RACEMASK_ALL_PLAYABLE) == 0)
{
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) for data type ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE (%u) has non-existing race in value2 (%u), ignored.",
- criteria->ID, criteria->requiredType, dataType, classRace.race_id);
+ criteria->ID, criteria->type, dataType, classRace.race_id);
return false;
}
return true;
default:
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->requiredType, dataType);
+ TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` (Entry: %u Type: %u) has data for non-supported data type (%u), ignored.", criteria->ID, criteria->type, dataType);
return false;
}
}
-bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscvalue1 /*= 0*/) const
+bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Unit const* target, uint32 miscValue1 /*= 0*/) const
{
switch (dataType)
{
@@ -328,25 +303,12 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
if (!target || target->GetTypeId() != TYPEID_PLAYER)
return false;
return !target->HealthAbovePct(health.percent);
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD:
- if (target && !target->IsAlive())
- if (const Player* player = target->ToPlayer())
- if (player->GetDeathTimer() != 0)
- // flag set == must be same team, not set == different team
- return (player->GetTeam() == source->GetTeam()) == (player_dead.own_team_flag != 0);
- return false;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA:
return source->HasAuraEffect(aura.spell_id, aura.effect_idx);
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA:
- {
- uint32 zone_id, area_id;
- source->GetZoneAndAreaId(zone_id, area_id);
- return area.id == zone_id || area.id == area_id;
- }
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA:
return target && target->HasAuraEffect(aura.spell_id, aura.effect_idx);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE:
- return CompareValues(ComparisionType(value.compType), miscvalue1, value.value);
+ return CompareValues(ComparisionType(value.compType), miscValue1, value.value);
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL:
if (!target)
return false;
@@ -357,11 +319,6 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
return target->getGender() == gender.gender;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT:
return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(target));
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY:
- if (source->GetMap()->IsRaid())
- if (source->GetMap()->Is25ManRaid() != ((difficulty.difficulty & RAID_DIFFICULTY_MASK_25MAN) != 0))
- return false;
- return source->GetMap()->GetSpawnMode() >= difficulty.difficulty;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
return source->GetMap()->GetPlayersCountExceptGMs() <= map_players.maxcount;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM:
@@ -399,69 +356,112 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT, criteria_id, map->GetId());
return false;
}
- return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscvalue1);
+ return instance->CheckAchievementCriteriaMeet(criteria_id, source, target, miscValue1);
}
case ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM:
{
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscvalue1);
+ ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscValue1);
if (!pProto)
return false;
return pProto->ItemLevel >= equipped_item.item_level && pProto->Quality >= equipped_item.item_quality;
}
- case ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID:
- return source->GetMapId() == map_id.mapId;
default:
break;
}
return false;
}
-bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscvalue /*= 0*/) const
+bool AchievementCriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscValue /*= 0*/) const
{
for (Storage::const_iterator itr = storage.begin(); itr != storage.end(); ++itr)
- if (!itr->Meets(criteria_id, source, target, miscvalue))
+ if (!itr->Meets(criteria_id, source, target, miscValue))
return false;
return true;
}
-AchievementMgr::AchievementMgr(Player* player)
+template<class T>
+AchievementMgr<T>::AchievementMgr(T* owner): _owner(owner), _achievementPoints(0) { }
+
+template<class T>
+AchievementMgr<T>::~AchievementMgr() { }
+
+template<class T>
+void AchievementMgr<T>::SendPacket(WorldPacket* data) const { }
+
+template<>
+void AchievementMgr<Guild>::SendPacket(WorldPacket* data) const
{
- m_player = player;
+ GetOwner()->BroadcastPacket(data);
}
-AchievementMgr::~AchievementMgr() { }
+template<>
+void AchievementMgr<Player>::SendPacket(WorldPacket* data) const
+{
+ GetOwner()->GetSession()->SendPacket(data);
+}
-void AchievementMgr::Reset()
+template<class T>
+void AchievementMgr<T>::RemoveCriteriaProgress(AchievementCriteriaEntry const* entry)
{
- for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
- {
- WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4);
- data << uint32(iter->first);
- m_player->SendDirectMessage(&data);
- }
+ if (!entry)
+ return;
- for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
- {
- WorldPacket data(SMSG_CRITERIA_DELETED, 4);
- data << uint32(iter->first);
- m_player->SendDirectMessage(&data);
- }
+ CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
+ if (criteriaProgress == m_criteriaProgress.end())
+ return;
- m_completedAchievements.clear();
- m_criteriaProgress.clear();
- DeleteFromDB(m_player->GetGUIDLow());
+ WorldPacket data(SMSG_CRITERIA_DELETED, 4);
+ data << uint32(entry->ID);
+ SendPacket(&data);
- // re-fill data
- CheckAllAchievementCriteria();
+ m_criteriaProgress.erase(criteriaProgress);
+}
+
+template<>
+void AchievementMgr<Guild>::RemoveCriteriaProgress(AchievementCriteriaEntry const* entry)
+{
+ if (!entry)
+ return;
+
+ CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
+ if (criteriaProgress == m_criteriaProgress.end())
+ return;
+
+ ObjectGuid guid = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_GUILD_CRITERIA_DELETED, 4 + 8);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[4]);
+
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[7]);
+ data << uint32(entry->ID);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[6]);
+
+ SendPacket(&data);
+
+ m_criteriaProgress.erase(criteriaProgress);
}
-void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, bool evenIfCriteriaComplete)
+template<class T>
+void AchievementMgr<T>::ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, bool evenIfCriteriaComplete)
{
- TC_LOG_DEBUG("achievement", "AchievementMgr::ResetAchievementCriteria(%u, %u, %u)", type, miscvalue1, miscvalue2);
+ TC_LOG_DEBUG("achievement", "ResetAchievementCriteria(%u, " UI64FMTD ", " UI64FMTD ")", type, miscValue1, miscValue2);
// disable for gamemasters with GM-mode enabled
- if (m_player->IsGameMaster())
+ if (GetOwner()->IsGameMaster())
return;
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
@@ -469,7 +469,7 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
{
AchievementCriteriaEntry const* achievementCriteria = (*i);
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->referredAchievement);
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->achievement);
if (!achievement)
continue;
@@ -478,9 +478,9 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
continue;
for (uint8 j = 0; j < MAX_CRITERIA_REQUIREMENTS; ++j)
- if (achievementCriteria->additionalRequirements[j].additionalRequirement_type == miscvalue1 &&
+ if (achievementCriteria->additionalRequirements[j].additionalRequirement_type == miscValue1 &&
(!achievementCriteria->additionalRequirements[j].additionalRequirement_value ||
- achievementCriteria->additionalRequirements[j].additionalRequirement_value == miscvalue2))
+ achievementCriteria->additionalRequirements[j].additionalRequirement_value == miscValue2))
{
RemoveCriteriaProgress(achievementCriteria);
break;
@@ -488,7 +488,19 @@ void AchievementMgr::ResetAchievementCriteria(AchievementCriteriaTypes type, uin
}
}
-void AchievementMgr::DeleteFromDB(uint32 lowguid)
+template<>
+void AchievementMgr<Guild>::ResetAchievementCriteria(AchievementCriteriaTypes /*type*/, uint64 /*miscValue1*/, uint64 /*miscValue2*/, bool /*evenIfCriteriaComplete*/)
+{
+ // Not needed
+}
+
+template<class T>
+void AchievementMgr<T>::DeleteFromDB(uint32 /*lowguid*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::DeleteFromDB(uint32 lowguid)
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -503,7 +515,29 @@ void AchievementMgr::DeleteFromDB(uint32 lowguid)
CharacterDatabase.CommitTransaction(trans);
}
-void AchievementMgr::SaveToDB(SQLTransaction& trans)
+template<>
+void AchievementMgr<Guild>::DeleteFromDB(uint32 lowguid)
+{
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS);
+ stmt->setUInt32(0, lowguid);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, lowguid);
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+}
+
+template<class T>
+void AchievementMgr<T>::SaveToDB(SQLTransaction& /*trans*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::SaveToDB(SQLTransaction& trans)
{
if (!m_completedAchievements.empty())
{
@@ -514,11 +548,11 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT);
stmt->setUInt16(0, iter->first);
- stmt->setUInt32(1, GetPlayer()->GetGUID());
+ stmt->setUInt32(1, GetOwner()->GetGUID());
trans->Append(stmt);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT);
- stmt->setUInt32(0, GetPlayer()->GetGUID());
+ stmt->setUInt32(0, GetOwner()->GetGUID());
stmt->setUInt16(1, iter->first);
stmt->setUInt32(2, uint32(iter->second.date));
trans->Append(stmt);
@@ -535,14 +569,14 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
continue;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA);
- stmt->setUInt32(0, GetPlayer()->GetGUID());
+ stmt->setUInt32(0, GetOwner()->GetGUID());
stmt->setUInt16(1, iter->first);
trans->Append(stmt);
if (iter->second.counter)
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS);
- stmt->setUInt32(0, GetPlayer()->GetGUID());
+ stmt->setUInt32(0, GetOwner()->GetGUID());
stmt->setUInt16(1, iter->first);
stmt->setUInt32(2, iter->second.counter);
stmt->setUInt32(3, uint32(iter->second.date));
@@ -554,7 +588,61 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans)
}
}
-void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+template<>
+void AchievementMgr<Guild>::SaveToDB(SQLTransaction& trans)
+{
+ PreparedStatement* stmt;
+ std::ostringstream guidstr;
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!itr->second.changed)
+ continue;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ stmt->setUInt32(2, itr->second.date);
+ for (std::set<uint64>::const_iterator gItr = itr->second.guids.begin(); gItr != itr->second.guids.end(); ++gItr)
+ guidstr << GUID_LOPART(*gItr) << ',';
+
+ stmt->setString(3, guidstr.str());
+ trans->Append(stmt);
+
+ guidstr.str("");
+ }
+
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ if (!itr->second.changed)
+ continue;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, GetOwner()->GetId());
+ stmt->setUInt16(1, itr->first);
+ stmt->setUInt64(2, itr->second.counter);
+ stmt->setUInt32(3, itr->second.date);
+ stmt->setUInt32(4, GUID_LOPART(itr->second.CompletedGUID));
+ trans->Append(stmt);
+ }
+}
+
+template<class T>
+void AchievementMgr<T>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+{
+}
+
+template<>
+void AchievementMgr<Player>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
{
if (achievementResult)
{
@@ -572,22 +660,26 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
ca.date = time_t(fields[1].GetUInt32());
ca.changed = false;
+ _achievementPoints += achievement->points;
+
// title achievement rewards are retroactive
if (AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement))
- if (uint32 titleId = reward->titleId[Player::TeamForRace(GetPlayer()->getRace()) == ALLIANCE ? 0 : 1])
+ if (uint32 titleId = reward->titleId[Player::TeamForRace(GetOwner()->getRace()) == ALLIANCE ? 0 : 1])
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
- GetPlayer()->SetTitle(titleEntry);
+ GetOwner()->SetTitle(titleEntry);
- } while (achievementResult->NextRow());
+ }
+ while (achievementResult->NextRow());
}
if (criteriaResult)
{
+ time_t now = time(NULL);
do
{
Field* fields = criteriaResult->Fetch();
uint32 id = fields[0].GetUInt16();
- uint32 counter = fields[1].GetUInt32();
+ uint64 counter = fields[1].GetUInt64();
time_t date = time_t(fields[2].GetUInt32());
AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id);
@@ -597,87 +689,249 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ
TC_LOG_ERROR("achievement", "Non-existing achievement criteria %u data removed from table `character_achievement_progress`.", id);
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA);
-
stmt->setUInt16(0, uint16(id));
-
CharacterDatabase.Execute(stmt);
continue;
}
- if (criteria->timeLimit && time_t(date + criteria->timeLimit) < time(NULL))
+ if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now)
continue;
CriteriaProgress& progress = m_criteriaProgress[id];
progress.counter = counter;
progress.date = date;
progress.changed = false;
+ }
+ while (criteriaResult->NextRow());
+ }
+}
+
+template<>
+void AchievementMgr<Guild>::LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult)
+{
+ if (achievementResult)
+ {
+ do
+ {
+ Field* fields = achievementResult->Fetch();
+ uint32 achievementid = fields[0].GetUInt16();
+
+ // must not happen: cleanup at server startup in sAchievementMgr->LoadCompletedAchievements()
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementid);
+ if (!achievement)
+ continue;
+
+ CompletedAchievementData& ca = m_completedAchievements[achievementid];
+ ca.date = time_t(fields[1].GetUInt32());
+ Tokenizer guids(fields[2].GetString(), ' ');
+ for (uint32 i = 0; i < guids.size(); ++i)
+ ca.guids.insert(MAKE_NEW_GUID(atol(guids[i]), 0, HIGHGUID_PLAYER));
+
+ ca.changed = false;
+
+ _achievementPoints += achievement->points;
+ }
+ while (achievementResult->NextRow());
+ }
+
+ if (criteriaResult)
+ {
+ time_t now = time(NULL);
+ do
+ {
+ Field* fields = criteriaResult->Fetch();
+ uint32 id = fields[0].GetUInt16();
+ uint32 counter = fields[1].GetUInt32();
+ time_t date = time_t(fields[2].GetUInt32());
+ uint64 guid = fields[3].GetUInt32();
+
+ AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(id);
+ if (!criteria)
+ {
+ // we will remove not existed criteria for all guilds
+ TC_LOG_ERROR("achievement", "Non-existing achievement criteria %u data removed from table `guild_achievement_progress`.", id);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD);
+ stmt->setUInt16(0, uint16(id));
+ CharacterDatabase.Execute(stmt);
+ continue;
+ }
+
+ if (criteria->timeLimit && time_t(date + criteria->timeLimit) < now)
+ continue;
+
+ CriteriaProgress& progress = m_criteriaProgress[id];
+ progress.counter = counter;
+ progress.date = date;
+ progress.CompletedGUID = MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER);
+ progress.changed = false;
} while (criteriaResult->NextRow());
}
}
-void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) const
+template<class T>
+void AchievementMgr<T>::Reset()
{
- if (GetPlayer()->GetSession()->PlayerLoading())
- return;
+}
+
+template<>
+void AchievementMgr<Player>::Reset()
+{
+ for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_ACHIEVEMENT_DELETED, 4);
+ data << uint32(iter->first);
+ SendPacket(&data);
+ }
+
+ for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
+ {
+ WorldPacket data(SMSG_CRITERIA_DELETED, 4);
+ data << uint32(iter->first);
+ SendPacket(&data);
+ }
+
+ m_completedAchievements.clear();
+ _achievementPoints = 0;
+ m_criteriaProgress.clear();
+ DeleteFromDB(GetOwner()->GetGUIDLow());
- // Don't send for achievements with ACHIEVEMENT_FLAG_TRACKING
+ // re-fill data
+ CheckAllAchievementCriteria(GetOwner());
+}
+
+template<>
+void AchievementMgr<Guild>::Reset()
+{
+ ObjectGuid guid = GetOwner()->GetGUID();
+ for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+ {
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DELETED, 4);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[6]);
+ data << uint32(iter->first);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[7]);
+ data.AppendPackedTime(iter->second.date);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[2]);
+ SendPacket(&data);
+ }
+
+ while (!m_criteriaProgress.empty())
+ if (AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(m_criteriaProgress.begin()->first))
+ RemoveCriteriaProgress(criteria);
+
+ _achievementPoints = 0;
+ m_completedAchievements.clear();
+ DeleteFromDB(GetOwner()->GetId());
+}
+
+template<class T>
+void AchievementMgr<T>::SendAchievementEarned(AchievementEntry const* achievement) const
+{
+ // Don't send for achievements with ACHIEVEMENT_FLAG_HIDDEN
if (achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
return;
- #ifdef TRINITY_DEBUG
- TC_LOG_DEBUG("achievement", "AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
- #endif
+ TC_LOG_DEBUG("achievement", "AchievementMgr::SendAchievementEarned(%u)", achievement->ID);
- if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId()))
+ if (Guild* guild = sGuildMgr->GetGuildById(GetOwner()->GetGuildId()))
{
- Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
+ Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_GUILD_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder);
- guild->BroadcastWorker(say_do, GetPlayer());
+ guild->BroadcastWorker(say_do);
}
if (achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL | ACHIEVEMENT_FLAG_REALM_FIRST_REACH))
{
// broadcast realm first reached
- WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, GetPlayer()->GetName().size() + 1 + 8 + 4 + 4);
- data << GetPlayer()->GetName();
- data << uint64(GetPlayer()->GetGUID());
+ WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, GetOwner()->GetName().size() + 1 + 8 + 4 + 4);
+ data << GetOwner()->GetName();
+ data << uint64(GetOwner()->GetGUID());
data << uint32(achievement->ID);
data << uint32(0); // 1=link supplied string as player name, 0=display plain string
sWorld->SendGlobalMessage(&data);
}
// if player is in world he can tell his friends about new achievement
- else if (GetPlayer()->IsInWorld())
+ else if (GetOwner()->IsInWorld())
{
- CellCoord p = Trinity::ComputeCellCoord(GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY());
+ Trinity::AchievementChatBuilder say_builder(*GetOwner(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
+
+ CellCoord p = Trinity::ComputeCellCoord(GetOwner()->GetPositionX(), GetOwner()->GetPositionY());
Cell cell(p);
cell.SetNoCreate();
- Trinity::AchievementChatBuilder say_builder(*GetPlayer(), CHAT_MSG_ACHIEVEMENT, LANG_ACHIEVEMENT_EARNED, achievement->ID);
Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> say_do(say_builder);
- Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
+ Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> > say_worker(GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::AchievementChatBuilder> >, WorldTypeMapContainer > message(say_worker);
- cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
+ cell.Visit(p, message, *GetOwner()->GetMap(), *GetOwner(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8);
- data.append(GetPlayer()->GetPackGUID());
+ data.append(GetOwner()->GetPackGUID());
data << uint32(achievement->ID);
data.AppendPackedTime(time(NULL));
- data << uint32(0);
- GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+ data << uint32(0); // does not notify player ingame
+ GetOwner()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
+}
+
+template<>
+void AchievementMgr<Guild>::SendAchievementEarned(AchievementEntry const* achievement) const
+{
+ ObjectGuid guid = GetOwner()->GetGUID();
+
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_EARNED, 8+4+8);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[5]);
+
+ data.WriteByteSeq(guid[2]);
+ data.AppendPackedTime(time(NULL));
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[3]);
+ data << uint32(achievement->ID);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[6]);
+
+ SendPacket(&data);
}
-void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
+template<class T>
+void AchievementMgr<T>::SendCriteriaUpdate(AchievementCriteriaEntry const* /*entry*/, CriteriaProgress const* /*progress*/, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
{
- WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8);
+}
+
+template<>
+void AchievementMgr<Player>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const
+{
+ WorldPacket data(SMSG_CRITERIA_UPDATE, 8 + 4 + 8);
data << uint32(entry->ID);
// the counter is packed like a packed Guid
data.appendPackGUID(progress->counter);
- data.append(GetPlayer()->GetPackGUID());
+ data.appendPackGUID(GetOwner()->GetGUID());
if (!entry->timeLimit)
data << uint32(0);
else
@@ -685,20 +939,75 @@ void AchievementMgr::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, C
data.AppendPackedTime(progress->date);
data << uint32(timeElapsed); // time elapsed in seconds
data << uint32(0); // unk
- GetPlayer()->SendDirectMessage(&data);
+ SendPacket(&data);
+}
+
+template<>
+void AchievementMgr<Guild>::SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 /*timeElapsed*/, bool /*timedCompleted*/) const
+{
+ //will send response to criteria progress request
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3 + 1 + 1 + 8 + 8 + 4 + 4 + 4 + 4 + 4);
+
+ ObjectGuid counter = progress->counter; // for accessing every byte individually
+ ObjectGuid guid = progress->CompletedGUID;
+
+ data.WriteBits(1, 21);
+ data.WriteBit(counter[4]);
+ data.WriteBit(counter[1]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(counter[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(counter[5]);
+ data.WriteBit(counter[0]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(counter[2]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(counter[6]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(counter[7]);
+ data.WriteBit(guid[4]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guid[5]);
+ data << uint32(progress->date); // unknown date
+ data.WriteByteSeq(counter[3]);
+ data.WriteByteSeq(counter[7]);
+ data << uint32(progress->date); // unknown date
+ data.WriteByteSeq(counter[6]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(counter[4]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(counter[0]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(counter[1]);
+ data.WriteByteSeq(guid[6]);
+ data << uint32(progress->date); // last update time (not packed!)
+ data << uint32(entry->ID);
+ data.WriteByteSeq(counter[5]);
+ data << uint32(0);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(counter[2]);
+ data.WriteByteSeq(guid[0]);
+
+ SendPacket(&data);
}
/**
* called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet
*/
-void AchievementMgr::CheckAllAchievementCriteria()
+template<class T>
+void AchievementMgr<T>::CheckAllAchievementCriteria(Player* referencePlayer)
{
// suppress sending packets
for (uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; ++i)
- UpdateAchievementCriteria(AchievementCriteriaTypes(i));
+ UpdateAchievementCriteria(AchievementCriteriaTypes(i), 0, 0, 0, NULL, referencePlayer);
}
-static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 };
+static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = {1057, 1107, 1108};
static const uint32 achievIdForDungeon[][4] =
{
// ach_cr_id, is_dungeon, is_raid, is_heroic_dungeon
@@ -710,28 +1019,62 @@ static const uint32 achievIdForDungeon[][4] =
{ 0, false, false, false }
};
+// Helper function to avoid having to specialize template for a 800 line long function
+template <typename T> static bool IsGuild() { return false; }
+template<> bool IsGuild<Guild>() { return true; }
+
/**
* this function will be called whenever the user might have done a criteria relevant action
*/
-void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/)
+template<class T>
+void AchievementMgr<T>::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit const* unit /*= NULL*/, Player* referencePlayer /*= NULL*/)
{
- TC_LOG_DEBUG("achievement", "AchievementMgr::UpdateAchievementCriteria(%u, %u, %u)", type, miscValue1, miscValue2);
+ if (type >= ACHIEVEMENT_CRITERIA_TYPE_TOTAL)
+ {
+ TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: Wrong criteria type %u", type);
+ return;
+ }
+
+ if (!referencePlayer)
+ {
+ TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: Player is NULL! Cant update criteria");
+ return;
+ }
// disable for gamemasters with GM-mode enabled
- if (m_player->IsGameMaster())
+ if (referencePlayer->IsGameMaster())
+ {
+ TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: [Player %s GM mode on] %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD
+ , referencePlayer->GetName().c_str(), GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3);
return;
+ }
- AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type);
+ TC_LOG_DEBUG("achievement", "UpdateAchievementCriteria: %s, %s (%u), " UI64FMTD ", " UI64FMTD ", " UI64FMTD
+ , GetLogNameForGuid(GetOwner()->GetGUID()), AchievementGlobalMgr::GetCriteriaTypeString(type), type, miscValue1, miscValue2, miscValue3);
+
+ // Lua_GetGuildLevelEnabled() is checked in achievement UI to display guild tab
+ if (IsGuild<T>() && !sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
+ return;
+
+ AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetAchievementCriteriaByType(type, IsGuild<T>());
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
AchievementCriteriaEntry const* achievementCriteria = (*i);
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->referredAchievement);
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementCriteria->achievement);
if (!achievement)
+ {
+ TC_LOG_ERROR("achievement", "UpdateAchievementCriteria: Achievement %u not found!", achievementCriteria->achievement);
continue;
+ }
- if (!CanUpdateCriteria(achievementCriteria, achievement))
+ if (!CanUpdateCriteria(achievementCriteria, achievement, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
continue;
+ // requirements not found in the dbc
+ if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
+ if (!data->Meets(referencePlayer, unit, miscValue1))
+ continue;
+
switch (type)
{
// std. case: increment at 1
@@ -744,13 +1087,38 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
- case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, PROGRESS_ACCUMULATE);
break;
- // std case: increment at miscvalue1
+ // std case: increment at miscValue1
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
@@ -761,116 +1129,44 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:/* FIXME: for online player only currently */
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
- // std case: high value at miscvalue1
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY:
+ SetCriteriaProgress(achievementCriteria, miscValue2, referencePlayer, PROGRESS_ACCUMULATE);
+ break;
+ // std case: high value at miscValue1
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD: /* FIXME: for online player only currently */
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CAST:
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
break;
-
- // specialized cases
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- if (achievement->categoryId == CATEGORY_CHILDRENS_WEEK)
- {
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), NULL))
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId())
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (achievementCriteria->kill_creature.creatureID != miscValue1)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue2)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit, miscValue1))
- continue;
-
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
- break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
- if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
- if (!data->Meets(GetPlayer(), unit))
- continue;
- SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->getLevel(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
- // update at loading or specific skill update
- if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID)
- continue;
- if (uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
- SetCriteriaProgress(achievementCriteria, skillvalue);
+ if (uint32 skillvalue = referencePlayer->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, skillvalue, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
- // update at loading or specific skill update
- if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID)
- continue;
- if (uint32 maxSkillvalue = GetPlayer()->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
- SetCriteriaProgress(achievementCriteria, maxSkillvalue);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
- if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end())
- SetCriteriaProgress(achievementCriteria, 1);
+ if (uint32 maxSkillvalue = referencePlayer->GetPureMaxSkillValue(achievementCriteria->learn_skill_level.skillID))
+ SetCriteriaProgress(achievementCriteria, maxSkillvalue, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
- {
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetRewardedQuestCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetRewardedQuestCount(), referencePlayer);
break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY:
{
time_t nextDailyResetTime = sWorld->GetNextDailyQuestsResetTime();
@@ -880,7 +1176,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
{
// reset if player missed one day.
if (progress && progress->date < (nextDailyResetTime - 2 * DAY))
- SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET);
+ SetCriteriaProgress(achievementCriteria, 0, referencePlayer, PROGRESS_SET);
continue;
}
@@ -889,7 +1185,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// 1st time. Start count.
progressType = PROGRESS_SET;
else if (progress->date < (nextDailyResetTime - 2 * DAY))
- // last progress is older than 2 days. Player missed 1 day => Retart count.
+ // last progress is older than 2 days. Player missed 1 day => Restart count.
progressType = PROGRESS_SET;
else if (progress->date < (nextDailyResetTime - DAY))
// last progress is between 1 and 2 days. => 1st time of the day.
@@ -898,462 +1194,54 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// last progress is within the day before the reset => Already counted today.
continue;
- SetCriteriaProgress(achievementCriteria, 1, progressType);
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer, progressType);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
{
- // speedup for non-login case
- if (miscValue1 && miscValue1 != achievementCriteria->complete_quests_in_zone.zoneID)
- continue;
-
uint32 counter = 0;
- const RewardedQuestSet &rewQuests = GetPlayer()->getRewardedQuests();
+ const RewardedQuestSet &rewQuests = referencePlayer->getRewardedQuests();
for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr)
{
Quest const* quest = sObjectMgr->GetQuestTemplate(*itr);
if (quest && quest->GetZoneOrSort() >= 0 && uint32(quest->GetZoneOrSort()) == achievementCriteria->complete_quests_in_zone.zoneID)
++counter;
}
- SetCriteriaProgress(achievementCriteria, counter);
+ SetCriteriaProgress(achievementCriteria, counter, referencePlayer);
break;
}
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID)
- continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter
- bool notfit = false;
- for (int j = 0; j < MAX_ARENA_SLOT; ++j)
- {
- if (achievIdByArenaSlot[j] == achievement->ID)
- {
- Battleground* bg = GetPlayer()->GetBattleground();
- if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j)
- notfit = true;
-
- break;
- }
- }
- if (notfit)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : sMapMgr->FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId());
- if (!map || !map->IsDungeon())
- continue;
-
- // search case
- bool found = false;
- for (int j = 0; achievIdForDungeon[j][0]; ++j)
- {
- if (achievIdForDungeon[j][0] == achievement->ID)
- {
- if (map->IsRaid())
- {
- // if raid accepted (ignore difficulty)
- if (!achievIdForDungeon[j][2])
- break; // for
- }
- else if (GetPlayer()->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
- {
- // dungeon in normal mode accepted
- if (!achievIdForDungeon[j][1])
- break; // for
- }
- else
- {
- // dungeon in heroic mode accepted
- if (!achievIdForDungeon[j][3])
- break; // for
- }
-
- found = true;
- break; // for
- }
- }
- if (!found)
- continue;
-
- //FIXME: work only for instances where max == min for players
- if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
-
- }
- case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->killed_by_creature.creatureEntry)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- // if team check required: must kill by opposition faction
- if (achievement->ID == 318 && miscValue2 == GetPlayer()->GetTeam())
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
-
- // miscvalue1 is the ingame fallheight*100 as stored in dbc
- SetCriteriaProgress(achievementCriteria, miscValue1);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- if (miscValue2 != achievementCriteria->death_from.type)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ // miscValue1 is the ingame fallheight*100 as stored in dbc
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
- {
- // if miscvalues != 0, it contains the questID.
- if (miscValue1)
- {
- if (miscValue1 != achievementCriteria->complete_quest.questID)
- continue;
- }
- else
- {
- // login case.
- if (!GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
- continue;
- }
-
- if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
- if (!data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
- {
- if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data)
- continue;
-
- if (!data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
- {
- if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data)
- continue;
-
- if (!data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
- if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID)
- continue;
-
- if (GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID))
- SetCriteriaProgress(achievementCriteria, 1);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
- {
- // miscvalue1=loot_type (note: 0 = LOOT_CORPSE and then it ignored)
- // miscvalue2=count of item loot
- if (!miscValue1 || !miscValue2)
- continue;
- if (miscValue1 != achievementCriteria->loot_type.lootType)
- continue;
-
- // zone specific
- if (achievementCriteria->loot_type.lootTypeCount == 1)
- {
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
- // speedup for non-login case
- if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1)
- continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
- if (!miscValue1) // no update at login
- continue;
-
- // additional requirements
- if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE)
- {
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit, miscValue1))
- {
- // reset the progress as we have a win without the requirement.
- SetCriteriaProgress(achievementCriteria, 0);
- continue;
- }
- }
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- if (achievementCriteria->use_item.itemID != miscValue1)
- continue;
-
- // Children's Week achievements have extra requirements
- if (achievement->categoryId == CATEGORY_CHILDRENS_WEEK)
- {
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), NULL))
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
- // You _have_ to loot that item, just owning it when logging in does _not_ count!
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->own_item.itemID)
- continue;
- SetCriteriaProgress(achievementCriteria, miscValue2, PROGRESS_ACCUMULATE);
- break;
case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
- {
- WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
- if (!worldOverlayEntry)
- break;
-
- bool matchFound = false;
- for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
- {
- uint32 area_id = worldOverlayEntry->areatableID[j];
- if (!area_id) // array have 0 only in empty tail
- break;
-
- int32 exploreFlag = GetAreaFlagByAreaID(area_id);
- if (exploreFlag < 0)
- continue;
-
- uint32 playerIndexOffset = uint32(exploreFlag) / 32;
- uint32 mask = 1<< (uint32(exploreFlag) % 32);
-
- if (GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
- {
- matchFound = true;
- break;
- }
- }
-
- if (matchFound)
- SetCriteriaProgress(achievementCriteria, 1);
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ SetCriteriaProgress(achievementCriteria, 1, referencePlayer);
break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetBankBagSlotCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetBankBagSlotCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
{
- // skip faction check only at loading
- if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID)
- continue;
-
- int32 reputation = GetPlayer()->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
+ int32 reputation = referencePlayer->GetReputationMgr().GetReputation(achievementCriteria->gain_reputation.factionID);
if (reputation > 0)
- SetCriteriaProgress(achievementCriteria, reputation);
+ SetCriteriaProgress(achievementCriteria, reputation, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
- {
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetExaltedFactionCount());
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
- {
- // skip for login case
- if (!miscValue1)
- continue;
- SetCriteriaProgress(achievementCriteria, 1);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
- {
- // miscvalue1 = itemid
- // miscvalue2 = itemSlot
- if (!miscValue1)
- continue;
-
- if (miscValue2 != achievementCriteria->equip_epic_item.itemSlot)
- continue;
-
- // check item level and quality via achievement_criteria_data
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), 0, miscValue1))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
- {
- // miscvalue1 = itemid
- // miscvalue2 = diced value
- if (!miscValue1)
- continue;
- if (miscValue2 != achievementCriteria->roll_greed_on_loot.rollValue)
- continue;
-
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(miscValue1);
- if (!pProto)
- continue;
-
- // check item level via achievement_criteria_data
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), 0, pProto->ItemLevel))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
- {
- // miscvalue1 = emote
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->do_emote.emoteID)
- continue;
- if (achievementCriteria->do_emote.count)
- {
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
- case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
- {
- if (!miscValue1)
- continue;
-
- if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP)
- {
- if (GetPlayer()->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value)
- continue;
-
- // map specific case (BG in fact) expected player targeted damage/heal
- if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
- // miscvalue1 = item_id
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->equip_item.itemID)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
- // miscvalue1 = go entry
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->use_gameobject.goEntry)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
- if (!miscValue1)
- continue;
- if (miscValue1 != achievementCriteria->fish_in_gameobject.goEntry)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetExaltedFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
{
- if (miscValue1 && miscValue1 != achievementCriteria->learn_skillline_spell.skillLine)
- continue;
-
uint32 spellCount = 0;
- for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
- spellIter != GetPlayer()->GetSpellMap().end();
+ for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
+ spellIter != referencePlayer->GetSpellMap().end();
++spellIter)
{
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
@@ -1363,56 +1251,23 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
spellCount++;
}
}
- SetCriteriaProgress(achievementCriteria, spellCount);
+ SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
break;
}
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
-
- if (achievementCriteria->win_duel.duelCount)
- {
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data)
- continue;
-
- if (!data->Meets(GetPlayer(), unit))
- continue;
- }
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetReveredFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetReveredFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetHonoredFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetHonoredFactionCount(), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetReputationMgr().GetVisibleFactionCount());
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetReputationMgr().GetVisibleFactionCount(), referencePlayer);
break;
- case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
- case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
- {
- // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
- if (!miscValue1)
- continue;
- ItemTemplate const* proto = sObjectMgr->GetItemTemplate(miscValue1);
- if (!proto || proto->Quality < ITEM_QUALITY_EPIC)
- continue;
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
{
- if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_line.skillLine)
- continue;
-
uint32 spellCount = 0;
- for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin();
- spellIter != GetPlayer()->GetSpellMap().end();
+ for (PlayerSpellMap::const_iterator spellIter = referencePlayer->GetSpellMap().begin();
+ spellIter != referencePlayer->GetSpellMap().end();
++spellIter)
{
SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(spellIter->first);
@@ -1420,78 +1275,21 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (skillIter->second->skillId == achievementCriteria->learn_skill_line.skillLine)
spellCount++;
}
- SetCriteriaProgress(achievementCriteria, spellCount);
+ SetCriteriaProgress(achievementCriteria, spellCount, referencePlayer);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
- if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
- if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS), referencePlayer);
break;
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
- SetCriteriaProgress(achievementCriteria, GetPlayer()->GetMoney(), PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, referencePlayer->GetMoney(), referencePlayer, PROGRESS_HIGHEST);
break;
case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
- {
if (!miscValue1)
- {
- uint32 points = 0;
- for (CompletedAchievementMap::iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
- if (AchievementEntry const* pAchievement = sAchievementMgr->GetAchievement(itr->first))
- points += pAchievement->points;
- SetCriteriaProgress(achievementCriteria, points, PROGRESS_SET);
- }
+ SetCriteriaProgress(achievementCriteria, _achievementPoints, referencePlayer, PROGRESS_SET);
else
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_ACCUMULATE);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_ACCUMULATE);
break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
- {
- if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
- case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
- case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
- {
- // skip login update
- if (!miscValue1)
- continue;
-
- // those requirements couldn't be found in the dbc
- AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria);
- if (!data || !data->Meets(GetPlayer(), unit))
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
- {
- if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID)
- continue;
-
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
{
uint32 reqTeamType = achievementCriteria->highest_team_rating.teamtype;
@@ -1501,13 +1299,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue2 != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
}
- else // login case
+ else // login case
{
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
- uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot);
+ uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
if (!teamId)
continue;
@@ -1515,7 +1313,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!team || team->GetType() != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, team->GetStats().Rating, referencePlayer, PROGRESS_HIGHEST);
break;
}
}
@@ -1531,13 +1329,13 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (miscValue2 != reqTeamType)
continue;
- SetCriteriaProgress(achievementCriteria, miscValue1, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer, PROGRESS_HIGHEST);
}
- else // login case
+ else // login case
{
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
- uint32 teamId = GetPlayer()->GetArenaTeamId(arena_slot);
+ uint32 teamId = referencePlayer->GetArenaTeamId(arena_slot);
if (!teamId)
continue;
@@ -1545,56 +1343,58 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
if (!team || team->GetType() != reqTeamType)
continue;
- if (ArenaTeamMember const* member = team->GetMember(GetPlayer()->GetGUID()))
+ if (ArenaTeamMember const* member = team->GetMember(referencePlayer->GetGUID()))
{
- SetCriteriaProgress(achievementCriteria, member->PersonalRating, PROGRESS_HIGHEST);
+ SetCriteriaProgress(achievementCriteria, member->PersonalRating, referencePlayer, PROGRESS_HIGHEST);
break;
}
}
}
-
break;
}
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: // This also behaves like ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA
- {
- // Check map id requirement
- if (miscValue1 == achievementCriteria->win_arena.mapID)
- SetCriteriaProgress(achievementCriteria, 1, PROGRESS_ACCUMULATE);
- break;
- }
- // std case: not exist in DBC, not triggered in code as result
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
+ SetCriteriaProgress(achievementCriteria, miscValue1, referencePlayer);
break;
// FIXME: not triggered in code as result, need to implement
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS:
+ case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL:
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE:
break; // Not implemented yet :(
}
if (IsCompletedCriteria(achievementCriteria, achievement))
- CompletedCriteriaFor(achievement);
+ CompletedCriteriaFor(achievement, referencePlayer);
// check again the completeness for SUMM and REQ COUNT achievements,
// as they don't depend on the completed criteria but on the sum of the progress of each individual criteria
if (achievement->flags & ACHIEVEMENT_FLAG_SUMM)
if (IsCompletedAchievement(achievement))
- CompletedAchievement(achievement);
+ CompletedAchievement(achievement, referencePlayer);
if (AchievementEntryList const* achRefList = sAchievementMgr->GetAchievementByReferencedId(achievement->ID))
for (AchievementEntryList::const_iterator itr = achRefList->begin(); itr != achRefList->end(); ++itr)
if (IsCompletedAchievement(*itr))
- CompletedAchievement(*itr);
+ CompletedAchievement(*itr, referencePlayer);
}
}
-bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
+template<class T>
+bool AchievementMgr<T>::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement)
{
if (!achievement)
return false;
@@ -1614,13 +1414,14 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
if (!progress)
return false;
- switch (achievementCriteria->requiredType)
+ switch (AchievementCriteriaTypes(achievementCriteria->type))
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
return progress->counter >= achievementCriteria->win_bg.winCount;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
return progress->counter >= achievementCriteria->kill_creature.creatureCount;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
return progress->counter >= achievementCriteria->reach_level.level;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
return progress->counter >= achievementCriteria->reach_skill_level.skillLevel;
@@ -1715,6 +1516,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->use_lfg.dungeonsComplete;
case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
return progress->counter >= achievementCriteria->get_killing_blow.killCount;
+ case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY:
+ return progress->counter >= achievementCriteria->currencyGain.count;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
return achievementCriteria->win_arena.count && progress->counter >= achievementCriteria->win_arena.count;
// handle all statistic-only criteria here
@@ -1746,19 +1549,18 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER:
- case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR:
case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
default:
break;
}
+
return false;
}
-void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
+template<class T>
+void AchievementMgr<T>::CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer)
{
// counter can never complete
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER)
@@ -1769,26 +1571,27 @@ void AchievementMgr::CompletedCriteriaFor(AchievementEntry const* achievement)
return;
if (IsCompletedAchievement(achievement))
- CompletedAchievement(achievement);
+ CompletedAchievement(achievement, referencePlayer);
}
-bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
+template<class T>
+bool AchievementMgr<T>::IsCompletedAchievement(AchievementEntry const* entry)
{
// counter can never complete
if (entry->flags & ACHIEVEMENT_FLAG_COUNTER)
return false;
// for achievement with referenced achievement criterias get from referenced and counter from self
- uint32 achievmentForTestId = entry->refAchievement ? entry->refAchievement : entry->ID;
- uint32 achievmentForTestCount = entry->count;
+ uint32 achievementForTestId = entry->refAchievement ? entry->refAchievement : entry->ID;
+ uint32 achievementForTestCount = entry->count;
- AchievementCriteriaEntryList const* cList = sAchievementMgr->GetAchievementCriteriaByAchievement(achievmentForTestId);
+ AchievementCriteriaEntryList const* cList = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementForTestId);
if (!cList)
return false;
- uint32 count = 0;
+ uint64 count = 0;
// For SUMM achievements, we have to count the progress of each criteria of the achievement.
- // Oddly, the target count is NOT countained in the achievement, but in each individual criteria
+ // Oddly, the target count is NOT contained in the achievement, but in each individual criteria
if (entry->flags & ACHIEVEMENT_FLAG_SUMM)
{
for (AchievementCriteriaEntryList::const_iterator itr = cList->begin(); itr != cList->end(); ++itr)
@@ -1823,18 +1626,19 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry)
completed_all = false;
// completed as have req. count of completed criterias
- if (achievmentForTestCount > 0 && achievmentForTestCount <= count)
+ if (achievementForTestCount > 0 && achievementForTestCount <= count)
return true;
}
// all criterias completed requirement
- if (completed_all && achievmentForTestCount == 0)
+ if (completed_all && achievementForTestCount == 0)
return true;
return false;
}
-CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry const* entry)
+template<class T>
+CriteriaProgress* AchievementMgr<T>::GetCriteriaProgress(AchievementCriteriaEntry const* entry)
{
CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID);
@@ -1844,14 +1648,16 @@ CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry c
return &(iter->second);
}
-void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype)
+template<class T>
+void AchievementMgr<T>::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint64 changeValue, Player* referencePlayer, ProgressType ptype)
{
// Don't allow to cheat - doing timed achievements without timer active
TimedAchievementMap::iterator timedIter = m_timedAchievements.find(entry->ID);
if (entry->timeLimit && timedIter == m_timedAchievements.end())
return;
- TC_LOG_DEBUG("achievement", "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow());
+ TC_LOG_DEBUG("achievement", "SetCriteriaProgress(%u, " UI64FMTD ") for (%s GUID: %u)",
+ entry->ID, changeValue, GetLogNameForGuid(GetOwner()->GetGUID()), GUID_LOPART(GetOwner()->GetGUID()));
CriteriaProgress* progress = GetCriteriaProgress(entry);
if (!progress)
@@ -1866,7 +1672,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
}
else
{
- uint32 newValue = 0;
+ uint64 newValue = 0;
switch (ptype)
{
case PROGRESS_SET:
@@ -1875,7 +1681,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
case PROGRESS_ACCUMULATE:
{
// avoid overflow
- uint32 max_value = std::numeric_limits<uint32>::max();
+ uint64 max_value = std::numeric_limits<uint64>::max();
newValue = max_value - progress->counter > changeValue ? progress->counter + changeValue : max_value;
break;
}
@@ -1894,41 +1700,28 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry,
progress->changed = true;
progress->date = time(NULL); // set the date to the latest update.
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(entry->achievement);
uint32 timeElapsed = 0;
- bool timedCompleted = false;
+ bool criteriaComplete = IsCompletedCriteria(entry, achievement);
if (entry->timeLimit)
{
- // has to exist else we wouldn't be here
- timedCompleted = IsCompletedCriteria(entry, sAchievementMgr->GetAchievement(entry->referredAchievement));
// Client expects this in packet
timeElapsed = entry->timeLimit - (timedIter->second/IN_MILLISECONDS);
// Remove the timer, we wont need it anymore
- if (timedCompleted)
+ if (criteriaComplete)
m_timedAchievements.erase(timedIter);
}
- SendCriteriaUpdate(entry, progress, timeElapsed, timedCompleted);
-}
-
-void AchievementMgr::RemoveCriteriaProgress(AchievementCriteriaEntry const* entry)
-{
- if (!entry)
- return;
+ if (criteriaComplete && achievement->flags & ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS && !progress->CompletedGUID)
+ progress->CompletedGUID = referencePlayer->GetGUID();
- CriteriaProgressMap::iterator criteriaProgress = m_criteriaProgress.find(entry->ID);
- if (criteriaProgress == m_criteriaProgress.end())
- return;
-
- WorldPacket data(SMSG_CRITERIA_DELETED, 4);
- data << uint32(entry->ID);
- m_player->SendDirectMessage(&data);
-
- m_criteriaProgress.erase(criteriaProgress);
+ SendCriteriaUpdate(entry, progress, timeElapsed, criteriaComplete);
}
-void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
+template<class T>
+void AchievementMgr<T>::UpdateTimedAchievements(uint32 timeDiff)
{
if (!m_timedAchievements.empty())
{
@@ -1950,15 +1743,21 @@ void AchievementMgr::UpdateTimedAchievements(uint32 timeDiff)
}
}
-void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /*= 0*/)
+template<class T>
+void AchievementMgr<T>::StartTimedAchievement(AchievementCriteriaTimedTypes /*type*/, uint32 /*entry*/, uint32 /*timeLost = 0*/)
+{
+}
+
+template<>
+void AchievementMgr<Player>::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost /* = 0 */)
{
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
- if ((*i)->timerStartEvent != entry)
+ if ((*i)->timedCriteriaMiscId != entry)
continue;
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement((*i)->referredAchievement);
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement((*i)->achievement);
if (m_timedAchievements.find((*i)->ID) == m_timedAchievements.end() && !IsCompletedCriteria(*i, achievement))
{
// Start the timer
@@ -1967,18 +1766,19 @@ void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, u
m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILLISECONDS - timeLost;
// and at client too
- SetCriteriaProgress(*i, 0, PROGRESS_SET);
+ SetCriteriaProgress(*i, 0, GetOwner(), PROGRESS_SET);
}
}
}
}
-void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
+template<class T>
+void AchievementMgr<T>::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry)
{
AchievementCriteriaEntryList const& achievementCriteriaList = sAchievementMgr->GetTimedAchievementCriteriaByType(type);
- for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i)
+ for (AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i != achievementCriteriaList.end(); ++i)
{
- if ((*i)->timerStartEvent != entry)
+ if ((*i)->timedCriteriaMiscId != entry)
continue;
TimedAchievementMap::iterator timedIter = m_timedAchievements.find((*i)->ID);
@@ -1994,19 +1794,26 @@ void AchievementMgr::RemoveTimedAchievement(AchievementCriteriaTimedTypes type,
}
}
-void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
+template<>
+void AchievementMgr<Player>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer)
{
// disable for gamemasters with GM-mode enabled
- if (m_player->IsGameMaster())
+ if (GetOwner()->IsGameMaster())
return;
if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
return;
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
+ if (Guild* guild = referencePlayer->GetGuild())
+ guild->AddGuildNews(GUILD_NEWS_PLAYER_ACHIEVEMENT, referencePlayer->GetGUID(), achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
+
+ if (!GetOwner()->GetSession()->PlayerLoading())
+ SendAchievementEarned(achievement);
+
TC_LOG_INFO("achievement", "AchievementMgr::CompletedAchievement(%u). Player: %s (%u)",
- achievement->ID, m_player->GetName().c_str(), m_player->GetGUIDLow());
+ achievement->ID, GetOwner()->GetName().c_str(), GetOwner()->GetGUIDLow());
- SendAchievementEarned(achievement);
CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
ca.date = time(NULL);
ca.changed = true;
@@ -2016,8 +1823,10 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
if (!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL))
sAchievementMgr->SetRealmCompleted(achievement);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points);
+ _achievementPoints += achievement->points;
+
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, 0, NULL, referencePlayer);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, 0, NULL, referencePlayer);
// reward items and titles if any
AchievementReward const* reward = sAchievementMgr->GetAchievementReward(achievement);
@@ -2031,16 +1840,16 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
//! Since no common attributes were found, (not even in titleRewardFlags field)
//! we explicitly check by ID. Maybe in the future we could move the achievement_reward
//! condition fields to the condition system.
- if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetPlayer()->getGender() : (GetPlayer()->GetTeam() == ALLIANCE ? 0 : 1)])
+ if (uint32 titleId = reward->titleId[achievement->ID == 1793 ? GetOwner()->getGender() : (GetOwner()->GetTeam() == ALLIANCE ? 0 : 1)])
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId))
- GetPlayer()->SetTitle(titleEntry);
+ GetOwner()->SetTitle(titleEntry);
// mail
if (reward->sender)
{
- Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetPlayer()) : NULL;
+ Item* item = reward->itemId ? Item::CreateItem(reward->itemId, 1, GetOwner()) : NULL;
- int loc_idx = GetPlayer()->GetSession()->GetSessionDbLocaleIndex();
+ int loc_idx = GetOwner()->GetSession()->GetSessionDbLocaleIndex();
// subject and text
std::string subject = reward->subject;
@@ -2066,74 +1875,391 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement)
draft.AddItem(item);
}
- draft.SendMailTo(trans, GetPlayer(), MailSender(MAIL_CREATURE, reward->sender));
+ draft.SendMailTo(trans, GetOwner(), MailSender(MAIL_CREATURE, reward->sender));
CharacterDatabase.CommitTransaction(trans);
}
}
-void AchievementMgr::SendAllAchievementData() const
+template<>
+void AchievementMgr<Guild>::CompletedAchievement(AchievementEntry const* achievement, Player* referencePlayer)
+{
+ TC_LOG_DEBUG("achievement", "AchievementMgr<Guild>::CompletedAchievement(%u)", achievement->ID);
+
+ if (achievement->flags & ACHIEVEMENT_FLAG_COUNTER || HasAchieved(achievement->ID))
+ return;
+
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS)
+ if (Guild* guild = referencePlayer->GetGuild())
+ guild->AddGuildNews(GUILD_NEWS_GUILD_ACHIEVEMENT, 0, achievement->flags & ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER, achievement->ID);
+
+ SendAchievementEarned(achievement);
+ CompletedAchievementData& ca = m_completedAchievements[achievement->ID];
+ ca.date = time(NULL);
+ ca.changed = true;
+
+ if (achievement->flags & ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS)
+ {
+ if (referencePlayer->GetGuildId() == GetOwner()->GetId())
+ ca.guids.insert(referencePlayer->GetGUID());
+
+ if (Group const* group = referencePlayer->GetGroup())
+ for (GroupReference const* ref = group->GetFirstMember(); ref != NULL; ref = ref->next())
+ if (Player const* groupMember = ref->GetSource())
+ if (groupMember->GetGuildId() == GetOwner()->GetId())
+ ca.guids.insert(groupMember->GetGUID());
+ }
+
+ sAchievementMgr->SetRealmCompleted(achievement);
+
+ _achievementPoints += achievement->points;
+
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, 0, 0, 0, NULL, referencePlayer);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS, achievement->points, 0, 0, NULL, referencePlayer);
+}
+
+struct VisibleAchievementPred
+{
+ bool operator()(CompletedAchievementMap::value_type const& val)
+ {
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(val.first);
+ return achievement && !(achievement->flags & ACHIEVEMENT_FLAG_HIDDEN);
+ }
+};
+
+template<class T>
+void AchievementMgr<T>::SendAllAchievementData(Player* /*receiver*/) const
+{
+ VisibleAchievementPred isVisible;
+ size_t numCriteria = m_criteriaProgress.size();
+ size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
+ ByteBuffer criteriaData(numCriteria * (4 + 4 + 4 + 4 + 8 + 8));
+ ObjectGuid guid = GetOwner()->GetGUID();
+ ObjectGuid counter;
+
+ WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4 + numAchievements * (4 + 4) + 4 + numCriteria * (4 + 4 + 4 + 4 + 8 + 8));
+ data.WriteBits(numCriteria, 21);
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ counter = itr->second.counter;
+
+ data.WriteBit(guid[4]);
+ data.WriteBit(counter[3]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(counter[0]);
+ data.WriteBit(counter[6]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(counter[4]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(counter[7]);
+ data.WriteBit(guid[7]);
+ data.WriteBits(0u, 2);
+ data.WriteBit(guid[6]);
+ data.WriteBit(counter[2]);
+ data.WriteBit(counter[1]);
+ data.WriteBit(counter[5]);
+ data.WriteBit(guid[1]);
+
+ criteriaData.WriteByteSeq(guid[3]);
+ criteriaData.WriteByteSeq(counter[5]);
+ criteriaData.WriteByteSeq(counter[6]);
+ criteriaData.WriteByteSeq(guid[4]);
+ criteriaData.WriteByteSeq(guid[6]);
+ criteriaData.WriteByteSeq(counter[2]);
+ criteriaData << uint32(0); // timer 2
+ criteriaData.WriteByteSeq(guid[2]);
+ criteriaData << uint32(itr->first); // criteria id
+ criteriaData.WriteByteSeq(guid[5]);
+ criteriaData.WriteByteSeq(counter[0]);
+ criteriaData.WriteByteSeq(counter[3]);
+ criteriaData.WriteByteSeq(counter[1]);
+ criteriaData.WriteByteSeq(counter[4]);
+ criteriaData.WriteByteSeq(guid[0]);
+ criteriaData.WriteByteSeq(guid[7]);
+ criteriaData.WriteByteSeq(counter[7]);
+ criteriaData << uint32(0); // timer 1
+ criteriaData.AppendPackedTime(itr->second.date); // criteria date
+ criteriaData.WriteByteSeq(guid[1]);
+ }
+
+ data.WriteBits(numAchievements, 23);
+ data.FlushBits();
+ data.append(criteriaData);
+
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!isVisible(*itr))
+ continue;
+
+ data << uint32(itr->first);
+ data.AppendPackedTime(itr->second.date);
+ }
+
+ SendPacket(&data);
+}
+
+template<>
+void AchievementMgr<Guild>::SendAllAchievementData(Player* receiver) const
{
- WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
- BuildAllDataPacket(&data);
- GetPlayer()->GetSession()->SendPacket(&data);
+ VisibleAchievementPred isVisible;
+ WorldPacket data(SMSG_GUILD_ACHIEVEMENT_DATA, m_completedAchievements.size() * (4 + 4) + 3);
+ data.WriteBits(std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible), 23);
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!isVisible(*itr))
+ continue;
+
+ data.AppendPackedTime(itr->second.date);
+ data << uint32(itr->first);
+ }
+
+ receiver->GetSession()->SendPacket(&data);
}
-void AchievementMgr::SendRespondInspectAchievements(Player* player) const
+template<>
+void AchievementMgr<Player>::SendAchievementInfo(Player* receiver, uint32 /*achievementId = 0 */) const
{
- WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9+m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4);
- data.append(GetPlayer()->GetPackGUID());
- BuildAllDataPacket(&data);
- player->GetSession()->SendPacket(&data);
+ ObjectGuid guid = GetOwner()->GetGUID();
+ ObjectGuid counter;
+
+ VisibleAchievementPred isVisible;
+ size_t numCriteria = m_criteriaProgress.size();
+ size_t numAchievements = std::count_if(m_completedAchievements.begin(), m_completedAchievements.end(), isVisible);
+ ByteBuffer criteriaData(numCriteria * 16);
+
+ WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 1 + 8 + 3 + 3 + numAchievements * (4 + 4) + numCriteria * (0));
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[1]);
+ data.WriteBits(numAchievements, 23);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[3]);
+ data.WriteBits(numCriteria, 21);
+ data.WriteBit(guid[2]);
+ for (CriteriaProgressMap::const_iterator itr = m_criteriaProgress.begin(); itr != m_criteriaProgress.end(); ++itr)
+ {
+ counter = itr->second.counter;
+
+ data.WriteBit(counter[5]);
+ data.WriteBit(counter[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(counter[6]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(counter[4]);
+ data.WriteBit(counter[1]);
+ data.WriteBit(counter[2]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[7]);
+ data.WriteBits(0, 2); // criteria progress flags
+ data.WriteBit(counter[0]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(counter[7]);
+
+ criteriaData.WriteByteSeq(guid[3]);
+ criteriaData.WriteByteSeq(counter[4]);
+ criteriaData << uint32(0); // timer 1
+ criteriaData.WriteByteSeq(guid[1]);
+ criteriaData.AppendPackedTime(itr->second.date);
+ criteriaData.WriteByteSeq(counter[3]);
+ criteriaData.WriteByteSeq(counter[7]);
+ criteriaData.WriteByteSeq(guid[5]);
+ criteriaData.WriteByteSeq(counter[0]);
+ criteriaData.WriteByteSeq(guid[4]);
+ criteriaData.WriteByteSeq(guid[2]);
+ criteriaData.WriteByteSeq(guid[6]);
+ criteriaData.WriteByteSeq(guid[7]);
+ criteriaData.WriteByteSeq(counter[6]);
+ criteriaData << uint32(itr->first);
+ criteriaData << uint32(0); // timer 2
+ criteriaData.WriteByteSeq(counter[1]);
+ criteriaData.WriteByteSeq(counter[5]);
+ criteriaData.WriteByteSeq(guid[0]);
+ criteriaData.WriteByteSeq(counter[2]);
+ }
+
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.FlushBits();
+ data.append(criteriaData);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[2]);
+
+ for (CompletedAchievementMap::const_iterator itr = m_completedAchievements.begin(); itr != m_completedAchievements.end(); ++itr)
+ {
+ if (!isVisible(*itr))
+ continue;
+
+ data << uint32(itr->first);
+ data.AppendPackedTime(itr->second.date);
+ }
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[5]);
+
+ receiver->GetSession()->SendPacket(&data);
}
-/**
- * used by SMSG_RESPOND_INSPECT_ACHIEVEMENT and SMSG_ALL_ACHIEVEMENT_DATA
- */
-void AchievementMgr::BuildAllDataPacket(WorldPacket* data) const
+template<>
+void AchievementMgr<Guild>::SendAchievementInfo(Player* receiver, uint32 achievementId /*= 0*/) const
{
- for (CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter != m_completedAchievements.end(); ++iter)
+ //will send response to criteria progress request
+ AchievementCriteriaEntryList const* criteria = sAchievementMgr->GetAchievementCriteriaByAchievement(achievementId);
+ if (!criteria)
{
- // Skip hidden achievements
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement(iter->first);
- if (!achievement || achievement->flags & ACHIEVEMENT_FLAG_HIDDEN)
+ // send empty packet
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, 3);
+ data.WriteBits(0, 21);
+ receiver->GetSession()->SendPacket(&data);
+ return;
+ }
+
+ ObjectGuid counter;
+ ObjectGuid guid;
+ uint32 numCriteria = 0;
+ ByteBuffer criteriaData(criteria->size() * (8 + 8 + 4 + 4 + 4));
+ ByteBuffer criteriaBits(criteria->size() * (8 + 8) / 8);
+ for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr)
+ {
+ uint32 criteriaId = (*itr)->ID;
+ CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId);
+ if (progress == m_criteriaProgress.end())
continue;
- *data << uint32(iter->first);
- data->AppendPackedTime(iter->second.date);
+ ++numCriteria;
}
- *data << int32(-1);
- for (CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter != m_criteriaProgress.end(); ++iter)
+ criteriaBits.WriteBits(numCriteria, 21);
+
+ for (AchievementCriteriaEntryList::const_iterator itr = criteria->begin(); itr != criteria->end(); ++itr)
{
- *data << uint32(iter->first);
- data->appendPackGUID(iter->second.counter);
- data->append(GetPlayer()->GetPackGUID());
- *data << uint32(0);
- data->AppendPackedTime(iter->second.date);
- *data << uint32(0);
- *data << uint32(0);
+ uint32 criteriaId = (*itr)->ID;
+ CriteriaProgressMap::const_iterator progress = m_criteriaProgress.find(criteriaId);
+ if (progress == m_criteriaProgress.end())
+ continue;
+
+ counter = progress->second.counter;
+ guid = progress->second.CompletedGUID;
+
+ criteriaBits.WriteBit(counter[4]);
+ criteriaBits.WriteBit(counter[1]);
+ criteriaBits.WriteBit(guid[2]);
+ criteriaBits.WriteBit(counter[3]);
+ criteriaBits.WriteBit(guid[1]);
+ criteriaBits.WriteBit(counter[5]);
+ criteriaBits.WriteBit(counter[0]);
+ criteriaBits.WriteBit(guid[3]);
+ criteriaBits.WriteBit(counter[2]);
+ criteriaBits.WriteBit(guid[7]);
+ criteriaBits.WriteBit(guid[5]);
+ criteriaBits.WriteBit(guid[0]);
+ criteriaBits.WriteBit(counter[6]);
+ criteriaBits.WriteBit(guid[6]);
+ criteriaBits.WriteBit(counter[7]);
+ criteriaBits.WriteBit(guid[4]);
+
+ criteriaData.WriteByteSeq(guid[5]);
+ criteriaData << uint32(progress->second.date); // unknown date
+ criteriaData.WriteByteSeq(counter[3]);
+ criteriaData.WriteByteSeq(counter[7]);
+ criteriaData << uint32(progress->second.date); // unknown date
+ criteriaData.WriteByteSeq(counter[6]);
+ criteriaData.WriteByteSeq(guid[4]);
+ criteriaData.WriteByteSeq(guid[1]);
+ criteriaData.WriteByteSeq(counter[4]);
+ criteriaData.WriteByteSeq(guid[3]);
+ criteriaData.WriteByteSeq(counter[0]);
+ criteriaData.WriteByteSeq(guid[2]);
+ criteriaData.WriteByteSeq(counter[1]);
+ criteriaData.WriteByteSeq(guid[6]);
+ criteriaData << uint32(progress->second.date); // last update time (not packed!)
+ criteriaData << uint32(criteriaId);
+ criteriaData.WriteByteSeq(counter[5]);
+ criteriaData << uint32(0);
+ criteriaData.WriteByteSeq(guid[7]);
+ criteriaData.WriteByteSeq(counter[2]);
+ criteriaData.WriteByteSeq(guid[0]);
}
- *data << int32(-1);
+ WorldPacket data(SMSG_GUILD_CRITERIA_DATA, criteriaBits.size() + criteriaData.size());
+ data.append(criteriaBits);
+ if (numCriteria)
+ data.append(criteriaData);
+
+ receiver->GetSession()->SendPacket(&data);
}
-bool AchievementMgr::HasAchieved(uint32 achievementId) const
+template<class T>
+bool AchievementMgr<T>::HasAchieved(uint32 achievementId) const
{
return m_completedAchievements.find(achievementId) != m_completedAchievements.end();
}
-bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement)
+template<class T>
+bool AchievementMgr<T>::CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer)
{
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, criteria->ID, NULL))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Disabled",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
return false;
+ }
- if (achievement->mapID != -1 && GetPlayer()->GetMapId() != uint32(achievement->mapID))
+ if (achievement->mapID != -1 && referencePlayer->GetMapId() != uint32(achievement->mapID))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Wrong map",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
return false;
+ }
- if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && GetPlayer()->GetTeam() != HORDE) ||
- (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE))
+ if ((achievement->requiredFaction == ACHIEVEMENT_FACTION_HORDE && referencePlayer->GetTeam() != HORDE) ||
+ (achievement->requiredFaction == ACHIEVEMENT_FACTION_ALLIANCE && referencePlayer->GetTeam() != ALLIANCE))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Wrong faction",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
return false;
+ }
+ if (IsCompletedCriteria(criteria, achievement))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Is Completed",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
+ return false;
+ }
+
+ if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Requirements not satisfied",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
+ return false;
+ }
+
+ if (!AdditionalRequirementsSatisfied(criteria, miscValue1, miscValue2, unit, referencePlayer))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Additional requirements not satisfied",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
+ return false;
+ }
+
+ if (!ConditionsSatisfied(criteria, referencePlayer))
+ {
+ TC_LOG_TRACE("achievement", "CanUpdateCriteria: %s (Id: %u Type %s) Conditions not satisfied",
+ criteria->name, criteria->ID, AchievementGlobalMgr::GetCriteriaTypeString(criteria->type));
+ return false;
+ }
+
+ return true;
+}
+
+template<class T>
+bool AchievementMgr<T>::ConditionsSatisfied(AchievementCriteriaEntry const* criteria, Player* referencePlayer) const
+{
for (uint32 i = 0; i < MAX_CRITERIA_REQUIREMENTS; ++i)
{
if (!criteria->additionalRequirements[i].additionalRequirement_type)
@@ -2142,11 +2268,11 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
switch (criteria->additionalRequirements[i].additionalRequirement_type)
{
case ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP:
- if (GetPlayer()->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value)
+ if (referencePlayer->GetMapId() != criteria->additionalRequirements[i].additionalRequirement_value)
return false;
break;
case ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP:
- if (GetPlayer()->GetGroup())
+ if (referencePlayer->GetGroup())
return false;
break;
default:
@@ -2154,13 +2280,746 @@ bool AchievementMgr::CanUpdateCriteria(AchievementCriteriaEntry const* criteria,
}
}
- // don't update already completed criteria
- if (IsCompletedCriteria(criteria, achievement))
- return false;
+ return true;
+}
+
+template<class T>
+bool AchievementMgr<T>::RequirementsSatisfied(AchievementCriteriaEntry const* achievementCriteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const
+{
+ switch (AchievementCriteriaTypes(achievementCriteria->type))
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
+ case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CAST:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
+ case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
+ case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
+ case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
+ case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
+ if (!miscValue1)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY:
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ if (m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) == m_completedAchievements.end())
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ if (!miscValue1 || achievementCriteria->win_bg.bgMapID != referencePlayer->GetMapId())
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ if (!miscValue1 || achievementCriteria->kill_creature.creatureID != miscValue1)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ // update at loading or specific skill update
+ if (miscValue1 && miscValue1 != achievementCriteria->reach_skill_level.skillID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
+ // update at loading or specific skill update
+ if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_level.skillID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ if (miscValue1 && miscValue1 != achievementCriteria->complete_quests_in_zone.zoneID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->complete_battleground.mapID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ if (!miscValue1 || referencePlayer->GetMapId() != achievementCriteria->death_at_map.mapID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
+ {
+ if (!miscValue1)
+ return false;
+ // skip wrong arena achievements, if not achievIdByArenaSlot then normal total death counter
+ bool notfit = false;
+ for (int j = 0; j < MAX_ARENA_SLOT; ++j)
+ {
+ if (achievIdByArenaSlot[j] == achievementCriteria->achievement)
+ {
+ Battleground* bg = referencePlayer->GetBattleground();
+ if (!bg || !bg->isArena() || ArenaTeam::GetSlotByType(bg->GetArenaType()) != j)
+ notfit = true;
+ break;
+ }
+ }
+ if (notfit)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
+ {
+ if (!miscValue1)
+ return false;
+
+ Map const* map = referencePlayer->IsInWorld() ? referencePlayer->GetMap() : sMapMgr->FindMap(referencePlayer->GetMapId(), referencePlayer->GetInstanceId());
+ if (!map || !map->IsDungeon())
+ return false;
+
+ // search case
+ bool found = false;
+ for (int j = 0; achievIdForDungeon[j][0]; ++j)
+ {
+ if (achievIdForDungeon[j][0] == achievementCriteria->achievement)
+ {
+ if (map->IsRaid())
+ {
+ // if raid accepted (ignore difficulty)
+ if (!achievIdForDungeon[j][2])
+ break; // for
+ }
+ else if (referencePlayer->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL)
+ {
+ // dungeon in normal mode accepted
+ if (!achievIdForDungeon[j][1])
+ break; // for
+ }
+ else
+ {
+ // dungeon in heroic mode accepted
+ if (!achievIdForDungeon[j][3])
+ break; // for
+ }
+
+ found = true;
+ break; // for
+ }
+ }
+ if (!found)
+ return false;
+
+ //FIXME: work only for instances where max == min for players
+ if (((InstanceMap*)map)->GetMaxPlayers() != achievementCriteria->death_in_dungeon.manLimit)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ if (!miscValue1 || miscValue1 != achievementCriteria->killed_by_creature.creatureEntry)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ if (!miscValue1 || !unit || unit->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
+ if (!miscValue1 || miscValue2 != achievementCriteria->death_from.type)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ {
+ // if miscValues != 0, it contains the questID.
+ if (miscValue1)
+ {
+ if (miscValue1 != achievementCriteria->complete_quest.questID)
+ return false;
+ }
+ else
+ {
+ // login case.
+ if (!referencePlayer->GetQuestRewardStatus(achievementCriteria->complete_quest.questID))
+ return false;
+ }
+
+ if (AchievementCriteriaDataSet const* data = sAchievementMgr->GetCriteriaDataSet(achievementCriteria))
+ if (!data->Meets(referencePlayer, unit))
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ if (!miscValue1 || miscValue1 != achievementCriteria->be_spell_target.spellID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ if (!miscValue1 || miscValue1 != achievementCriteria->cast_spell.spellID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ if (miscValue1 && miscValue1 != achievementCriteria->learn_spell.spellID)
+ return false;
+
+ if (!referencePlayer->HasSpell(achievementCriteria->learn_spell.spellID))
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ // miscValue1 = itemId - miscValue2 = count of item loot
+ // miscValue3 = loot_type (note: 0 = LOOT_CORPSE and then it ignored)
+ if (!miscValue1 || !miscValue2 || !miscValue3 || miscValue3 != achievementCriteria->loot_type.lootType)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ if (miscValue1 && achievementCriteria->own_item.itemID != miscValue1)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ if (!miscValue1 || achievementCriteria->use_item.itemID != miscValue1)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ if (!miscValue1 || miscValue1 != achievementCriteria->own_item.itemID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ {
+ WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference);
+ if (!worldOverlayEntry)
+ break;
+
+ bool matchFound = false;
+ for (int j = 0; j < MAX_WORLD_MAP_OVERLAY_AREA_IDX; ++j)
+ {
+ uint32 area_id = worldOverlayEntry->areatableID[j];
+ if (!area_id) // array have 0 only in empty tail
+ break;
+
+ int32 exploreFlag = GetAreaFlagByAreaID(area_id);
+ if (exploreFlag < 0)
+ continue;
+
+ uint32 playerIndexOffset = uint32(exploreFlag) / 32;
+ uint32 mask = 1 << (uint32(exploreFlag) % 32);
+
+ if (referencePlayer->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask)
+ {
+ matchFound = true;
+ break;
+ }
+ }
+
+ if (!matchFound)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ if (miscValue1 && miscValue1 != achievementCriteria->gain_reputation.factionID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ // miscValue1 = itemid miscValue2 = itemSlot
+ if (!miscValue1 || miscValue2 != achievementCriteria->equip_epic_item.itemSlot)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ {
+ // miscValue1 = itemid miscValue2 = diced value
+ if (!miscValue1 || miscValue2 != achievementCriteria->roll_greed_on_loot.rollValue)
+ return false;
+
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1));
+ if (!proto)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ if (!miscValue1 || miscValue1 != achievementCriteria->do_emote.emoteID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
+ if (!miscValue1)
+ return false;
+
+ if (achievementCriteria->additionalRequirements[0].additionalRequirement_type == ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP)
+ {
+ if (referencePlayer->GetMapId() != achievementCriteria->additionalRequirements[0].additionalRequirement_value)
+ return false;
+
+ // map specific case (BG in fact) expected player targeted damage/heal
+ if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ }
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ // miscValue1 = item_id
+ if (!miscValue1 || miscValue1 != achievementCriteria->equip_item.itemID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ if (!miscValue1 || miscValue1 != achievementCriteria->use_gameobject.goEntry)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ if (!miscValue1 || miscValue1 != achievementCriteria->fish_in_gameobject.goEntry)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ if (miscValue1 && miscValue1 != achievementCriteria->learn_skillline_spell.skillLine)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
+ case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
+ {
+ if (!miscValue1)
+ return false;
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(uint32(miscValue1));
+ if (!proto || proto->Quality < ITEM_QUALITY_EPIC)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
+ if (miscValue1 && miscValue1 != achievementCriteria->learn_skill_line.skillLine)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
+ if (!miscValue1 || miscValue1 != achievementCriteria->hk_class.classID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
+ if (!miscValue1 || miscValue1 != achievementCriteria->hk_race.raceID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ if (!miscValue1 || miscValue1 != achievementCriteria->bg_objective.objectiveId)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
+ if (!miscValue1 || miscValue1 != achievementCriteria->honorable_kill_at_area.areaID)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY:
+ if (!miscValue1 || !miscValue2 || int64(miscValue2) < 0
+ || miscValue1 != achievementCriteria->currencyGain.currency)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
+ if (miscValue1 != achievementCriteria->win_arena.mapID)
+ return false;
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+template<class T>
+bool AchievementMgr<T>::AdditionalRequirementsSatisfied(AchievementCriteriaEntry const* criteria, uint64 miscValue1, uint64 /*miscValue2*/, Unit const* unit, Player* referencePlayer) const
+{
+ for (uint8 i = 0; i < MAX_ADDITIONAL_CRITERIA_CONDITIONS; ++i)
+ {
+ uint32 reqType = criteria->additionalConditionType[i];
+
+ ///@TODO Extract additionalConditionValue[2] column from an older dbc and store it in database
+ /// This column is not present in 4.3.4 Achievement_Criteria.dbc
+ /// so for now, just return as failed condition to prevent invalid memory access
+ if (i == 2 && reqType)
+ return false;
+
+ uint32 reqValue = criteria->additionalConditionValue[i];
+
+ switch (AchievementCriteriaAdditionalCondition(reqType))
+ {
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY: // 4
+ if (!unit || unit->GetEntry() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER: // 5
+ if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD: // 6
+ if (!unit || unit->IsAlive())
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY: // 7
+ if (!unit || !referencePlayer->IsHostileTo(unit))
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA: // 8
+ if (!referencePlayer->HasAura(reqValue))
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA: // 10
+ if (!unit || !unit->HasAura(reqValue))
+ return false;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA_TYPE: // 11
+ if (!unit || !unit->HasAuraType(AuraType(reqValue)))
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN: // 14
+ {
+ // miscValue1 is itemid
+ ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1));
+ if (!item || item->Quality < reqValue)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS: // 15
+ {
+ // miscValue1 is itemid
+ ItemTemplate const* const item = sObjectMgr->GetItemTemplate(uint32(miscValue1));
+ if (!item || item->Quality != reqValue)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE: // 17
+ {
+ uint32 zoneId, areaId;
+ referencePlayer->GetZoneAndAreaId(zoneId, areaId);
+ if (zoneId != reqValue && areaId != reqValue)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE: // 18
+ {
+ if (!unit)
+ return false;
+ uint32 zoneId, areaId;
+ unit->GetZoneAndAreaId(zoneId, areaId);
+ if (zoneId != reqValue && areaId != reqValue)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY: // 20
+ if (uint32(referencePlayer->GetMap()->GetDifficulty()) != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE: // 25
+ if (referencePlayer->getRace() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS: // 26
+ if (referencePlayer->getClass() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE: // 27
+ if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getRace() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS: // 28
+ if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getClass() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS: // 29
+ if (referencePlayer->GetGroup() && referencePlayer->GetGroup()->GetMembersCount() >= reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE: // 30
+ {
+ if (!unit)
+ return false;
+ Creature const* const creature = unit->ToCreature();
+ if (!creature || creature->GetCreatureType() != reqValue)
+ return false;
+ break;
+ }
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP: // 32
+ if (referencePlayer->GetMapId() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX: // 38
+ // miscValue1 is title's bit index
+ if (miscValue1 != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL: // 39
+ if (referencePlayer->getLevel() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL: // 40
+ if (!unit || unit->getLevel() != reqValue)
+ return false;
+ break;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE: // 41
+ if (!unit || unit->GetZoneId() != reqValue)
+ return false;
+ case ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW: // 46
+ if (!unit || unit->GetHealthPct() >= reqValue)
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
return true;
}
+char const* AchievementGlobalMgr::GetCriteriaTypeString(uint32 type)
+{
+ return GetCriteriaTypeString(AchievementCriteriaTypes(type));
+}
+
+char const* AchievementGlobalMgr::GetCriteriaTypeString(AchievementCriteriaTypes type)
+{
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ return "KILL_CREATURE";
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ return "TYPE_WIN_BG";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS:
+ return "COMPLETE_RESEARCH";
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
+ return "REACH_LEVEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
+ return "REACH_SKILL_LEVEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
+ return "COMPLETE_ACHIEVEMENT";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT:
+ return "COMPLETE_QUEST_COUNT";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY:
+ return "COMPLETE_DAILY_QUEST_DAILY";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
+ return "COMPLETE_QUESTS_IN_ZONE";
+ case ACHIEVEMENT_CRITERIA_TYPE_CURRENCY:
+ return "CURRENCY";
+ case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE:
+ return "DAMAGE_DONE";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
+ return "COMPLETE_DAILY_QUEST";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
+ return "COMPLETE_BATTLEGROUND";
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
+ return "DEATH_AT_MAP";
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH:
+ return "DEATH";
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON:
+ return "DEATH_IN_DUNGEON";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID:
+ return "COMPLETE_RAID";
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
+ return "KILLED_BY_CREATURE";
+ case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER:
+ return "KILLED_BY_PLAYER";
+ case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
+ return "FALL_WITHOUT_DYING";
+ case ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM:
+ return "DEATHS_FROM";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+ return "COMPLETE_QUEST";
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
+ return "BE_SPELL_TARGET";
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
+ return "CAST_SPELL";
+ case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
+ return "BG_OBJECTIVE_CAPTURE";
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
+ return "HONORABLE_KILL_AT_AREA";
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
+ return "WIN_ARENA";
+ case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
+ return "PLAY_ARENA";
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
+ return "LEARN_SPELL";
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL:
+ return "HONORABLE_KILL";
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
+ return "OWN_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ return "WIN_RATED_ARENA";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING:
+ return "HIGHEST_TEAM_RATING";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING:
+ return "HIGHEST_PERSONAL_RATING";
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
+ return "LEARN_SKILL_LEVEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
+ return "USE_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
+ return "LOOT_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA:
+ return "EXPLORE_AREA";
+ case ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK:
+ return "OWN_RANK";
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT:
+ return "BUY_BANK_SLOT";
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
+ return "GAIN_REPUTATION";
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION:
+ return "GAIN_EXALTED_REPUTATION";
+ case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP:
+ return "VISIT_BARBER_SHOP";
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM:
+ return "EQUIP_EPIC_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
+ return "ROLL_NEED_ON_LOOT";
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
+ return "GREED_ON_LOOT";
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
+ return "HK_CLASS";
+ case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
+ return "HK_RACE";
+ case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE:
+ return "DO_EMOTE";
+ case ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE:
+ return "HEALING_DONE";
+ case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
+ return "GET_KILLING_BLOWS";
+ case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
+ return "EQUIP_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS:
+ return "MONEY_FROM_VENDORS";
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS:
+ return "GOLD_SPENT_FOR_TALENTS";
+ case ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS:
+ return "NUMBER_OF_TALENT_RESETS";
+ case ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD:
+ return "MONEY_FROM_QUEST_REWARD";
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING:
+ return "GOLD_SPENT_FOR_TRAVELLING";
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER:
+ return "GOLD_SPENT_AT_BARBER";
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL:
+ return "GOLD_SPENT_FOR_MAIL";
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY:
+ return "LOOT_MONEY";
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
+ return "USE_GAMEOBJECT";
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
+ return "BE_SPELL_TARGET2";
+ case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
+ return "SPECIAL_PVP_KILL";
+ case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
+ return "FISH_IN_GAMEOBJECT";
+ case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
+ return "EARNED_PVP_TITLE";
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
+ return "LEARN_SKILLLINE_SPELLS";
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL:
+ return "WIN_DUEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL:
+ return "LOSE_DUEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
+ return "KILL_CREATURE_TYPE";
+ case ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS:
+ return "GOLD_EARNED_BY_AUCTIONS";
+ case ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION:
+ return "CREATE_AUCTION";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID:
+ return "HIGHEST_AUCTION_BID";
+ case ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS:
+ return "WON_AUCTIONS";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD:
+ return "HIGHEST_AUCTION_SOLD";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED:
+ return "HIGHEST_GOLD_VALUE_OWNED";
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION:
+ return "GAIN_REVERED_REPUTATION";
+ case ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION:
+ return "GAIN_HONORED_REPUTATION";
+ case ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS:
+ return "KNOWN_FACTIONS";
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM:
+ return "LOOT_EPIC_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM:
+ return "RECEIVE_EPIC_ITEM";
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED:
+ return "ROLL_NEED";
+ case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED:
+ return "ROLL_GREED";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT:
+ return "HIT_DEALT";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED:
+ return "HIT_RECEIVED";
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED:
+ return "TOTAL_DAMAGE_RECEIVED";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CAST:
+ return "HIGHEST_HEAL_CAST";
+ case ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED:
+ return "TOTAL_HEALING_RECEIVED";
+ case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED:
+ return "HIGHEST_HEALING_RECEIVED";
+ case ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED:
+ return "QUEST_ABANDONED";
+ case ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN:
+ return "FLIGHT_PATHS_TAKEN";
+ case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE:
+ return "LOOT_TYPE";
+ case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
+ return "CAST_SPELL2";
+ case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
+ return "LEARN_SKILL_LINE";
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
+ return "EARN_HONORABLE_KILL";
+ case ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS:
+ return "ACCEPTED_SUMMONINGS";
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS:
+ return "EARN_ACHIEVEMENT_POINTS";
+ case ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS:
+ return "USE_LFD_TO_GROUP_WITH_PLAYERS";
+ case ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS:
+ return "SPENT_GOLD_GUILD_REPAIRS";
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL:
+ return "REACH_GUILD_LEVEL";
+ case ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD:
+ return "CRAFT_ITEMS_GUILD";
+ case ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL:
+ return "CATCH_FROM_POOL";
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS:
+ return "BUY_GUILD_BANK_SLOTS";
+ case ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS:
+ return "EARN_GUILD_ACHIEVEMENT_POINTS";
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND:
+ return "WIN_RATED_BATTLEGROUND";
+ case ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING:
+ return "REACH_BG_RATING";
+ case ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD:
+ return "BUY_GUILD_TABARD";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD:
+ return "COMPLETE_QUESTS_GUILD";
+ case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD:
+ return "HONORABLE_KILLS_GUILD";
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD:
+ return "KILL_CREATURE_TYPE_GUILD";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE:
+ return "GUILD_CHALLENGE_TYPE";
+ case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE:
+ return "GUILD_CHALLENGE";
+ }
+ return "MISSING_TYPE";
+}
+
+template class AchievementMgr<Guild>;
+template class AchievementMgr<Player>;
+
//==========================================================
void AchievementGlobalMgr::LoadAchievementCriteriaList()
{
@@ -2172,23 +3031,28 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
return;
}
- uint32 loaded = 0;
+ uint32 criterias = 0;
+ uint32 guildCriterias = 0;
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
{
AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(entryId);
if (!criteria)
continue;
- m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria);
- m_AchievementCriteriaListByAchievement[criteria->referredAchievement].push_back(criteria);
+ AchievementEntry const* achievement = sAchievementMgr->GetAchievement(criteria->achievement);
- if (criteria->timeLimit)
- m_AchievementCriteriasByTimedType[criteria->timedType].push_back(criteria);
+ m_AchievementCriteriaListByAchievement[criteria->achievement].push_back(criteria);
+
+ if (achievement && achievement->flags & ACHIEVEMENT_FLAG_GUILD)
+ ++guildCriterias, m_GuildAchievementCriteriasByType[criteria->type].push_back(criteria);
+ else
+ ++criterias, m_AchievementCriteriasByType[criteria->type].push_back(criteria);
- ++loaded;
+ if (criteria->timeLimit)
+ m_AchievementCriteriasByTimedType[criteria->timedCriteriaStartType].push_back(criteria);
}
- TC_LOG_INFO("server.loading", ">> Loaded %u achievement criteria in %u ms", loaded, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u achievement criteria and %u guild achievement crieteria in %u ms", criterias, guildCriterias, GetMSTimeDiffToNow(oldMSTime));
}
void AchievementGlobalMgr::LoadAchievementReferenceList()
@@ -2278,90 +3142,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
}
while (result->NextRow());
- // post loading checks
- for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
- {
- AchievementCriteriaEntry const* criteria = sAchievementMgr->GetAchievementCriteria(entryId);
- if (!criteria)
- continue;
-
- switch (criteria->requiredType)
- {
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
- case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
- {
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement(criteria->referredAchievement);
- if (!achievement)
- continue;
-
- // exist many achievements with this criteria, use at this moment hardcoded check to skil simple case
- if (achievement->ID == 1282)
- break;
-
- continue;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA: // need skip generic cases
- if (criteria->additionalRequirements[0].additionalRequirement_type != ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE)
- continue;
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE: // need skip generic cases
- if (criteria->do_emote.count == 0)
- continue;
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL: // skip statistics
- if (criteria->win_duel.duelCount == 0)
- continue;
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE: // need skip generic cases
- if (criteria->loot_type.lootTypeCount != 1)
- continue;
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL:
- break; // any cases
- case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL: // any cases
- break;
- case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST:
- case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: // only Children's Week achievements
- {
- AchievementEntry const* achievement = sAchievementMgr->GetAchievement(criteria->referredAchievement);
- if (!achievement)
- continue;
- if (achievement->categoryId != CATEGORY_CHILDRENS_WEEK)
- continue;
- break;
- }
- case ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS:
- break;
- default: // type not use DB data, ignore
- continue;
- }
-
- if (!GetCriteriaDataSet(criteria) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, NULL))
- TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` does not have expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->requiredType, criteria->referredAchievement);
- }
-
TC_LOG_INFO("server.loading", ">> Loaded %u additional achievement criteria data in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h
index 1a6777d1055..25328dd3f98 100644
--- a/src/server/game/Achievements/AchievementMgr.h
+++ b/src/server/game/Achievements/AchievementMgr.h
@@ -40,8 +40,9 @@ typedef UNORDERED_MAP<uint32, AchievementEntryList> AchievementListByRef
struct CriteriaProgress
{
- uint32 counter;
+ uint64 counter;
time_t date; // latest update time.
+ uint64 CompletedGUID; // GUID of the player that completed this criteria (guild achievements)
bool changed;
};
@@ -51,15 +52,13 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_CREATURE = 1, // creature_id 0
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_CLASS_RACE = 2, // class_id race_id
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH= 3, // health_percent 0
- ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4, // own_team 0 not corpse (not released body), own_team == false if enemy team expected
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5, // spell_id effect_idx
- ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6, // area id 0
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7, // spell_id effect_idx
ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8, // minvalue value provided with achievement update must be not less that limit
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_LEVEL = 9, // minlevel minlevel of target
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_GENDER = 10, // gender 0=male; 1=female
ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11, // scripted requirement
- ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12, // difficulty normal/heroic difficulty for current event map
+ // REUSE
ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13, // count "with less than %u people in the zone"
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14, // team HORDE(67), ALLIANCE(469)
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15, // drunken_state 0 (enum DrunkenState) of player
@@ -67,7 +66,6 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17, // min_score max_score player's team win bg and opposition team have team score in range
ACHIEVEMENT_CRITERIA_DATA_INSTANCE_SCRIPT = 18, // 0 0 maker instance script call for check current criteria requirements fit
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_EQUIPED_ITEM = 19, // item_level item_quality for equipped item in slot to check item level and quality
- ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20, // map_id 0 player must be on map with id in map_id
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_PLAYER_CLASS_RACE = 21 // class_id race_id
};
@@ -96,11 +94,6 @@ struct AchievementCriteriaData
{
uint32 percent;
} health;
- // ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD = 4
- struct
- {
- uint32 own_team_flag;
- } player_dead;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AURA = 5
// ACHIEVEMENT_CRITERIA_DATA_TYPE_T_AURA = 7
struct
@@ -108,11 +101,6 @@ struct AchievementCriteriaData
uint32 spell_id;
uint32 effect_idx;
} aura;
- // ACHIEVEMENT_CRITERIA_DATA_TYPE_S_AREA = 6
- struct
- {
- uint32 id;
- } area;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_VALUE = 8
struct
{
@@ -130,11 +118,6 @@ struct AchievementCriteriaData
uint32 gender;
} gender;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT = 11 (no data)
- // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_DIFFICULTY = 12
- struct
- {
- uint32 difficulty;
- } difficulty;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT = 13
struct
{
@@ -168,12 +151,7 @@ struct AchievementCriteriaData
uint32 item_level;
uint32 item_quality;
} equipped_item;
- // ACHIEVEMENT_CRITERIA_DATA_TYPE_MAP_ID = 20
- struct
- {
- uint32 mapId;
- } map_id;
- // ...
+ // raw
struct
{
uint32 value1;
@@ -236,6 +214,7 @@ typedef UNORDERED_MAP<uint32, AchievementRewardLocale> AchievementRewardLocales;
struct CompletedAchievementData
{
time_t date;
+ std::set<uint64> guids;
bool changed;
};
@@ -249,45 +228,53 @@ enum ProgressType
PROGRESS_HIGHEST
};
+template<class T>
class AchievementMgr
{
public:
- AchievementMgr(Player* player);
+ AchievementMgr(T* owner);
~AchievementMgr();
void Reset();
static void DeleteFromDB(uint32 lowguid);
void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult);
void SaveToDB(SQLTransaction& trans);
- void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false);
- void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
- void CompletedAchievement(AchievementEntry const* entry);
- void CheckAllAchievementCriteria();
- void SendAllAchievementData() const;
- void SendRespondInspectAchievements(Player* player) const;
+ void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false);
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit const* unit = NULL, Player* referencePlayer = NULL);
+ void CompletedAchievement(AchievementEntry const* entry, Player* referencePlayer);
+ void CheckAllAchievementCriteria(Player* referencePlayer);
+ void SendAllAchievementData(Player* receiver) const;
+ void SendAchievementInfo(Player* receiver, uint32 achievementId = 0) const;
bool HasAchieved(uint32 achievementId) const;
- Player* GetPlayer() const { return m_player; }
+ T* GetOwner() const { return _owner; }
+
void UpdateTimedAchievements(uint32 timeDiff);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); // used for quest and scripted timed achievements
+ uint32 GetAchievementPoints() const { return _achievementPoints; }
private:
void SendAchievementEarned(AchievementEntry const* achievement) const;
void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted) const;
CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry);
- void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET);
+ void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint64 changeValue, Player* referencePlayer, ProgressType ptype = PROGRESS_SET);
void RemoveCriteriaProgress(AchievementCriteriaEntry const* entry);
- void CompletedCriteriaFor(AchievementEntry const* achievement);
+ void CompletedCriteriaFor(AchievementEntry const* achievement, Player* referencePlayer);
bool IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria, AchievementEntry const* achievement);
bool IsCompletedAchievement(AchievementEntry const* entry);
- bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement);
- void BuildAllDataPacket(WorldPacket* data) const;
+ bool CanUpdateCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer);
+ void SendPacket(WorldPacket* data) const;
- Player* m_player;
+ bool ConditionsSatisfied(AchievementCriteriaEntry const* criteria, Player* referencePlayer) const;
+ bool RequirementsSatisfied(AchievementCriteriaEntry const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const;
+ bool AdditionalRequirementsSatisfied(AchievementCriteriaEntry const* criteria, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const;
+
+ T* _owner;
CriteriaProgressMap m_criteriaProgress;
CompletedAchievementMap m_completedAchievements;
typedef std::map<uint32, uint32> TimedAchievementMap;
TimedAchievementMap m_timedAchievements; // Criteria id/time left in MS
+ uint32 _achievementPoints;
};
class AchievementGlobalMgr
@@ -297,9 +284,12 @@ class AchievementGlobalMgr
~AchievementGlobalMgr() { }
public:
- AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type) const
+ static char const* GetCriteriaTypeString(AchievementCriteriaTypes type);
+ static char const* GetCriteriaTypeString(uint32 type);
+
+ AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type, bool guild = false) const
{
- return m_AchievementCriteriasByType[type];
+ return guild ? m_GuildAchievementCriteriasByType[type] : m_AchievementCriteriasByType[type];
}
AchievementCriteriaEntryList const& GetTimedAchievementCriteriaByType(AchievementCriteriaTimedTypes type) const
@@ -347,6 +337,24 @@ class AchievementGlobalMgr
m_allCompletedAchievements.insert(achievement->ID);
}
+ bool IsGroupCriteriaType(AchievementCriteriaTypes type) const
+ {
+ switch (type)
+ {
+ case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: // NYI
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA:
+ case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: // NYI
+ case ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND: // NYI
+ return true;
+ default:
+ break;
+ }
+
+ return false;
+ }
+
void LoadAchievementCriteriaList();
void LoadAchievementCriteriaData();
void LoadAchievementReferenceList();
@@ -360,6 +368,7 @@ class AchievementGlobalMgr
// store achievement criterias by type to speed up lookup
AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
+ AchievementCriteriaEntryList m_GuildAchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];
AchievementCriteriaEntryList m_AchievementCriteriasByTimedType[ACHIEVEMENT_TIMED_TYPE_MAX];
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
index 29d80f5fa6b..07b4eb5b594 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp
@@ -231,7 +231,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new
}
//this function sends mail, when auction is cancelled to old bidder
-void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans)
+void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item)
{
uint64 bidder_guid = MAKE_NEW_GUID(auction->bidder, 0, HIGHGUID_PLAYER);
Player* bidder = ObjectAccessor::FindPlayer(bidder_guid);
@@ -240,6 +240,9 @@ void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQ
if (!bidder)
bidder_accId = sObjectMgr->GetPlayerAccountIdByGUID(bidder_guid);
+ if (bidder)
+ bidder->GetSession()->SendAuctionRemovedNotification(auction->Id, auction->itemEntry, item->GetItemRandomPropertyId());
+
// bidder exist
if (bidder || bidder_accId)
MailDraft(auction->BuildAuctionMailSubject(AUCTION_CANCELLED_TO_BIDDER), AuctionEntry::BuildAuctionMailBody(auction->owner, auction->bid, auction->buyout, auction->deposit, 0))
@@ -574,7 +577,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player
if (itemRandProp)
{
- char* const* temp = itemRandProp->nameSuffix;
+ char* temp = itemRandProp->nameSuffix;
// dbc local name
if (temp)
@@ -614,7 +617,7 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const
data << uint32(Id);
data << uint32(item->GetEntry());
- for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; ++i)
+ for (uint8 i = 0; i < PROP_ENCHANTMENT_SLOT_0; ++i) // PROP_ENCHANTMENT_SLOT_0 = 10
{
data << uint32(item->GetEnchantmentId(EnchantmentSlot(i)));
data << uint32(item->GetEnchantmentDuration(EnchantmentSlot(i)));
@@ -627,13 +630,13 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket& data) const
data << uint32(item->GetSpellCharges()); // item->charge FFFFFFF
data << uint32(0); // Unknown
data << uint64(owner); // Auction->owner
- data << uint32(startbid); // Auction->startbid (not sure if useful)
- data << uint32(bid ? GetAuctionOutBid() : 0);
+ data << uint64(startbid); // Auction->startbid (not sure if useful)
+ data << uint64(bid ? GetAuctionOutBid() : 0);
// Minimal outbid
- data << uint32(buyout); // Auction->buyout
+ data << uint64(buyout); // Auction->buyout
data << uint32((expire_time - time(NULL)) * IN_MILLISECONDS); // time left
data << uint64(bidder); // auction->bidder current
- data << uint32(bid); // current bid
+ data << uint64(bid); // current bid
return true;
}
diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h
index 506c4bea0c5..b81db2aa79a 100644
--- a/src/server/game/AuctionHouse/AuctionHouseMgr.h
+++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h
@@ -165,7 +165,7 @@ class AuctionHouseMgr
void SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans);
void SendAuctionExpiredMail(AuctionEntry* auction, SQLTransaction& trans);
void SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans);
- void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans);
+ void SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans, Item* item);
static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item* pItem, uint32 count);
static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId);
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index d8674ed476b..bd5ffc057dc 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -38,6 +38,7 @@ Battlefield::Battlefield()
m_isActive = false;
m_DefenderTeam = TEAM_NEUTRAL;
+ m_Guid = 0;
m_TypeId = 0;
m_BattleId = 0;
m_ZoneId = 0;
@@ -107,7 +108,7 @@ void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
if (m_PlayersInWar[player->GetTeamId()].find(player->GetGUID()) != m_PlayersInWar[player->GetTeamId()].end())
{
m_PlayersInWar[player->GetTeamId()].erase(player->GetGUID());
- player->GetSession()->SendBfLeaveMessage(m_BattleId);
+ player->GetSession()->SendBfLeaveMessage(m_Guid);
if (Group* group = player->GetGroup()) // Remove the player from the raid group
group->RemoveMember(player->GetGUID());
@@ -211,7 +212,7 @@ void Battlefield::InvitePlayerToQueue(Player* player)
return;
if (m_PlayersInQueue[player->GetTeamId()].size() <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player->GetTeamId())].size() >= m_MinPlayer)
- player->GetSession()->SendBfInvitePlayerToQueue(m_BattleId);
+ player->GetSession()->SendBfInvitePlayerToQueue(m_Guid);
}
void Battlefield::InvitePlayersInQueueToWar()
@@ -280,7 +281,7 @@ void Battlefield::InvitePlayerToWar(Player* player)
m_PlayersWillBeKick[player->GetTeamId()].erase(player->GetGUID());
m_InvitedPlayers[player->GetTeamId()][player->GetGUID()] = time(NULL) + m_TimeForAcceptInvite;
- player->GetSession()->SendBfInvitePlayerToWar(m_BattleId, m_ZoneId, m_TimeForAcceptInvite);
+ player->GetSession()->SendBfInvitePlayerToWar(m_Guid, m_ZoneId, m_TimeForAcceptInvite);
}
void Battlefield::InitStalker(uint32 entry, float x, float y, float z, float o)
@@ -358,6 +359,7 @@ void Battlefield::DoPlaySoundToAll(uint32 SoundID)
WorldPacket data;
data.Initialize(SMSG_PLAY_SOUND, 4);
data << uint32(SoundID);
+ data << uint64(0);
for (int team = 0; team < BG_TEAMS_COUNT; team++)
for (GuidSet::const_iterator itr = m_PlayersInWar[team].begin(); itr != m_PlayersInWar[team].end(); ++itr)
@@ -376,7 +378,7 @@ void Battlefield::PlayerAcceptInviteToQueue(Player* player)
// Add player in queue
m_PlayersInQueue[player->GetTeamId()].insert(player->GetGUID());
// Send notification
- player->GetSession()->SendBfQueueInviteResponse(m_BattleId, m_ZoneId);
+ player->GetSession()->SendBfQueueInviteResponse(m_Guid, m_ZoneId);
}
// Called in WorldSession::HandleBfExitRequest
@@ -394,7 +396,7 @@ void Battlefield::PlayerAcceptInviteToWar(Player* player)
if (AddOrSetPlayerToCorrectBfGroup(player))
{
- player->GetSession()->SendBfEntered(m_BattleId);
+ player->GetSession()->SendBfEntered(m_Guid);
m_PlayersInWar[player->GetTeamId()].insert(player->GetGUID());
m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID());
diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h
index e0e223c9e56..1781209e779 100644
--- a/src/server/game/Battlefield/Battlefield.h
+++ b/src/server/game/Battlefield/Battlefield.h
@@ -28,7 +28,8 @@
enum BattlefieldTypes
{
- BATTLEFIELD_WG // Wintergrasp
+ BATTLEFIELD_WG, // Wintergrasp
+ BATTLEFIELD_TB // Tol Barad (cataclysm)
};
enum BattlefieldIDs
@@ -227,6 +228,7 @@ class Battlefield : public ZoneScript
uint32 GetTypeId() { return m_TypeId; }
uint32 GetZoneId() { return m_ZoneId; }
+ uint64 GetGUID() { return m_Guid; }
void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0);
@@ -347,6 +349,8 @@ class Battlefield : public ZoneScript
void InitStalker(uint32 entry, float x, float y, float z, float o);
protected:
+ uint64 m_Guid;
+
uint64 StalkerGuid;
uint32 m_Timer; // Global timer for event
bool m_IsEnabled;
diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp
index 8aa58f0ac4b..c531e22bc20 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.cpp
+++ b/src/server/game/Battlefield/BattlefieldMgr.cpp
@@ -123,6 +123,15 @@ Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleId)
return NULL;
}
+Battlefield* BattlefieldMgr::GetBattlefieldByGUID(uint64 guid)
+{
+ for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr)
+ if ((*itr)->GetGUID() == guid)
+ return *itr;
+
+ return NULL;
+}
+
ZoneScript* BattlefieldMgr::GetZoneScript(uint32 zoneId)
{
BattlefieldMap::iterator itr = _battlefieldMap.find(zoneId);
diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h
index bb8a076d5d0..225fa380870 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.h
+++ b/src/server/game/Battlefield/BattlefieldMgr.h
@@ -44,6 +44,7 @@ class BattlefieldMgr
// return assigned battlefield
Battlefield* GetBattlefieldToZoneId(uint32 zoneId);
Battlefield* GetBattlefieldByBattleId(uint32 battleId);
+ Battlefield* GetBattlefieldByGUID(uint64 guid);
ZoneScript* GetZoneScript(uint32 zoneId);
diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.h b/src/server/game/Battlefield/Zones/BattlefieldWG.h
index c54d8915a33..6b5b64974a8 100644
--- a/src/server/game/Battlefield/Zones/BattlefieldWG.h
+++ b/src/server/game/Battlefield/Zones/BattlefieldWG.h
@@ -76,7 +76,7 @@ enum WintergraspSpells
// Other spells
SPELL_WINTERGRASP_WATER = 36444,
SPELL_ESSENCE_OF_WINTERGRASP = 58045,
- SPELL_WINTERGRASP_RESTRICTED_FLIGHT_AREA = 58730,
+ SPELL_WINTERGRASP_RESTRICTED_FLIGHT_AREA = 91604,
// Phasing spells
SPELL_HORDE_CONTROLS_FACTORY_PHASE_SHIFT = 56618, // ADDS PHASE 16
diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp
index 2ca60534f30..17d95dbbe6b 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeam.cpp
@@ -41,14 +41,16 @@ ArenaTeam::ArenaTeam()
ArenaTeam::~ArenaTeam()
{ }
-bool ArenaTeam::Create(uint64 captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor)
+bool ArenaTeam::Create(uint64 captainGuid, uint8 type, std::string const& arenaTeamName,
+ uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor,
+ uint8 borderStyle, uint32 borderColor)
{
// Check if captain is present
if (!ObjectAccessor::FindPlayer(captainGuid))
return false;
// Check if arena team name is already taken
- if (sArenaTeamMgr->GetArenaTeamByName(teamName))
+ if (sArenaTeamMgr->GetArenaTeamByName(arenaTeamName))
return false;
// Generate new arena team id
@@ -57,7 +59,7 @@ bool ArenaTeam::Create(uint64 captainGuid, uint8 type, std::string const& teamNa
// Assign member variables
CaptainGuid = captainGuid;
Type = type;
- TeamName = teamName;
+ TeamName = arenaTeamName;
BackgroundColor = backgroundColor;
EmblemStyle = emblemStyle;
EmblemColor = emblemColor;
@@ -179,7 +181,7 @@ bool ArenaTeam::AddMember(uint64 playerGuid)
player->SetArenaTeamInfoField(GetSlot(), ARENA_TEAM_MEMBER, 1);
}
- TC_LOG_INFO("bg.arena", "Player: %s [GUID: %u] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), GUID_LOPART(playerGuid), GetType(), GetId(), GetName().c_str());
+ TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] joined arena team type: %u [Id: %u, Name: %s].", playerName.c_str(), GUID_LOPART(playerGuid), GetType(), GetId(), GetName().c_str());
return true;
}
@@ -321,10 +323,9 @@ void ArenaTeam::DelMember(uint64 guid, bool cleanDb)
break;
}
- // Inform player and remove arena team info from player data
+ // Remove arena team info from player data
if (Player* player = ObjectAccessor::FindPlayer(guid))
{
- player->GetSession()->SendArenaTeamCommandResult(ERR_ARENA_TEAM_QUIT_S, GetName(), "", 0);
// delete all info regarding this team
for (uint32 i = 0; i < ARENA_TEAM_END; ++i)
player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0);
@@ -343,19 +344,18 @@ void ArenaTeam::DelMember(uint64 guid, bool cleanDb)
void ArenaTeam::Disband(WorldSession* session)
{
- // Remove all members from arena team
- while (!Members.empty())
- DelMember(Members.front().Guid, false);
-
// Broadcast update
if (session)
{
BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, 0, 2, session->GetPlayerName(), GetName(), "");
-
if (Player* player = session->GetPlayer())
TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u, Name: %s].", player->GetName().c_str(), player->GetGUIDLow(), GetType(), GetId(), GetName().c_str());
}
+ // Remove all members from arena team
+ while (!Members.empty())
+ DelMember(Members.front().Guid, false);
+
// Update database
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -580,6 +580,20 @@ uint8 ArenaTeam::GetSlotByType(uint32 type)
return 0xFF;
}
+uint8 ArenaTeam::GetTypeBySlot(uint8 slot)
+{
+ switch (slot)
+ {
+ case 0: return ARENA_TEAM_2v2;
+ case 1: return ARENA_TEAM_3v3;
+ case 2: return ARENA_TEAM_5v5;
+ default:
+ break;
+ }
+ TC_LOG_ERROR("bg.arena", "FATAL: Unknown arena team slot %u for some arena team", slot);
+ return 0xFF;
+}
+
bool ArenaTeam::IsMember(uint64 guid) const
{
for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
@@ -589,32 +603,6 @@ bool ArenaTeam::IsMember(uint64 guid) const
return false;
}
-uint32 ArenaTeam::GetPoints(uint32 memberRating)
-{
- // Returns how many points would be awarded with this team type with this rating
- float points;
-
- uint32 rating = memberRating + 150 < Stats.Rating ? memberRating : Stats.Rating;
-
- if (rating <= 1500)
- {
- if (sWorld->getIntConfig(CONFIG_ARENA_SEASON_ID) < 6)
- points = (float)rating * 0.22f + 14.0f;
- else
- points = 344;
- }
- else
- points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
-
- // Type penalties for teams < 5v5
- if (Type == ARENA_TEAM_2v2)
- points *= 0.76f;
- else if (Type == ARENA_TEAM_3v3)
- points *= 0.88f;
-
- return (uint32) points;
-}
-
uint32 ArenaTeam::GetAverageMMR(Group* group) const
{
if (!group)
@@ -628,7 +616,7 @@ uint32 ArenaTeam::GetAverageMMR(Group* group) const
if (!ObjectAccessor::FindPlayer(itr->Guid))
continue;
- // Skip if player is not member of group
+ // Skip if player is not a member of group
if (!group->IsMember(itr->Guid))
continue;
@@ -652,7 +640,7 @@ float ArenaTeam::GetChanceAgainst(uint32 ownRating, uint32 opponentRating)
return 1.0f / (1.0f + exp(log(10.0f) * (float)((float)opponentRating - (float)ownRating) / 650.0f));
}
-int32 ArenaTeam::GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won /*, float& confidence_factor*/)
+int32 ArenaTeam::GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won)
{
// 'Chance' calculation - to beat the opponent
// This is a simulation. Not much info on how it really works
@@ -731,17 +719,17 @@ void ArenaTeam::FinishGame(int32 mod)
}
}
-int32 ArenaTeam::WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change)
+int32 ArenaTeam::WonAgainst(uint32 ownMMRating, uint32 opponentMMRating, int32& ratingChange)
{
// Called when the team has won
// Change in Matchmaker rating
- int32 mod = GetMatchmakerRatingMod(Own_MMRating, Opponent_MMRating, true);
+ int32 mod = GetMatchmakerRatingMod(ownMMRating, opponentMMRating, true);
// Change in Team Rating
- rating_change = GetRatingMod(Stats.Rating, Opponent_MMRating, true);
+ ratingChange = GetRatingMod(Stats.Rating, opponentMMRating, true);
// Modify the team stats accordingly
- FinishGame(rating_change);
+ FinishGame(ratingChange);
// Update number of wins per season and week
Stats.WeekWins += 1;
@@ -751,23 +739,23 @@ int32 ArenaTeam::WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32
return mod;
}
-int32 ArenaTeam::LostAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change)
+int32 ArenaTeam::LostAgainst(uint32 ownMMRating, uint32 opponentMMRating, int32& ratingChange)
{
// Called when the team has lost
// Change in Matchmaker Rating
- int32 mod = GetMatchmakerRatingMod(Own_MMRating, Opponent_MMRating, false);
+ int32 mod = GetMatchmakerRatingMod(ownMMRating, opponentMMRating, false);
// Change in Team Rating
- rating_change = GetRatingMod(Stats.Rating, Opponent_MMRating, false);
+ ratingChange = GetRatingMod(Stats.Rating, opponentMMRating, false);
// Modify the team stats accordingly
- FinishGame(rating_change);
+ FinishGame(ratingChange);
// return the rating change, used to display it on the results screen
return mod;
}
-void ArenaTeam::MemberLost(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange)
+void ArenaTeam::MemberLost(Player* player, uint32 againstMatchmakerRating, int32 matchmakerRatingChange)
{
// Called for each participant of a match after losing
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
@@ -779,7 +767,7 @@ void ArenaTeam::MemberLost(Player* player, uint32 againstMatchmakerRating, int32
itr->ModifyPersonalRating(player, mod, GetType());
// Update matchmaker rating
- itr->ModifyMatchmakerRating(MatchmakerRatingChange, GetSlot());
+ itr->ModifyMatchmakerRating(matchmakerRatingChange, GetSlot());
// Update personal played stats
itr->WeekGames +=1;
@@ -793,7 +781,7 @@ void ArenaTeam::MemberLost(Player* player, uint32 againstMatchmakerRating, int32
}
}
-void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange)
+void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 matchmakerRatingChange)
{
// Called for offline player after ending rated arena match!
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
@@ -805,7 +793,7 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, i
itr->ModifyPersonalRating(NULL, mod, GetType());
// update matchmaker rating
- itr->ModifyMatchmakerRating(MatchmakerRatingChange, GetSlot());
+ itr->ModifyMatchmakerRating(matchmakerRatingChange, GetSlot());
// update personal played stats
itr->WeekGames += 1;
@@ -815,7 +803,7 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, i
}
}
-void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange)
+void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32 matchmakerRatingChange)
{
// called for each participant after winning a match
for (MemberList::iterator itr = Members.begin(); itr != Members.end(); ++itr)
@@ -827,7 +815,7 @@ void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32
itr->ModifyPersonalRating(player, mod, GetType());
// update matchmaker rating
- itr->ModifyMatchmakerRating(MatchmakerRatingChange, GetSlot());
+ itr->ModifyMatchmakerRating(matchmakerRatingChange, GetSlot());
// update personal stats
itr->WeekGames +=1;
@@ -842,36 +830,6 @@ void ArenaTeam::MemberWon(Player* player, uint32 againstMatchmakerRating, int32
}
}
-void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& playerPoints)
-{
- // Called after a match has ended and the stats are already modified
- // Helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
- // 10 played games per week is a minimum
- if (Stats.WeekGames < 10)
- return;
-
- // To get points, a player has to participate in at least 30% of the matches
- uint32 requiredGames = (uint32)ceil(Stats.WeekGames * 0.3f);
-
- for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr)
- {
- // The player participated in enough games, update his points
- uint32 pointsToAdd = 0;
- if (itr->WeekGames >= requiredGames)
- pointsToAdd = GetPoints(itr->PersonalRating);
-
- std::map<uint32, uint32>::iterator plr_itr = playerPoints.find(GUID_LOPART(itr->Guid));
- if (plr_itr != playerPoints.end())
- {
- // Check if there is already more points
- if (plr_itr->second < pointsToAdd)
- playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
- }
- else
- playerPoints[GUID_LOPART(itr->Guid)] = pointsToAdd;
- }
-}
-
void ArenaTeam::SaveToDB()
{
// Save team and member stats to db
diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h
index cd9e2be4318..c4f6201434f 100644
--- a/src/server/game/Battlegrounds/ArenaTeam.h
+++ b/src/server/game/Battlegrounds/ArenaTeam.h
@@ -19,9 +19,10 @@
#ifndef TRINITYCORE_ARENATEAM_H
#define TRINITYCORE_ARENATEAM_H
+#include "Define.h"
#include "QueryResult.h"
-#include <ace/Singleton.h>
#include <list>
+#include <string>
#include <map>
class WorldSession;
@@ -39,6 +40,7 @@ enum ArenaTeamCommandTypes
enum ArenaTeamCommandErrors
{
+ ERR_ARENA_TEAM_CREATED = 0x00,
ERR_ARENA_TEAM_INTERNAL = 0x01,
ERR_ALREADY_IN_ARENA_TEAM = 0x02,
ERR_ALREADY_IN_ARENA_TEAM_S = 0x03,
@@ -57,7 +59,8 @@ enum ArenaTeamCommandErrors
ERR_ARENA_TEAM_TARGET_TOO_HIGH_S = 0x16,
ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S = 0x17,
ERR_ARENA_TEAM_NOT_FOUND = 0x1B,
- ERR_ARENA_TEAMS_LOCKED = 0x1E
+ ERR_ARENA_TEAMS_LOCKED = 0x1E,
+ ERR_ARENA_TEAM_TOO_MANY_CREATE = 0x21,
};
enum ArenaTeamEvents
@@ -70,14 +73,6 @@ enum ArenaTeamEvents
ERR_ARENA_TEAM_DISBANDED_S = 8 // captain name + arena team name
};
-/*
-need info how to send these ones:
-ERR_ARENA_TEAM_YOU_JOIN_S - client show it automatically when accept invite
-ERR_ARENA_TEAM_TARGET_TOO_LOW_S
-ERR_ARENA_TEAM_TOO_MANY_MEMBERS_S
-ERR_ARENA_TEAM_LEVEL_TOO_LOW_I
-*/
-
enum ArenaTeamTypes
{
ARENA_TEAM_2v2 = 2,
@@ -119,18 +114,21 @@ class ArenaTeam
ArenaTeam();
~ArenaTeam();
- bool Create(uint64 captainGuid, uint8 type, std::string const& teamName, uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor, uint8 borderStyle, uint32 borderColor);
+ bool Create(uint64 captainGuid, uint8 type, std::string const& teamName,
+ uint32 backgroundColor, uint8 emblemStyle, uint32 emblemColor,
+ uint8 borderStyle, uint32 borderColor);
void Disband(WorldSession* session);
void Disband();
typedef std::list<ArenaTeamMember> MemberList;
- uint32 GetId() const { return TeamId; }
- uint32 GetType() const { return Type; }
- uint8 GetSlot() const { return GetSlotByType(GetType()); }
+ uint32 GetId() const { return TeamId; }
+ uint32 GetType() const { return Type; }
+ uint8 GetSlot() const { return GetSlotByType(GetType()); }
static uint8 GetSlotByType(uint32 type);
- uint64 GetCaptain() const { return CaptainGuid; }
- std::string const& GetName() const { return TeamName; }
+ static uint8 GetTypeBySlot(uint8 slot);
+ uint64 GetCaptain() const { return CaptainGuid; }
+ std::string const& GetName() const { return TeamName; }
const ArenaTeamStats& GetStats() const { return Stats; }
uint32 GetRating() const { return Stats.Rating; }
@@ -139,9 +137,6 @@ class ArenaTeam
void SetCaptain(uint64 guid);
bool SetName(std::string const& name);
bool AddMember(uint64 PlayerGuid);
-
- // Shouldn't be uint64 ed, because than can reference guid from members on Disband
- // and this method removes given record from list. So invalid reference can happen.
void DelMember(uint64 guid, bool cleanDb);
size_t GetMembersSize() const { return Members.size(); }
@@ -171,27 +166,26 @@ class ArenaTeam
void SendStats(WorldSession* session);
void Inspect(WorldSession* session, uint64 guid);
- uint32 GetPoints(uint32 MemberRating);
- int32 GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
- int32 GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
- float GetChanceAgainst(uint32 ownRating, uint32 opponentRating);
- int32 WonAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change);
- void MemberWon(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange);
- int32 LostAgainst(uint32 Own_MMRating, uint32 Opponent_MMRating, int32& rating_change);
- void MemberLost(Player* player, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange = -12);
- void OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 MatchmakerRatingChange = -12);
+ static int32 GetMatchmakerRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
+ static int32 GetRatingMod(uint32 ownRating, uint32 opponentRating, bool won);
+ static float GetChanceAgainst(uint32 ownRating, uint32 opponentRating);
+
+ int32 WonAgainst(uint32 ownMMRating, uint32 opponentMMRating, int32& rating_change);
+ void MemberWon(Player* player, uint32 againstMatchmakerRating, int32 matchmakerRatingChange = 12);
- void UpdateArenaPointsHelper(std::map<uint32, uint32> & PlayerPoints);
+ int32 LostAgainst(uint32 ownMMRating, uint32 opponentMMRating, int32& rating_change);
+ void MemberLost(Player* player, uint32 againstMatchmakerRating, int32 matchmakerRatingChange = -12);
+ void OfflineMemberLost(uint64 guid, uint32 againstMatchmakerRating, int32 matchmakerRatingChange = -12);
void FinishWeek();
void FinishGame(int32 mod);
protected:
- uint32 TeamId;
- uint8 Type;
+ uint32 TeamId;
+ uint8 Type;
std::string TeamName;
- uint64 CaptainGuid;
+ uint64 CaptainGuid;
uint32 BackgroundColor; // ARGB format
uint8 EmblemStyle; // icon id
@@ -199,7 +193,7 @@ class ArenaTeam
uint8 BorderStyle; // border image id
uint32 BorderColor; // ARGB format
- MemberList Members;
+ MemberList Members;
ArenaTeamStats Stats;
};
#endif
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
index dba891c96db..0098c8a1bcb 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
@@ -134,59 +134,3 @@ void ArenaTeamMgr::LoadArenaTeams()
TC_LOG_INFO("server.loading", ">> Loaded %u arena teams in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-
-void ArenaTeamMgr::DistributeArenaPoints()
-{
- // Used to distribute arena points based on last week's stats
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_START);
-
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_START);
-
- // Temporary structure for storing maximum points to add values for all players
- std::map<uint32, uint32> PlayerPoints;
-
- // At first update all points for all team members
- for (ArenaTeamContainer::iterator teamItr = GetArenaTeamMapBegin(); teamItr != GetArenaTeamMapEnd(); ++teamItr)
- if (ArenaTeam* at = teamItr->second)
- at->UpdateArenaPointsHelper(PlayerPoints);
-
- SQLTransaction trans = CharacterDatabase.BeginTransaction();
-
- PreparedStatement* stmt;
-
- // Cycle that gives points to all players
- for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr)
- {
- // Add points to player if online
- if (Player* player = HashMapHolder<Player>::Find(playerItr->first))
- player->ModifyArenaPoints(playerItr->second, &trans);
- else // Update database
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS);
- stmt->setUInt32(0, playerItr->second);
- stmt->setUInt32(1, playerItr->first);
- trans->Append(stmt);
- }
- }
-
- CharacterDatabase.CommitTransaction(trans);
-
- PlayerPoints.clear();
-
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_ONLINE_END);
-
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_START);
- for (ArenaTeamContainer::iterator titr = GetArenaTeamMapBegin(); titr != GetArenaTeamMapEnd(); ++titr)
- {
- if (ArenaTeam* at = titr->second)
- {
- at->FinishWeek();
- at->SaveToDB();
- at->NotifyStatsChanged();
- }
- }
-
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_TEAM_END);
-
- sWorld->SendWorldText(LANG_DIST_ARENA_POINTS_END);
-}
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h
index 123cbe2d41b..bbb0d87f398 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.h
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h
@@ -40,8 +40,6 @@ public:
ArenaTeamContainer::iterator GetArenaTeamMapBegin() { return ArenaTeamStore.begin(); }
ArenaTeamContainer::iterator GetArenaTeamMapEnd() { return ArenaTeamStore.end(); }
- void DistributeArenaPoints();
-
uint32 GenerateArenaTeamId();
void SetNextArenaTeamId(uint32 Id) { NextArenaTeamId = Id; }
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 3fcfab81c73..4860f226a67 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -25,6 +25,8 @@
#include "Formulas.h"
#include "GridNotifiersImpl.h"
#include "Group.h"
+#include "Guild.h"
+#include "GuildMgr.h"
#include "MapManager.h"
#include "Object.h"
#include "ObjectMgr.h"
@@ -112,6 +114,7 @@ void Battleground::BroadcastWorker(Do& _do)
Battleground::Battleground()
{
+ m_Guid = 0;
m_TypeID = BATTLEGROUND_TYPE_NONE;
m_RandomTypeID = BATTLEGROUND_TYPE_NONE;
m_InstanceID = 0;
@@ -126,6 +129,7 @@ Battleground::Battleground()
m_IsArena = false;
m_Winner = 2;
m_StartTime = 0;
+ m_CountdownTimer = 0;
m_ResetStatTimer = 0;
m_ValidStartPositionTimer = 0;
m_Events = 0;
@@ -259,7 +263,7 @@ void Battleground::Update(uint32 diff)
// after 47 minutes without one team losing, the arena closes with no winner and no rating change
if (isArena())
{
- if (GetStartTime() >= 47 * MINUTE*IN_MILLISECONDS)
+ if (GetElapsedTime() >= 47 * MINUTE*IN_MILLISECONDS)
{
UpdateArenaWorldState();
CheckArenaAfterTimerConditions();
@@ -283,8 +287,12 @@ void Battleground::Update(uint32 diff)
}
// Update start time and reset stats timer
- m_StartTime += diff;
- m_ResetStatTimer += diff;
+ SetElapsedTime(GetElapsedTime() + diff);
+ if (GetStatus() == STATUS_WAIT_JOIN)
+ {
+ m_ResetStatTimer += diff;
+ m_CountdownTimer += diff;
+ }
PostUpdateImpl(diff);
}
@@ -447,6 +455,9 @@ inline void Battleground::_ProcessJoin(uint32 diff)
// *********************************************************
ModifyStartDelayTime(diff);
+ if (!isArena())
+ SetRemainingTime(300000);
+
if (m_ResetStatTimer > 5000)
{
m_ResetStatTimer = 0;
@@ -455,6 +466,23 @@ inline void Battleground::_ProcessJoin(uint32 diff)
player->ResetAllPowers();
}
+ // Send packet every 10 seconds until the 2nd field reach 0
+ if (m_CountdownTimer >= 10000)
+ {
+ uint32 countdownMaxForBGType = isArena() ? ARENA_COUNTDOWN_MAX : BATTLEGROUND_COUNTDOWN_MAX;
+
+ WorldPacket data(SMSG_START_TIMER, 4+4+4);
+ data << uint32(0); // unk
+ data << uint32(countdownMaxForBGType - (GetElapsedTime() / 1000));
+ data << uint32(countdownMaxForBGType);
+
+ for (BattlegroundPlayerMap::const_iterator itr = GetPlayers().begin(); itr != GetPlayers().end(); ++itr)
+ if (Player* player = ObjectAccessor::FindPlayer(itr->first))
+ player->GetSession()->SendPacket(&data);
+
+ m_CountdownTimer = 0;
+ }
+
if (!(m_Events & BG_STARTING_EVENT_1))
{
m_Events |= BG_STARTING_EVENT_1;
@@ -512,8 +540,12 @@ inline void Battleground::_ProcessJoin(uint32 diff)
WorldPacket status;
BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType());
uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, queueSlot, STATUS_IN_PROGRESS, 0, GetStartTime(), GetArenaType(), player->GetBGTeam());
- player->SendDirectMessage(&status);
+
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&status, this, player, queueSlot, STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(m_TypeID), GetElapsedTime(), GetArenaType());
+ player->GetSession()->SendPacket(&status);
+
+ // Correctly display EnemyUnitFrame
+ player->SetByteValue(PLAYER_BYTES_3, 3, player->GetBGTeam());
player->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
player->ResetAllPowers();
@@ -554,6 +586,9 @@ inline void Battleground::_ProcessJoin(uint32 diff)
sWorld->SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, GetName(), GetMinLevel(), GetMaxLevel());
}
}
+
+ if (GetRemainingTime() > 0 && (m_EndTime -= diff) > 0)
+ SetRemainingTime(GetRemainingTime() - diff);
}
inline void Battleground::_ProcessLeave(uint32 diff)
@@ -562,10 +597,10 @@ inline void Battleground::_ProcessLeave(uint32 diff)
// *** BATTLEGROUND ENDING SYSTEM ***
// *********************************************************
// remove all players from battleground after 2 minutes
- m_EndTime -= diff;
- if (m_EndTime <= 0)
+ SetRemainingTime(GetRemainingTime() - diff);
+ if (GetRemainingTime() <= 0)
{
- m_EndTime = 0;
+ SetRemainingTime(0);
BattlegroundPlayerMap::iterator itr, next;
for (itr = m_Players.begin(); itr != m_Players.end(); itr = next)
{
@@ -756,7 +791,7 @@ void Battleground::EndBattleground(uint32 winner)
SetStatus(STATUS_WAIT_LEAVE);
//we must set it this way, because end time is sent in packet!
- m_EndTime = TIME_TO_AUTOREMOVE;
+ SetRemainingTime(TIME_AUTOCLOSE_BATTLEGROUND);
// arena rating calculation
if (isArena() && isRated())
@@ -807,6 +842,7 @@ void Battleground::EndBattleground(uint32 winner)
}
}
+ bool guildAwarded = false;
WorldPacket pvpLogData;
sBattlegroundMgr->BuildPvpLogDataPacket(&pvpLogData, this);
@@ -863,6 +899,7 @@ void Battleground::EndBattleground(uint32 winner)
uint32 rating = player->GetArenaPersonalRating(winnerArenaTeam->GetSlot());
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA, GetMapId());
+ player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD));
winnerArenaTeam->MemberWon(player, loserMatchmakerRating, winnerMatchmakerChange);
}
@@ -875,28 +912,46 @@ void Battleground::EndBattleground(uint32 winner)
}
}
- uint32 winner_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST);
- uint32 loser_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST);
- uint32 winner_arena = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_FIRST);
+ uint32 winnerKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST);
+ uint32 loserKills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST);
+
+ // remove temporary currency bonus auras before rewarding player
+ player->RemoveAura(SPELL_HONORABLE_DEFENDER_25Y);
+ player->RemoveAura(SPELL_HONORABLE_DEFENDER_60Y);
// Reward winner team
if (team == winner)
{
if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetTypeID()))
{
- UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winner_kills));
- if (CanAwardArenaPoints())
- player->ModifyArenaPoints(winner_arena);
+ UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(winnerKills));
if (!player->GetRandomWinner())
+ {
+ // 100cp awarded for the first random battleground won each day
+ player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_CONQUEST_FIRST));
player->SetRandomWinner(true);
+ }
}
+ else // 50cp awarded for each non-rated battleground won
+ player->ModifyCurrency(CURRENCY_TYPE_CONQUEST_META_ARENA, sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_CONQUEST_LAST));
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1);
+ if (!guildAwarded)
+ {
+ guildAwarded = true;
+ if (uint32 guildId = GetBgMap()->GetOwnerGuildId(player->GetTeam()))
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ {
+ guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1, 0, 0, NULL, player);
+ if (isArena() && isRated() && winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam)
+ guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, std::max<uint32>(winnerArenaTeam->GetRating(), 1), 0, 0, NULL, player);
+ }
+ }
}
else
{
if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetTypeID()))
- UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(loser_kills));
+ UpdatePlayerScore(player, SCORE_BONUS_HONOR, GetBonusHonorFromKill(loserKills));
}
player->ResetAllPowers();
@@ -907,8 +962,9 @@ void Battleground::EndBattleground(uint32 winner)
player->SendDirectMessage(&pvpLogData);
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime(), GetArenaType(), player->GetBGTeam());
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType());
player->SendDirectMessage(&data);
+
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);
}
@@ -981,10 +1037,11 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
RemovePlayer(player, guid, team); // BG subclass specific code
+ BattlegroundTypeId bgTypeId = GetTypeID();
+ BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
+
if (participant) // if the player was a match participant, remove auras, calc rating, update queue
{
- BattlegroundTypeId bgTypeId = GetTypeID();
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(GetTypeID(), GetArenaType());
if (player)
{
player->ClearAfkReports();
@@ -1012,7 +1069,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
if (SendPacket)
{
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, 0, 0, 0, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_NONE, player->GetBattlegroundQueueJoinTime(bgTypeId), 0, 0);
player->SendDirectMessage(&data);
}
@@ -1060,6 +1117,7 @@ void Battleground::RemovePlayerAtLeave(uint64 guid, bool Transport, bool SendPac
player->SetBattlegroundId(0, BATTLEGROUND_TYPE_NONE); // We're not in BG.
// reset destination bg team
player->SetBGTeam(0);
+ player->RemoveBattlegroundQueueJoinTime(bgTypeId);
if (Transport)
player->TeleportToBGEntryPoint();
@@ -1075,8 +1133,8 @@ void Battleground::Reset()
{
SetWinner(WINNER_NONE);
SetStatus(STATUS_WAIT_QUEUE);
- SetStartTime(0);
- SetEndTime(0);
+ SetElapsedTime(0);
+ SetRemainingTime(0);
SetLastResurrectTime(0);
m_Events = 0;
@@ -1099,7 +1157,7 @@ void Battleground::Reset()
void Battleground::StartBattleground()
{
- SetStartTime(0);
+ SetElapsedTime(0);
SetLastResurrectTime(0);
// add BG to free slot queue
AddToBGFreeSlotQueue();
@@ -1123,10 +1181,12 @@ void Battleground::AddPlayer(Player* player)
uint64 guid = player->GetGUID();
uint32 team = player->GetBGTeam();
+ int32 primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());
BattlegroundPlayer bp;
bp.OfflineRemoveTime = 0;
bp.Team = team;
+ bp.PrimaryTree = primaryTree;
// Add to list/maps
m_Players[guid] = bp;
@@ -1134,9 +1194,16 @@ void Battleground::AddPlayer(Player* player)
UpdatePlayersCountByTeam(team, false); // +1 player
WorldPacket data;
- sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player);
+ sBattlegroundMgr->BuildPlayerJoinedBattlegroundPacket(&data, player->GetGUID());
SendPacketToTeam(team, &data, player, false);
+ // BG Status packet
+ BattlegroundQueueTypeId bgQueueTypeId = sBattlegroundMgr->BGQueueTypeId(m_TypeID, GetArenaType());
+ uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId);
+
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, queueSlot, STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(m_TypeID), GetElapsedTime(), GetArenaType());
+ player->GetSession()->SendPacket(&data);
+
player->RemoveAurasByType(SPELL_AURA_MOUNTED);
// add arena specific auras
@@ -1170,7 +1237,16 @@ void Battleground::AddPlayer(Player* player)
else
{
if (GetStatus() == STATUS_WAIT_JOIN) // not started yet
+ {
player->CastSpell(player, SPELL_PREPARATION, true); // reduces all mana cost of spells.
+
+ int32 countdownMaxForBGType = isArena() ? ARENA_COUNTDOWN_MAX : BATTLEGROUND_COUNTDOWN_MAX;
+ WorldPacket data(SMSG_START_TIMER, 4+4+4);
+ data << uint32(0); // unk
+ data << uint32(countdownMaxForBGType - (GetElapsedTime() / 1000));
+ data << uint32(countdownMaxForBGType);
+ player->GetSession()->SendPacket(&data);
+ }
}
player->ResetAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP, GetMapId(), true);
@@ -1655,6 +1731,7 @@ bool Battleground::AddSpiritGuide(uint32 type, float x, float y, float z, float
creature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL);
// correct cast speed
creature->SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
+ creature->SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f);
//creature->CastSpell(creature, SPELL_SPIRIT_HEAL_CHANNEL, true);
return true;
}
@@ -1726,7 +1803,7 @@ void Battleground::EndNow()
{
RemoveFromBGFreeSlotQueue();
SetStatus(STATUS_WAIT_LEAVE);
- SetEndTime(0);
+ SetRemainingTime(0);
}
// To be removed
@@ -1846,7 +1923,7 @@ void Battleground::PlayerAddedToBGCheckIfBGIsRunning(Player* player)
sBattlegroundMgr->BuildPvpLogDataPacket(&data, this);
player->SendDirectMessage(&data);
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, GetEndTime(), GetStartTime(), GetArenaType(), player->GetBGTeam());
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, this, player, player->GetBattlegroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, player->GetBattlegroundQueueJoinTime(GetTypeID()), GetElapsedTime(), GetArenaType());
player->SendDirectMessage(&data);
}
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index a866f09639a..824a71bc89b 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -119,12 +119,14 @@ enum BattlegroundTimeIntervals
RESURRECTION_INTERVAL = 30000, // ms
//REMIND_INTERVAL = 10000, // ms
INVITATION_REMIND_TIME = 20000, // ms
- INVITE_ACCEPT_WAIT_TIME = 60000, // ms
- TIME_TO_AUTOREMOVE = 120000, // ms
+ INVITE_ACCEPT_WAIT_TIME = 90000, // ms
+ TIME_AUTOCLOSE_BATTLEGROUND = 120000, // ms
MAX_OFFLINE_TIME = 300, // secs
RESPAWN_ONE_DAY = 86400, // secs
RESPAWN_IMMEDIATELY = 0, // secs
- BUFF_RESPAWN_TIME = 180 // secs
+ BUFF_RESPAWN_TIME = 180, // secs
+ BATTLEGROUND_COUNTDOWN_MAX = 120, // secs
+ ARENA_COUNTDOWN_MAX = 60 // secs
};
enum BattlegroundStartTimeIntervals
@@ -143,7 +145,7 @@ enum BattlegroundBuffObjects
BG_OBJECTID_BERSERKERBUFF_ENTRY = 179905
};
-const uint32 Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY };
+uint32 const Buff_Entries[3] = { BG_OBJECTID_SPEEDBUFF_ENTRY, BG_OBJECTID_REGENBUFF_ENTRY, BG_OBJECTID_BERSERKERBUFF_ENTRY };
enum BattlegroundStatus
{
@@ -158,6 +160,7 @@ struct BattlegroundPlayer
{
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
uint32 Team; // Player's team
+ int32 PrimaryTree; // Player's primary tree
};
struct BattlegroundObjectInfo
@@ -297,13 +300,14 @@ class Battleground
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
+ uint64 GetGUID() { return m_Guid; }
BattlegroundTypeId GetTypeID(bool GetRandom = false) const { return GetRandom ? m_RandomTypeID : m_TypeID; }
BattlegroundBracketId GetBracketId() const { return m_BracketId; }
uint32 GetInstanceID() const { return m_InstanceID; }
BattlegroundStatus GetStatus() const { return m_Status; }
uint32 GetClientInstanceID() const { return m_ClientInstanceID; }
- uint32 GetStartTime() const { return m_StartTime; }
- uint32 GetEndTime() const { return m_EndTime; }
+ uint32 GetElapsedTime() const { return m_StartTime; }
+ uint32 GetRemainingTime() const { return m_EndTime; }
uint32 GetLastResurrectTime() const { return m_LastResurrectTime; }
uint32 GetMaxPlayers() const { return m_MaxPlayers; }
uint32 GetMinPlayers() const { return m_MinPlayers; }
@@ -322,6 +326,7 @@ class Battleground
bool IsRandom() const { return m_IsRandom; }
// Set methods:
+ void SetGuid(uint64 newGuid) { m_Guid = newGuid; }
void SetName(char const* Name) { m_Name = Name; }
void SetTypeID(BattlegroundTypeId TypeID) { m_TypeID = TypeID; }
void SetRandomTypeID(BattlegroundTypeId TypeID) { m_RandomTypeID = TypeID; }
@@ -330,8 +335,8 @@ class Battleground
void SetInstanceID(uint32 InstanceID) { m_InstanceID = InstanceID; }
void SetStatus(BattlegroundStatus Status) { m_Status = Status; }
void SetClientInstanceID(uint32 InstanceID) { m_ClientInstanceID = InstanceID; }
- void SetStartTime(uint32 Time) { m_StartTime = Time; }
- void SetEndTime(uint32 Time) { m_EndTime = Time; }
+ void SetElapsedTime(uint32 Time) { m_StartTime = Time; }
+ void SetRemainingTime(uint32 Time) { m_EndTime = Time; }
void SetLastResurrectTime(uint32 Time) { m_LastResurrectTime = Time; }
void SetMaxPlayers(uint32 MaxPlayers) { m_MaxPlayers = MaxPlayers; }
void SetMinPlayers(uint32 MinPlayers) { m_MinPlayers = MinPlayers; }
@@ -586,6 +591,7 @@ class Battleground
BattlegroundStatus m_Status;
uint32 m_ClientInstanceID; // the instance-id which is sent to the client and without any other internal use
uint32 m_StartTime;
+ uint32 m_CountdownTimer;
uint32 m_ResetStatTimer;
uint32 m_ValidStartPositionTimer;
int32 m_EndTime; // it is set to 120000 when bg is ending and it decreases itself
@@ -601,6 +607,7 @@ class Battleground
bool m_PrematureCountDown;
uint32 m_PrematureCountDownTimer;
char const* m_Name;
+ uint64 m_Guid;
/* Pre- and post-update hooks */
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 9d7a67ee0dc..823b869623d 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -35,6 +35,8 @@
#include "BattlegroundDS.h"
#include "BattlegroundRV.h"
#include "BattlegroundIC.h"
+#include "BattlegroundTP.h"
+#include "BattlegroundBFG.h"
#include "Chat.h"
#include "Map.h"
#include "MapInstanced.h"
@@ -52,8 +54,7 @@
BattlegroundMgr::BattlegroundMgr() :
m_NextRatedArenaUpdate(sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER)),
- m_NextAutoDistributionTime(0),
- m_AutoDistributionTimeChecker(0), m_ArenaTesting(false), m_Testing(false)
+ m_ArenaTesting(false), m_Testing(false)
{ }
BattlegroundMgr::~BattlegroundMgr()
@@ -145,222 +146,401 @@ void BattlegroundMgr::Update(uint32 diff)
else
m_NextRatedArenaUpdate -= diff;
}
-
- if (sWorld->getBoolConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
- {
- if (m_AutoDistributionTimeChecker < diff)
- {
- if (time(NULL) > m_NextAutoDistributionTime)
- {
- sArenaTeamMgr->DistributeArenaPoints();
- m_NextAutoDistributionTime = m_NextAutoDistributionTime + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld->getIntConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS);
- sWorld->setWorldState(WS_ARENA_DISTRIBUTION_TIME, uint64(m_NextAutoDistributionTime));
- }
- m_AutoDistributionTimeChecker = 600000; // check 10 minutes
- }
- else
- m_AutoDistributionTimeChecker -= diff;
- }
}
-void BattlegroundMgr::BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype, uint32 arenaFaction)
+void BattlegroundMgr::BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, Player* player, uint8 QueueSlot, uint8 StatusID, uint32 Time1, uint32 Time2, uint8 arenatype)
{
- // we can be in 2 queues in same time...
+ ObjectGuid playerGuid = player->GetGUID();
+ ObjectGuid bgGuid;
- if (StatusID == 0 || !bg)
- {
- data->Initialize(SMSG_BATTLEFIELD_STATUS, 4+8);
- *data << uint32(QueueSlot); // queue id (0...1)
- *data << uint64(0);
- return;
- }
+ if (bg)
+ bgGuid = bg->GetGUID();
+ else
+ StatusID = STATUS_NONE;
- data->Initialize(SMSG_BATTLEFIELD_STATUS, (4+8+1+1+4+1+4+4+4));
- *data << uint32(QueueSlot); // queue id (0...1) - player can be in 2 queues in time
- // The following segment is read as uint64 in client but can be appended as their original type.
- *data << uint8(arenatype);
- TC_LOG_DEBUG("network", "BattlegroundMgr::BuildBattlegroundStatusPacket: arenatype = %u for bg instanceID %u, TypeID %u.", arenatype, bg->GetClientInstanceID(), bg->GetTypeID());
- *data << uint8(bg->isArena() ? 0xE : 0x0);
- *data << uint32(bg->GetTypeID());
- *data << uint16(0x1F90);
- // End of uint64 segment, decomposed this way for simplicity
- *data << uint8(bg->GetMinLevel());
- *data << uint8(bg->GetMaxLevel());
- *data << uint32(bg->GetClientInstanceID());
- // alliance/horde for BG and skirmish/rated for Arenas
- // following displays the minimap-icon 0 = faction icon 1 = arenaicon
- *data << uint8(bg->isRated()); // 1 for rated match, 0 for bg or non rated match
-
- *data << uint32(StatusID); // status
switch (StatusID)
{
- case STATUS_WAIT_QUEUE: // status_in_queue
- *data << uint32(Time1); // average wait time, milliseconds
- *data << uint32(Time2); // time in queue, updated every minute!, milliseconds
+ case STATUS_NONE:
+ {
+ data->Initialize(SMSG_BATTLEFIELD_STATUS);
+
+ data->WriteBit(playerGuid[0]);
+ data->WriteBit(playerGuid[4]);
+ data->WriteBit(playerGuid[7]);
+ data->WriteBit(playerGuid[1]);
+ data->WriteBit(playerGuid[6]);
+ data->WriteBit(playerGuid[3]);
+ data->WriteBit(playerGuid[5]);
+ data->WriteBit(playerGuid[2]);
+
+ data->WriteByteSeq(playerGuid[5]);
+ data->WriteByteSeq(playerGuid[6]);
+ data->WriteByteSeq(playerGuid[7]);
+ data->WriteByteSeq(playerGuid[2]);
+ *data << uint32(1); // unk, always 1
+ data->WriteByteSeq(playerGuid[3]);
+ data->WriteByteSeq(playerGuid[1]);
+ *data << uint32(QueueSlot); // Queue slot
+ *data << uint32(Time1); // Join Time
+ data->WriteByteSeq(playerGuid[0]);
+ data->WriteByteSeq(playerGuid[4]);
break;
- case STATUS_WAIT_JOIN: // status_invite
- *data << uint32(bg->GetMapId()); // map id
- *data << uint64(0); // 3.3.5, unknown
- *data << uint32(Time1); // time to remove from queue, milliseconds
+ }
+ case STATUS_WAIT_QUEUE:
+ {
+ data->Initialize(SMSG_BATTLEFIELD_STATUS_QUEUED);
+
+ data->WriteBit(playerGuid[3]);
+ data->WriteBit(playerGuid[0]);
+ data->WriteBit(bgGuid[3]);
+ data->WriteBit(playerGuid[2]);
+ data->WriteBit(1); // Eligible In Queue
+ data->WriteBit(0); // Join Failed, 1 when it's arena ...
+ data->WriteBit(bgGuid[2]);
+ data->WriteBit(playerGuid[1]);
+ data->WriteBit(bgGuid[0]);
+ data->WriteBit(bgGuid[6]);
+ data->WriteBit(bgGuid[4]);
+ data->WriteBit(playerGuid[6]);
+ data->WriteBit(playerGuid[7]);
+ data->WriteBit(bgGuid[7]);
+ data->WriteBit(bgGuid[5]);
+ data->WriteBit(playerGuid[4]);
+ data->WriteBit(playerGuid[5]);
+ data->WriteBit(bg->isRated()); // Is Rated
+ data->WriteBit(0); // Waiting On Other Activity
+ data->WriteBit(bgGuid[1]);
+
+ data->FlushBits();
+
+ data->WriteByteSeq(playerGuid[0]);
+ *data << uint32(bg->isArena() ? arenatype : 1); // Player count, 1 for bgs, 2-3-5 for arena (2v2, 3v3, 5v5)
+ data->WriteByteSeq(bgGuid[5]);
+ data->WriteByteSeq(playerGuid[3]);
+ *data << uint32(Time1); // Estimated Wait Time
+ data->WriteByteSeq(bgGuid[7]);
+ data->WriteByteSeq(bgGuid[1]);
+ data->WriteByteSeq(bgGuid[2]);
+ *data << uint8(0); // unk
+ data->WriteByteSeq(bgGuid[4]);
+ data->WriteByteSeq(playerGuid[2]);
+ *data << uint8(0); // unk
+ data->WriteByteSeq(bgGuid[6]);
+ data->WriteByteSeq(playerGuid[7]);
+ data->WriteByteSeq(bgGuid[3]);
+ data->WriteByteSeq(playerGuid[6]);
+ data->WriteByteSeq(bgGuid[0]);
+ *data << uint32(Time2); // Join Time
+ *data << uint32(QueueSlot); // Queue slot
+ *data << uint8(bg->GetMinLevel()); // Min Level
+ *data << uint32(GetMSTimeDiffToNow(Time2)); // Time since joined
+ data->WriteByteSeq(playerGuid[1]);
+ data->WriteByteSeq(playerGuid[5]);
+ *data << uint32(bg->GetClientInstanceID()); // Client Instance ID
+ data->WriteByteSeq(playerGuid[4]);
break;
- case STATUS_IN_PROGRESS: // status_in_progress
- *data << uint32(bg->GetMapId()); // map id
- *data << uint64(0); // 3.3.5, unknown
- *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds
- *data << uint32(Time2); // time from bg start, milliseconds
- *data << uint8(arenaFaction == ALLIANCE ? 1 : 0); // arenafaction (0 for horde, 1 for alliance)
+ }
+ case STATUS_WAIT_JOIN:
+ {
+ data->Initialize(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION);
+
+ *data << uint32(bg->GetClientInstanceID()); // Client Instance ID
+ *data << uint32(Time1); // Time until closed
+ *data << uint8(0); // unk
+ *data << uint32(QueueSlot); // Queue slot
+ *data << uint32(Time2); // Join Time
+ *data << uint8(bg->GetMinLevel()); // Min Level
+ *data << uint32(bg->isArena() ? arenatype : 1); // Player count, 1 for bgs, 2-3-5 for arena (2v2, 3v3, 5v5)
+ *data << uint32(bg->GetMapId()); // Map Id
+ *data << uint8(0); // unk
+
+ data->WriteBit(playerGuid[5]);
+ data->WriteBit(playerGuid[2]);
+ data->WriteBit(playerGuid[1]);
+ data->WriteBit(bgGuid[2]);
+ data->WriteBit(playerGuid[4]);
+ data->WriteBit(bgGuid[6]);
+ data->WriteBit(bgGuid[3]);
+ data->WriteBit(bg->isRated()); // Is Rated
+ data->WriteBit(playerGuid[7]);
+ data->WriteBit(playerGuid[3]);
+ data->WriteBit(bgGuid[7]);
+ data->WriteBit(bgGuid[0]);
+ data->WriteBit(bgGuid[4]);
+ data->WriteBit(playerGuid[6]);
+ data->WriteBit(bgGuid[1]);
+ data->WriteBit(bgGuid[5]);
+ data->WriteBit(playerGuid[0]);
+
+ data->WriteByteSeq(bgGuid[6]);
+ data->WriteByteSeq(bgGuid[5]);
+ data->WriteByteSeq(bgGuid[7]);
+ data->WriteByteSeq(bgGuid[2]);
+ data->WriteByteSeq(playerGuid[0]);
+ data->WriteByteSeq(playerGuid[7]);
+ data->WriteByteSeq(bgGuid[4]);
+ data->WriteByteSeq(playerGuid[1]);
+ data->WriteByteSeq(bgGuid[0]);
+ data->WriteByteSeq(playerGuid[4]);
+ data->WriteByteSeq(bgGuid[1]);
+ data->WriteByteSeq(playerGuid[5]);
+ data->WriteByteSeq(bgGuid[3]);
+ data->WriteByteSeq(playerGuid[6]);
+ data->WriteByteSeq(playerGuid[2]);
+ data->WriteByteSeq(playerGuid[3]);
break;
- default:
- TC_LOG_ERROR("bg.battleground", "Unknown BG status!");
+ }
+ case STATUS_IN_PROGRESS:
+ {
+ data->Initialize(SMSG_BATTLEFIELD_STATUS_ACTIVE);
+
+ data->WriteBit(playerGuid[2]);
+ data->WriteBit(playerGuid[7]);
+ data->WriteBit(bgGuid[7]);
+ data->WriteBit(bgGuid[1]);
+ data->WriteBit(playerGuid[5]);
+ data->WriteBit(player->GetBGTeam() == HORDE ? 0 : 1);
+ data->WriteBit(bgGuid[0]);
+ data->WriteBit(playerGuid[1]);
+ data->WriteBit(bgGuid[3]);
+ data->WriteBit(playerGuid[6]);
+ data->WriteBit(bgGuid[5]);
+ data->WriteBit(bg->isRated()); // Is Rated
+ data->WriteBit(playerGuid[4]);
+ data->WriteBit(bgGuid[6]);
+ data->WriteBit(bgGuid[4]);
+ data->WriteBit(bgGuid[2]);
+ data->WriteBit(playerGuid[3]);
+ data->WriteBit(playerGuid[0]);
+
+ data->FlushBits();
+
+ data->WriteByteSeq(bgGuid[4]);
+ data->WriteByteSeq(bgGuid[5]);
+ data->WriteByteSeq(playerGuid[5]);
+ data->WriteByteSeq(bgGuid[1]);
+ data->WriteByteSeq(bgGuid[6]);
+ data->WriteByteSeq(bgGuid[3]);
+ data->WriteByteSeq(bgGuid[7]);
+ data->WriteByteSeq(playerGuid[6]);
+
+ *data << uint32(Time1); // Join Time
+ *data << uint8(0); // unk
+
+ data->WriteByteSeq(playerGuid[4]);
+ data->WriteByteSeq(playerGuid[1]);
+
+ *data << uint32(QueueSlot); // Queue slot
+ *data << uint8(0); // unk
+ *data << uint32(bg->isArena() ? arenatype : 1); // Player count, 1 for bgs, 2-3-5 for arena (2v2, 3v3, 5v5)
+ *data << uint32(bg->GetMapId()); // Map Id
+ *data << uint8(bg->GetMinLevel()); // Min Level
+ *data << uint32(Time2); // Elapsed Time
+
+ data->WriteByteSeq(playerGuid[2]);
+ *data << uint32(bg->GetRemainingTime()); // Remaining Time
+
+ data->WriteByteSeq(playerGuid[0]);
+ data->WriteByteSeq(playerGuid[3]);
+ data->WriteByteSeq(bgGuid[2]);
+
+ *data << uint32(bg->GetClientInstanceID()); // Client Instance ID or faction ?
+
+ data->WriteByteSeq(bgGuid[0]);
+ data->WriteByteSeq(playerGuid[7]);
+ break;
+ }
+ case STATUS_WAIT_LEAVE:
break;
}
}
void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg)
{
- uint8 type = (bg->isArena() ? 1 : 0);
+ ByteBuffer buff;
+ uint8 isRated = (bg->isRated() ? 1 : 0); // type (normal=0/rated=1) -- ATM arena or bg, RBG NYI
+ uint8 isArena = (bg->isArena() ? 1 : 0); // Arena names
- data->Initialize(MSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
- *data << uint8(type); // type (battleground=0/arena=1)
+ data->Initialize(SMSG_PVP_LOG_DATA, (1+1+4+40*bg->GetPlayerScoresSize()));
+ data->WriteBit(isArena);
+ data->WriteBit(isRated);
- if (type) // arena
+ if (isArena)
{
- // it seems this must be according to BG_WINNER_A/H and _NOT_ TEAM_A/H
- for (int8 i = 1; i >= 0; --i)
- {
- int32 rating_change = bg->GetArenaTeamRatingChangeByIndex(i);
-
- uint32 pointsLost = rating_change < 0 ? -rating_change : 0;
- uint32 pointsGained = rating_change > 0 ? rating_change : 0;
- uint32 MatchmakerRating = bg->GetArenaMatchmakerRatingByIndex(i);
-
- *data << uint32(pointsLost); // Rating Lost
- *data << uint32(pointsGained); // Rating gained
- *data << uint32(MatchmakerRating); // Matchmaking Value
- TC_LOG_DEBUG("bg.battleground", "rating change: %d", rating_change);
- }
- for (int8 i = 1; i >= 0; --i)
+ for (int8 i = 0; i < BG_TEAMS_COUNT; ++i)
{
if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdByIndex(i)))
- *data << at->GetName();
+ data->WriteBits(at->GetName().length(), 8);
else
- *data << uint8(0);
+ data->WriteBits(0, 8);
}
}
- if (bg->GetStatus() != STATUS_WAIT_LEAVE)
- *data << uint8(0); // bg not ended
- else
- {
- *data << uint8(1); // bg ended
- *data << uint8(bg->GetWinner()); // who win
- }
-
- size_t wpos = data->wpos();
- uint32 scoreCount = 0;
- *data << uint32(scoreCount); // placeholder
+ size_t count_pos = data->bitwpos();
+ data->WriteBits(0, 21);
+ uint32 count = 0;
+ Battleground::BattlegroundPlayerMap const& bgPlayers = bg->GetPlayers();
- Battleground::BattlegroundScoreMap::const_iterator itr2 = bg->GetPlayerScoresBegin();
- for (Battleground::BattlegroundScoreMap::const_iterator itr = itr2; itr != bg->GetPlayerScoresEnd();)
+ for (Battleground::BattlegroundScoreMap::const_iterator itr = bg->GetPlayerScoresBegin(); itr != bg->GetPlayerScoresEnd(); ++itr)
{
- itr2 = itr++;
- BattlegroundScore* score = itr2->second;
- if (!bg->IsPlayerInBattleground(itr2->first))
+ if (!bg->IsPlayerInBattleground(itr->first))
{
TC_LOG_ERROR("bg.battleground", "Player " UI64FMTD " has scoreboard entry for battleground %u but is not in battleground!", itr->first, bg->GetTypeID(true));
continue;
}
- *data << uint64(itr2->first);
- *data << uint32(score->KillingBlows);
- if (type == 0)
+ uint32 team;
+ int32 primaryTree;
+ if (Player* player = ObjectAccessor::FindPlayer(itr->first))
{
- *data << uint32(score->HonorableKills);
- *data << uint32(score->Deaths);
- *data << uint32(score->BonusHonor);
+ team = player->GetBGTeam();
+ primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());
}
else
{
- Player* player = ObjectAccessor::FindPlayer(itr2->first);
- uint32 team = bg->GetPlayerTeam(itr2->first);
- if (!team && player)
- team = player->GetBGTeam();
- *data << uint8(team == ALLIANCE ? 1 : 0); // green or yellow
+ Battleground::BattlegroundPlayerMap::const_iterator itr2 = bgPlayers.find(itr->first);
+ if (itr2 == bgPlayers.end())
+ {
+ TC_LOG_ERROR("bg.battleground", "Player " UI64FMTD " has scoreboard entry for battleground %u but do not have battleground data!", itr->first, bg->GetTypeID(true));
+ continue;
+ }
+
+ team = itr2->second.Team;
+ primaryTree = itr2->second.PrimaryTree;
}
- *data << uint32(score->DamageDone); // damage done
- *data << uint32(score->HealingDone); // healing done
- switch (bg->GetTypeID(true)) // battleground specific things
+
+ ObjectGuid playerGUID = itr->first;
+ BattlegroundScore* score = itr->second;
+
+ data->WriteBit(0); // Unk 1
+ data->WriteBit(0); // Unk 2
+ data->WriteBit(playerGUID[2]);
+ data->WriteBit(!isArena);
+ data->WriteBit(0); // Unk 4
+ data->WriteBit(0); // Unk 5
+ data->WriteBit(0); // Unk 6
+ data->WriteBit(playerGUID[3]);
+ data->WriteBit(playerGUID[0]);
+ data->WriteBit(playerGUID[5]);
+ data->WriteBit(playerGUID[1]);
+ data->WriteBit(playerGUID[6]);
+ data->WriteBit(team == HORDE ? 0 : 1);
+ data->WriteBit(playerGUID[7]);
+
+ buff << uint32(score->HealingDone); // healing done
+ buff << uint32(score->DamageDone); // damage done
+
+ if (!isArena)
+ {
+ buff << uint32(score->BonusHonor / 100);
+ buff << uint32(score->Deaths);
+ buff << uint32(score->HonorableKills);
+ }
+
+ buff.WriteByteSeq(playerGUID[4]);
+ buff << uint32(score->KillingBlows);
+ // if (unk 5) << uint32() unk
+ buff.WriteByteSeq(playerGUID[5]);
+ // if (unk 6) << uint32() unk
+ // if (unk 2) << uint32() unk
+ buff.WriteByteSeq(playerGUID[1]);
+ buff.WriteByteSeq(playerGUID[6]);
+
+ buff << int32(primaryTree);
+
+ switch (bg->GetTypeID(true)) // Custom values
{
case BATTLEGROUND_RB:
switch (bg->GetMapId())
{
case 489:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundWGScore*)score)->FlagCaptures); // flag captures
- *data << uint32(((BattlegroundWGScore*)score)->FlagReturns); // flag returns
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundWGScore*)score)->FlagCaptures); // flag captures
+ buff << uint32(((BattlegroundWGScore*)score)->FlagReturns); // flag returns
break;
case 566:
- *data << uint32(0x00000001); // count of next fields
- *data << uint32(((BattlegroundEYScore*)score)->FlagCaptures); // flag captures
+ data->WriteBits(0x00000001, 24);
+ buff << uint32(((BattlegroundEYScore*)score)->FlagCaptures); // flag captures
break;
case 529:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundABScore*)score)->BasesAssaulted); // bases asssulted
- *data << uint32(((BattlegroundABScore*)score)->BasesDefended); // bases defended
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundABScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundABScore*)score)->BasesDefended); // bases defended
break;
case 30:
- *data << uint32(0x00000005); // count of next fields
- *data << uint32(((BattlegroundAVScore*)score)->GraveyardsAssaulted); // GraveyardsAssaulted
- *data << uint32(((BattlegroundAVScore*)score)->GraveyardsDefended); // GraveyardsDefended
- *data << uint32(((BattlegroundAVScore*)score)->TowersAssaulted); // TowersAssaulted
- *data << uint32(((BattlegroundAVScore*)score)->TowersDefended); // TowersDefended
- *data << uint32(((BattlegroundAVScore*)score)->MinesCaptured); // MinesCaptured
+ data->WriteBits(0x00000005, 24);
+ buff << uint32(((BattlegroundAVScore*)score)->GraveyardsAssaulted); // GraveyardsAssaulted
+ buff << uint32(((BattlegroundAVScore*)score)->GraveyardsDefended); // GraveyardsDefended
+ buff << uint32(((BattlegroundAVScore*)score)->TowersAssaulted); // TowersAssaulted
+ buff << uint32(((BattlegroundAVScore*)score)->TowersDefended); // TowersDefended
+ buff << uint32(((BattlegroundAVScore*)score)->MinesCaptured); // MinesCaptured
break;
case 607:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundSAScore*)score)->demolishers_destroyed);
- *data << uint32(((BattlegroundSAScore*)score)->gates_destroyed);
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundSAScore*)score)->demolishers_destroyed);
+ buff << uint32(((BattlegroundSAScore*)score)->gates_destroyed);
break;
case 628: // IC
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundICScore*)score)->BasesAssaulted); // bases asssulted
- *data << uint32(((BattlegroundICScore*)score)->BasesDefended); // bases defended
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundICScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundICScore*)score)->BasesDefended); // bases defended
+ break;
+ case 726:
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundTPScore*)score)->FlagCaptures); // flag captures
+ buff << uint32(((BattlegroundTPScore*)score)->FlagReturns); // flag returns
+ break;
+ case 761:
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundBFGScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundBFGScore*)score)->BasesDefended); // bases defended
+ break;
default:
- *data << uint32(0);
+ data->WriteBits(0, 24);
break;
}
break;
case BATTLEGROUND_AV:
- *data << uint32(0x00000005); // count of next fields
- *data << uint32(((BattlegroundAVScore*)score)->GraveyardsAssaulted); // GraveyardsAssaulted
- *data << uint32(((BattlegroundAVScore*)score)->GraveyardsDefended); // GraveyardsDefended
- *data << uint32(((BattlegroundAVScore*)score)->TowersAssaulted); // TowersAssaulted
- *data << uint32(((BattlegroundAVScore*)score)->TowersDefended); // TowersDefended
- *data << uint32(((BattlegroundAVScore*)score)->MinesCaptured); // MinesCaptured
+ data->WriteBits(0x00000005, 24);
+ buff << uint32(((BattlegroundAVScore*)score)->GraveyardsAssaulted); // GraveyardsAssaulted
+ buff << uint32(((BattlegroundAVScore*)score)->GraveyardsDefended); // GraveyardsDefended
+ buff << uint32(((BattlegroundAVScore*)score)->TowersAssaulted); // TowersAssaulted
+ buff << uint32(((BattlegroundAVScore*)score)->TowersDefended); // TowersDefended
+ buff << uint32(((BattlegroundAVScore*)score)->MinesCaptured); // MinesCaptured
break;
case BATTLEGROUND_WS:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundWGScore*)score)->FlagCaptures); // flag captures
- *data << uint32(((BattlegroundWGScore*)score)->FlagReturns); // flag returns
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundWGScore*)score)->FlagCaptures); // flag captures
+ buff << uint32(((BattlegroundWGScore*)score)->FlagReturns); // flag returns
break;
case BATTLEGROUND_AB:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundABScore*)score)->BasesAssaulted); // bases assaulted
- *data << uint32(((BattlegroundABScore*)score)->BasesDefended); // bases defended
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundABScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundABScore*)score)->BasesDefended); // bases defended
break;
case BATTLEGROUND_EY:
- *data << uint32(0x00000001); // count of next fields
- *data << uint32(((BattlegroundEYScore*)score)->FlagCaptures); // flag captures
+ data->WriteBits(0x00000001, 24);
+ buff << uint32(((BattlegroundEYScore*)score)->FlagCaptures); // flag captures
break;
case BATTLEGROUND_SA:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundSAScore*)score)->demolishers_destroyed);
- *data << uint32(((BattlegroundSAScore*)score)->gates_destroyed);
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundSAScore*)score)->demolishers_destroyed);
+ buff << uint32(((BattlegroundSAScore*)score)->gates_destroyed);
break;
case BATTLEGROUND_IC:
- *data << uint32(0x00000002); // count of next fields
- *data << uint32(((BattlegroundICScore*)score)->BasesAssaulted); // bases assaulted
- *data << uint32(((BattlegroundICScore*)score)->BasesDefended); // bases defended
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundICScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundICScore*)score)->BasesDefended); // bases defended
+ break;
+ case BATTLEGROUND_TP:
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundTPScore*)score)->FlagCaptures); // flag captures
+ buff << uint32(((BattlegroundTPScore*)score)->FlagReturns); // flag returns
+ break;
+ case BATTLEGROUND_BFG:
+ data->WriteBits(0x00000002, 24);
+ buff << uint32(((BattlegroundBFGScore*)score)->BasesAssaulted); // bases assaulted
+ buff << uint32(((BattlegroundBFGScore*)score)->BasesDefended); // bases defended
break;
case BATTLEGROUND_NA:
case BATTLEGROUND_BE:
@@ -368,30 +548,130 @@ void BattlegroundMgr::BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg)
case BATTLEGROUND_RL:
case BATTLEGROUND_DS:
case BATTLEGROUND_RV:
- *data << uint32(0);
+ data->WriteBits(0, 24);
break;
default:
- TC_LOG_DEBUG("network", "Unhandled MSG_PVP_LOG_DATA for BG id %u", bg->GetTypeID());
- *data << uint32(0);
+ data->WriteBits(0, 24);
break;
}
- // should never happen
- if (++scoreCount >= bg->GetMaxPlayers() && itr != bg->GetPlayerScoresEnd())
+
+ data->WriteBit(playerGUID[4]);
+
+ buff.WriteByteSeq(playerGUID[0]);
+ buff.WriteByteSeq(playerGUID[3]);
+ // if (unk 4) << uint32() unk
+ buff.WriteByteSeq(playerGUID[7]);
+ buff.WriteByteSeq(playerGUID[2]);
+ ++count;
+ }
+
+ data->PutBits(count_pos, count, 21);
+ data->WriteBit(bg->GetStatus() == STATUS_WAIT_LEAVE); // If Ended
+
+ if (isRated) // arena
+ {
+ // it seems this must be according to BG_WINNER_A/H and _NOT_ BG_TEAM_A/H
+ for (int8 i = 0; i < BG_TEAMS_COUNT; ++i)
{
- TC_LOG_ERROR("bg.battleground", "Battleground %u scoreboard has more entries (%u) than allowed players in this bg (%u)", bg->GetTypeID(true), bg->GetPlayerScoresSize(), bg->GetMaxPlayers());
- break;
+ int32 rating_change = bg->GetArenaTeamRatingChangeByIndex(i);
+
+ uint32 pointsLost = rating_change < 0 ? -rating_change : 0;
+ uint32 pointsGained = rating_change > 0 ? rating_change : 0;
+ uint32 MatchmakerRating = bg->GetArenaMatchmakerRatingByIndex(i);
+
+ *data << uint32(MatchmakerRating); // Matchmaking Value
+ *data << uint32(pointsLost); // Rating Lost
+ *data << uint32(pointsGained); // Rating gained
+
+ TC_LOG_DEBUG("bg.battleground", "rating change: %d", rating_change);
}
}
- data->put(wpos, scoreCount);
+ data->FlushBits();
+ data->append(buff);
+
+ if (isArena)
+ for (int8 i = 0; i < BG_TEAMS_COUNT; ++i)
+ if (ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(bg->GetArenaTeamIdByIndex(i)))
+ data->WriteString(at->GetName());
+
+ *data << uint8(bg->GetPlayersCountByTeam(HORDE));
+
+ if (bg->GetStatus() == STATUS_WAIT_LEAVE)
+ *data << uint8(bg->GetWinner());
+
+ *data << uint8(bg->GetPlayersCountByTeam(ALLIANCE));
}
-void BattlegroundMgr::BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result)
+void BattlegroundMgr::BuildStatusFailedPacket(WorldPacket* data, Battleground* bg, Player* player, uint8 QueueSlot, GroupJoinBattlegroundResult result)
{
- data->Initialize(SMSG_GROUP_JOINED_BATTLEGROUND, 4);
- *data << int32(result);
- if (result == ERR_BATTLEGROUND_JOIN_TIMED_OUT || result == ERR_BATTLEGROUND_JOIN_FAILED)
- *data << uint64(0); // player guid
+ ObjectGuid guidBytes1 = player->GetGUID(); // player who caused the error
+ ObjectGuid guidBytes2 = bg->GetGUID();
+ ObjectGuid unkGuid3 = 0;
+
+ data->Initialize(SMSG_BATTLEFIELD_STATUS_FAILED);
+
+ data->WriteBit(guidBytes2[3]);
+ data->WriteBit(unkGuid3[3]);
+ data->WriteBit(guidBytes1[3]);
+ data->WriteBit(unkGuid3[0]);
+ data->WriteBit(guidBytes2[6]);
+ data->WriteBit(guidBytes1[5]);
+ data->WriteBit(guidBytes1[6]);
+ data->WriteBit(guidBytes1[4]);
+
+ data->WriteBit(guidBytes1[2]);
+ data->WriteBit(unkGuid3[1]);
+ data->WriteBit(guidBytes2[1]);
+ data->WriteBit(unkGuid3[5]);
+ data->WriteBit(unkGuid3[6]);
+ data->WriteBit(guidBytes1[1]);
+ data->WriteBit(guidBytes2[7]);
+ data->WriteBit(unkGuid3[4]);
+
+ data->WriteBit(guidBytes2[2]);
+ data->WriteBit(guidBytes2[5]);
+ data->WriteBit(unkGuid3[7]);
+ data->WriteBit(guidBytes2[4]);
+ data->WriteBit(guidBytes2[0]);
+ data->WriteBit(guidBytes1[0]);
+ data->WriteBit(unkGuid3[2]);
+ data->WriteBit(guidBytes1[7]);
+
+ data->WriteByteSeq(guidBytes2[1]);
+
+ *data << uint32(1); // Unk, always 1
+ *data << uint32(QueueSlot); // Queue slot
+
+ data->WriteByteSeq(guidBytes1[6]);
+ data->WriteByteSeq(guidBytes1[3]);
+ data->WriteByteSeq(guidBytes1[7]);
+ data->WriteByteSeq(guidBytes1[4]);
+ data->WriteByteSeq(guidBytes2[0]);
+ data->WriteByteSeq(guidBytes1[5]);
+ data->WriteByteSeq(guidBytes2[7]);
+ data->WriteByteSeq(guidBytes2[6]);
+ data->WriteByteSeq(guidBytes2[2]);
+ data->WriteByteSeq(unkGuid3[6]);
+ data->WriteByteSeq(unkGuid3[3]);
+ data->WriteByteSeq(guidBytes1[1]);
+ data->WriteByteSeq(guidBytes2[3]);
+ data->WriteByteSeq(unkGuid3[0]);
+ data->WriteByteSeq(unkGuid3[1]);
+ data->WriteByteSeq(unkGuid3[4]);
+ data->WriteByteSeq(guidBytes1[0]);
+ data->WriteByteSeq(guidBytes2[5]);
+ data->WriteByteSeq(unkGuid3[7]);
+ data->WriteByteSeq(guidBytes2[4]);
+ data->WriteByteSeq(guidBytes1[2]);
+
+ *data << uint32(result); // Result
+
+ data->WriteByteSeq(unkGuid3[2]);
+
+ *data << uint32(player->GetBattlegroundQueueJoinTime(bg->GetTypeID())); // Join Time
+
+ data->WriteByteSeq(unkGuid3[5]);
}
void BattlegroundMgr::BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value)
@@ -405,18 +685,57 @@ void BattlegroundMgr::BuildPlaySoundPacket(WorldPacket* data, uint32 soundid)
{
data->Initialize(SMSG_PLAY_SOUND, 4);
*data << uint32(soundid);
+ *data << uint64(0);
}
void BattlegroundMgr::BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid)
{
+ ObjectGuid guidBytes = guid;
+
data->Initialize(SMSG_BATTLEGROUND_PLAYER_LEFT, 8);
- *data << uint64(guid);
+
+ data->WriteBit(guidBytes[7]);
+ data->WriteBit(guidBytes[6]);
+ data->WriteBit(guidBytes[2]);
+ data->WriteBit(guidBytes[4]);
+ data->WriteBit(guidBytes[5]);
+ data->WriteBit(guidBytes[1]);
+ data->WriteBit(guidBytes[3]);
+ data->WriteBit(guidBytes[0]);
+
+ data->WriteByteSeq(guidBytes[4]);
+ data->WriteByteSeq(guidBytes[2]);
+ data->WriteByteSeq(guidBytes[5]);
+ data->WriteByteSeq(guidBytes[7]);
+ data->WriteByteSeq(guidBytes[0]);
+ data->WriteByteSeq(guidBytes[6]);
+ data->WriteByteSeq(guidBytes[1]);
+ data->WriteByteSeq(guidBytes[3]);
}
-void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player)
+void BattlegroundMgr::BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, uint64 guid)
{
+ ObjectGuid guidBytes = guid;
+
data->Initialize(SMSG_BATTLEGROUND_PLAYER_JOINED, 8);
- *data << uint64(player->GetGUID());
+
+ data->WriteBit(guidBytes[0]);
+ data->WriteBit(guidBytes[4]);
+ data->WriteBit(guidBytes[3]);
+ data->WriteBit(guidBytes[5]);
+ data->WriteBit(guidBytes[7]);
+ data->WriteBit(guidBytes[6]);
+ data->WriteBit(guidBytes[2]);
+ data->WriteBit(guidBytes[1]);
+
+ data->WriteByteSeq(guidBytes[1]);
+ data->WriteByteSeq(guidBytes[5]);
+ data->WriteByteSeq(guidBytes[3]);
+ data->WriteByteSeq(guidBytes[2]);
+ data->WriteByteSeq(guidBytes[0]);
+ data->WriteByteSeq(guidBytes[7]);
+ data->WriteByteSeq(guidBytes[4]);
+ data->WriteByteSeq(guidBytes[6]);
}
Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 instanceId, BattlegroundTypeId bgTypeId)
@@ -481,7 +800,7 @@ Battleground* BattlegroundMgr::GetBattlegroundTemplate(BattlegroundTypeId bgType
return NULL;
BattlegroundContainer const& bgs = itr->second.m_Battlegrounds;
- //map is sorted and we can be sure that lowest instance id has only BG template
+ // map is sorted and we can be sure that lowest instance id has only BG template
return bgs.empty() ? NULL : bgs.begin()->second;
}
@@ -574,6 +893,12 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
case BATTLEGROUND_IC:
bg = new BattlegroundIC(*(BattlegroundIC*)bg_template);
break;
+ case BATTLEGROUND_TP:
+ bg = new BattlegroundTP(*(BattlegroundTP*)bg_template);
+ break;
+ case BATTLEGROUND_BFG:
+ bg = new BattlegroundBFG(*(BattlegroundBFG*)bg_template);
+ break;
case BATTLEGROUND_RB:
case BATTLEGROUND_AA:
bg = new Battleground(*bg_template);
@@ -592,6 +917,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original
bg->SetRandomTypeID(bgTypeId);
bg->SetRated(isRated);
bg->SetRandom(isRandom);
+ bg->SetGuid(MAKE_NEW_GUID(bgTypeId, 0, HIGHGUID_BATTLEGROUND));
// Set up correct min/max player counts for scoreboards
if (bg->isArena())
@@ -664,6 +990,12 @@ bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data)
bg = new Battleground;
bg->SetRandom(true);
break;
+ case BATTLEGROUND_TP:
+ bg = new BattlegroundTP;
+ break;
+ case BATTLEGROUND_BFG:
+ bg = new BattlegroundBFG;
+ break;
default:
return false;
}
@@ -682,6 +1014,7 @@ bool BattlegroundMgr::CreateBattleground(CreateBattlegroundData& data)
bg->SetStartMaxDist(data.StartMaxDist);
bg->SetLevelRange(data.LevelMin, data.LevelMax);
bg->SetScriptId(data.scriptId);
+ bg->SetGuid(MAKE_NEW_GUID(data.bgTypeId, 0, HIGHGUID_BATTLEGROUND));
AddBattleground(bg);
@@ -729,7 +1062,7 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
data.StartMaxDist = dist * dist;
data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
- data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()];
+ data.BattlegroundName = bl->name;
data.MapID = bl->mapid[0];
if (data.MaxPlayersPerTeam == 0 || data.MinPlayersPerTeam > data.MaxPlayersPerTeam)
@@ -806,86 +1139,75 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
TC_LOG_INFO("server.loading", ">> Loaded %u battlegrounds in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void BattlegroundMgr::InitAutomaticArenaPointDistribution()
+void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId)
{
- if (!sWorld->getBoolConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
+ if (!player)
return;
- time_t wstime = time_t(sWorld->getWorldState(WS_ARENA_DISTRIBUTION_TIME));
- time_t curtime = time(NULL);
- TC_LOG_DEBUG("bg.battleground", "Initializing Automatic Arena Point Distribution");
- if (wstime < curtime)
- {
- m_NextAutoDistributionTime = curtime; // reset will be called in the next update
- TC_LOG_DEBUG("bg.battleground", "Battleground: Next arena point distribution time in the past, reseting it now.");
- }
- else
- m_NextAutoDistributionTime = wstime;
- TC_LOG_DEBUG("bg.battleground", "Automatic Arena Point Distribution initialized.");
-}
+ BattlegroundDataContainer::iterator it = bgDataStore.find(bgTypeId);
+ if (it == bgDataStore.end())
+ return;
-void BattlegroundMgr::BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere)
-{
- if (!player)
+ PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(it->second.m_Battlegrounds.begin()->second->GetMapId(), player->getLevel());
+ if (!bracketEntry)
return;
- uint32 winner_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST);
- uint32 winner_arena = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_ARENA_FIRST);
- uint32 loser_kills = player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST);
+ uint32 winnerConquest = (player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_CONQUEST_FIRST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_CONQUEST_LAST)) / CURRENCY_PRECISION;
+ uint32 winnerHonor = (player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_FIRST) : sWorld->getIntConfig(CONFIG_BG_REWARD_WINNER_HONOR_LAST)) / CURRENCY_PRECISION;
+ uint32 loserHonor = (!player->GetRandomWinner() ? sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_FIRST) : sWorld->getIntConfig(CONFIG_BG_REWARD_LOSER_HONOR_LAST)) / CURRENCY_PRECISION;
- winner_kills = Trinity::Honor::hk_honor_at_level(player->getLevel(), float(winner_kills));
- loser_kills = Trinity::Honor::hk_honor_at_level(player->getLevel(), float(loser_kills));
+ ObjectGuid guidBytes = guid;
data->Initialize(SMSG_BATTLEFIELD_LIST);
- *data << uint64(guid); // battlemaster guid
- *data << uint8(fromWhere); // from where you joined
- *data << uint32(bgTypeId); // battleground id
- *data << uint8(0); // unk
- *data << uint8(0); // unk
-
- // Rewards
- *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin
- *data << uint32(winner_kills); // 3.3.3 winHonor
- *data << uint32(winner_arena); // 3.3.3 winArena
- *data << uint32(loser_kills); // 3.3.3 lossHonor
-
- uint8 isRandom = bgTypeId == BATTLEGROUND_RB;
-
- *data << uint8(isRandom); // 3.3.3 isRandom
- if (isRandom)
- {
- // Rewards (random)
- *data << uint8(player->GetRandomWinner()); // 3.3.3 hasWin_Random
- *data << uint32(winner_kills); // 3.3.3 winHonor_Random
- *data << uint32(winner_arena); // 3.3.3 winArena_Random
- *data << uint32(loser_kills); // 3.3.3 lossHonor_Random
- }
+ *data << uint32(winnerConquest) // Winner Conquest Reward or Random Winner Conquest Reward
+ << uint32(winnerConquest) // Winner Conquest Reward or Random Winner Conquest Reward
+ << uint32(loserHonor) // Loser Honor Reward or Random Loser Honor Reward
+ << uint32(bgTypeId) // battleground id
+ << uint32(loserHonor) // Loser Honor Reward or Random Loser Honor Reward
+ << uint32(winnerHonor) // Winner Honor Reward or Random Winner Honor Reward
+ << uint32(winnerHonor) // Winner Honor Reward or Random Winner Honor Reward
+ << uint8(bracketEntry->maxLevel) // max level
+ << uint8(bracketEntry->minLevel); // min level
+
+ data->WriteBit(guidBytes[0]);
+ data->WriteBit(guidBytes[1]);
+ data->WriteBit(guidBytes[7]);
+ data->WriteBit(0); // unk
+ data->WriteBit(0); // unk
+
+ data->FlushBits();
+ size_t count_pos = data->bitwpos();
+ data->WriteBits(0, 24); // placeholder
+
+ data->WriteBit(guidBytes[6]);
+ data->WriteBit(guidBytes[4]);
+ data->WriteBit(guidBytes[2]);
+ data->WriteBit(guidBytes[3]);
+ data->WriteBit(0); // unk
+ data->WriteBit(guidBytes[5]);
+ data->WriteBit(0); // unk
+
+ data->FlushBits();
+
+ data->WriteByteSeq(guidBytes[6]);
+ data->WriteByteSeq(guidBytes[1]);
+ data->WriteByteSeq(guidBytes[7]);
+ data->WriteByteSeq(guidBytes[5]);
- if (bgTypeId == BATTLEGROUND_AA) // arena
- *data << uint32(0); // unk (count?)
- else // battleground
+ uint32 count = 0;
+ BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
+ BattlegroundClientIdsContainer& clientIds = it->second.m_ClientBattlegroundIds[bracketId];
+ for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end(); ++itr)
{
- size_t count_pos = data->wpos();
- *data << uint32(0); // number of bg instances
-
- BattlegroundDataContainer::iterator it = bgDataStore.find(bgTypeId);
- if (it != bgDataStore.end())
- {
- // expected bracket entry
- if (PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(it->second.m_Battlegrounds.begin()->second->GetMapId(), player->getLevel()))
- {
- uint32 count = 0;
- BattlegroundBracketId bracketId = bracketEntry->GetBracketId();
- BattlegroundClientIdsContainer& clientIds = it->second.m_ClientBattlegroundIds[bracketId];
- for (BattlegroundClientIdsContainer::const_iterator itr = clientIds.begin(); itr != clientIds.end(); ++itr)
- {
- *data << uint32(*itr);
- ++count;
- }
- data->put<uint32>(count_pos, count);
- }
- }
+ *data << uint32(*itr);
+ ++count;
}
+ data->PutBits(count_pos, count, 24); // bg instance count
+
+ data->WriteByteSeq(guidBytes[0]);
+ data->WriteByteSeq(guidBytes[2]);
+ data->WriteByteSeq(guidBytes[4]);
+ data->WriteByteSeq(guidBytes[3]);
}
void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, BattlegroundTypeId bgTypeId)
@@ -895,8 +1217,6 @@ void BattlegroundMgr::SendToBattleground(Player* player, uint32 instanceId, Batt
float x, y, z, O;
uint32 mapid = bg->GetMapId();
uint32 team = player->GetBGTeam();
- if (team == 0)
- team = player->GetTeam();
bg->GetTeamStartLoc(team, x, y, z, O);
TC_LOG_DEBUG("bg.battleground", "BattlegroundMgr::SendToBattleground: Sending %s to map %u, X %f, Y %f, Z %f, O %f (bgType %u)", player->GetName().c_str(), mapid, x, y, z, O, bgTypeId);
@@ -938,6 +1258,10 @@ BattlegroundQueueTypeId BattlegroundMgr::BGQueueTypeId(BattlegroundTypeId bgType
return BATTLEGROUND_QUEUE_EY;
case BATTLEGROUND_IC:
return BATTLEGROUND_QUEUE_IC;
+ case BATTLEGROUND_TP:
+ return BATTLEGROUND_QUEUE_TP;
+ case BATTLEGROUND_BFG:
+ return BATTLEGROUND_QUEUE_BFG;
case BATTLEGROUND_RB:
return BATTLEGROUND_QUEUE_RB;
case BATTLEGROUND_SA:
@@ -982,6 +1306,10 @@ BattlegroundTypeId BattlegroundMgr::BGTemplateId(BattlegroundQueueTypeId bgQueue
return BATTLEGROUND_SA;
case BATTLEGROUND_QUEUE_IC:
return BATTLEGROUND_IC;
+ case BATTLEGROUND_QUEUE_TP:
+ return BATTLEGROUND_TP;
+ case BATTLEGROUND_QUEUE_BFG:
+ return BATTLEGROUND_BFG;
case BATTLEGROUND_QUEUE_RB:
return BATTLEGROUND_RB;
case BATTLEGROUND_QUEUE_2v2:
@@ -1106,6 +1434,8 @@ HolidayIds BattlegroundMgr::BGTypeToWeekendHolidayId(BattlegroundTypeId bgTypeId
case BATTLEGROUND_SA: return HOLIDAY_CALL_TO_ARMS_SA;
case BATTLEGROUND_AB: return HOLIDAY_CALL_TO_ARMS_AB;
case BATTLEGROUND_IC: return HOLIDAY_CALL_TO_ARMS_IC;
+ case BATTLEGROUND_TP: return HOLIDAY_CALL_TO_ARMS_TP;
+ case BATTLEGROUND_BFG: return HOLIDAY_CALL_TO_ARMS_BFG;
default: return HOLIDAY_NONE;
}
}
@@ -1120,6 +1450,8 @@ BattlegroundTypeId BattlegroundMgr::WeekendHolidayIdToBGType(HolidayIds holiday)
case HOLIDAY_CALL_TO_ARMS_SA: return BATTLEGROUND_SA;
case HOLIDAY_CALL_TO_ARMS_AB: return BATTLEGROUND_AB;
case HOLIDAY_CALL_TO_ARMS_IC: return BATTLEGROUND_IC;
+ case HOLIDAY_CALL_TO_ARMS_TP: return BATTLEGROUND_TP;
+ case HOLIDAY_CALL_TO_ARMS_BFG: return BATTLEGROUND_BFG;
default: return BATTLEGROUND_TYPE_NONE;
}
}
@@ -1209,4 +1541,3 @@ void BattlegroundMgr::RemoveBattleground(BattlegroundTypeId bgTypeId, uint32 ins
{
bgDataStore[bgTypeId].m_Battlegrounds.erase(instanceId);
}
-
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index f10614baafc..2c94636f3e8 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -30,8 +30,7 @@ typedef std::set<uint32> BattlegroundClientIdsContainer;
typedef UNORDERED_MAP<uint32, BattlegroundTypeId> BattleMastersMap;
-#define BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY 86400 // seconds in a day
-#define WS_ARENA_DISTRIBUTION_TIME 20001 // Custom worldstate
+#define WS_CURRENCY_RESET_TIME 20001 // Custom worldstate
struct CreateBattlegroundData
{
@@ -74,13 +73,13 @@ class BattlegroundMgr
void Update(uint32 diff);
/* Packet Building */
- void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, Player* player);
+ void BuildPlayerJoinedBattlegroundPacket(WorldPacket* data, uint64 guid);
void BuildPlayerLeftBattlegroundPacket(WorldPacket* data, uint64 guid);
- void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId, uint8 fromWhere);
- void BuildGroupJoinedBattlegroundPacket(WorldPacket* data, GroupJoinBattlegroundResult result);
+ void BuildBattlegroundListPacket(WorldPacket* data, uint64 guid, Player* player, BattlegroundTypeId bgTypeId);
+ void BuildStatusFailedPacket(WorldPacket* data, Battleground* bg, Player* pPlayer, uint8 QueueSlot, GroupJoinBattlegroundResult result);
void BuildUpdateWorldStatePacket(WorldPacket* data, uint32 field, uint32 value);
void BuildPvpLogDataPacket(WorldPacket* data, Battleground* bg);
- void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType, uint32 arenaFaction);
+ void BuildBattlegroundStatusPacket(WorldPacket* data, Battleground* bg, Player* player, uint8 queueSlot, uint8 statusId, uint32 time1, uint32 time2, uint8 arenaType);
void BuildPlaySoundPacket(WorldPacket* data, uint32 soundId);
void SendAreaSpiritHealerQueryOpcode(Player* player, Battleground* bg, uint64 guid);
@@ -124,7 +123,6 @@ class BattlegroundMgr
uint32 GetMaxRatingDifference() const;
uint32 GetRatingDiscardTimer() const;
- void InitAutomaticArenaPointDistribution();
void LoadBattleMastersEntry();
BattlegroundTypeId GetBattleMasterBG(uint32 entry) const
{
@@ -150,8 +148,6 @@ class BattlegroundMgr
BattlegroundSelectionWeightMap m_BGSelectionWeights;
std::vector<uint64> m_QueueUpdateScheduler;
uint32 m_NextRatedArenaUpdate;
- time_t m_NextAutoDistributionTime;
- uint32 m_AutoDistributionTimeChecker;
bool m_ArenaTesting;
bool m_Testing;
BattleMastersMap mBattleMastersMap;
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 547d6e972c5..313a92ff68d 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -392,10 +392,11 @@ void BattlegroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(group->BgTypeId);
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(group->BgTypeId, group->ArenaType);
uint32 queueSlot = plr2->GetBattlegroundQueueIndex(bgQueueTypeId);
+
plr2->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to
// queue->removeplayer, it causes bugs
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, plr2, queueSlot, STATUS_NONE, plr2->GetBattlegroundQueueJoinTime(group->BgTypeId), 0, 0);
plr2->GetSession()->SendPacket(&data);
}
// then actually delete, this may delete the group as well!
@@ -480,7 +481,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg,
player->GetName().c_str(), player->GetGUIDLow(), bg->GetInstanceID(), queueSlot, bg->GetTypeID());
// send status packet
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, player->GetBattlegroundQueueJoinTime(bgTypeId), ginfo->ArenaType);
player->GetSession()->SendPacket(&data);
}
return true;
@@ -630,7 +631,7 @@ bool BattlegroundQueue::CheckPremadeMatch(BattlegroundBracketId bracket_id, uint
}
// this method tries to create battleground or arena with MinPlayersPerTeam against MinPlayersPerTeam
-bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
+bool BattlegroundQueue::CheckNormalMatch(Battleground* /*bg_template*/, BattlegroundBracketId bracket_id, uint32 minPlayers, uint32 maxPlayers)
{
GroupsQueueType::const_iterator itr_team[BG_TEAMS_COUNT];
for (uint32 i = 0; i < BG_TEAMS_COUNT; i++)
@@ -666,7 +667,7 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* bg_template, Battleground
return false;
}
//allow 1v0 if debug bg
- if (sBattlegroundMgr->isTesting() && bg_template->isBattleground() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount()))
+ if (sBattlegroundMgr->isTesting() && (m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() || m_SelectionPools[TEAM_HORDE].GetPlayerCount()))
return true;
//return true if there are enough players in selection pools - enable to work .debug bg command correctly
return m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers;
@@ -1002,7 +1003,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
{
WorldPacket data;
//we must send remaining time in queue
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, player->GetBattlegroundQueueJoinTime(m_BgTypeId), m_ArenaType);
player->GetSession()->SendPacket(&data);
}
}
@@ -1050,7 +1051,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
sBattlegroundMgr->ScheduleQueueUpdate(0, 0, m_BgQueueTypeId, m_BgTypeId, bg->GetBracketId());
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, player, queueSlot, STATUS_NONE, player->GetBattlegroundQueueJoinTime(m_BgTypeId), 0, 0);
player->GetSession()->SendPacket(&data);
}
}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp
new file mode 100644
index 00000000000..b7e97b406e3
--- /dev/null
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 "Battleground.h"
+#include "BattlegroundBFG.h"
+#include "Creature.h"
+#include "GameObject.h"
+#include "Language.h"
+#include "Object.h"
+#include "ObjectMgr.h"
+#include "BattlegroundMgr.h"
+#include "Player.h"
+#include "World.h"
+#include "WorldPacket.h"
+
+BattlegroundBFG::BattlegroundBFG()
+{
+}
+
+BattlegroundBFG::~BattlegroundBFG()
+{
+}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h
new file mode 100644
index 00000000000..1d514eced23
--- /dev/null
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundBFG.h
@@ -0,0 +1,40 @@
+/*
+ * 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 __BATTLEGROUNDBFG_H
+#define __BATTLEGROUNDBFG_H
+
+#include "Battleground.h"
+
+class BattlegroundBFGScore : public BattlegroundScore
+{
+ public:
+ BattlegroundBFGScore(): BasesAssaulted(0), BasesDefended(0) {};
+ virtual ~BattlegroundBFGScore() {};
+
+ uint32 BasesAssaulted;
+ uint32 BasesDefended;
+};
+
+class BattlegroundBFG : public Battleground
+{
+ public:
+ BattlegroundBFG();
+ ~BattlegroundBFG();
+};
+
+#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
index 126077f7988..483dd852d3f 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
@@ -284,7 +284,7 @@ void BattlegroundSA::StartShips()
{
if (Player* p = ObjectAccessor::FindPlayer(itr->first))
{
- UpdateData data;
+ UpdateData data(p->GetMapId());
WorldPacket pkt;
GetBGObject(i)->BuildValuesUpdateBlockForPlayer(&data, p);
data.BuildPacket(&pkt);
@@ -948,8 +948,9 @@ void BattlegroundSA::SendTransportInit(Player* player)
{
if (BgObjects[BG_SA_BOAT_ONE] || BgObjects[BG_SA_BOAT_TWO])
{
- UpdateData transData;
+ UpdateData transData(player->GetMapId());
if (BgObjects[BG_SA_BOAT_ONE])
+
GetBGObject(BG_SA_BOAT_ONE)->BuildCreateUpdateBlockForPlayer(&transData, player);
if (BgObjects[BG_SA_BOAT_TWO])
GetBGObject(BG_SA_BOAT_TWO)->BuildCreateUpdateBlockForPlayer(&transData, player);
@@ -963,7 +964,7 @@ void BattlegroundSA::SendTransportsRemove(Player* player)
{
if (BgObjects[BG_SA_BOAT_ONE] || BgObjects[BG_SA_BOAT_TWO])
{
- UpdateData transData;
+ UpdateData transData(player->GetMapId());
if (BgObjects[BG_SA_BOAT_ONE])
GetBGObject(BG_SA_BOAT_ONE)->BuildOutOfRangeUpdateBlock(&transData);
if (BgObjects[BG_SA_BOAT_TWO])
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp
new file mode 100644
index 00000000000..6d4c6ce0bac
--- /dev/null
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundTP.cpp
@@ -0,0 +1,36 @@
+/*
+ * 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 "Battleground.h"
+#include "BattlegroundTP.h"
+#include "Creature.h"
+#include "GameObject.h"
+#include "Language.h"
+#include "Object.h"
+#include "ObjectMgr.h"
+#include "BattlegroundMgr.h"
+#include "Player.h"
+#include "World.h"
+#include "WorldPacket.h"
+
+BattlegroundTP::BattlegroundTP()
+{
+}
+
+BattlegroundTP::~BattlegroundTP()
+{
+}
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundTP.h b/src/server/game/Battlegrounds/Zones/BattlegroundTP.h
new file mode 100644
index 00000000000..99ac9fbfedc
--- /dev/null
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundTP.h
@@ -0,0 +1,40 @@
+/*
+ * 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 __BATTLEGROUNDTP_H
+#define __BATTLEGROUNDTP_H
+
+#include "Battleground.h"
+
+class BattlegroundTPScore : public BattlegroundScore
+{
+ public:
+ BattlegroundTPScore() : FlagCaptures(0), FlagReturns(0) {};
+ virtual ~BattlegroundTPScore() {};
+
+ uint32 FlagCaptures;
+ uint32 FlagReturns;
+};
+
+class BattlegroundTP : public Battleground
+{
+ public:
+ BattlegroundTP();
+ ~BattlegroundTP();
+};
+
+#endif
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
index 92d56bbf5f0..4814728c26d 100644
--- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp
@@ -77,7 +77,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
{
if (GetStatus() == STATUS_IN_PROGRESS)
{
- if (GetStartTime() >= 27*MINUTE*IN_MILLISECONDS)
+ if (GetElapsedTime() >= 27*MINUTE*IN_MILLISECONDS)
{
if (GetTeamScore(TEAM_ALLIANCE) == 0)
{
@@ -96,7 +96,7 @@ void BattlegroundWS::PostUpdateImpl(uint32 diff)
EndBattleground(ALLIANCE);
}
// first update needed after 1 minute of game already in progress
- else if (GetStartTime() > uint32(_minutesElapsed * MINUTE * IN_MILLISECONDS) + 3 * MINUTE * IN_MILLISECONDS)
+ else if (GetElapsedTime() > uint32(_minutesElapsed * MINUTE * IN_MILLISECONDS) + 3 * MINUTE * IN_MILLISECONDS)
{
++_minutesElapsed;
UpdateWorldState(BG_WS_STATE_TIMER, 25 - _minutesElapsed);
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index bf46c1fd7c6..dc0edd5c1cf 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -145,6 +145,7 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/DataStores
${CMAKE_CURRENT_SOURCE_DIR}/DungeonFinding
${CMAKE_CURRENT_SOURCE_DIR}/Entities
+ ${CMAKE_CURRENT_SOURCE_DIR}/Entities/AreaTrigger
${CMAKE_CURRENT_SOURCE_DIR}/Entities/Creature
${CMAKE_CURRENT_SOURCE_DIR}/Entities/Corpse
${CMAKE_CURRENT_SOURCE_DIR}/Entities/DynamicObject
diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp
index 52ed50f3948..8c2d60aac5f 100644
--- a/src/server/game/Calendar/CalendarMgr.cpp
+++ b/src/server/game/Calendar/CalendarMgr.cpp
@@ -520,6 +520,10 @@ void CalendarMgr::SendCalendarEventInviteAlert(CalendarEvent const& calendarEven
data << uint32(calendarEvent.GetType());
data << int32(calendarEvent.GetDungeonId());
data << uint64(invite.GetInviteId());
+
+ Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId());
+ data << uint64(guild ? guild->GetGUID() : 0);
+
data << uint8(invite.GetStatus());
data << uint8(invite.GetRank());
data.appendPackGUID(calendarEvent.GetCreatorGUID());
@@ -556,7 +560,9 @@ void CalendarMgr::SendCalendarEvent(uint64 guid, CalendarEvent const& calendarEv
data << uint32(calendarEvent.GetFlags());
data.AppendPackedTime(calendarEvent.GetEventTime());
data.AppendPackedTime(calendarEvent.GetTimeZoneTime());
- data << uint32(calendarEvent.GetGuildId());
+
+ Guild* guild = sGuildMgr->GetGuildById(calendarEvent.GetGuildId());
+ data << uint64(guild ? guild->GetGUID() : 0);
data << uint32(eventInviteeList.size());
for (CalendarInviteStore::const_iterator itr = eventInviteeList.begin(); itr != eventInviteeList.end(); ++itr)
diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h
index da185d519d5..bdc49ad8e09 100644
--- a/src/server/game/Calendar/CalendarMgr.h
+++ b/src/server/game/Calendar/CalendarMgr.h
@@ -58,7 +58,8 @@ enum CalendarEventType
CALENDAR_TYPE_DUNGEON = 1,
CALENDAR_TYPE_PVP = 2,
CALENDAR_TYPE_MEETING = 3,
- CALENDAR_TYPE_OTHER = 4
+ CALENDAR_TYPE_OTHER = 4,
+ CALENDAR_TYPE_HEROIC = 5
};
enum CalendarRepeatType
diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp
index 0975a690889..5926d67cbd5 100644
--- a/src/server/game/Chat/Channels/ChannelMgr.cpp
+++ b/src/server/game/Chat/Channels/ChannelMgr.cpp
@@ -19,6 +19,7 @@
#include "ChannelMgr.h"
#include "Player.h"
#include "World.h"
+#include "WorldSession.h"
ChannelMgr::~ChannelMgr()
{
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index d90fd6f8443..c7fbb4c9df1 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -351,10 +351,9 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
std::string zoneName = "Unknown";
if (AreaTableEntry const* area = GetAreaEntryByAreaID(areaId))
{
- int locale = GetSessionDbcLocale();
- areaName = area->area_name[locale];
+ areaName = area->area_name;
if (AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone))
- zoneName = zone->area_name[locale];
+ zoneName = zone->area_name;
}
sLog->outCommand(m_session->GetAccountId(), "Command: %s [Player: %s (Guid: %u) (Account: %u) X: %f Y: %f Z: %f Map: %u (%s) Area: %u (%s) Zone: %s Selected %s: %s (GUID: %u)]",
@@ -631,7 +630,8 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, uint64 senderGUID, uint64 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 /*= ""*/)
+ uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/,
+ std::string const& addonPrefix /*= ""*/)
{
size_t receiverGUIDPos = 0;
data.Initialize(!gmMessage ? SMSG_MESSAGECHAT : SMSG_GM_MESSAGECHAT);
@@ -658,12 +658,17 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
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 << uint64(receiverGUID);
+ if (language == LANG_ADDON)
+ data << addonPrefix;
break;
case CHAT_MSG_BG_SYSTEM_NEUTRAL:
case CHAT_MSG_BG_SYSTEM_ALLIANCE:
@@ -675,11 +680,16 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
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 << uint64(receiverGUID);
+ if (language == LANG_ADDON)
+ data << addonPrefix;
break;
default:
if (gmMessage)
@@ -696,6 +706,9 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
receiverGUIDPos = data.wpos();
data << uint64(receiverGUID);
+
+ if (language == LANG_ADDON)
+ data << addonPrefix;
break;
}
@@ -705,12 +718,17 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
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)
+ {
+ 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)
+ }
return receiverGUIDPos;
}
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*/)
+ uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/, std::string const& addonPrefix /*= ""*/)
{
uint64 senderGUID = 0;
std::string senderName = "";
@@ -735,7 +753,7 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
receiverName = receiver->GetNameForLocaleIdx(locale);
}
- return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName);
+ return BuildChatPacket(data, chatType, language, senderGUID, receiverGUID, message, chatTag, senderName, receiverName, achievementId, gmMessage, channelName, addonPrefix);
}
Player* ChatHandler::getSelectedPlayer()
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index f9000f636c5..eb4c89bb8ea 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -56,10 +56,11 @@ class 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, uint64 senderGUID, uint64 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 = "");
+ 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);
+ 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 char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = NULL; return start; }
diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp
index 66758930f7f..c1c59389397 100644
--- a/src/server/game/Chat/ChatLink.cpp
+++ b/src/server/game/Chat/ChatLink.cpp
@@ -167,7 +167,7 @@ bool ItemChatLink::Initialize(std::istringstream& iss)
return true;
}
-inline std::string ItemChatLink::FormatName(uint8 index, ItemLocale const* locale, char* const* suffixStrings) const
+inline std::string ItemChatLink::FormatName(uint8 index, ItemLocale const* locale, char* suffixStrings) const
{
std::stringstream ss;
if (locale == NULL || index >= locale->Name.size())
@@ -183,7 +183,7 @@ bool ItemChatLink::ValidateName(char* buffer, const char* context)
{
ChatLink::ValidateName(buffer, context);
- char* const* suffixStrings = _suffix ? _suffix->nameSuffix : (_property ? _property->nameSuffix : NULL);
+ char* suffixStrings = _suffix ? _suffix->nameSuffix : (_property ? _property->nameSuffix : NULL);
bool res = (FormatName(LOCALE_enUS, NULL, suffixStrings) == buffer);
if (!res)
@@ -306,22 +306,18 @@ bool SpellChatLink::ValidateName(char* buffer, const char* context)
return false;
}
- for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
+ uint32 skillLineNameLength = strlen(skillLine->name);
+ if (skillLineNameLength > 0 && strncmp(skillLine->name, buffer, skillLineNameLength) == 0)
{
- uint32 skillLineNameLength = strlen(skillLine->name[i]);
- if (skillLineNameLength > 0 && strncmp(skillLine->name[i], buffer, skillLineNameLength) == 0)
- {
- // found the prefix, remove it to perform spellname validation below
- // -2 = strlen(": ")
- uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2;
- memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1);
- }
+ // found the prefix, remove it to perform spellname validation below
+ // -2 = strlen(": ")
+ uint32 spellNameLength = strlen(buffer) - skillLineNameLength - 2;
+ memcpy(buffer, buffer + skillLineNameLength + 2, spellNameLength + 1);
}
}
- for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
- if (*_spell->SpellName[i] && strcmp(_spell->SpellName[i], buffer) == 0)
- return true;
+ if (*_spell->SpellName && strcmp(_spell->SpellName, buffer) == 0)
+ return true;
TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): linked spell (id: %u) name wasn't found in any localization", context, _spell->Id);
return false;
@@ -376,9 +372,8 @@ bool AchievementChatLink::ValidateName(char* buffer, const char* context)
{
ChatLink::ValidateName(buffer, context);
- for (uint8 i = 0; i < TOTAL_LOCALES; ++i)
- if (*_achievement->name[i] && strcmp(_achievement->name[i], buffer) == 0)
- return true;
+ if (*_achievement->name && strcmp(_achievement->name, buffer) == 0)
+ return true;
TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): linked achievement (id: %u) name wasn't found in any localization", context, _achievement->ID);
return false;
diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h
index cc86cb538ea..e9573a631e4 100644
--- a/src/server/game/Chat/ChatLink.h
+++ b/src/server/game/Chat/ChatLink.h
@@ -64,7 +64,7 @@ public:
virtual bool ValidateName(char* buffer, const char* context);
protected:
- std::string FormatName(uint8 index, ItemLocale const* locale, char* const* suffixStrings) const;
+ std::string FormatName(uint8 index, ItemLocale const* locale, char* suffixStrings) const;
ItemTemplate const* _item;
int32 _data[8];
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index e76ba18f1e2..57b6b90cc2c 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -30,7 +30,7 @@
#include "Spell.h"
// Checks if object meets the condition
-// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI)
+// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
bool Condition::Meets(ConditionSourceInfo& sourceInfo)
{
ASSERT(ConditionTarget < MAX_CONDITION_TARGETS);
@@ -434,6 +434,9 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
case TYPEID_CORPSE:
mask |= GRID_MAP_TYPE_MASK_CORPSE;
break;
+ case TYPEID_AREATRIGGER:
+ mask |= GRID_MAP_TYPE_MASK_AREATRIGGER;
+ break;
default:
break;
}
@@ -447,6 +450,8 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
mask |= GRID_MAP_TYPE_MASK_GAMEOBJECT;
if (ConditionValue1 & TYPEMASK_CORPSE)
mask |= GRID_MAP_TYPE_MASK_CORPSE;
+ if (ConditionValue1 & TYPEMASK_AREATRIGGER)
+ mask |= GRID_MAP_TYPE_MASK_AREATRIGGER;
break;
case CONDITION_RELATION_TO:
mask |= GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER;
@@ -658,6 +663,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
+ sourceType == CONDITION_SOURCE_TYPE_PHASE_DEFINITION ||
sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
}
@@ -733,6 +739,22 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32
return cond;
}
+ConditionList const* ConditionMgr::GetConditionsForPhaseDefinition(uint32 zone, uint32 entry)
+{
+ PhaseDefinitionConditionContainer::const_iterator itr = PhaseDefinitionsConditionStore.find(zone);
+ if (itr != PhaseDefinitionsConditionStore.end())
+ {
+ ConditionTypeContainer::const_iterator i = itr->second.find(entry);
+ if (i != itr->second.end())
+ {
+ TC_LOG_DEBUG("condition", "GetConditionsForPhaseDefinition: found conditions for zone %u entry %u", zone, entry);
+ return &i->second;
+ }
+ }
+
+ return NULL;
+}
+
ConditionList ConditionMgr::GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId)
{
ConditionList cond;
@@ -972,6 +994,13 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
+ case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
+ {
+ PhaseDefinitionsConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
+ valid = true;
+ ++count;
+ continue;
+ }
case CONDITION_SOURCE_TYPE_NPC_VENDOR:
{
NpcVendorConditionContainerStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
@@ -1483,6 +1512,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return false;
}
break;
+ case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
+ if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType))
+ {
+ TC_LOG_ERROR("sql.sql", "Condition source type `CONDITION_SOURCE_TYPE_PHASE_DEFINITION` does not support condition type %u, ignoring.", cond->ConditionType);
+ return false;
+ }
+ break;
case CONDITION_SOURCE_TYPE_NPC_VENDOR:
{
if (!sObjectMgr->GetCreatureTemplate(cond->SourceGroup))
@@ -1498,11 +1534,6 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
break;
}
- case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
- {
- TC_LOG_ERROR("sql.sql", "CONDITION_SOURCE_TYPE_PHASE_DEFINITION:: is only for 4.3.4 branch, skipped");
- return false;
- }
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
@@ -2079,6 +2110,19 @@ void ConditionMgr::Clean()
SpellClickEventConditionStore.clear();
+ for (PhaseDefinitionConditionContainer::iterator itr = PhaseDefinitionsConditionStore.begin(); itr != PhaseDefinitionsConditionStore.end(); ++itr)
+ {
+ for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ {
+ for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ delete *i;
+ it->second.clear();
+ }
+ itr->second.clear();
+ }
+
+ PhaseDefinitionsConditionStore.clear();
+
for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
{
for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 876b922d243..8843aa243a7 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -218,6 +218,7 @@ typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer
typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer;
typedef std::map<uint32, ConditionTypeContainer> NpcVendorConditionContainer;
typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
+typedef std::map<int32 /*zoneId*/, ConditionTypeContainer> PhaseDefinitionConditionContainer;
typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
@@ -244,6 +245,7 @@ class ConditionMgr
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
+ ConditionList const* GetConditionsForPhaseDefinition(uint32 zone, uint32 entry);
ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId);
private:
@@ -263,6 +265,7 @@ class ConditionMgr
CreatureSpellConditionContainer SpellClickEventConditionStore;
NpcVendorConditionContainer NpcVendorConditionContainerStore;
SmartEventConditionContainer SmartEventConditionStore;
+ PhaseDefinitionConditionContainer PhaseDefinitionsConditionStore;
};
#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp
new file mode 100644
index 00000000000..4034bd0c1c2
--- /dev/null
+++ b/src/server/game/DataStores/DB2Stores.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 "DB2Stores.h"
+#include "DB2fmt.h"
+#include "DB2Utility.h"
+#include "Common.h"
+#include "Log.h"
+#include "World.h"
+
+DB2Storage<ItemEntry> sItemStore(Itemfmt, &DB2Utilities::HasItemEntry, &DB2Utilities::WriteItemDbReply);
+DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore(ItemCurrencyCostfmt);
+DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt);
+DB2Storage<ItemSparseEntry> sItemSparseStore(ItemSparsefmt, &DB2Utilities::HasItemSparseEntry, &DB2Utilities::WriteItemSparseDbReply);
+DB2Storage<KeyChainEntry> sKeyChainStore(KeyChainfmt);
+
+typedef std::list<std::string> DB2StoreProblemList;
+
+typedef std::map<uint32 /*hash*/, DB2StorageBase*> DB2StorageMap;
+DB2StorageMap DB2Stores;
+
+uint32 DB2FilesCount = 0;
+
+static bool LoadDB2_assert_print(uint32 fsize, uint32 rsize, std::string const& filename)
+{
+ TC_LOG_ERROR("misc", "Size of '%s' setted by format string (%u) not equal size of C++ structure (%u).", filename.c_str(), fsize, rsize);
+
+ // ASSERT must fail after function call
+ return false;
+}
+
+template<class T>
+inline void LoadDB2(uint32& availableDb2Locales, DB2StoreProblemList& errlist, DB2Storage<T>& storage, std::string const& db2_path, std::string const& filename)
+{
+ // compatibility format and C++ structure sizes
+ ASSERT(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDB2_assert_print(DB2FileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename));
+
+ ++DB2FilesCount;
+
+ std::string db2_filename = db2_path + filename;
+ if (storage.Load(db2_filename.c_str(), uint32(sWorld->GetDefaultDbcLocale())))
+ {
+ for (uint32 i = 0; i < TOTAL_LOCALES; ++i)
+ {
+ if (!(availableDb2Locales & (1 << i)))
+ continue;
+
+ if (uint32(sWorld->GetDefaultDbcLocale()) == i)
+ continue;
+
+ std::string localizedName(db2_path);
+ localizedName.append(localeNames[i]);
+ localizedName.push_back('/');
+ localizedName.append(filename);
+
+ if (!storage.LoadStringsFrom(localizedName.c_str(), i))
+ availableDb2Locales &= ~(1<<i); // mark as not available for speedup next checks
+ }
+ }
+ else
+ {
+ // sort problematic db2 to (1) non compatible and (2) nonexistent
+ if (FILE* f = fopen(db2_filename.c_str(), "rb"))
+ {
+ char buf[100];
+ snprintf(buf, 100,"(exist, but have %d fields instead " SIZEFMTD ") Wrong client version DBC file?", storage.GetFieldCount(), strlen(storage.GetFormat()));
+ errlist.push_back(db2_filename + buf);
+ fclose(f);
+ }
+ else
+ errlist.push_back(db2_filename);
+ }
+
+ DB2Stores[storage.GetHash()] = &storage;
+}
+
+void LoadDB2Stores(std::string const& dataPath)
+{
+ std::string db2Path = dataPath + "dbc/";
+
+ DB2StoreProblemList bad_db2_files;
+ uint32 availableDb2Locales = 0xFF;
+
+ LoadDB2(availableDb2Locales, bad_db2_files, sItemStore, db2Path, "Item.db2");
+ LoadDB2(availableDb2Locales, bad_db2_files, sItemCurrencyCostStore, db2Path, "ItemCurrencyCost.db2");
+ LoadDB2(availableDb2Locales, bad_db2_files, sItemSparseStore, db2Path, "Item-sparse.db2");
+ LoadDB2(availableDb2Locales, bad_db2_files, sItemExtendedCostStore, db2Path, "ItemExtendedCost.db2");
+ LoadDB2(availableDb2Locales, bad_db2_files, sKeyChainStore, db2Path, "KeyChain.db2");
+
+ // error checks
+ if (bad_db2_files.size() >= DB2FilesCount)
+ {
+ TC_LOG_ERROR("misc", "\nIncorrect DataDir value in worldserver.conf or ALL required *.db2 files (%d) not found by path: %sdb2", DB2FilesCount, dataPath.c_str());
+ exit(1);
+ }
+ else if (!bad_db2_files.empty())
+ {
+ std::string str;
+ for (std::list<std::string>::iterator i = bad_db2_files.begin(); i != bad_db2_files.end(); ++i)
+ str += *i + "\n";
+
+ TC_LOG_ERROR("misc", "\nSome required *.db2 files (%u from %d) not found or not compatible:\n%s", (uint32)bad_db2_files.size(), DB2FilesCount, str.c_str());
+ exit(1);
+ }
+
+ // Check loaded DB2 files proper version
+ if (!sItemStore.LookupEntry(83086) || // last item added in 4.3.4 (15595)
+ !sItemExtendedCostStore.LookupEntry(3872) ) // last item extended cost added in 4.3.4 (15595)
+ {
+ TC_LOG_ERROR("misc", "Please extract correct db2 files from client 4.3.4 15595.");
+ exit(1);
+ }
+
+ TC_LOG_INFO("misc", ">> Initialized %d DB2 data stores.", DB2FilesCount);
+}
+
+DB2StorageBase const* GetDB2Storage(uint32 type)
+{
+ DB2StorageMap::const_iterator itr = DB2Stores.find(type);
+ if (itr != DB2Stores.end())
+ return itr->second;
+
+ return NULL;
+}
diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h
new file mode 100644
index 00000000000..17a92f98cde
--- /dev/null
+++ b/src/server/game/DataStores/DB2Stores.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 TRINITY_DB2STORES_H
+#define TRINITY_DB2STORES_H
+
+#include "DB2Store.h"
+#include "DB2Structure.h"
+#include <string>
+
+extern DB2Storage<ItemEntry> sItemStore;
+extern DB2Storage<ItemCurrencyCostEntry> sItemCurrencyCostStore;
+extern DB2Storage<ItemExtendedCostEntry> sItemExtendedCostStore;
+extern DB2Storage<ItemSparseEntry> sItemSparseStore;
+extern DB2Storage<KeyChainEntry> sKeyChainStore;
+
+void LoadDB2Stores(std::string const& dataPath);
+
+DB2StorageBase const* GetDB2Storage(uint32 type);
+
+#endif
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
new file mode 100644
index 00000000000..0a60d0b860f
--- /dev/null
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 TRINITY_DB2STRUCTURE_H
+#define TRINITY_DB2STRUCTURE_H
+
+#include "Common.h"
+#include "ItemPrototype.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__)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+// Structures used to access raw DB2 data and required packing to portability
+struct ItemEntry
+{
+ uint32 ID; // 0
+ uint32 Class; // 1
+ uint32 SubClass; // 2
+ int32 SoundOverrideSubclass; // 3
+ int32 Material; // 4
+ uint32 DisplayId; // 5
+ uint32 InventoryType; // 6
+ uint32 Sheath; // 7
+};
+
+struct ItemCurrencyCostEntry
+{
+ //uint32 Id;
+ uint32 ItemId;
+};
+
+struct ItemSparseEntry
+{
+ 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
+};
+
+#define MAX_ITEM_EXT_COST_ITEMS 5
+#define MAX_ITEM_EXT_COST_CURRENCIES 5
+
+struct ItemExtendedCostEntry
+{
+ uint32 ID; // 0 extended-cost entry id
+ //uint32 reqhonorpoints; // 1 required honor points
+ //uint32 reqarenapoints; // 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 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;
+ uint32 RequiredFactionStanding;
+ uint32 RequirementFlags;
+ uint32 RequiredGuildLevel;
+ uint32 RequiredAchievement;
+};
+
+#define KEYCHAIN_SIZE 32
+
+struct KeyChainEntry
+{
+ uint32 Id;
+ uint8 Key[KEYCHAIN_SIZE];
+};
+
+// 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__)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+#endif \ No newline at end of file
diff --git a/src/server/game/DataStores/DB2Utility.cpp b/src/server/game/DataStores/DB2Utility.cpp
new file mode 100644
index 00000000000..5a0174c3a74
--- /dev/null
+++ b/src/server/game/DataStores/DB2Utility.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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 "DB2Utility.h"
+#include "ObjectMgr.h"
+
+inline bool ItemExists(uint32 id)
+{
+ return sObjectMgr->GetItemTemplate(id) != NULL;
+}
+
+bool DB2Utilities::HasItemEntry(DB2Storage<ItemEntry> const& /*store*/, uint32 id)
+{
+ return ItemExists(id);
+}
+
+bool DB2Utilities::HasItemSparseEntry(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id)
+{
+ return ItemExists(id);
+}
+
+void DB2Utilities::WriteItemDbReply(DB2Storage<ItemEntry> const& /*store*/, uint32 id, uint32 /*locale*/, ByteBuffer& buffer)
+{
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id);
+ ASSERT(proto);
+
+ buffer << uint32(proto->ItemId);
+ buffer << uint32(proto->Class);
+ buffer << uint32(proto->SubClass);
+ buffer << int32(proto->SoundOverrideSubclass);
+ buffer << uint32(proto->Material);
+ buffer << uint32(proto->DisplayInfoID);
+ buffer << uint32(proto->InventoryType);
+ buffer << uint32(proto->Sheath);
+}
+
+void DB2Utilities::WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& /*store*/, uint32 id, uint32 locale, ByteBuffer& buffer)
+{
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(id);
+ ASSERT(proto);
+
+ ItemLocale const* localeData = locale ? sObjectMgr->GetItemLocale(id) : NULL;
+
+ 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);
+ buffer << uint32(proto->BuyCount);
+ buffer << int32(proto->BuyPrice);
+ buffer << uint32(proto->SellPrice);
+ buffer << uint32(proto->InventoryType);
+ buffer << int32(proto->AllowableClass);
+ buffer << int32(proto->AllowableRace);
+ buffer << uint32(proto->ItemLevel);
+ buffer << uint32(proto->RequiredLevel);
+ buffer << uint32(proto->RequiredSkill);
+ buffer << uint32(proto->RequiredSkillRank);
+ buffer << uint32(proto->RequiredSpell);
+ buffer << uint32(proto->RequiredHonorRank);
+ buffer << uint32(proto->RequiredCityRank);
+ buffer << uint32(proto->RequiredReputationFaction);
+ buffer << uint32(proto->RequiredReputationRank);
+ buffer << int32(proto->MaxCount);
+ buffer << int32(proto->Stackable);
+ buffer << uint32(proto->ContainerSlots);
+
+ for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
+ buffer << uint32(proto->ItemStat[x].ItemStatType);
+
+ for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
+ buffer << int32(proto->ItemStat[x].ItemStatValue);
+
+ for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
+ buffer << int32(proto->ItemStat[x].ItemStatUnk1);
+
+ for (uint32 x = 0; x < MAX_ITEM_PROTO_STATS; ++x)
+ buffer << int32(proto->ItemStat[x].ItemStatUnk2);
+
+ buffer << uint32(proto->ScalingStatDistribution);
+ 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
+ std::string name = proto->Name1;
+ if (localeData)
+ ObjectMgr::GetLocaleString(localeData->Name, locale, name);
+
+ buffer << uint16(name.length());
+ if (name.length())
+ buffer << name;
+
+ for (uint32 i = 0; i < 3; ++i) // other 3 names
+ buffer << uint16(0);
+
+ std::string desc = proto->Description;
+ if (localeData)
+ ObjectMgr::GetLocaleString(localeData->Description, locale, desc);
+
+ buffer << uint16(desc.length());
+ if (desc.length())
+ buffer << desc;
+
+ buffer << uint32(proto->PageText);
+ buffer << uint32(proto->LanguageID);
+ buffer << uint32(proto->PageMaterial);
+ buffer << uint32(proto->StartQuest);
+ buffer << uint32(proto->LockID);
+ buffer << int32(proto->Material);
+ buffer << uint32(proto->Sheath);
+ buffer << int32(proto->RandomProperty);
+ buffer << int32(proto->RandomSuffix);
+ buffer << uint32(proto->ItemSet);
+
+ buffer << uint32(proto->Area);
+ buffer << uint32(proto->Map);
+ buffer << uint32(proto->BagFamily);
+ buffer << uint32(proto->TotemCategory);
+
+ 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);
+ buffer << int32(proto->Duration);
+ buffer << uint32(proto->ItemLimitCategory);
+ buffer << uint32(proto->HolidayId);
+ buffer << float(proto->StatScalingFactor); // StatScalingFactor
+ buffer << uint32(proto->CurrencySubstitutionId);
+ buffer << uint32(proto->CurrencySubstitutionCount);
+}
diff --git a/src/server/game/DataStores/DB2Utility.h b/src/server/game/DataStores/DB2Utility.h
new file mode 100644
index 00000000000..f2d58de91ca
--- /dev/null
+++ b/src/server/game/DataStores/DB2Utility.h
@@ -0,0 +1,40 @@
+/*
+ * 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 DB2PACKETWRITER_H
+#define DB2PACKETWRITER_H
+
+#include "Define.h"
+
+template<class T>
+class DB2Storage;
+class ByteBuffer;
+struct ItemEntry;
+struct ItemSparseEntry;
+
+namespace DB2Utilities
+{
+ //
+ bool HasItemEntry(DB2Storage<ItemEntry> const& store, uint32 id);
+ bool HasItemSparseEntry(DB2Storage<ItemSparseEntry> const& store, uint32 id);
+
+ //
+ void WriteItemDbReply(DB2Storage<ItemEntry> const& store, uint32 id, uint32 locale, ByteBuffer& buffer);
+ void WriteItemSparseDbReply(DB2Storage<ItemSparseEntry> const& store, uint32 id, uint32 locale, ByteBuffer& buffer);
+}
+
+#endif // DB2PACKETWRITER_H
diff --git a/src/server/game/DataStores/DB2fmt.h b/src/server/game/DataStores/DB2fmt.h
new file mode 100644
index 00000000000..e2904aed51e
--- /dev/null
+++ b/src/server/game/DataStores/DB2fmt.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 TRINITY_DB2SFRM_H
+#define TRINITY_DB2SFRM_H
+
+char const Itemfmt[]="niiiiiii";
+char const ItemCurrencyCostfmt[]="xn";
+char const ItemSparsefmt[]="niiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisssssiiiiiiiiiiiiiiiiiiiiiifiiifii";
+char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiiiiiii";
+char const KeyChainfmt[]="nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
+
+#endif
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 87397c6685b..73319d5eefd 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -24,7 +24,7 @@ enum LevelLimit
// Client expected level limitation, like as used in DBC item max levels for "until max player level"
// use as default max player level, must be fit max level for used client
// also see MAX_LEVEL and STRONG_MAX_LEVEL define
- DEFAULT_MAX_LEVEL = 80,
+ DEFAULT_MAX_LEVEL = 85,
// client supported max level for player/pets/etc. Avoid overflow or client stability affected.
// also see GT_MAX_LEVEL define
@@ -63,17 +63,28 @@ enum AchievementFlags
{
ACHIEVEMENT_FLAG_COUNTER = 0x00000001, // Just count statistic (never stop and complete)
ACHIEVEMENT_FLAG_HIDDEN = 0x00000002, // Not sent to client - internal use only
- ACHIEVEMENT_FLAG_STORE_MAX_VALUE = 0x00000004, // Store only max value? used only in "Reach level xx"
+ ACHIEVEMENT_FLAG_PLAY_NO_VISUAL = 0x00000004, // Client does not play achievement earned visual
ACHIEVEMENT_FLAG_SUMM = 0x00000008, // Use summ criteria value from all requirements (and calculate max value)
ACHIEVEMENT_FLAG_MAX_USED = 0x00000010, // Show max criteria (and calculate max value ??)
ACHIEVEMENT_FLAG_REQ_COUNT = 0x00000020, // Use not zero req count (and calculate max value)
ACHIEVEMENT_FLAG_AVERAGE = 0x00000040, // Show as average value (value / time_in_days) depend from other flag (by def use last criteria value)
ACHIEVEMENT_FLAG_BAR = 0x00000080, // Show as progress bar (value / max vale) depend from other flag (by def use last criteria value)
ACHIEVEMENT_FLAG_REALM_FIRST_REACH = 0x00000100, //
- ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200 //
+ ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, //
+ ACHIEVEMENT_FLAG_UNK3 = 0x00000400, // ACHIEVEMENT_FLAG_HIDE_NAME_IN_TIE
+ ACHIEVEMENT_FLAG_REALM_FIRST_GUILD = 0x00000800, // first guild on realm done something
+ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_NEWS = 0x00001000, // Shows in guild news
+ ACHIEVEMENT_FLAG_SHOW_IN_GUILD_HEADER = 0x00002000, // Shows in guild news header
+ ACHIEVEMENT_FLAG_GUILD = 0x00004000, //
+ ACHIEVEMENT_FLAG_SHOW_GUILD_MEMBERS = 0x00008000, //
+ ACHIEVEMENT_FLAG_SHOW_CRITERIA_MEMBERS = 0x00010000 //
};
-#define MAX_CRITERIA_REQUIREMENTS 2
+enum AchievementCriteriaLimits
+{
+ MAX_CRITERIA_REQUIREMENTS = 2,
+ MAX_ADDITIONAL_CRITERIA_CONDITIONS = 3
+};
enum AchievementCriteriaCondition
{
@@ -82,11 +93,60 @@ enum AchievementCriteriaCondition
ACHIEVEMENT_CRITERIA_CONDITION_UNK2 = 2, // only used in "Complete a daily quest every day for five consecutive days"
ACHIEVEMENT_CRITERIA_CONDITION_BG_MAP = 3, // requires you to be on specific map, reset at change
ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE = 4, // only used in "Win 10 arenas without losing"
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK5 = 5, // Have spell?
+ ACHIEVEMENT_CRITERIA_CONDITION_UNK8 = 8,
ACHIEVEMENT_CRITERIA_CONDITION_NO_SPELL_HIT = 9, // requires the player not to be hit by specific spell
ACHIEVEMENT_CRITERIA_CONDITION_NOT_IN_GROUP = 10, // requires the player not to be in group
ACHIEVEMENT_CRITERIA_CONDITION_UNK13 = 13 // unk
};
+enum AchievementCriteriaAdditionalCondition
+{
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_DRUNK_VALUE = 1, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK2 = 2,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_LEVEL = 3, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_ENTRY = 4,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_PLAYER = 5,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_DEAD = 6,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_MUST_BE_ENEMY = 7,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_HAS_AURA = 8,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA = 10,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HAS_AURA_TYPE = 11,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_MIN = 14,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_QUALITY_EQUALS = 15,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK16 = 16,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_AREA_OR_ZONE = 17,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_AREA_OR_ZONE = 18,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAP_DIFFICULTY = 20,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_YIELDS_XP = 21, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ARENA_TYPE = 24, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_RACE = 25,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_CLASS = 26,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_RACE = 27,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CLASS = 28,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MAX_GROUP_MEMBERS = 29,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_CREATURE_TYPE = 30,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_MAP = 32,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_CLASS = 33, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_ITEM_SUBCLASS = 34, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_COMPLETE_QUEST_NOT_IN_GROUP = 35, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_PERSONAL_RATING = 37, // NYI (when implementing don't forget about ACHIEVEMENT_CRITERIA_CONDITION_NO_LOSE)
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TITLE_BIT_INDEX = 38,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_SOURCE_LEVEL = 39,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_LEVEL = 40,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_ZONE = 41,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_TARGET_HEALTH_PERCENT_BELOW = 46,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK55 = 55,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_MIN_ACHIEVEMENT_POINTS = 56, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_LFG_GROUP = 58, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_UNK60 = 60,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_REQUIRES_GUILD_GROUP = 61, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_GUILD_REPUTATION = 62, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_RATED_BATTLEGROUND = 63, // NYI
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RARITY = 65,
+ ACHIEVEMENT_CRITERIA_ADDITIONAL_CONDITION_PROJECT_RACE = 66,
+};
+
enum AchievementCriteriaFlags
{
ACHIEVEMENT_CRITERIA_FLAG_SHOW_PROGRESS_BAR = 0x00000001, // Show progress as bar
@@ -105,6 +165,7 @@ enum AchievementCriteriaTimedTypes
ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET = 6, // Timer is started by being target of spell with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_CREATURE = 7, // Timer is started by killing creature with entry in timerStartEvent
ACHIEVEMENT_TIMED_TYPE_ITEM = 9, // Timer is started by using item with entry in timerStartEvent
+ ACHIEVEMENT_TIMED_TYPE_UNK = 10, // Unknown
ACHIEVEMENT_TIMED_TYPE_MAX
};
@@ -113,12 +174,14 @@ enum AchievementCriteriaTypes
{
ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0,
ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ARCHAEOLOGY_PROJECTS = 3, // struct { uint32 itemCount; }
ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5,
ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7,
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8,
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9,
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, // you have to complete a daily quest x times in a row
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11,
+ ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12,
ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13,
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14,
ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND = 15,
@@ -192,12 +255,6 @@ enum AchievementCriteriaTypes
ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91,
ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93,
ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99,
- ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100,
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101,
ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102,
ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103,
@@ -213,46 +270,56 @@ enum AchievementCriteriaTypes
ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114,
ACHIEVEMENT_CRITERIA_TYPE_EARN_ACHIEVEMENT_POINTS = 115,
ACHIEVEMENT_CRITERIA_TYPE_USE_LFD_TO_GROUP_WITH_PLAYERS = 119,
+ ACHIEVEMENT_CRITERIA_TYPE_SPENT_GOLD_GUILD_REPAIRS = 124,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125,
+ ACHIEVEMENT_CRITERIA_TYPE_CRAFT_ITEMS_GUILD = 126,
+ ACHIEVEMENT_CRITERIA_TYPE_CATCH_FROM_POOL = 127,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_BANK_SLOTS = 128,
+ ACHIEVEMENT_CRITERIA_TYPE_EARN_GUILD_ACHIEVEMENT_POINTS = 129,
+ ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_BATTLEGROUND = 130,
+ ACHIEVEMENT_CRITERIA_TYPE_REACH_BG_RATING = 132,
+ ACHIEVEMENT_CRITERIA_TYPE_BUY_GUILD_TABARD = 133,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_GUILD = 134,
+ ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILLS_GUILD = 135,
+ ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE_GUILD = 136,
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE_TYPE = 138, //struct { Flag flag; uint32 count; } 1: Guild Dungeon, 2:Guild Challenge, 3:Guild battlefield
+ ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_GUILD_CHALLENGE = 139 //struct { uint32 count; } Guild Challenge
};
-#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 120
-
-enum AchievementCategory
-{
- CATEGORY_CHILDRENS_WEEK = 163
-};
+#define ACHIEVEMENT_CRITERIA_TYPE_TOTAL 140
enum AreaFlags
{
- AREA_FLAG_UNK0 = 0x00000001, // Unknown
- AREA_FLAG_UNK1 = 0x00000002, // Razorfen Downs, Naxxramas and Acherus: The Ebon Hold (3.3.5a)
- AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before)
- AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones
- AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning
- AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag?
- AREA_FLAG_ALLOW_DUELS = 0x00000040, // allow to duel here
- AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
- AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
- AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
- AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
- AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
- AREA_FLAG_NEED_FLY = 0x00001000, // Respawn alive at the graveyard without corpse
- AREA_FLAG_UNUSED1 = 0x00002000, // Unused in 3.3.5a
- AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
- AREA_FLAG_OUTDOOR_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
- AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
- AREA_FLAG_UNUSED2 = 0x00020000, // Unused in 3.3.5a
- AREA_FLAG_CONTESTED_AREA = 0x00040000, // On PvP servers these areas are considered contested, even though the zone it is contained in is a Horde/Alliance territory.
- AREA_FLAG_UNK4 = 0x00080000, // Valgarde and Acherus: The Ebon Hold
- AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <= 15
- AREA_FLAG_TOWN = 0x00200000, // small towns with Inn
- AREA_FLAG_REST_ZONE_HORDE = 0x00400000, // Instead of using areatriggers, the zone will act as one for Horde players (Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn, Sunreaver Pavilion, etc)
- AREA_FLAG_REST_ZONE_ALLIANCE = 0x00800000, // Instead of using areatriggers, the zone will act as one for Alliance players (Valgarde, Acherus: The Ebon Hold, Westguard Inn, Silver Covenant Pavilion, etc)
- AREA_FLAG_WINTERGRASP = 0x01000000, // Wintergrasp and it's subzones
- AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
- AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
- AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area
- AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly
+ AREA_FLAG_SNOW = 0x00000001, // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring)
+ AREA_FLAG_UNK1 = 0x00000002, // Razorfen Downs, Naxxramas and Acherus: The Ebon Hold (3.3.5a)
+ AREA_FLAG_UNK2 = 0x00000004, // Only used for areas on map 571 (development before)
+ AREA_FLAG_SLAVE_CAPITAL = 0x00000008, // city and city subsones
+ AREA_FLAG_UNK3 = 0x00000010, // can't find common meaning
+ AREA_FLAG_SLAVE_CAPITAL2 = 0x00000020, // slave capital city flag?
+ AREA_FLAG_ALLOW_DUELS = 0x00000040, // allow to duel here
+ AREA_FLAG_ARENA = 0x00000080, // arena, both instanced and world arenas
+ AREA_FLAG_CAPITAL = 0x00000100, // main capital city flag
+ AREA_FLAG_CITY = 0x00000200, // only for one zone named "City" (where it located?)
+ AREA_FLAG_OUTLAND = 0x00000400, // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)
+ AREA_FLAG_SANCTUARY = 0x00000800, // sanctuary area (PvP disabled)
+ AREA_FLAG_NEED_FLY = 0x00001000, // Respawn alive at the graveyard without corpse
+ AREA_FLAG_UNUSED1 = 0x00002000, // Unused in 3.3.5a
+ AREA_FLAG_OUTLAND2 = 0x00004000, // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)
+ AREA_FLAG_OUTDOOR_PVP = 0x00008000, // pvp objective area? (Death's Door also has this flag although it's no pvp object area)
+ AREA_FLAG_ARENA_INSTANCE = 0x00010000, // used by instanced arenas only
+ AREA_FLAG_UNUSED2 = 0x00020000, // Unused in 3.3.5a
+ AREA_FLAG_CONTESTED_AREA = 0x00040000, // On PvP servers these areas are considered contested, even though the zone it is contained in is a Horde/Alliance territory.
+ AREA_FLAG_UNK6 = 0x00080000, // Valgarde and Acherus: The Ebon Hold
+ AREA_FLAG_LOWLEVEL = 0x00100000, // used for some starting areas with area_level <= 15
+ AREA_FLAG_TOWN = 0x00200000, // small towns with Inn
+ AREA_FLAG_REST_ZONE_HORDE = 0x00400000, // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn, Sunreaver Pavilion (Something to do with team?)
+ AREA_FLAG_REST_ZONE_ALLIANCE = 0x00800000, // Valgarde, Acherus: The Ebon Hold, Westguard Inn, Silver Covenant Pavilion (Something to do with team?)
+ AREA_FLAG_WINTERGRASP = 0x01000000, // Wintergrasp and it's subzones
+ AREA_FLAG_INSIDE = 0x02000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
+ AREA_FLAG_OUTSIDE = 0x04000000, // used for determinating spell related inside/outside questions in Map::IsOutdoors
+ AREA_FLAG_WINTERGRASP_2 = 0x08000000, // Can Hearth And Resurrect From Area
+ AREA_FLAG_NO_FLY_ZONE = 0x20000000, // Marks zones where you cannot fly
+ AREA_FLAG_UNK9 = 0x40000000
};
enum Difficulty
@@ -338,16 +405,33 @@ enum ItemEnchantmentType
ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
};
+enum ItemExtendedCostFlags
+{
+ ITEM_EXT_COST_FLAG_REQUIRE_GUILD = 0x01,
+ ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 = 0x02,
+ ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_2 = 0x04,
+ ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_3 = 0x08,
+ ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_4 = 0x10,
+ ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_5 = 0x20,
+};
+
enum ItemLimitCategoryMode
{
ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank
ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems)
};
+enum MountFlags
+{
+ MOUNT_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING
+ MOUNT_FLAG_CAN_SWIM = 0x8, // client checks MOVEMENTFLAG_SWIMMING
+};
+
enum SpellCategoryFlags
{
SPELL_CATEGORY_FLAG_COOLDOWN_SCALES_WITH_WEAPON_SPEED = 0x01, // unused
- SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04
+ SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04,
+ SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_MIDNIGHT = 0x08
};
enum TotemCategoryType
@@ -371,6 +455,25 @@ enum SummonPropGroup
SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
};
+// SummonProperties.dbc, col 3
+enum SummonPropType
+{
+ SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
+ SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
+ SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
+ SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
+ SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
+ SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
+ SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
+ SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
+ SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
+ SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
+ SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
+ SUMMON_PROP_TYPE_LIGHTWELL = 11, // summon lightwell, 6 spells in 3.0.3
+ SUMMON_PROP_TYPE_JEEVES = 12, // summon Jeeves, 1 spell in 3.3.5a
+ SUMMON_PROP_TYPE_LASHTAIL = 13 // Lashtail Hatchling, 1 spell in 4.2.2
+};
+
// SummonProperties.dbc, col 5
enum SummonPropFlags
{
@@ -390,7 +493,12 @@ enum SummonPropFlags
SUMMON_PROP_FLAG_UNK13 = 0x00001000, // Lightwell, Jeeves, Gnomish Alarm-o-bot, Build vehicles(wintergrasp)
SUMMON_PROP_FLAG_UNK14 = 0x00002000, // Guides, player follows
SUMMON_PROP_FLAG_UNK15 = 0x00004000, // Force of Nature, Shadowfiend, Feral Spirit, Summon Water Elemental
- SUMMON_PROP_FLAG_UNK16 = 0x00008000 // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related?
+ SUMMON_PROP_FLAG_UNK16 = 0x00008000, // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related?
+ SUMMON_PROP_FLAG_UNK17 = 0x00010000,
+ SUMMON_PROP_FLAG_UNK18 = 0x00020000,
+ SUMMON_PROP_FLAG_UNK19 = 0x00040000,
+ SUMMON_PROP_FLAG_UNK20 = 0x00080000,
+ SUMMON_PROP_FLAG_UNK21 = 0x00100000 // Totems
};
enum VehicleSeatFlags
@@ -442,4 +550,15 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000 // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
+// CurrencyTypes.dbc
+enum CurrencyTypes
+{
+ CURRENCY_TYPE_CONQUEST_POINTS = 390,
+ CURRENCY_TYPE_HONOR_POINTS = 392,
+ CURRENCY_TYPE_JUSTICE_POINTS = 395,
+ CURRENCY_TYPE_VALOR_POINTS = 396,
+ CURRENCY_TYPE_CONQUEST_META_ARENA = 483,
+ CURRENCY_TYPE_CONQUEST_META_RBG = 484,
+};
+
#endif
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index a4b3ded80e5..f05b2c714ce 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -22,6 +22,7 @@
#include "SpellMgr.h"
#include "TransportMgr.h"
#include "DBCfmt.h"
+#include "ItemPrototype.h"
#include "Timer.h"
#include "ObjectDefines.h"
@@ -60,6 +61,7 @@ static WMOAreaInfoByTripple sWMOAreaInfoByTripple;
DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt);
DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);
DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);
+DBCStorage <ArmorLocationEntry> sArmorLocationStore(ArmorLocationfmt);
DBCStorage <AuctionHouseEntry> sAuctionHouseStore(AuctionHouseEntryfmt);
DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);
DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore(BannedAddOnsfmt);
@@ -71,6 +73,7 @@ DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);
DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
+DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt);
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore(CreatureFamilyfmt);
@@ -78,6 +81,7 @@ DBCStorage <CreatureModelDataEntry> sCreatureModelDataStore(CreatureModelDatafmt
DBCStorage <CreatureSpellDataEntry> sCreatureSpellDataStore(CreatureSpellDatafmt);
DBCStorage <CreatureTypeEntry> sCreatureTypeStore(CreatureTypefmt);
DBCStorage <CurrencyTypesEntry> sCurrencyTypesStore(CurrencyTypesfmt);
+uint32 PowersByClass[MAX_CLASSES][MAX_POWERS];
DBCStorage <DestructibleModelDataEntry> sDestructibleModelDataStore(DestructibleModelDatafmt);
DBCStorage <DungeonEncounterEntry> sDungeonEncounterStore(DungeonEncounterfmt);
@@ -107,16 +111,36 @@ DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore(GtNPCManaCos
DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore(GtOCTClassCombatRatingScalarfmt);
DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore(GtOCTRegenHPfmt);
//DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore(GtOCTRegenMPfmt); -- not used currently
-DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore(GtRegenHPPerSptfmt);
+DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore(GtOCTHpPerStaminafmt);
DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore(GtRegenMPPerSptfmt);
+DBCStorage <GtSpellScalingEntry> sGtSpellScalingStore(GtSpellScalingfmt);
+DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore(GtOCTBaseHPByClassfmt);
+DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore(GtOCTBaseMPByClassfmt);
+DBCStorage <GuildPerkSpellsEntry> sGuildPerkSpellsStore(GuildPerkSpellsfmt);
DBCStorage <HolidaysEntry> sHolidaysStore(Holidaysfmt);
-DBCStorage <ItemEntry> sItemStore(Itemfmt);
+DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore(ImportPriceArmorfmt);
+DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore(ImportPriceQualityfmt);
+DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore(ImportPriceShieldfmt);
+DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore(ImportPriceWeaponfmt);
+DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore(ItemPriceBasefmt);
+DBCStorage <ItemReforgeEntry> sItemReforgeStore(ItemReforgefmt);
+DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore(ItemArmorQualityfmt);
+DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore(ItemArmorShieldfmt);
+DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore(ItemArmorTotalfmt);
+DBCStorage <ItemClassEntry> sItemClassStore(ItemClassfmt);
DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore(ItemBagFamilyfmt);
-//DBCStorage <ItemCondExtCostsEntry> sItemCondExtCostsStore(ItemCondExtCostsEntryfmt);
+DBCStorage <ItemDamageEntry> sItemDamageAmmoStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageOneHandStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageOneHandCasterStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageRangedStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageThrownStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageTwoHandStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageTwoHandCasterStore(ItemDamagefmt);
+DBCStorage <ItemDamageEntry> sItemDamageWandStore(ItemDamagefmt);
+DBCStorage <ItemDisenchantLootEntry> sItemDisenchantLootStore(ItemDisenchantLootfmt);
//DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore(ItemDisplayTemplateEntryfmt); -- not used currently
-DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore(ItemExtendedCostEntryfmt);
DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore(ItemLimitCategoryEntryfmt);
DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore(ItemRandomPropertiesfmt);
DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore(ItemRandomSuffixfmt);
@@ -134,6 +158,12 @@ DBCStorage <MapDifficultyEntry> sMapDifficultyStore(MapDifficultyEntryfmt); // o
MapDifficultyMap sMapDifficultyMap;
DBCStorage <MovieEntry> sMovieStore(MovieEntryfmt);
+DBCStorage <MountCapabilityEntry> sMountCapabilityStore(MountCapabilityfmt);
+DBCStorage <MountTypeEntry> sMountTypeStore(MountTypefmt);
+
+DBCStorage <NameGenEntry> sNameGenStore(NameGenfmt);
+NameGenVectorArraysMap sGenNameVectoArraysMap;
+DBCStorage <NumTalentsAtLevelEntry> sNumTalentsAtLevelStore(NumTalentsAtLevelfmt);
DBCStorage <OverrideSpellDataEntry> sOverrideSpellDataStore(OverrideSpellDatafmt);
@@ -157,20 +187,40 @@ DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt);
SpellCategoryStore sSpellsByCategoryStore;
PetFamilySpellsStore sPetFamilySpellsStore;
+
+DBCStorage <SpellReagentsEntry> sSpellReagentsStore(SpellReagentsEntryfmt);
+DBCStorage <SpellScalingEntry> sSpellScalingStore(SpellScalingEntryfmt);
+DBCStorage <SpellTotemsEntry> sSpellTotemsStore(SpellTotemsEntryfmt);
+DBCStorage <SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore(SpellTargetRestrictionsEntryfmt);
+DBCStorage <SpellPowerEntry> sSpellPowerStore(SpellPowerEntryfmt);
+DBCStorage <SpellLevelsEntry> sSpellLevelsStore(SpellLevelsEntryfmt);
+DBCStorage <SpellInterruptsEntry> sSpellInterruptsStore(SpellInterruptsEntryfmt);
+DBCStorage <SpellEquippedItemsEntry> sSpellEquippedItemsStore(SpellEquippedItemsEntryfmt);
+DBCStorage <SpellClassOptionsEntry> sSpellClassOptionsStore(SpellClassOptionsEntryfmt);
+DBCStorage <SpellCooldownsEntry> sSpellCooldownsStore(SpellCooldownsEntryfmt);
+DBCStorage <SpellAuraOptionsEntry> sSpellAuraOptionsStore(SpellAuraOptionsEntryfmt);
+DBCStorage <SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore(SpellAuraRestrictionsEntryfmt);
+DBCStorage <SpellCastingRequirementsEntry> sSpellCastingRequirementsStore(SpellCastingRequirementsEntryfmt);
DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore(SpellCastTimefmt);
+DBCStorage <SpellCategoriesEntry> sSpellCategoriesStore(SpellCategoriesEntryfmt);
DBCStorage <SpellCategoryEntry> sSpellCategoryStore(SpellCategoryfmt);
+DBCStorage <SpellEffectEntry> sSpellEffectStore(SpellEffectEntryfmt);
DBCStorage <SpellDifficultyEntry> sSpellDifficultyStore(SpellDifficultyfmt);
DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);
DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);
DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt);
DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt);
DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt);
-DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt);
+DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftEntryfmt);
+DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore(SpellShapeshiftFormfmt);
DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
+DBCStorage <TalentTreePrimarySpellsEntry> sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt);
+typedef std::map<uint32, std::vector<uint32> > TalentTreePrimarySpellsMap;
+TalentTreePrimarySpellsMap sTalentTreePrimarySpellsMap;
// store absolute bit position for first rank for talent inspect
static uint32 sTalentTabPages[MAX_CLASSES][3];
@@ -190,16 +240,17 @@ DBCStorage <TaxiPathEntry> sTaxiPathStore(TaxiPathEntryfmt);
TaxiPathNodesByPath sTaxiPathNodesByPath;
static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);
-DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore(TeamContributionPointsfmt);
DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt);
DBCStorage <TransportAnimationEntry> sTransportAnimationStore(TransportAnimationfmt);
DBCStorage <TransportRotationEntry> sTransportRotationStore(TransportRotationfmt);
+DBCStorage <UnitPowerBarEntry> sUnitPowerBarStore(UnitPowerBarfmt);
DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt);
DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);
DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore(WMOAreaTableEntryfmt);
DBCStorage <WorldMapAreaEntry> sWorldMapAreaStore(WorldMapAreaEntryfmt);
DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);
DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt);
+DBCStorage <PhaseEntry> sPhaseStores(PhaseEntryfmt);
typedef std::list<std::string> StoreProblemList;
@@ -284,39 +335,58 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex);
- LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex);//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sArmorLocationStore, dbcPath, "ArmorLocation.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sBannedAddOnsStore, dbcPath, "BannedAddOns.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc");//15595
for (uint32 i = 0; i < sCharStartOutfitStore.GetNumRows(); ++i)
if (CharStartOutfitEntry const* outfit = sCharStartOutfitStore.LookupEntry(i))
sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit;
- LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sChrPowerTypesStore, dbcPath, "ChrClassesXPowerTypes.dbc");//15595
+ for (uint32 i = 0; i < MAX_CLASSES; ++i)
+ for (uint32 j = 0; j < MAX_POWERS; ++j)
+ PowersByClass[i][j] = MAX_POWERS;
+
+ for (uint32 i = 0; i < sChrPowerTypesStore.GetNumRows(); ++i)
+ {
+ if (ChrPowerTypesEntry const* power = sChrPowerTypesStore.LookupEntry(i))
+ {
+ uint32 index = 0;
+ for (uint32 j = 0; j < MAX_POWERS; ++j)
+ if (PowersByClass[power->classId][j] != MAX_POWERS)
+ ++index;
+
+ PowersByClass[power->classId][power->power] = index;
+ }
+ }
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc");//15595
for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i)
{
FactionEntry const* faction = sFactionStore.LookupEntry(i);
@@ -327,8 +397,8 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc");//15595
for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i)
{
if (GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(i))
@@ -342,84 +412,155 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc");//15595
+ 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");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.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, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc");
-
- LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc");
-
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemStore, dbcPath, "Item.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc");
+ 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");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceArmorStore, dbcPath, "ImportPriceArmor.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceQualityStore, dbcPath, "ImportPriceQuality.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceShieldStore, dbcPath, "ImportPriceShield.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sImportPriceWeaponStore, dbcPath, "ImportPriceWeapon.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemPriceBaseStore, dbcPath, "ItemPriceBase.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemReforgeStore, dbcPath, "ItemReforge.dbc"); // 15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemClassStore, dbcPath, "ItemClass.dbc"); // 15595
//LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently
- //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");
-
- LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc");
-
- LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorQualityStore, dbcPath, "ItemArmorQuality.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorShieldStore, dbcPath, "ItemArmorShield.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorTotalStore, dbcPath, "ItemArmorTotal.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageAmmoStore, dbcPath, "ItemDamageAmmo.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageOneHandStore, dbcPath, "ItemDamageOneHand.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageOneHandCasterStore, dbcPath, "ItemDamageOneHandCaster.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageRangedStore, dbcPath, "ItemDamageRanged.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageThrownStore, dbcPath, "ItemDamageThrown.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageTwoHandStore, dbcPath, "ItemDamageTwoHand.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageTwoHandCasterStore, dbcPath, "ItemDamageTwoHandCaster.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDamageWandStore, dbcPath, "ItemDamageWand.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sItemDisenchantLootStore, dbcPath, "ItemDisenchantLoot.dbc");
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sPhaseStores, dbcPath, "Phase.dbc");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc");//15595
// fill data
- for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i)
+ sMapDifficultyMap[MAKE_PAIR32(0, 0)] = MapDifficulty(0, 0, false);//map 0 is missingg from MapDifficulty.dbc use this till its ported to sql
+ for (uint32 i = 0; i < sMapDifficultyStore.GetNumRows(); ++i)
if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i))
- sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0');
+ sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] > 0);
sMapDifficultyStore.Clear();
- LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMountCapabilityStore, dbcPath, "MountCapability.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMountTypeStore, dbcPath, "MountType.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sNameGenStore, dbcPath, "NameGen.dbc");//15595
+ for (uint32 i = 0; i < sNameGenStore.GetNumRows(); ++i)
+ if (NameGenEntry const* entry = sNameGenStore.LookupEntry(i))
+ sGenNameVectoArraysMap[entry->race].stringVectorArray[entry->gender].push_back(std::string(entry->name));
+ sNameGenStore.Clear();
+ LoadDBC(availableDbcLocales, bad_dbc_files, sNumTalentsAtLevelStore, dbcPath, "NumTalentsAtLevel.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc");//15595
for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i)
if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i))
if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS)
ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data");
- LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex);
+ LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex);//
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath,"SpellCategories.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoryStore, dbcPath, "SpellCategory.dbc");
for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
{
SpellEntry const* spell = sSpellStore.LookupEntry(i);
- if (spell && spell->Category)
- sSpellsByCategoryStore[spell->Category].insert(i);
+ if (!spell)
+ continue;
+
+ if (SpellCategoriesEntry const* category = sSpellCategoriesStore.LookupEntry(spell->SpellCategoriesId))
+ sSpellsByCategoryStore[category->Category].insert(i);
}
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellReagentsStore, dbcPath,"SpellReagents.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellScalingStore, dbcPath,"SpellScaling.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTotemsStore, dbcPath,"SpellTotems.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTargetRestrictionsStore, dbcPath,"SpellTargetRestrictions.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellPowerStore, dbcPath,"SpellPower.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellLevelsStore, dbcPath,"SpellLevels.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellInterruptsStore, dbcPath,"SpellInterrupts.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEquippedItemsStore, dbcPath,"SpellEquippedItems.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellClassOptionsStore, dbcPath,"SpellClassOptions.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCooldownsStore, dbcPath,"SpellCooldowns.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraOptionsStore, dbcPath,"SpellAuraOptions.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraRestrictionsStore, dbcPath,"SpellAuraRestrictions.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastingRequirementsStore, dbcPath,"SpellCastingRequirements.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEffectStore, dbcPath,"SpellEffect.dbc", &CustomSpellEffectEntryfmt, &CustomSpellEffectEntryIndex);//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex);//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshift.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftFormStore, dbcPath, "SpellShapeshiftForm.dbc");//15595
+ //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
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->SpellLevelsId);
+ if (spellInfo->SpellLevelsId && (!levels || levels->spellLevel))
+ continue;
if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
{
@@ -431,8 +572,6 @@ void LoadDBCStores(const std::string& dataPath)
if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1])
continue;
- if (spellInfo->spellLevel)
- continue;
if (skillLine->learnOnGetSkill != ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL)
continue;
@@ -442,21 +581,7 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoryStore, dbcPath, "SpellCategory.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex);
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshiftForm.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc");
-
- LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc");//15595
// Create Spelldifficulty searcher
for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i)
@@ -467,7 +592,7 @@ void LoadDBCStores(const std::string& dataPath)
SpellDifficultyEntry newEntry;
memset(newEntry.SpellID, 0, 4*sizeof(uint32));
- for (int x = 0; x < MAX_DIFFICULTY; ++x)
+ for (uint32 x = 0; x < MAX_DIFFICULTY; ++x)
{
if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x]))
{
@@ -478,10 +603,11 @@ void LoadDBCStores(const std::string& dataPath)
else
newEntry.SpellID[x] = spellDiff->SpellID[x];
}
+
if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set!
continue;
- for (int x = 0; x < MAX_DIFFICULTY; ++x)
+ for (uint32 x = 0; x < MAX_DIFFICULTY; ++x)
if (newEntry.SpellID[x])
sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID);
}
@@ -498,7 +624,7 @@ void LoadDBCStores(const std::string& dataPath)
sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j);
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc");//15595
// prepare fast data access to bit pos of talent ranks for use at inspecting
{
@@ -520,15 +646,21 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc");
+ for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i)
+ if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i))
+ sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId);
+ sTalentTreePrimarySpellsStore.Clear();
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc");//15595
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i))
sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price);
uint32 pathCount = sTaxiPathStore.GetNumRows();
//## TaxiPathNode.dbc ## Loaded only for initialization different structures
- LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc");//15595
// Calculate path nodes count
std::vector<uint32> pathLength;
pathLength.resize(pathCount); // 0 and some other indexes not used
@@ -551,11 +683,10 @@ void LoadDBCStores(const std::string& dataPath)
// include existed nodes that have at least single not spell base (scripted) path
{
std::set<uint32> spellPaths;
- for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
- if (SpellEntry const* sInfo = sSpellStore.LookupEntry (i))
- for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
- if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI)
- spellPaths.insert(sInfo->EffectMiscValue[j]);
+ for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i)
+ if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i))
+ if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI)
+ spellPaths.insert(sInfo->EffectMiscValue);
memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask));
memset(sOldContinentsNodesMask, 0, sizeof(sOldContinentsNodesMask));
@@ -587,10 +718,10 @@ void LoadDBCStores(const std::string& dataPath)
}
// valid taxi network node
- uint8 field = (uint8)((i - 1) / 32);
- uint32 submask = 1<<((i-1)%32);
- sTaxiNodesMask[field] |= submask;
+ uint8 field = (uint8)((i - 1) / 8);
+ uint32 submask = 1 << ((i-1) % 8);
+ sTaxiNodesMask[field] |= submask;
if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981)
sHordeTaxiNodesMask[field] |= submask;
if (node->MountCreatureID[1] && node->MountCreatureID[1] != 32981)
@@ -608,8 +739,8 @@ void LoadDBCStores(const std::string& dataPath)
}
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc");
+ //LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sTransportAnimationStore, dbcPath, "TransportAnimation.dbc");
for (uint32 i = 0; i < sTransportAnimationStore.GetNumRows(); ++i)
{
@@ -630,16 +761,18 @@ void LoadDBCStores(const std::string& dataPath)
sTransportMgr->AddPathRotationToTransport(rot->TransportEntry, rot->TimeSeg, rot);
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sUnitPowerBarStore, dbcPath, "UnitPowerBar.dbc");//15595
- LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc");//15595
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc");//15595
for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i)
if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i))
sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry));
- LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc");
- LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc");//15595
// error checks
if (bad_dbc_files.size() >= DBCFileCount)
@@ -658,20 +791,25 @@ void LoadDBCStores(const std::string& dataPath)
}
// Check loaded DBC files proper version
- if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.5a
- !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a
- !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a
- !sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a
- !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a
- !sMapStore.LookupEntry(724) || // last map added in 3.3.5a
- !sSpellStore.LookupEntry(80864) ) // last client known item added in 3.3.5a
+ if (!sAreaStore.LookupEntry(4713) || // last area (areaflag) added in 4.3.4 (15595)
+ !sCharTitlesStore.LookupEntry(287) || // last char title added in 4.3.4 (15595)
+ !sGemPropertiesStore.LookupEntry(2250) || // last gem property added in 4.3.4 (15595)
+ !sMapStore.LookupEntry(980) || // last map added in 4.3.4 (15595)
+ !sSpellStore.LookupEntry(121820) ) // last spell added in 4.3.4 (15595)
{
TC_LOG_ERROR("misc", "You have _outdated_ DBC files. Please extract correct versions from current using client.");
exit(1);
}
- TC_LOG_INFO("server.loading", ">> Initialized %d data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Initialized %d DBC data stores in %u ms", DBCFileCount, GetMSTimeDiffToNow(oldMSTime));
+}
+const std::string* GetRandomCharacterName(uint8 race, uint8 gender)
+{
+ uint32 size = sGenNameVectoArraysMap[race].stringVectorArray[gender].size();
+ uint32 randPos = urand(0, size-1);
+
+ return &sGenNameVectoArraysMap[race].stringVectorArray[gender][randPos];
}
SimpleFactionsList const* GetFactionTeamList(uint32 faction)
@@ -683,14 +821,14 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction)
return NULL;
}
-char* GetPetName(uint32 petfamily, uint32 dbclang)
+char const* GetPetName(uint32 petfamily, uint32 /*dbclang*/)
{
if (!petfamily)
return NULL;
CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(petfamily);
if (!pet_family)
return NULL;
- return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL;
+ return pet_family->Name ? pet_family->Name : NULL;
}
TalentSpellPos const* GetTalentSpellPos(uint32 spellId)
@@ -747,16 +885,16 @@ AreaTableEntry const* GetAreaEntryByAreaFlagAndMap(uint32 area_flag, uint32 map_
return NULL;
}
-char const* GetRaceName(uint8 race, uint8 locale)
+char const* GetRaceName(uint8 race, uint8 /*locale*/)
{
ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race);
- return raceEntry ? raceEntry->name[locale] : NULL;
+ return raceEntry ? raceEntry->name : NULL;
}
-char const* GetClassName(uint8 class_, uint8 locale)
+char const* GetClassName(uint8 class_, uint8 /*locale*/)
{
ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_);
- return classEntry ? classEntry->name[locale] : NULL;
+ return classEntry ? classEntry->name : NULL;
}
uint32 GetAreaFlagByMapId(uint32 mapid)
@@ -770,7 +908,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid)
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
{
- if (mapid != 530 && mapid != 571) // speed for most cases
+ if (mapid != 530 && mapid != 571 && mapid != 732) // speed for most cases
return mapid;
if (WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId))
@@ -779,6 +917,28 @@ uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
return mapid;
}
+uint32 GetMaxLevelForExpansion(uint32 expansion)
+{
+ switch (expansion)
+ {
+ case CONTENT_1_60:
+ return 60;
+ case CONTENT_61_70:
+ return 70;
+ case CONTENT_71_80:
+ return 80;
+ case CONTENT_81_85:
+ return 85;
+ default:
+ break;
+ }
+ return 0;
+}
+
+/*
+Used only for calculate xp gain by content lvl.
+Calculation on Gilneas and group maps of LostIslands calculated as CONTENT_1_60.
+*/
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
{
mapid = GetVirtualMapForMapAndZone(mapid, zoneId);
@@ -789,11 +949,17 @@ ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
if (!mapEntry)
return CONTENT_1_60;
- switch (mapEntry->Expansion())
+ // no need enum all maps from phasing
+ if (mapEntry->rootPhaseMap >= 0)
+ mapid = mapEntry->rootPhaseMap;
+
+ switch (mapid)
{
- default: return CONTENT_1_60;
- case 1: return CONTENT_61_70;
- case 2: return CONTENT_71_80;
+ case 648: //LostIslands
+ case 654: //Gilneas
+ return CONTENT_1_60;
+ default:
+ return ContentLevels(mapEntry->Expansion());
}
}
@@ -912,6 +1078,15 @@ uint32 const* GetTalentTabPages(uint8 cls)
return sTalentTabPages[cls];
}
+std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree)
+{
+ TalentTreePrimarySpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree);
+ if (itr == sTalentTreePrimarySpellsMap.end())
+ return NULL;
+
+ return &itr->second;
+}
+
uint32 GetLiquidFlags(uint32 liquidType)
{
if (LiquidTypeEntry const* liq = sLiquidTypeStore.LookupEntry(liquidType))
@@ -929,6 +1104,163 @@ CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, ui
return itr->second;
}
+uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId)
+{
+ return PowersByClass[classId][powerType];
+}
+
+uint32 ScalingStatValuesEntry::GetStatMultiplier(uint32 inventoryType) const
+{
+ if (inventoryType < MAX_INVTYPE)
+ {
+ switch (inventoryType)
+ {
+ case INVTYPE_NON_EQUIP:
+ case INVTYPE_BODY:
+ case INVTYPE_BAG:
+ case INVTYPE_TABARD:
+ case INVTYPE_AMMO:
+ case INVTYPE_QUIVER:
+ return 0;
+ case INVTYPE_HEAD:
+ case INVTYPE_CHEST:
+ case INVTYPE_LEGS:
+ case INVTYPE_2HWEAPON:
+ case INVTYPE_ROBE:
+ return StatMultiplier[0];
+ case INVTYPE_SHOULDERS:
+ case INVTYPE_WAIST:
+ case INVTYPE_FEET:
+ case INVTYPE_HANDS:
+ case INVTYPE_TRINKET:
+ return StatMultiplier[1];
+ case INVTYPE_NECK:
+ case INVTYPE_WRISTS:
+ case INVTYPE_FINGER:
+ case INVTYPE_SHIELD:
+ case INVTYPE_CLOAK:
+ case INVTYPE_HOLDABLE:
+ return StatMultiplier[2];
+ case INVTYPE_RANGED:
+ case INVTYPE_THROWN:
+ case INVTYPE_RANGEDRIGHT:
+ case INVTYPE_RELIC:
+ return StatMultiplier[3];
+ case INVTYPE_WEAPON:
+ case INVTYPE_WEAPONMAINHAND:
+ case INVTYPE_WEAPONOFFHAND:
+ return StatMultiplier[4];
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+uint32 ScalingStatValuesEntry::GetArmor(uint32 inventoryType, uint32 armorType) const
+{
+ if (inventoryType <= INVTYPE_ROBE && armorType < 4)
+ {
+ switch (inventoryType)
+ {
+ case INVTYPE_NON_EQUIP:
+ case INVTYPE_NECK:
+ case INVTYPE_BODY:
+ case INVTYPE_FINGER:
+ case INVTYPE_TRINKET:
+ case INVTYPE_WEAPON:
+ case INVTYPE_SHIELD:
+ case INVTYPE_RANGED:
+ case INVTYPE_2HWEAPON:
+ case INVTYPE_BAG:
+ case INVTYPE_TABARD:
+ break;
+ case INVTYPE_SHOULDERS:
+ return Armor[0][armorType];
+ case INVTYPE_CHEST:
+ case INVTYPE_ROBE:
+ return Armor[1][armorType];
+ case INVTYPE_HEAD:
+ return Armor[2][armorType];
+ case INVTYPE_LEGS:
+ return Armor[3][armorType];
+ case INVTYPE_FEET:
+ return Armor[4][armorType];
+ case INVTYPE_WAIST:
+ return Armor[5][armorType];
+ case INVTYPE_HANDS:
+ return Armor[6][armorType];
+ case INVTYPE_WRISTS:
+ return Armor[7][armorType];
+ case INVTYPE_CLOAK:
+ return CloakArmor;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+
+uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const
+{
+ if (!isCasterWeapon)
+ {
+ switch (subClass)
+ {
+ case ITEM_SUBCLASS_WEAPON_AXE:
+ case ITEM_SUBCLASS_WEAPON_MACE:
+ case ITEM_SUBCLASS_WEAPON_SWORD:
+ case ITEM_SUBCLASS_WEAPON_DAGGER:
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ *damageMultiplier = 0.3f;
+ return dpsMod[0];
+ case ITEM_SUBCLASS_WEAPON_AXE2:
+ case ITEM_SUBCLASS_WEAPON_MACE2:
+ case ITEM_SUBCLASS_WEAPON_POLEARM:
+ case ITEM_SUBCLASS_WEAPON_SWORD2:
+ case ITEM_SUBCLASS_WEAPON_STAFF:
+ case ITEM_SUBCLASS_WEAPON_FISHING_POLE:
+ *damageMultiplier = 0.2f;
+ return dpsMod[1];
+ case ITEM_SUBCLASS_WEAPON_BOW:
+ case ITEM_SUBCLASS_WEAPON_GUN:
+ case ITEM_SUBCLASS_WEAPON_CROSSBOW:
+ *damageMultiplier = 0.3f;
+ return dpsMod[4];
+ case ITEM_SUBCLASS_WEAPON_Obsolete:
+ case ITEM_SUBCLASS_WEAPON_EXOTIC:
+ case ITEM_SUBCLASS_WEAPON_EXOTIC2:
+ case ITEM_SUBCLASS_WEAPON_FIST_WEAPON:
+ case ITEM_SUBCLASS_WEAPON_MISCELLANEOUS:
+ case ITEM_SUBCLASS_WEAPON_SPEAR:
+ case ITEM_SUBCLASS_WEAPON_WAND:
+ break;
+ }
+ }
+ else
+ {
+ if (subClass <= ITEM_SUBCLASS_WEAPON_WAND)
+ {
+ uint32 mask = 1 << subClass;
+ // two-handed weapons
+ if (mask & 0x562)
+ {
+ *damageMultiplier = 0.2f;
+ return dpsMod[3];
+ }
+
+ if (mask & (1 << ITEM_SUBCLASS_WEAPON_WAND))
+ {
+ *damageMultiplier = 0.3f;
+ return dpsMod[5];
+ }
+ }
+ *damageMultiplier = 0.3f;
+ return dpsMod[2];
+ }
+ return 0;
+}
+
/// Returns LFGDungeonEntry for a specific map and difficulty. Will return first found entry if multiple dungeons use the same map (such as Scarlet Monastery)
LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty)
{
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index fe8fb35220b..e12d0ea45ac 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -28,7 +28,7 @@
typedef std::list<uint32> SimpleFactionsList;
SimpleFactionsList const* GetFactionTeamList(uint32 faction);
-char* GetPetName(uint32 petfamily, uint32 dbclang);
+char const* GetPetName(uint32 petfamily, uint32 dbclang);
uint32 GetTalentSpellCost(uint32 spellId);
TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
@@ -44,12 +44,19 @@ WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId);
+const std::string* GetRandomCharacterName(uint8 race, uint8 gender);
+
enum ContentLevels
{
- CONTENT_1_60 = 0,
- CONTENT_61_70,
- CONTENT_71_80
+ CONTENT_1_60 = 0,
+ CONTENT_61_70 = 1,
+ CONTENT_71_80 = 2,
+ CONTENT_81_85 = 3,
+ MAX_CONTENT
};
+
+uint32 GetMaxLevelForExpansion(uint32 expansion);
+
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId);
bool IsTotemCategoryCompatiableWith(uint32 itemTotemCategoryId, uint32 requiredTotemCategoryId);
@@ -62,6 +69,7 @@ MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty);
uint32 const* /*[MAX_TALENT_TABS]*/ GetTalentTabPages(uint8 cls);
+std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree);
uint32 GetLiquidFlags(uint32 liquidType);
@@ -70,6 +78,7 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB
CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, uint8 gender);
+uint32 GetPowerIndexByClass(uint32 powerType, uint32 classId);
LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty);
extern DBCStorage <AchievementEntry> sAchievementStore;
@@ -78,6 +87,7 @@ extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access
extern DBCStorage <AreaGroupEntry> sAreaGroupStore;
extern DBCStorage <AreaPOIEntry> sAreaPOIStore;
extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore;
+extern DBCStorage <ArmorLocationEntry> sArmorLocationStore;
extern DBCStorage <AuctionHouseEntry> sAuctionHouseStore;
extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore;
extern DBCStorage <BannedAddOnsEntry> sBannedAddOnsStore;
@@ -88,6 +98,7 @@ extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore;
extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
+extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore;
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
extern DBCStorage <CreatureFamilyEntry> sCreatureFamilyStore;
@@ -116,15 +127,35 @@ extern DBCStorage <GtChanceToSpellCritBaseEntry> sGtChanceToSpellCritBaseStore;
extern DBCStorage <GtChanceToSpellCritEntry> sGtChanceToSpellCritStore;
extern DBCStorage <GtNPCManaCostScalerEntry> sGtNPCManaCostScalerStore;
extern DBCStorage <GtOCTClassCombatRatingScalarEntry> sGtOCTClassCombatRatingScalarStore;
-extern DBCStorage <GtOCTRegenHPEntry> sGtOCTRegenHPStore;
//extern DBCStorage <GtOCTRegenMPEntry> sGtOCTRegenMPStore; -- not used currently
-extern DBCStorage <GtRegenHPPerSptEntry> sGtRegenHPPerSptStore;
+extern DBCStorage <gtOCTHpPerStaminaEntry> sGtOCTHpPerStaminaStore;
extern DBCStorage <GtRegenMPPerSptEntry> sGtRegenMPPerSptStore;
+extern DBCStorage <GtSpellScalingEntry> sGtSpellScalingStore;
+extern DBCStorage <GtOCTBaseHPByClassEntry> sGtOCTBaseHPByClassStore;
+extern DBCStorage <GtOCTBaseMPByClassEntry> sGtOCTBaseMPByClassStore;
+extern DBCStorage <GuildPerkSpellsEntry> sGuildPerkSpellsStore;
extern DBCStorage <HolidaysEntry> sHolidaysStore;
-extern DBCStorage <ItemEntry> sItemStore;
+extern DBCStorage <ImportPriceArmorEntry> sImportPriceArmorStore;
+extern DBCStorage <ImportPriceQualityEntry> sImportPriceQualityStore;
+extern DBCStorage <ImportPriceShieldEntry> sImportPriceShieldStore;
+extern DBCStorage <ImportPriceWeaponEntry> sImportPriceWeaponStore;
+extern DBCStorage <ItemPriceBaseEntry> sItemPriceBaseStore;
+extern DBCStorage <ItemReforgeEntry> sItemReforgeStore;
+extern DBCStorage <ItemArmorQualityEntry> sItemArmorQualityStore;
+extern DBCStorage <ItemArmorShieldEntry> sItemArmorShieldStore;
+extern DBCStorage <ItemArmorTotalEntry> sItemArmorTotalStore;
+extern DBCStorage <ItemClassEntry> sItemClassStore;
extern DBCStorage <ItemBagFamilyEntry> sItemBagFamilyStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageAmmoStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageOneHandStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageOneHandCasterStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageRangedStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageThrownStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageTwoHandStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageTwoHandCasterStore;
+extern DBCStorage <ItemDamageEntry> sItemDamageWandStore;
//extern DBCStorage <ItemDisplayInfoEntry> sItemDisplayInfoStore; -- not used currently
-extern DBCStorage <ItemExtendedCostEntry> sItemExtendedCostStore;
+extern DBCStorage <ItemDisenchantLootEntry> sItemDisenchantLootStore;
extern DBCStorage <ItemLimitCategoryEntry> sItemLimitCategoryStore;
extern DBCStorage <ItemRandomPropertiesEntry> sItemRandomPropertiesStore;
extern DBCStorage <ItemRandomSuffixEntry> sItemRandomSuffixStore;
@@ -134,6 +165,11 @@ extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore;
extern DBCStorage <LockEntry> sLockStore;
extern DBCStorage <MailTemplateEntry> sMailTemplateStore;
extern DBCStorage <MapEntry> sMapStore;
+extern DBCStorage <MountCapabilityEntry> sMountCapabilityStore;
+extern DBCStorage <MountTypeEntry> sMountTypeStore;
+extern DBCStorage <NameGenEntry> sNameGenStore;
+extern DBCStorage <NumTalentsAtLevelEntry> sNumTalentsAtLevelStore;
+extern DBCStorage <PhaseEntry> sPhaseStore;
//extern DBCStorage <MapDifficultyEntry> sMapDifficultyStore; -- use GetMapDifficultyData insteed
extern MapDifficultyMap sMapDifficultyMap;
extern DBCStorage <MovieEntry> sMovieStore;
@@ -160,8 +196,24 @@ extern DBCStorage <SpellRadiusEntry> sSpellRadiusStore;
extern DBCStorage <SpellRangeEntry> sSpellRangeStore;
extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
+extern DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore;
extern DBCStorage <SpellEntry> sSpellStore;
-extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
+extern DBCStorage <SpellAuraOptionsEntry> sSpellAuraOptionsStore;
+extern DBCStorage <SpellAuraRestrictionsEntry> sSpellAuraRestrictionsStore;
+extern DBCStorage <SpellCastingRequirementsEntry> sSpellCastingRequirementsStore;
+extern DBCStorage <SpellCategoriesEntry> sSpellCategoriesStore;
+extern DBCStorage <SpellClassOptionsEntry> sSpellClassOptionsStore;
+extern DBCStorage <SpellCooldownsEntry> sSpellCooldownsStore;
+extern DBCStorage <SpellEffectEntry> sSpellEffectStore;
+extern DBCStorage <SpellEquippedItemsEntry> sSpellEquippedItemsStore;
+extern DBCStorage <SpellInterruptsEntry> sSpellInterruptsStore;
+extern DBCStorage <SpellLevelsEntry> sSpellLevelsStore;
+extern DBCStorage <SpellPowerEntry> sSpellPowerStore;
+extern DBCStorage <SpellReagentsEntry> sSpellReagentsStore;
+extern DBCStorage <SpellScalingEntry> sSpellScalingStore;
+extern DBCStorage <SpellTargetRestrictionsEntry> sSpellTargetRestrictionsStore;
+extern DBCStorage <SpellTotemsEntry> sSpellTotemsStore;
+//extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <TalentEntry> sTalentStore;
extern DBCStorage <TalentTabEntry> sTalentTabStore;
@@ -174,8 +226,8 @@ extern TaxiMask sAllianceTaxiNodesMask;
extern TaxiMask sDeathKnightTaxiNodesMask;
extern TaxiPathSetBySource sTaxiPathSetBySource;
extern TaxiPathNodesByPath sTaxiPathNodesByPath;
-extern DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore;
extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore;
+extern DBCStorage <UnitPowerBarEntry> sUnitPowerBarStore;
extern DBCStorage <VehicleEntry> sVehicleStore;
extern DBCStorage <VehicleSeatEntry> sVehicleSeatStore;
extern DBCStorage <WMOAreaTableEntry> sWMOAreaTableStore;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 7fb82ac8e03..6b08fed517a 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -44,35 +44,31 @@ struct AchievementEntry
int32 requiredFaction; // 1 -1=all, 0=horde, 1=alliance
int32 mapID; // 2 -1=none
//uint32 parentAchievement; // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin)
- char *name[16]; // 4-19
- //uint32 name_flags; // 20
- //char *description[16]; // 21-36
- //uint32 desc_flags; // 37
- uint32 categoryId; // 38
- uint32 points; // 39 reward points
- //uint32 OrderInCategory; // 40
- uint32 flags; // 41
- //uint32 icon; // 42 icon (from SpellIcon.dbc)
- //char *titleReward[16]; // 43-58
- //uint32 titleReward_flags; // 59
- uint32 count; // 60 - need this count of completed criterias (own or referenced achievement criterias)
- uint32 refAchievement; // 61 - referenced achievement (counting of all completed criterias)
+ char* name; // 4
+ //char* description; // 5
+ uint32 categoryId; // 6
+ uint32 points; // 7 reward points
+ //uint32 OrderInCategory; // 8
+ uint32 flags; // 9
+ //uint32 icon; // 10 icon (from SpellIcon.dbc)
+ //char* reward; // 11
+ uint32 count; // 12 - need this count of completed criterias (own or referenced achievement criterias)
+ uint32 refAchievement; // 13 - referenced achievement (counting of all completed criterias)
};
struct AchievementCategoryEntry
{
uint32 ID; // 0
uint32 parentCategory; // 1 -1 for main category
- //char *name[16]; // 2-17
- //uint32 name_flags; // 18
- //uint32 sortOrder; // 19
+ //char* name; // 2
+ //uint32 sortOrder; // 3
};
struct AchievementCriteriaEntry
{
uint32 ID; // 0
- uint32 referredAchievement; // 1
- uint32 requiredType; // 2
+ uint32 achievement; // 1
+ uint32 type; // 2
union
{
// ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0
@@ -91,6 +87,7 @@ struct AchievementCriteriaEntry
} win_bg;
// ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5
+ // ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL = 125
struct
{
uint32 unused; // 3
@@ -131,6 +128,13 @@ struct AchievementCriteriaEntry
uint32 questCount; // 4
} complete_quests_in_zone;
+ // ACHIEVEMENT_CRITERIA_TYPE_CURRENCY = 12
+ struct
+ {
+ uint32 currency;
+ uint32 count;
+ } currencyGain;
+
// ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14
struct
{
@@ -261,7 +265,14 @@ struct AchievementCriteriaEntry
struct
{
uint32 teamtype; // 3 {2, 3, 5}
- uint32 PersonalRating; // 4
+ uint32 teamrating; // 4
+ } reach_team_rating;
+
+ // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_PERSONAL_RATING = 39
+ struct
+ {
+ uint32 teamtype; // 3 {2, 3, 5}
+ uint32 PersonalRating; // 4
} highest_personal_rating;
// ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40
@@ -371,6 +382,7 @@ struct AchievementCriteriaEntry
} do_emote;
// ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13
// ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55
+ // ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56
struct
{
uint32 unused; // 3
@@ -499,21 +511,27 @@ struct AchievementCriteriaEntry
} raw;
};
+ //uint32 unk; // 5
+
struct
{
uint32 additionalRequirement_type;
uint32 additionalRequirement_value;
} additionalRequirements[MAX_CRITERIA_REQUIREMENTS];
- //char* name[16]; // 9-24
- //uint32 name_flags; // 25
- uint32 flags; // 26
- uint32 timedType; // 27
- uint32 timerStartEvent; // 28 Alway appears with timed events
- // for timed spells it is spell id for
- // timed kills it is creature id
- uint32 timeLimit; // 29 time limit in seconds
- //uint32 showOrder; // 30 show order
+ char* name; // 10 m_description_lang
+ uint32 completionFlag; // 11 m_flags
+ uint32 timedCriteriaStartType; // 12 m_timer_start_event Only appears with timed achievements, seems to be the type of starting a timed Achievement, only type 1 and some of type 6 need manual starting
+ // 1: ByEventId(?) (serverside IDs), 2: ByQuestId, 5: ByCastSpellId(?)
+ // 6: BySpellIdTarget(some of these are unknown spells, some not, some maybe spells)
+ // 7: ByKillNpcId, 9: ByUseItemId
+ uint32 timedCriteriaMiscId; // 13 m_timer_asset_id Alway appears with timed events, used internally to start the achievement, store
+ uint32 timeLimit; // 14 m_timer_time time limit in seconds
+ uint32 showOrder; // 15 m_ui_order also used in achievement shift-links as index in state bitmask
+ //uint32 unk1; // 16 only one value, still unknown
+ //uint32 unk2; // 17 all zeros
+ uint32 additionalConditionType[MAX_ADDITIONAL_CRITERIA_CONDITIONS]; // 18-20
+ uint32 additionalConditionValue[MAX_ADDITIONAL_CRITERIA_CONDITIONS - 1]; // 21-22 WTF one column was cut off here in 4.3.4
};
struct AreaTableEntry
@@ -522,13 +540,25 @@ struct AreaTableEntry
uint32 mapid; // 1
uint32 zone; // 2 if 0 then it's zone, else it's zone id of this area
uint32 exploreFlag; // 3, main index
- uint32 flags; // 4, unknown value but 312 for all cities
- // 5-9 unused
+ uint32 flags; // 4,
+ //uint32 unk5; // 5,
+ //uint32 unk6; // 6,
+ //uint32 unk7; // 7,
+ //uint32 unk8; // 8,
+ //uint32 unk9; // 9,
int32 area_level; // 10
- char* area_name[16]; // 11-26
- // 27, string flags, unused
- uint32 team; // 28
- uint32 LiquidTypeOverride[4]; // 29-32 liquid override by type
+ char* area_name; // 11
+ uint32 team; // 12
+ uint32 LiquidTypeOverride[4]; // 13-16 liquid override by type
+ float MaxDepth; // 17,
+ float AmbientMultiplier; // 18 client only?
+ uint32 LightId; // 19
+ //uint32 unk20; // 20 4.0.0 - Mounting related
+ //uint32 unk21; // 21 4.0.0
+ //uint32 unk22; // 22 4.0.0
+ //uint32 unk23; // 23 4.0.0
+ //uint32 unk24; // 24 - worldStateId
+ //uint32 unk25 // 25
// helpers
bool IsSanctuary() const
@@ -554,16 +584,14 @@ struct AreaPOIEntry
uint32 icon[11]; //1-11
float x; //12
float y; //13
- float z; //14
- uint32 mapId; //15
- //uint32 val1; //16
- uint32 zoneId; //17
- //char* name[16]; //18-33
- //uint32 name_flag; //34
- //char* name2[16]; //35-50
- //uint32 name_flag2; //51
- uint32 worldState; //52
- //uint32 val2; //53
+ uint32 mapId; //14
+ //uint32 val1; //15
+ uint32 zoneId; //16
+ //char* name; //17 - name
+ //char* name2; //18 - name2
+ uint32 worldState; //19
+ //uint32 val2; //20
+ //uint32 unk; //21
};
struct AreaTriggerEntry
@@ -573,11 +601,20 @@ struct AreaTriggerEntry
float x; // 2 m_x
float y; // 3 m_y
float z; // 4 m_z
- float radius; // 5 m_radius
- float box_x; // 6 m_box_length
- float box_y; // 7 m_box_width
- float box_z; // 8 m_box_heigh
- float box_orientation; // 9 m_box_yaw
+ //uint32 // 5
+ //uint32 // 6
+ //uint32 // 7
+ float radius; // 8 m_radius
+ float box_x; // 9 m_box_length
+ float box_y; // 10 m_box_width
+ float box_z; // 11 m_box_heigh
+ float box_orientation; // 12 m_box_yaw
+};
+
+struct ArmorLocationEntry
+{
+ uint32 InventoryType; // 0
+ float Value[5]; // 1-5 multiplier for armor types (cloth...plate, no armor?)
};
struct AuctionHouseEntry
@@ -586,8 +623,7 @@ struct AuctionHouseEntry
uint32 faction; // 1 id of faction.dbc for player factions associated with city
uint32 depositPercent; // 2 1/3 from real
uint32 cutPercent; // 3
- //char* name[16]; // 4-19
- // 20 string flag, unused
+ //char* name; // 4
};
struct BankBagSlotPricesEntry
@@ -609,14 +645,12 @@ struct BarberShopStyleEntry
{
uint32 Id; // 0
uint32 type; // 1 value 0 -> hair, value 2 -> facialhair
- //char* name[16]; // 2-17 name of hair style
- //uint32 name_flags; // 18
- //uint32 unk_name[16]; // 19-34, all empty
- //uint32 unk_flags; // 35
- //float CostMultiplier; // 36 values 1 and 0.75
- uint32 race; // 37 race
- uint32 gender; // 38 0 -> male, 1 -> female
- uint32 hair_id; // 39 real ID to hair/facial hair
+ //char* name; // 2 m_DisplayName_lang
+ //uint32 unk_name; // 3 m_Description_lang
+ //float CostMultiplier; // 4 m_Cost_Modifier
+ uint32 race; // 5 m_race
+ uint32 gender; // 6 m_sex
+ uint32 hair_id; // 7 m_data (real ID to hair/facial hair)
};
struct BattlemasterListEntry
@@ -625,12 +659,15 @@ struct BattlemasterListEntry
int32 mapid[8]; // 1-8 mapid
uint32 type; // 9 (3 - BG, 4 - arena)
//uint32 canJoinAsGroup; // 10 (0 or 1)
- char* name[16]; // 11-26
- //uint32 nameFlags // 27 string flag, unused
- uint32 maxGroupSize; // 28 maxGroupSize, used for checking if queue as group
- uint32 HolidayWorldStateId; // 29 new 3.1
- //uint32 MinLevel; // 30
- //uint32 SomeLevel; // 31, may be max level
+ char* name; // 11
+ uint32 maxGroupSize; // 12 maxGroupSize, used for checking if queue as group
+ uint32 HolidayWorldStateId; // 13 new 3.1
+ uint32 minLevel; // 14, min level (sync with PvPDifficulty.dbc content)
+ uint32 maxLevel; // 15, max level (sync with PvPDifficulty.dbc content)
+ //uint32 maxGroupSizeRated; // 16 4.0.1
+ //uint32 unk; // 17 - 4.0.6.13596
+ //uint32 maxPlayers; // 18 4.0.1
+ //uint32 unk1; // 19 4.0.3, value 2 for Rated Battlegrounds
};
#define MAX_OUTFIT_ITEMS 24
@@ -645,46 +682,45 @@ struct CharStartOutfitEntry
int32 ItemId[MAX_OUTFIT_ITEMS]; // 5-28
//int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 29-52 not required at server side
//int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 53-76 not required at server side
+ uint32 PetDisplayId; // 77 Pet Model ID for starting pet
+ uint32 PetFamilyEntry; // 78 Pet Family Entry for starting pet
};
struct CharTitlesEntry
{
uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId()
//uint32 unk1; // 1 flags?
- char* name[16]; // 2-17
- // 18 string flag, unused
- //char* name2[16]; // 19-34, unused
- // 35 string flag, unused
- uint32 bit_index; // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES
+ char* name; // 2 m_name_lang
+ //char* name2; // 3 m_name1_lang
+ uint32 bit_index; // 4 m_mask_ID used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES
+ //uint32 // 5
};
struct ChatChannelsEntry
{
uint32 ChannelID; // 0
uint32 flags; // 1
- char* pattern[16]; // 3-18
- // 19 string flags, unused
- //char* name[16]; // 20-35 unused
- // 36 string flag, unused
+ //uint32 // 2 m_factionGroup
+ char* pattern; // 3 m_name_lang
+ //char* name; // 4 m_shortcut_lang
};
struct ChrClassesEntry
{
uint32 ClassID; // 0
- // 1, unused
- uint32 powerType; // 2
- // 3-4, unused
- char* name[16]; // 5-20 unused
- // 21 string flag, unused
- //char* nameFemale[16]; // 21-36 unused, if different from base (male) case
- // 37 string flag, unused
- //char* nameNeutralGender[16]; // 38-53 unused, if different from base (male) case
- // 54 string flag, unused
- // 55, unused
- uint32 spellfamily; // 56
- // 57, unused
- uint32 CinematicSequence; // 58 id from CinematicSequences.dbc
- uint32 expansion; // 59 (0 - original race, 1 - tbc addon, ...)
+ uint32 powerType; // 1 m_DisplayPower
+ // 2 m_petNameToken
+ char* name; // 3 m_name_lang
+ //char* nameFemale; // 4 m_name_female_lang
+ //char* nameNeutralGender; // 5 m_name_male_lang
+ //char* capitalizedName // 6, m_filename
+ uint32 spellfamily; // 7 m_spellClassSet
+ //uint32 flags2; // 8 m_flags (0x08 HasRelicSlot)
+ uint32 CinematicSequence; // 9 m_cinematicSequenceID
+ uint32 expansion; // 10 m_required_expansion
+ uint32 APPerStrenth; // 11 Attack Power bonus per point of strength
+ uint32 APPerAgility; // 12 Attack Power bonus per point of agility
+ uint32 RAPPerAgility; // 13 Ranged Attack Power bonus per point of agility
};
struct ChrRacesEntry
@@ -699,15 +735,23 @@ struct ChrRacesEntry
uint32 TeamID; // 7 (7-Alliance 1-Horde)
// 8-11 unused
uint32 CinematicSequence; // 12 id from CinematicSequences.dbc
- //uint32 unk_322; // 13 faction (0 alliance, 1 horde, 2 not available?)
- char* name[16]; // 14-29 used for DBC language detection/selection
- // 30 string flags, unused
- //char* nameFemale[16]; // 31-46, if different from base (male) case
- // 47 string flags, unused
- //char* nameNeutralGender[16]; // 48-63, if different from base (male) case
- // 64 string flags, unused
- // 65-67 unused
- uint32 expansion; // 68 (0 - original race, 1 - tbc addon, ...)
+ //uint32 unk_322; // 13 m_alliance (0 alliance, 1 horde, 2 not available?)
+ char* name; // 14 m_name_lang used for DBC language detection/selection
+ //char* nameFemale; // 15 m_name_female_lang
+ //char* nameNeutralGender; // 16 m_name_male_lang
+ // 17-18 m_facialHairCustomization[2]
+ // 19 m_hairCustomization
+ uint32 expansion; // 20 m_required_expansion
+ //uint32 // 21 (23 for worgens)
+ //uint32 // 22 4.0.0
+ //uint32 // 23 4.0.0
+};
+
+struct ChrPowerTypesEntry
+{
+ uint32 entry; // 0
+ uint32 classId; // 1
+ uint32 power; // 2
};
/* not used
@@ -747,6 +791,7 @@ struct CreatureDisplayInfoEntry
// 13 m_particleColorID
// 14 m_creatureGeosetData
// 15 m_objectEffectPackageID
+ // 16
};
struct CreatureFamilyEntry
@@ -760,18 +805,17 @@ struct CreatureFamilyEntry
uint32 petFoodMask; // 7 m_petFoodMask
int32 petTalentType; // 8 m_petTalentType
// 9 m_categoryEnumID
- char* Name[16]; // 10-25 m_name_lang
- // 26 string flags
- // 27 m_iconFile
+ char* Name; // 10 m_name_lang
+ // 11 m_iconFile
};
struct CreatureModelDataEntry
{
uint32 Id;
//uint32 Flags;
- //char* ModelPath[16]
+ //char* ModelPath
//uint32 Unk1;
- float Scale; // Used in calculation of unit collision data
+ //float Scale; // Used in calculation of unit collision data
//int32 Unk2
//int32 Unk3
//uint32 Unk4
@@ -799,9 +843,8 @@ struct CreatureSpellDataEntry
struct CreatureTypeEntry
{
uint32 ID; // 0 m_ID
- //char* Name[16]; // 1-16 name
- // 17 string flags
- //uint32 no_expirience; // 18 no exp? critters, non-combat pets, gas cloud.
+ //char* Name; // 1 m_name_lang
+ //uint32 no_expirience; // 2 m_flags no exp? critters, non-combat pets, gas cloud.
};
/* not used
@@ -816,43 +859,55 @@ struct CurrencyCategoryEntry
struct CurrencyTypesEntry
{
- //uint32 ID; // 0 not used
- uint32 ItemId; // 1 used as real index
- //uint32 Category; // 2 may be category
- uint32 BitIndex; // 3 bit index in PLAYER_FIELD_KNOWN_CURRENCIES (1 << (index-1))
+ uint32 ID; // 0 not used
+ uint32 Category; // 1 may be category
+ //char* name; // 2
+ //char* iconName; // 3
+ //uint32 unk4; // 4 all 0
+ uint32 HasSubstitution; // 5 archaeology-related (?)
+ uint32 SubstitutionId; // 6
+ uint32 TotalCap; // 7
+ uint32 WeekCap; // 8
+ uint32 Flags; // 9
+ //char* description; // 10
};
struct DestructibleModelDataEntry
{
uint32 Id;
+ uint32 DamagedDisplayId;
//uint32 DamagedUnk1;
//uint32 DamagedUnk2;
- uint32 DamagedDisplayId;
//uint32 DamagedUnk3;
+ uint32 DestroyedDisplayId;
//uint32 DestroyedUnk1;
//uint32 DestroyedUnk2;
- uint32 DestroyedDisplayId;
//uint32 DestroyedUnk3;
+ //uint32 DestroyedUnk4;
+ uint32 RebuildingDisplayId;
//uint32 RebuildingUnk1;
//uint32 RebuildingUnk2;
- uint32 RebuildingDisplayId;
//uint32 RebuildingUnk3;
+ //uint32 RebuildingUnk4;
+ uint32 SmokeDisplayId;
//uint32 SmokeUnk1;
//uint32 SmokeUnk2;
- uint32 SmokeDisplayId;
//uint32 SmokeUnk3;
- //uint32 Unk4;
- //uint32 Unk5;
+ //uint32 SmokeUnk4;
+ //uint32 UnkDisplayid;
+ //uint32 Unk6;
+ //uint32 Unk7;
+ //uint32 Unk8;
};
struct DungeonEncounterEntry
{
uint32 id; // 0 unique id
uint32 mapId; // 1 map id
- uint32 difficulty; // 2 instance mode
+ int32 difficulty; // 2 instance mode
//uint32 unk0; // 3
uint32 encounterIndex; // 4 encounter index for creating completed mask
- char* encounterName[16]; // 5-20 encounter name
+ char* encounterName; // 5 encounter name
//uint32 nameFlags; // 21
//uint32 unk1; // 22
};
@@ -872,12 +927,13 @@ struct DurabilityQualityEntry
struct EmotesEntry
{
uint32 Id; // 0
- //char* Name; // 1, internal name
- //uint32 AnimationId; // 2, ref to animationData
+ //char* Name; // 1, internal name
+ //uint32 AnimationId; // 2, ref to animationData
uint32 Flags; // 3, bitmask, may be unit_flags
uint32 EmoteType; // 4, Can be 0, 1 or 2 (determine how emote are shown)
uint32 UnitStandState; // 5, uncomfirmed, may be enum UnitStandStateType
- //uint32 SoundId; // 6, ref to soundEntries
+ //uint32 SoundId; // 6, ref to soundEntries
+ //uint32 unk7 // 7
};
struct EmotesTextEntry
@@ -899,10 +955,9 @@ struct FactionEntry
float spilloverRateOut; // 20 Faction outputs rep * spilloverRateOut as spillover reputation
uint32 spilloverMaxRankIn; // 21 The highest rank the faction will profit from incoming spillover
//uint32 spilloverRank_unk; // 22 It does not seem to be the max standing at which a faction outputs spillover ...so no idea
- char* name[16]; // 23-38 m_name_lang
- // 39 string flags
- //char* description[16]; // 40-55 m_description_lang
- // 56 string flags
+ char* name; // 23 m_name_lang
+ //char* description; // 24 m_description_lang
+ uint32 GroupExpansion; // 25 m_factionGroupExpansion
// helpers
bool CanHaveReputation() const
@@ -928,6 +983,8 @@ struct FactionTemplateEntry
// helpers
bool IsFriendlyTo(FactionTemplateEntry const& entry) const
{
+ if (ID == entry.ID)
+ return true;
if (entry.faction)
{
for (int i = 0; i < MAX_FACTION_RELATIONS; ++i)
@@ -941,6 +998,8 @@ struct FactionTemplateEntry
}
bool IsHostileTo(FactionTemplateEntry const& entry) const
{
+ if (ID == entry.ID)
+ return false;
if (entry.faction)
{
for (int i = 0; i < MAX_FACTION_RELATIONS; ++i)
@@ -966,22 +1025,25 @@ struct FactionTemplateEntry
struct GameObjectDisplayInfoEntry
{
uint32 Displayid; // 0 m_ID
- char* filename; // 1
- //uint32 unk1[10]; //2-11
+ char* filename; // 1
+ //uint32 unk1[10]; //2-11
float minX;
float minY;
float minZ;
float maxX;
float maxY;
float maxZ;
- //uint32 transport; //18
+ //uint32 transport; //18
};
struct GemPropertiesEntry
{
- uint32 ID;
- uint32 spellitemenchantement;
- uint32 color;
+ uint32 ID; // 0 m_id
+ uint32 spellitemenchantement; // 1 m_enchant_id
+ // 2 m_maxcount_inv
+ // 3 m_maxcount_item
+ uint32 color; // 4 m_type
+ uint32 minJewelCraftingSkill; // 5 m_minJewelCraftingSkill
};
struct GlyphPropertiesEntry
@@ -989,7 +1051,7 @@ struct GlyphPropertiesEntry
uint32 Id;
uint32 SpellId;
uint32 TypeFlags;
- uint32 Unk1; // GlyphIconId (SpellIcon.dbc)
+ uint32 IconId; // GlyphIconId (SpellIcon.dbc)
};
struct GlyphSlotEntry
@@ -1006,21 +1068,25 @@ struct GlyphSlotEntry
struct GtBarberShopCostBaseEntry
{
+ //uint32 level;
float cost;
};
struct GtCombatRatingsEntry
{
+ //uint32 level;
float ratio;
};
struct GtChanceToMeleeCritBaseEntry
{
+ //uint32 level;
float base;
};
struct GtChanceToMeleeCritEntry
{
+ //uint32 level;
float ratio;
};
@@ -1049,10 +1115,15 @@ struct GtOCTRegenHPEntry
float ratio;
};
-//struct GtOCTRegenMPEntry
-//{
-// float ratio;
-//};
+struct GtOCTRegenMPEntry
+{
+ float ratio;
+};
+
+struct gtOCTHpPerStaminaEntry
+{
+ float ratio;
+};
struct GtRegenHPPerSptEntry
{
@@ -1064,12 +1135,33 @@ struct GtRegenMPPerSptEntry
float ratio;
};
+struct GtSpellScalingEntry
+{
+ float value;
+};
+
+struct GtOCTBaseHPByClassEntry
+{
+ float ratio;
+};
+
+struct GtOCTBaseMPByClassEntry
+{
+ float ratio;
+};
+
+struct GuildPerkSpellsEntry
+{
+ //uint32 Id;
+ uint32 Level;
+ uint32 SpellId;
+};
+
/* no used
struct HolidayDescriptionsEntry
{
uint32 ID; // 0, m_holidayDescriptionID
- //char* name[16] // 1-16 m_name_lang
- // 17 name flags
+ //char* name // 1 m_name_lang
};
*/
@@ -1077,8 +1169,7 @@ struct HolidayDescriptionsEntry
struct HolidayNamesEntry
{
uint32 ID; // 0, m_holidayNameID
- //char* name[16] // 1-16 m_name_lang
- // 17 name flags
+ //char* name // 1 m_name_lang
};
*/
@@ -1102,23 +1193,105 @@ struct HolidaysEntry
//uint32 flags; // 54 m_flags (0 = Darkmoon Faire, Fishing Contest and Wotlk Launch, rest is 1)
};
-struct ItemEntry
+// ImportPriceArmor.dbc
+struct ImportPriceArmorEntry
+{
+ uint32 InventoryType; // 1 Id/InventoryType
+ float ClothFactor; // 2 Price factor cloth
+ float LeatherFactor; // 3 Price factor leather
+ float MailFactor; // 4 Price factor mail
+ float PlateFactor; // 5 Price factor plate
+};
+
+// ImportPriceQuality.dbc
+struct ImportPriceQualityEntry
+{
+ uint32 QualityId; // 1 Quality Id (+1?)
+ float Factor; // 2 Price factor
+};
+
+// ImportPriceShield.dbc
+struct ImportPriceShieldEntry
+{
+ uint32 Id; // 1 Unk id (only 1 and 2)
+ float Factor; // 2 Price factor
+};
+
+// ImportPriceWeapon.dbc
+struct ImportPriceWeaponEntry
+{
+ uint32 Id; // 1 Unk id (mainhand - 0, offhand - 1, weapon - 2, 2hweapon - 3, ranged/rangedright/relic - 4)
+ float Factor; // 2 Price factor
+};
+
+// ItemPriceBase.dbc
+struct ItemPriceBaseEntry
+{
+ uint32 ItemLevel; // 2 Item level (1 - 1000)
+ float ArmorFactor; // 3 Price factor for armor
+ float WeaponFactor; // 4 Price factor for weapons
+};
+
+struct ItemReforgeEntry
+{
+ uint32 Id;
+ uint32 SourceStat;
+ float SourceMultiplier;
+ uint32 FinalStat;
+ float FinalMultiplier;
+};
+
+// common struct for:
+// ItemDamageAmmo.dbc
+// ItemDamageOneHand.dbc
+// ItemDamageOneHandCaster.dbc
+// ItemDamageRanged.dbc
+// ItemDamageThrown.dbc
+// ItemDamageTwoHand.dbc
+// ItemDamageTwoHandCaster.dbc
+// ItemDamageWand.dbc
+struct ItemDamageEntry
+{
+ uint32 Id; // 0 item level
+ float DPS[7]; // 1-7 multiplier for item quality
+ uint32 Id2; // 8 item level
+};
+
+struct ItemArmorQualityEntry
+{
+ uint32 Id; // 0 item level
+ float Value[7]; // 1-7 multiplier for item quality
+ uint32 Id2; // 8 item level
+};
+
+struct ItemArmorShieldEntry
{
- uint32 ID; // 0
- uint32 Class; // 1
- uint32 SubClass; // 2 some items have strange subclasses
- int32 SoundOverrideSubclass; // 3
- int32 Material; // 4
- uint32 DisplayId; // 5
- uint32 InventoryType; // 6
- uint32 Sheath; // 7
+ uint32 Id; // 0 item level
+ uint32 Id2; // 1 item level
+ float Value[7]; // 2-8 multiplier for item quality
+};
+
+struct ItemArmorTotalEntry
+{
+ uint32 Id; // 0 item level
+ uint32 Id2; // 1 item level
+ float Value[4]; // 2-5 multiplier for armor types (cloth...plate)
+};
+
+// ItemClass.dbc
+struct ItemClassEntry
+{
+ uint32 Class; // 1 item class id
+ //uint32 Unk; // 2 unk
+ //uint32 IsWeapon; // 3 1 for weapon, 0 for everything else
+ float PriceFactor; // 4 used to calculate certain prices
+ //char* Name; // class name
};
struct ItemBagFamilyEntry
{
uint32 ID; // 0
- //char* name[16] // 1-16 m_name_lang
- // // 17 name flags
+ //char* name; // 1 m_name_lang
};
struct ItemDisplayInfoEntry
@@ -1137,34 +1310,23 @@ struct ItemDisplayInfoEntry
// 11 m_particleColorID
};
-//struct ItemCondExtCostsEntry
-//{
-// uint32 ID;
-// uint32 condExtendedCost; // ItemTemplate::CondExtendedCost
-// uint32 itemextendedcostentry; // ItemTemplate::ExtendedCost
-// uint32 arenaseason; // arena season number(1-4)
-//};
-
-#define MAX_ITEM_EXTENDED_COST_REQUIREMENTS 5
-
-struct ItemExtendedCostEntry
+struct ItemDisenchantLootEntry
{
- uint32 ID; // 0 extended-cost entry id
- uint32 reqhonorpoints; // 1 required honor points
- uint32 reqarenapoints; // 2 required arena points
- uint32 reqarenaslot; // 3 arena slot restrctions (min slot value)
- uint32 reqitem[MAX_ITEM_EXTENDED_COST_REQUIREMENTS]; // 4-8 required item id
- uint32 reqitemcount[MAX_ITEM_EXTENDED_COST_REQUIREMENTS]; // 9-14 required count of 1st item
- uint32 reqpersonalarenarating; // 15 required personal arena rating};
+ uint32 Id;
+ uint32 ItemClass;
+ int32 ItemSubClass;
+ uint32 ItemQuality;
+ uint32 MinItemLevel;
+ uint32 MaxItemLevel;
+ uint32 RequiredDisenchantSkill;
};
struct ItemLimitCategoryEntry
{
uint32 ID; // 0 Id
- //char* name[16] // 1-16 m_name_lang
- // 17 name flags
- uint32 maxCount; // 18, max allowed equipped as item or in gem slot
- uint32 mode; // 19, 0 = have, 1 = equip (enum ItemLimitCategoryMode)
+ //char* name; // 1 m_name_lang
+ uint32 maxCount; // 2, m_quantity max allowed equipped as item or in gem slot
+ uint32 mode; // 3, m_flags 0 = have, 1 = equip (enum ItemLimitCategoryMode)
};
#define MAX_ITEM_ENCHANTMENT_EFFECTS 3
@@ -1172,23 +1334,19 @@ struct ItemLimitCategoryEntry
struct ItemRandomPropertiesEntry
{
uint32 ID; // 0 m_ID
- //char* internalName // 1 m_Name
+ //char* internalName // 1 m_Name
uint32 enchant_id[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 2-4 m_Enchantment
// 5-6 unused
- char* nameSuffix[16]; // 7-22 m_name_lang
- // 23 name flags
+ char* nameSuffix; // 7 m_name_lang
};
struct ItemRandomSuffixEntry
{
uint32 ID; // 0 m_ID
- char* nameSuffix[16]; // 1-16 m_name_lang
- // 17, name flags
- // 18 m_internalName
- uint32 enchant_id[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 19-21 m_enchantment
- //uint32 unk1[2] // 22-23 unknown
- uint32 prefix[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 24-26 m_allocationPct
- //uint32 unk2[2] // 27-28 unknown
+ char* nameSuffix; // 1 m_name_lang
+ // 2 m_internalName
+ uint32 enchant_id[5]; // 3-7 m_enchantment
+ uint32 prefix[5]; // 8-12 m_allocationPct
};
#define MAX_ITEM_SET_ITEMS 10
@@ -1197,35 +1355,34 @@ struct ItemRandomSuffixEntry
struct ItemSetEntry
{
//uint32 id // 0 m_ID
- char* name[16]; // 1-16 m_name_lang
- // 17 string flags, unused
- uint32 itemId[MAX_ITEM_SET_ITEMS]; // 18-27 m_itemID
- //uint32 unknown[7]; // 28-34 unk, all 0
- uint32 spells[MAX_ITEM_SET_SPELLS]; // 35-42 m_setSpellID
- uint32 items_to_triggerspell[MAX_ITEM_SET_SPELLS]; // 43-50 m_setThreshold
- uint32 required_skill_id; // 51 m_requiredSkill
- uint32 required_skill_value; // 52 m_requiredSkillRank
+ char* name; // 1 m_name_lang
+ uint32 itemId[MAX_ITEM_SET_ITEMS]; // 2-18 m_itemID
+ uint32 spells[MAX_ITEM_SET_SPELLS]; // 19-26 m_setSpellID
+ uint32 items_to_triggerspell[MAX_ITEM_SET_SPELLS]; // 27-34 m_setThreshold
+ uint32 required_skill_id; // 35 m_requiredSkill
+ uint32 required_skill_value; // 36 m_requiredSkillRank
};
struct LFGDungeonEntry
{
uint32 ID; // 0
- char* name[16]; // 1-17 Name lang
- uint32 minlevel; // 18
- uint32 maxlevel; // 19
- uint32 reclevel; // 20
- uint32 recminlevel; // 21
- uint32 recmaxlevel; // 22
- int32 map; // 23
- uint32 difficulty; // 24
- uint32 flags; // 25
- uint32 type; // 26
- //uint32 unk; // 27
- //char* iconname; // 28
- uint32 expansion; // 29
- //uint32 unk4; // 30
- uint32 grouptype; // 31
- //char* desc[16]; // 32-47 Description
+ char* name; // 1
+ uint32 minlevel; // 2
+ uint32 maxlevel; // 3
+ uint32 reclevel; // 4
+ uint32 recminlevel; // 5
+ uint32 recmaxlevel; // 6
+ int32 map; // 7
+ uint32 difficulty; // 8
+ uint32 flags; // 9
+ uint32 type; // 10
+ //uint32 unk2; // 11
+ //char* iconname; // 12
+ uint32 expansion; // 13
+ //uint32 unk4; // 14
+ uint32 grouptype; // 15
+ //char* desc; // 16 Description
+ uint32 randomCategoryId; // 17 RandomDungeonID assigned for this dungeon
// Helpers
uint32 Entry() const { return ID + (type << 24); }
};
@@ -1265,12 +1422,18 @@ struct LockEntry
//uint32 Action[MAX_LOCK_CASE]; // 25-32 m_Action
};
+struct PhaseEntry
+{
+ uint32 ID; // 0
+ char* Name; // 1
+ uint32 flag; // 2
+};
+
struct MailTemplateEntry
{
uint32 ID; // 0
- //char* subject[16]; // 1-16
- // 17 name flags, unused
- char* content[16]; // 18-33
+ //char* subject; // 1 m_subject_lang
+ char* content; // 2 m_body_lang
};
struct MapEntry
@@ -1279,23 +1442,22 @@ struct MapEntry
//char* internalname; // 1 unused
uint32 map_type; // 2
//uint32 unk_330; // 3
- // 4 0 or 1 for battlegrounds (not arenas)
- char* name[16]; // 5-20
- // 21 name flags, unused
- uint32 linked_zone; // 22 common zone for instance and continent map
- //char* hordeIntro[16]; // 23-38 text for PvP Zones
- // 39 intro text flags
- //char* allianceIntro[16]; // 40-55 text for PvP Zones
- // 56 intro text flags
- uint32 multimap_id; // 57
- // 58
- int32 entrance_map; // 59 map_id of entrance map
- float entrance_x; // 60 entrance x coordinate (if exist single entry)
- float entrance_y; // 61 entrance y coordinate (if exist single entry)
- // 62 -1, 0 and 720
- uint32 addon; // 63 (0-original maps, 1-tbc addon)
- uint32 unk_time; // 64 some kind of time?
- //uint32 maxPlayers; // 65 max players
+ //uint32 unk4; // 4 4.0.1
+ //uint32 isPvP; // 5 m_PVP 0 or 1 for battlegrounds (not arenas)
+ char* name; // 6 m_MapName_lang
+ uint32 linked_zone; // 7 m_areaTableID
+ //char* hordeIntro; // 8 m_MapDescription0_lang
+ //char* allianceIntro; // 9 m_MapDescription1_lang
+ uint32 multimap_id; // 10 m_LoadingScreenID (LoadingScreens.dbc)
+ //float BattlefieldMapIconScale; // 11 m_minimapIconScale
+ int32 entrance_map; // 12 m_corpseMapID map_id of entrance map in ghost mode (continent always and in most cases = normal entrance)
+ float entrance_x; // 13 m_corpseX entrance x coordinate in ghost mode (in most cases = normal entrance)
+ float entrance_y; // 14 m_corpseY entrance y coordinate in ghost mode (in most cases = normal entrance)
+ //uint32 timeOfDayOverride; // 15 m_timeOfDayOverride
+ uint32 addon; // 16 m_expansionID
+ uint32 expireTime; // 17 m_raidOffset
+ //uint32 maxPlayers; // 18 m_maxPlayers
+ int32 rootPhaseMap; // 19 new 4.0.0, mapid, related to phasing
// Helpers
uint32 Expansion() const { return addon; }
@@ -1330,18 +1492,52 @@ struct MapDifficultyEntry
//uint32 Id; // 0
uint32 MapId; // 1
uint32 Difficulty; // 2 (for arenas: arena slot)
- char* areaTriggerText; // 3-18 text showed when transfer to map failed (missing requirements)
- //uint32 textFlags; // 19
- uint32 resetTime; // 20
- uint32 maxPlayers; // 21
- //char* difficultyString; // 22
+ char* areaTriggerText; // 3 m_message_lang (text showed when transfer to map failed)
+ uint32 resetTime; // 4, m_raidDuration in secs, 0 if no fixed reset time
+ uint32 maxPlayers; // 5, m_maxPlayers some heroic versions have 0 when expected same amount as in normal version
+ //char* difficultyString; // 6 m_difficultystring
+};
+
+struct MountCapabilityEntry
+{
+ uint32 Id;
+ uint32 Flags;
+ uint32 RequiredRidingSkill;
+ uint32 RequiredArea;
+ uint32 RequiredAura;
+ uint32 RequiredSpell;
+ uint32 SpeedModSpell;
+ int32 RequiredMap;
+};
+
+#define MAX_MOUNT_CAPABILITIES 24
+
+struct MountTypeEntry
+{
+ uint32 Id;
+ uint32 MountCapability[MAX_MOUNT_CAPABILITIES];
};
struct MovieEntry
{
uint32 Id; // 0 index
//char* filename; // 1
- //uint32 unk2; // 2 always 100
+ //uint32 unk1; // 2 m_volume
+ //uint32 unk2; // 3 4.0.0
+};
+
+struct NameGenEntry
+{
+ //uint32 id;
+ char* name;
+ uint32 race;
+ uint32 gender;
+};
+
+struct NumTalentsAtLevelEntry
+{
+ //uint32 Level; // 0 index
+ float Talents; // 1 talent count
};
#define MAX_OVERRIDE_SPELL 10
@@ -1351,6 +1547,7 @@ struct OverrideSpellDataEntry
uint32 id; // 0
uint32 spellId[MAX_OVERRIDE_SPELL]; // 1-10
//uint32 unk0; // 11
+ //char* SpellBarName; // 12
};
struct PvPDifficultyEntry
@@ -1369,8 +1566,7 @@ struct PvPDifficultyEntry
struct QuestSortEntry
{
uint32 id; // 0 m_ID
- //char* name[16]; // 1-16 m_SortName_lang
- // 17 name flags
+ //char* name; // 1 m_SortName_lang
};
struct QuestXPEntry
@@ -1399,78 +1595,23 @@ struct ScalingStatDistributionEntry
uint32 Id; // 0
int32 StatMod[10]; // 1-10
uint32 Modifier[10]; // 11-20
- uint32 MaxLevel; // 21
+ //uint32 unk1; // 21
+ uint32 MaxLevel; // 22 m_maxlevel
};
struct ScalingStatValuesEntry
{
- uint32 Id; // 0
- uint32 Level; // 1
- uint32 ssdMultiplier[4]; // 2-5 Multiplier for ScalingStatDistribution
- uint32 armorMod[4]; // 6-9 Armor for level
- uint32 dpsMod[6]; // 10-15 DPS mod for level
- uint32 spellPower; // 16 spell power for level
- uint32 ssdMultiplier2; // 17 there's data from 3.1 dbc ssdMultiplier[3]
- uint32 ssdMultiplier3; // 18 3.3
- uint32 armorMod2[5]; // 19-23 Armor for level
-
- uint32 getssdMultiplier(uint32 mask) const
- {
- if (mask & 0x4001F)
- {
- if (mask & 0x00000001) return ssdMultiplier[0]; // Shoulder
- if (mask & 0x00000002) return ssdMultiplier[1]; // Trinket
- if (mask & 0x00000004) return ssdMultiplier[2]; // Weapon1H
- if (mask & 0x00000008) return ssdMultiplier2;
- if (mask & 0x00000010) return ssdMultiplier[3]; // Ranged
- if (mask & 0x00040000) return ssdMultiplier3;
- }
- return 0;
- }
-
- uint32 getArmorMod(uint32 mask) const
- {
- if (mask & 0x00F001E0)
- {
- if (mask & 0x00000020) return armorMod[0]; // Cloth shoulder
- if (mask & 0x00000040) return armorMod[1]; // Leather shoulder
- if (mask & 0x00000080) return armorMod[2]; // Mail shoulder
- if (mask & 0x00000100) return armorMod[3]; // Plate shoulder
-
- if (mask & 0x00080000) return armorMod2[0]; // cloak
- if (mask & 0x00100000) return armorMod2[1]; // cloth
- if (mask & 0x00200000) return armorMod2[2]; // leather
- if (mask & 0x00400000) return armorMod2[3]; // mail
- if (mask & 0x00800000) return armorMod2[4]; // plate
- }
- return 0;
- }
-
- uint32 getDPSMod(uint32 mask) const
- {
- if (mask & 0x7E00)
- {
- if (mask & 0x00000200) return dpsMod[0]; // Weapon 1h
- if (mask & 0x00000400) return dpsMod[1]; // Weapon 2h
- if (mask & 0x00000800) return dpsMod[2]; // Caster dps 1h
- if (mask & 0x00001000) return dpsMod[3]; // Caster dps 2h
- if (mask & 0x00002000) return dpsMod[4]; // Ranged
- if (mask & 0x00004000) return dpsMod[5]; // Wand
- }
- return 0;
- }
-
- uint32 getSpellBonus(uint32 mask) const
- {
- if (mask & 0x00008000) return spellPower;
- return 0;
- }
+ uint32 Id; // 0
+ uint32 Level; // 1
+ uint32 dpsMod[6]; // 2-7 DPS mod for level
+ uint32 Spellpower; // 8 spell power for level
+ uint32 StatMultiplier[5]; // 9-13 Multiplier for ScalingStatDistribution
+ uint32 Armor[8][4]; // 14-46 Armor for level
+ uint32 CloakArmor; // 47 armor for cloak
- uint32 getFeralBonus(uint32 mask) const // removed in 3.2.x?
- {
- if (mask & 0x00010000) return 0; // not used?
- return 0;
- }
+ uint32 GetStatMultiplier(uint32 inventoryType) const;
+ uint32 GetArmor(uint32 inventoryType, uint32 armorType) const;
+ uint32 GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const;
};
//struct SkillLineCategoryEntry{
@@ -1502,14 +1643,11 @@ struct SkillLineEntry
uint32 id; // 0 m_ID
int32 categoryId; // 1 m_categoryID
//uint32 skillCostID; // 2 m_skillCostsID
- char* name[16]; // 3-18 m_displayName_lang
- // 19 string flags
- //char* description[16]; // 20-35 m_description_lang
- // 36 string flags
- uint32 spellIcon; // 37 m_spellIconID
- //char* alternateVerb[16]; // 38-53 m_alternateVerb_lang
- // 54 string flags
- uint32 canLink; // 55 m_canLink (prof. with recipes
+ char* name; // 3 m_displayName_lang
+ //char* description; // 4 m_description_lang
+ uint32 spellIcon; // 5 m_spellIconID
+ //char* alternateVerb; // 6 m_alternateVerb_lang
+ uint32 canLink; // 7 m_canLink (prof. with recipes)
};
struct SkillLineAbilityEntry
@@ -1526,7 +1664,7 @@ struct SkillLineAbilityEntry
uint32 learnOnGetSkill; // 9 m_acquireMethod
uint32 max_value; // 10 m_trivialSkillLineRankHigh
uint32 min_value; // 11 m_trivialSkillLineRankLow
- //uint32 characterPoints[2]; // 12-13 m_characterPoints[2]
+ uint32 character_points[2]; // 12-13 m_characterPoints
};
struct SoundEntriesEntry
@@ -1542,124 +1680,155 @@ struct SoundEntriesEntry
// 26 m_minDistance
// 27 m_distanceCutoff
// 28 m_EAXDef
- // 29 new in 3.1
+ // 29 m_soundEntriesAdvancedID, new in 3.1
+ //unk // 30 4.0.0
+ //unk // 31 4.0.0
+ //unk // 32 4.0.0
+ //unk // 33 4.0.0
+};
+
+// SpellEffect.dbc
+struct SpellEffectEntry
+{
+ uint32 Id; // 0 m_ID
+ uint32 Effect; // 1 m_effect
+ float EffectValueMultiplier; // 2 m_effectAmplitude
+ uint32 EffectApplyAuraName; // 3 m_effectAura
+ uint32 EffectAmplitude; // 4 m_effectAuraPeriod
+ int32 EffectBasePoints; // 5 m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
+ float EffectBonusMultiplier; // 6 m_effectBonus
+ float EffectDamageMultiplier; // 7 m_effectChainAmplitude
+ uint32 EffectChainTarget; // 8 m_effectChainTargets
+ int32 EffectDieSides; // 9 m_effectDieSides
+ uint32 EffectItemType; // 10 m_effectItemType
+ uint32 EffectMechanic; // 11 m_effectMechanic
+ int32 EffectMiscValue; // 12 m_effectMiscValue
+ int32 EffectMiscValueB; // 13 m_effectMiscValueB
+ float EffectPointsPerComboPoint; // 14 m_effectPointsPerCombo
+ uint32 EffectRadiusIndex; // 15 m_effectRadiusIndex - spellradius.dbc
+ uint32 EffectRadiusMaxIndex; // 16 4.0.0
+ float EffectRealPointsPerLevel; // 17 m_effectRealPointsPerLevel
+ flag96 EffectSpellClassMask; // 18 19 20 m_effectSpellClassMask1(2/3), effect 0
+ uint32 EffectTriggerSpell; // 21 m_effectTriggerSpell
+ uint32 EffectImplicitTargetA; // 22 m_implicitTargetA
+ uint32 EffectImplicitTargetB; // 23 m_implicitTargetB
+ uint32 EffectSpellId; // 24 new 4.0.0
+ uint32 EffectIndex; // 25 new 4.0.0
+ //uint32 Unk0 // 26 4.2.0 only 0 or 1
};
#define MAX_SPELL_EFFECTS 3
#define MAX_EFFECT_MASK 7
#define MAX_SPELL_REAGENTS 8
+// SpellAuraOptions.dbc
+struct SpellAuraOptionsEntry
+{
+ uint32 Id; // 0 m_ID
+ uint32 StackAmount; // 1 m_cumulativeAura
+ uint32 procChance; // 2 m_procChance
+ uint32 procCharges; // 3 m_procCharges
+ uint32 procFlags; // 4 m_procTypeMask
+};
+
+// SpellAuraRestrictions.dbc/
+struct SpellAuraRestrictionsEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 CasterAuraState; // 1 m_casterAuraState
+ uint32 TargetAuraState; // 2 m_targetAuraState
+ uint32 CasterAuraStateNot; // 3 m_excludeCasterAuraState
+ uint32 TargetAuraStateNot; // 4 m_excludeTargetAuraState
+ uint32 casterAuraSpell; // 5 m_casterAuraSpell
+ uint32 targetAuraSpell; // 6 m_targetAuraSpell
+ uint32 excludeCasterAuraSpell; // 7 m_excludeCasterAuraSpell
+ uint32 excludeTargetAuraSpell; // 8 m_excludeTargetAuraSpell
+};
+
+// SpellCastingRequirements.dbc
+struct SpellCastingRequirementsEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 FacingCasterFlags; // 1 m_facingCasterFlags
+ //uint32 MinFactionId; // 2 m_minFactionID not used
+ //uint32 MinReputation; // 3 m_minReputation not used
+ int32 AreaGroupId; // 4 m_requiredAreaGroupId
+ //uint32 RequiredAuraVision; // 5 m_requiredAuraVision not used
+ uint32 RequiresSpellFocus; // 6 m_requiresSpellFocus
+};
+
+#define MAX_SPELL_TOTEMS 2
+
+// SpellTotems.dbc
+struct SpellTotemsEntry
+{
+ uint32 Id; // 0 m_ID
+ uint32 TotemCategory[MAX_SPELL_TOTEMS]; // 1 m_requiredTotemCategoryID
+ uint32 Totem[MAX_SPELL_TOTEMS]; // 2 m_totem
+};
+
+// Spell.dbc
struct SpellEntry
{
uint32 Id; // 0 m_ID
+ uint32 Attributes; // 1 m_attribute
+ uint32 AttributesEx; // 2 m_attributesEx
+ uint32 AttributesEx2; // 3 m_attributesExB
+ uint32 AttributesEx3; // 4 m_attributesExC
+ uint32 AttributesEx4; // 5 m_attributesExD
+ uint32 AttributesEx5; // 6 m_attributesExE
+ uint32 AttributesEx6; // 7 m_attributesExF
+ uint32 AttributesEx7; // 8 m_attributesExG
+ uint32 AttributesEx8; // 9 m_attributesExH
+ uint32 AttributesEx9; // 10 m_attributesExI
+ uint32 AttributesEx10; // 11 m_attributesExJ
+ uint32 CastingTimeIndex; // 12 m_castingTimeIndex
+ uint32 DurationIndex; // 13 m_durationIndex
+ uint32 powerType; // 14 m_powerType
+ uint32 rangeIndex; // 15 m_rangeIndex
+ float speed; // 16 m_speed
+ uint32 SpellVisual[2]; // 17-18 m_spellVisualID
+ uint32 SpellIconID; // 19 m_spellIconID
+ uint32 activeIconID; // 20 m_activeIconID
+ char* SpellName; // 21 m_name_lang
+ char* Rank; // 22 m_nameSubtext_lang
+ //char* Description; // 23 m_description_lang not used
+ //char* ToolTip; // 24 m_auraDescription_lang not used
+ uint32 SchoolMask; // 25 m_schoolMask
+ uint32 runeCostID; // 26 m_runeCostID
+ //uint32 spellMissileID; // 27 m_spellMissileID not used
+ //uint32 spellDescriptionVariableID; // 28 m_spellDescriptionVariableID, 3.2.0
+ uint32 SpellDifficultyId; // 29 m_spellDifficultyID - id from SpellDifficulty.dbc
+ float SpellCoef; // 30
+ uint32 SpellScalingId; // 31 SpellScaling.dbc
+ uint32 SpellAuraOptionsId; // 32 SpellAuraOptions.dbc
+ uint32 SpellAuraRestrictionsId; // 33 SpellAuraRestrictions.dbc
+ uint32 SpellCastingRequirementsId; // 34 SpellCastingRequirements.dbc
+ uint32 SpellCategoriesId; // 35 SpellCategories.dbc
+ uint32 SpellClassOptionsId; // 36 SpellClassOptions.dbc
+ uint32 SpellCooldownsId; // 37 SpellCooldowns.dbc
+ //uint32 unkIndex7; // 38 all zeros...
+ uint32 SpellEquippedItemsId; // 39 SpellEquippedItems.dbc
+ uint32 SpellInterruptsId; // 40 SpellInterrupts.dbc
+ uint32 SpellLevelsId; // 41 SpellLevels.dbc
+ uint32 SpellPowerId; // 42 SpellPower.dbc
+ uint32 SpellReagentsId; // 43 SpellReagents.dbc
+ uint32 SpellShapeshiftId; // 44 SpellShapeshift.dbc
+ uint32 SpellTargetRestrictionsId; // 45 SpellTargetRestrictions.dbc
+ uint32 SpellTotemsId; // 46 SpellTotems.dbc
+ //uint32 ResearchProject; // 47 ResearchProject.dbc
+};
+
+// SpellCategories.dbc
+struct SpellCategoriesEntry
+{
+ //uint32 Id; // 0 m_ID
uint32 Category; // 1 m_category
+ uint32 DmgClass; // 153 m_defenseType
uint32 Dispel; // 2 m_dispelType
uint32 Mechanic; // 3 m_mechanic
- uint32 Attributes; // 4 m_attributes
- uint32 AttributesEx; // 5 m_attributesEx
- uint32 AttributesEx2; // 6 m_attributesExB
- uint32 AttributesEx3; // 7 m_attributesExC
- uint32 AttributesEx4; // 8 m_attributesExD
- uint32 AttributesEx5; // 9 m_attributesExE
- uint32 AttributesEx6; // 10 m_attributesExF
- uint32 AttributesEx7; // 11 m_attributesExG
- uint32 Stances; // 12 m_shapeshiftMask
- // uint32 unk_320_2; // 13 3.2.0
- uint32 StancesNot; // 14 m_shapeshiftExclude
- // uint32 unk_320_3; // 15 3.2.0
- uint32 Targets; // 16 m_targets
- uint32 TargetCreatureType; // 17 m_targetCreatureType
- uint32 RequiresSpellFocus; // 18 m_requiresSpellFocus
- uint32 FacingCasterFlags; // 19 m_facingCasterFlags
- uint32 CasterAuraState; // 20 m_casterAuraState
- uint32 TargetAuraState; // 21 m_targetAuraState
- uint32 CasterAuraStateNot; // 22 m_excludeCasterAuraState
- uint32 TargetAuraStateNot; // 23 m_excludeTargetAuraState
- uint32 casterAuraSpell; // 24 m_casterAuraSpell
- uint32 targetAuraSpell; // 25 m_targetAuraSpell
- uint32 excludeCasterAuraSpell; // 26 m_excludeCasterAuraSpell
- uint32 excludeTargetAuraSpell; // 27 m_excludeTargetAuraSpell
- uint32 CastingTimeIndex; // 28 m_castingTimeIndex
- uint32 RecoveryTime; // 29 m_recoveryTime
- uint32 CategoryRecoveryTime; // 30 m_categoryRecoveryTime
- uint32 InterruptFlags; // 31 m_interruptFlags
- uint32 AuraInterruptFlags; // 32 m_auraInterruptFlags
- uint32 ChannelInterruptFlags; // 33 m_channelInterruptFlags
- uint32 procFlags; // 34 m_procTypeMask
- uint32 procChance; // 35 m_procChance
- uint32 procCharges; // 36 m_procCharges
- uint32 maxLevel; // 37 m_maxLevel
- uint32 baseLevel; // 38 m_baseLevel
- uint32 spellLevel; // 39 m_spellLevel
- uint32 DurationIndex; // 40 m_durationIndex
- uint32 powerType; // 41 m_powerType
- uint32 manaCost; // 42 m_manaCost
- uint32 manaCostPerlevel; // 43 m_manaCostPerLevel
- uint32 manaPerSecond; // 44 m_manaPerSecond
- uint32 manaPerSecondPerLevel; // 45 m_manaPerSecondPerLeve
- uint32 rangeIndex; // 46 m_rangeIndex
- float speed; // 47 m_speed
- //uint32 modalNextSpell; // 48 m_modalNextSpell not used
- uint32 StackAmount; // 49 m_cumulativeAura
- uint32 Totem[2]; // 50-51 m_totem
- int32 Reagent[MAX_SPELL_REAGENTS]; // 52-59 m_reagent
- uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 60-67 m_reagentCount
- int32 EquippedItemClass; // 68 m_equippedItemClass (value)
- int32 EquippedItemSubClassMask; // 69 m_equippedItemSubclass (mask)
- int32 EquippedItemInventoryTypeMask; // 70 m_equippedItemInvTypes (mask)
- uint32 Effect[MAX_SPELL_EFFECTS]; // 71-73 m_effect
- int32 EffectDieSides[MAX_SPELL_EFFECTS]; // 74-76 m_effectDieSides
- float EffectRealPointsPerLevel[MAX_SPELL_EFFECTS]; // 77-79 m_effectRealPointsPerLevel
- int32 EffectBasePoints[MAX_SPELL_EFFECTS]; // 80-82 m_effectBasePoints (must not be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints)
- uint32 EffectMechanic[MAX_SPELL_EFFECTS]; // 83-85 m_effectMechanic
- uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]; // 86-88 m_implicitTargetA
- uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]; // 89-91 m_implicitTargetB
- uint32 EffectRadiusIndex[MAX_SPELL_EFFECTS]; // 92-94 m_effectRadiusIndex - spellradius.dbc
- uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]; // 95-97 m_effectAura
- uint32 EffectAmplitude[MAX_SPELL_EFFECTS]; // 98-100 m_effectAuraPeriod
- float EffectValueMultiplier[MAX_SPELL_EFFECTS]; // 101-103
- uint32 EffectChainTarget[MAX_SPELL_EFFECTS]; // 104-106 m_effectChainTargets
- uint32 EffectItemType[MAX_SPELL_EFFECTS]; // 107-109 m_effectItemType
- int32 EffectMiscValue[MAX_SPELL_EFFECTS]; // 110-112 m_effectMiscValue
- int32 EffectMiscValueB[MAX_SPELL_EFFECTS]; // 113-115 m_effectMiscValueB
- uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]; // 116-118 m_effectTriggerSpell
- float EffectPointsPerComboPoint[MAX_SPELL_EFFECTS]; // 119-121 m_effectPointsPerCombo
- flag96 EffectSpellClassMask[MAX_SPELL_EFFECTS]; // 122-130
- uint32 SpellVisual[2]; // 131-132 m_spellVisualID
- uint32 SpellIconID; // 133 m_spellIconID
- uint32 activeIconID; // 134 m_activeIconID
- //uint32 spellPriority; // 135 not used
- char* SpellName[16]; // 136-151 m_name_lang
- //uint32 SpellNameFlag; // 152 not used
- char* Rank[16]; // 153-168 m_nameSubtext_lang
- //uint32 RankFlags; // 169 not used
- //char* Description[16]; // 170-185 m_description_lang not used
- //uint32 DescriptionFlags; // 186 not used
- //char* ToolTip[16]; // 187-202 m_auraDescription_lang not used
- //uint32 ToolTipFlags; // 203 not used
- uint32 ManaCostPercentage; // 204 m_manaCostPct
- uint32 StartRecoveryCategory; // 205 m_startRecoveryCategory
- uint32 StartRecoveryTime; // 206 m_startRecoveryTime
- uint32 MaxTargetLevel; // 207 m_maxTargetLevel
- uint32 SpellFamilyName; // 208 m_spellClassSet
- flag96 SpellFamilyFlags; // 209-211
- uint32 MaxAffectedTargets; // 212 m_maxTargets
- uint32 DmgClass; // 213 m_defenseType
- uint32 PreventionType; // 214 m_preventionType
- //uint32 StanceBarOrder; // 215 m_stanceBarOrder not used
- float EffectDamageMultiplier[MAX_SPELL_EFFECTS]; // 216-218 m_effectChainAmplitude
- //uint32 MinFactionId; // 219 m_minFactionID not used
- //uint32 MinReputation; // 220 m_minReputation not used
- //uint32 RequiredAuraVision; // 221 m_requiredAuraVision not used
- uint32 TotemCategory[2]; // 222-223 m_requiredTotemCategoryID
- int32 AreaGroupId; // 224 m_requiredAreaGroupId
- uint32 SchoolMask; // 225 m_schoolMask
- uint32 runeCostID; // 226 m_runeCostID
- //uint32 spellMissileID; // 227 m_spellMissileID not used
- //uint32 PowerDisplayId; // 228 PowerDisplay.dbc, new in 3.1
- float EffectBonusMultiplier[MAX_SPELL_EFFECTS]; // 229-231 3.2.0
- //uint32 spellDescriptionVariableID; // 232 3.2.0
- //uint32 SpellDifficultyId; // 233 3.3.0
+ uint32 PreventionType; // 154 m_preventionType
+ uint32 StartRecoveryCategory; // 145 m_startRecoveryCategory
};
typedef std::set<uint32> SpellCategorySet;
@@ -1679,6 +1848,8 @@ struct SpellCategoryEntry
{
uint32 Id;
uint32 Flags;
+ // uint32 unk;
+ // char* Name;
};
struct SpellDifficultyEntry
@@ -1690,8 +1861,7 @@ struct SpellDifficultyEntry
struct SpellFocusObjectEntry
{
uint32 ID; // 0
- //char* Name[16]; // 1-15 unused
- // 16 string flags, unused
+ //char* Name; // 1 m_name_lang
};
struct SpellRadiusEntry
@@ -1708,12 +1878,71 @@ struct SpellRangeEntry
float minRangeHostile;
float minRangeFriend;
float maxRangeHostile;
- float maxRangeFriend;
+ float maxRangeFriend; //friend means unattackable unit here
uint32 type;
- //char* Name[16]; // 7-23 unused
- // 24 string flags, unused
- //char* Name2[16]; // 25-40 unused
- // 41 string flags, unused
+ //char* Name; // 6-21 m_displayName_lang
+ //char* ShortName; // 23-38 m_displayNameShort_lang
+};
+
+// SpellEquippedItems.dbc
+struct SpellEquippedItemsEntry
+{
+ //uint32 Id; // 0 m_ID
+ int32 EquippedItemClass; // 70 m_equippedItemClass (value)
+ int32 EquippedItemInventoryTypeMask; // 72 m_equippedItemInvTypes (mask)
+ int32 EquippedItemSubClassMask; // 71 m_equippedItemSubclass (mask)
+};
+
+// SpellCooldowns.dbc
+struct SpellCooldownsEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 CategoryRecoveryTime; // 31 m_categoryRecoveryTime
+ uint32 RecoveryTime; // 30 m_recoveryTime
+ uint32 StartRecoveryTime; // 146 m_startRecoveryTime
+};
+
+// SpellClassOptions.dbc
+struct SpellClassOptionsEntry
+{
+ //uint32 Id; // 0 m_ID
+ //uint32 modalNextSpell; // 1 m_modalNextSpell not used
+ flag96 SpellFamilyFlags; // 2-4
+ uint32 SpellFamilyName; // 5 m_spellClassSet
+ //char* Description; // 6 4.0.0
+};
+
+// SpellInterrupts.dbc
+struct SpellInterruptsEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 AuraInterruptFlags; // 1 m_auraInterruptFlags
+ //uint32 // 2 4.0.0
+ uint32 ChannelInterruptFlags; // 3 m_channelInterruptFlags
+ //uint32 // 4 4.0.0
+ uint32 InterruptFlags; // 5 m_interruptFlags
+};
+
+// SpellLevels.dbc
+struct SpellLevelsEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 baseLevel; // 1 m_baseLevel
+ uint32 maxLevel; // 2 m_maxLevel
+ uint32 spellLevel; // 3 m_spellLevel
+};
+
+// SpellPower.dbc
+struct SpellPowerEntry
+{
+ //uint32 Id; // 0 m_ID
+ uint32 manaCost; // 1 m_manaCost
+ uint32 manaCostPerlevel; // 2 m_manaCostPerLevel
+ uint32 ManaCostPercentage; // 3 m_manaCostPct
+ uint32 manaPerSecond; // 4 m_manaPerSecond
+ uint32 manaPerSecondPerLevel; // 5 m_manaPerSecondPerLevel
+ //uint32 PowerDisplayId; // 6 m_powerDisplayID - id from PowerDisplay.dbc, new in 3.1
+ float ManaCostPercentageFloat; // 7 4.3.0
};
struct SpellRuneCostEntry
@@ -1728,21 +1957,67 @@ struct SpellRuneCostEntry
#define MAX_SHAPESHIFT_SPELLS 8
-struct SpellShapeshiftEntry
+struct SpellShapeshiftFormEntry
{
uint32 ID; // 0
//uint32 buttonPosition; // 1 unused
- //char* Name[16]; // 2-17 unused
- //uint32 NameFlags; // 18 unused
- uint32 flags1; // 19
- int32 creatureType; // 20 <= 0 humanoid, other normal creature types
- //uint32 unk1; // 21 unused
- uint32 attackSpeed; // 22
- uint32 modelID_A; // 23 alliance modelid
- uint32 modelID_H; // 24 horde modelid (only one form)
- //uint32 unk3; // 25 unused
- //uint32 unk4; // 26 unused
- uint32 stanceSpell[MAX_SHAPESHIFT_SPELLS]; // 27 - 34 unused
+ //char* Name; // 2 unused
+ uint32 flags1; // 3
+ int32 creatureType; // 4 <=0 humanoid, other normal creature types
+ //uint32 spellIcon; // 5 unused, related to next field
+ uint32 attackSpeed; // 6
+ // Models changed, 0 is main model, the rest 3 are unused.
+ uint32 modelID_A; // 7 alliance modelid (0 means no model)
+ uint32 modelID_H; // 8 horde modelid (but only for one form)
+ //uint32 unk3; // 9 unused always 0
+ //uint32 unk4; // 10 unused always 0
+ uint32 stanceSpell[MAX_SHAPESHIFT_SPELLS]; // 11-18 spells which appear in the bar after shapeshifting
+ //uint32 unk5; // 19
+ //uint32 unk6; // 20
+};
+
+// SpellShapeshift.dbc
+struct SpellShapeshiftEntry
+{
+ uint32 Id; // 0 - m_ID
+ uint32 StancesNot; // 3 - m_shapeshiftExclude
+ // uint32 unk_320_2; // 2 - 3.2.0
+ uint32 Stances; // 1 - m_shapeshiftMask
+ // uint32 unk_320_3; // 4 - 3.2.0
+ // uint32 StanceBarOrder; // 5 - m_stanceBarOrder not used
+};
+
+// SpellTargetRestrictions.dbc
+struct SpellTargetRestrictionsEntry
+{
+ uint32 Id; // 0 m_ID
+ uint32 MaxAffectedTargets; // 1 m_maxTargets
+ uint32 MaxTargetLevel; // 2 m_maxTargetLevel
+ uint32 TargetCreatureType; // 3 m_targetCreatureType
+ uint32 Targets; // 4 m_targets
+};
+
+// SpellReagents.dbc
+struct SpellReagentsEntry
+{
+ //uint32 Id; // 0 m_ID
+ int32 Reagent[MAX_SPELL_REAGENTS]; // 54-61 m_reagent
+ uint32 ReagentCount[MAX_SPELL_REAGENTS]; // 62-69 m_reagentCount
+};
+
+// SpellScaling.dbc
+struct SpellScalingEntry
+{
+ //uint32 Id; // 0 m_ID
+ int32 CastTimeMin; // 1
+ int32 CastTimeMax; // 2
+ int32 CastTimeMaxLevel; // 3
+ int32 ScalingClass; // 4 (index * 100) + charLevel - 1 => gtSpellScaling.dbc
+ float Multiplier[3]; // 5-7
+ float RandomMultiplier[3]; // 8-10
+ float OtherMultiplier[3]; // 11-13
+ float CoefBase; // 14 some coefficient, mostly 1.0f
+ int32 CoefLevelBase; // 15 some level
};
struct SpellDurationEntry
@@ -1759,15 +2034,15 @@ struct SpellItemEnchantmentEntry
uint32 amount[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 5-7 m_effectPointsMin[MAX_ITEM_ENCHANTMENT_EFFECTS]
//uint32 amount2[MAX_ITEM_ENCHANTMENT_EFFECTS] // 8-10 m_effectPointsMax[MAX_ITEM_ENCHANTMENT_EFFECTS]
uint32 spellid[MAX_ITEM_ENCHANTMENT_EFFECTS]; // 11-13 m_effectArg[MAX_ITEM_ENCHANTMENT_EFFECTS]
- char* description[16]; // 14-29 m_name_lang[16]
- //uint32 descriptionFlags; // 30 name flags
- uint32 aura_id; // 31 m_itemVisual
- uint32 slot; // 32 m_flags
- uint32 GemID; // 33 m_src_itemID
- uint32 EnchantmentCondition; // 34 m_condition_id
- uint32 requiredSkill; // 35 m_requiredSkillID
- uint32 requiredSkillValue; // 36 m_requiredSkillRank
- uint32 requiredLevel; // 37 m_requiredLevel
+ char* description; // 14 m_name_lang
+ uint32 aura_id; // 15 m_itemVisual
+ uint32 slot; // 16 m_flags
+ uint32 GemID; // 17 m_src_itemID
+ uint32 EnchantmentCondition; // 18 m_condition_id
+ uint32 requiredSkill; // 19 m_requiredSkillID
+ uint32 requiredSkillValue; // 20 m_requiredSkillRank
+ uint32 requiredLevel; // 21 new in 3.1
+ // 22 new in 3.1
};
struct SpellItemEnchantmentConditionEntry
@@ -1793,7 +2068,7 @@ struct SummonPropertiesEntry
uint32 Category; // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
uint32 Faction; // 2, 14 rows > 0
uint32 Type; // 3, see enum
- uint32 Slot; // 4, 0-6
+ int32 Slot; // 4, 0-6
uint32 Flags; // 5
};
@@ -1808,27 +2083,37 @@ struct TalentEntry
uint32 Row; // 2
uint32 Col; // 3
uint32 RankID[MAX_TALENT_RANK]; // 4-8
- // 9-12 not used, always 0, maybe not used high ranks
- uint32 DependsOn; // 13 index in Talent.dbc (TalentEntry)
- // 14-15 not used
- uint32 DependsOnRank; // 16
- // 17-18 not used
- //uint32 needAddInSpellBook; // 19 also need disable higest ranks on reset talent tree
- //uint32 unk2; // 20, all 0
- //uint64 allowForPet; // 21 its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc
+ uint32 DependsOn; // 9 m_prereqTalent (Talent.dbc)
+ // 10-11 part of prev field
+ uint32 DependsOnRank; // 12 m_prereqRank
+ // 13-14 part of prev field
+ //uint32 needAddInSpellBook; // 15 m_flags also need disable higest ranks on reset talent tree
+ //uint32 unk2; // 16 m_requiredSpellID
+ //uint64 allowForPet; // 17 m_categoryMask its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc
};
+#define MAX_MASTERY_SPELLS 2
+
struct TalentTabEntry
{
uint32 TalentTabID; // 0
- //char* name[16]; // 1-16, unused
- //uint32 nameFlags; // 17, unused
- //unit32 spellicon; // 18
- // 19 not used
- uint32 ClassMask; // 20
- uint32 petTalentMask; // 21
- uint32 tabpage; // 22
- //char* internalname; // 23
+ //char* name; // 1 m_name_lang
+ //unit32 spellicon; // 2 m_spellIconID
+ uint32 ClassMask; // 3 m_classMask
+ uint32 petTalentMask; // 4 m_petTalentMask
+ uint32 tabpage; // 5 m_orderIndex
+ //char* internalname; // 6 m_backgroundFile
+ //char* description; // 7
+ //uint32 rolesMask; // 8 4.0.0
+ uint32 MasterySpellId[MAX_MASTERY_SPELLS]; // 9-10 passive mastery bonus spells?
+};
+
+struct TalentTreePrimarySpellsEntry
+{
+ //uint32 Id; // 0 index
+ uint32 TalentTree; // 1 entry from TalentTab.dbc
+ uint32 SpellId; // 2 spell id to learn
+ //uint32 Flags; // 3 some kind of flags
};
struct TaxiNodesEntry
@@ -1838,9 +2123,9 @@ struct TaxiNodesEntry
float x; // 2 m_x
float y; // 3 m_y
float z; // 4 m_z
- char* name[16]; // 5-21 m_Name_lang
- // 22 string flags
- uint32 MountCreatureID[2]; // 23-24 m_MountCreatureID[2]
+ char* name; // 5 m_Name_lang
+ uint32 MountCreatureID[2]; // 6-7 m_MountCreatureID[2]
+ uint32 Flags; // 8 m_Flags
};
struct TaxiPathEntry
@@ -1866,19 +2151,33 @@ struct TaxiPathNodeEntry
uint32 departureEventID; // 10 m_departureEventID
};
-struct TeamContributionPointsEntry
+struct TotemCategoryEntry
{
- //uint32 entry; // 0
- float value; // 1 (???)
+ uint32 ID; // 0
+ //char* name; // 1 m_name_lang
+ uint32 categoryType; // 2 m_totemCategoryType (one for specialization)
+ uint32 categoryMask; // 3 m_totemCategoryMask (compatibility mask for same type: different for totems, compatible from high to low for rods)
};
-struct TotemCategoryEntry
+struct UnitPowerBarEntry
{
- uint32 ID; // 0
- //char* name[16]; // 1-16
- // 17 string flags, unused
- uint32 categoryType; // 18 (one for specialization)
- uint32 categoryMask; // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)
+ uint32 Id;
+ uint32 MinPower;
+ uint32 MaxPower;
+ //uint32 Unk0;
+ //uint32 Unk1;
+ //float Unk2;
+ //float Unk3;
+ //uint32 BarType;
+ //uint32 TextureFile[6];
+ //uint32 Unk4[6];
+ //uint32 DisplayFlags;
+ //char* PowerName;
+ //char* CostString;
+ //char* EmptyMessage;
+ //char* Tooltip;
+ //float StartInset;
+ //float EndInset;
};
struct TransportAnimationEntry
@@ -1930,9 +2229,9 @@ struct VehicleEntry
float m_msslTrgtArcRepeat; // 25
float m_msslTrgtArcWidth; // 26
float m_msslTrgtImpactRadius[2]; // 27-28
- char* m_msslTrgtArcTexture; // 29
- char* m_msslTrgtImpactTexture; // 30
- char* m_msslTrgtImpactModel[2]; // 31-32
+ char* m_msslTrgtArcTexture; // 29
+ char* m_msslTrgtImpactTexture; // 30
+ char* m_msslTrgtImpactModel[2]; // 31-32
float m_cameraYawOffset; // 33
uint32 m_uiLocomotionType; // 34
float m_msslTrgtImpactTexRadius; // 35
@@ -2013,8 +2312,10 @@ struct WMOAreaTableEntry
//uint32 field8;
uint32 Flags; // 9 used for indoor/outdoor determination
uint32 areaId; // 10 link to AreaTableEntry.ID
- //char *Name[16];
- //uint32 nameFlags;
+ //char *Name; // 11 m_AreaName_lang
+ //uint32 field12; // 12
+ //uint32 field13; // 13
+ //uint32 field14; // 14
};
struct WorldMapAreaEntry
@@ -2030,6 +2331,9 @@ struct WorldMapAreaEntry
int32 virtual_map_id; // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)
// int32 dungeonMap_id; // 9 pointer to DungeonMap.dbc (owerride x1, x2, y1, y2 coordinates)
// uint32 parentMapID; // 10
+
+ // uint32 minRecommendedLevel; // 12 Minimum recommended level displayed on world map
+ // uint32 maxRecommendedLevel; // 13 Maximum recommended level displayed on world map
};
#define MAX_WORLD_MAP_OVERLAY_AREA_IDX 4
@@ -2039,9 +2343,15 @@ struct WorldMapOverlayEntry
uint32 ID; // 0
//uint32 worldMapAreaId; // 1 idx in WorldMapArea.dbc
uint32 areatableID[MAX_WORLD_MAP_OVERLAY_AREA_IDX]; // 2-5
- // 6-7 always 0, possible part of areatableID[]
- //char* internal_name // 8
- // 9-16 some ints
+ //char* internal_name // 6 m_textureName
+ // 7 m_textureWidth
+ // 8 m_textureHeight
+ // 9 m_offsetX
+ // 10 m_offsetY
+ // 11 m_hitRectTop
+ // 12 m_hitRectLeft
+ // 13 m_hitRectBottom
+ // 14 m_hitRectRight
};
struct WorldSafeLocsEntry
@@ -2051,8 +2361,7 @@ struct WorldSafeLocsEntry
float x; // 2
float y; // 3
float z; // 4
- //char* name[16] // 5-20 name, unused
- // 21 name flags, unused
+ //char* name; // 5 m_AreaName_lang
};
/*
@@ -2098,6 +2407,13 @@ struct WorldStateUI
#pragma pack(pop)
#endif
+struct VectorArray
+{
+ std::vector<std::string> stringVectorArray[2];
+};
+
+typedef std::map<uint32, VectorArray> NameGenVectorArraysMap;
+
// Structures not used for casting to loaded DBC data and not required then packing
struct MapDifficulty
{
@@ -2142,7 +2458,6 @@ struct TaxiPathNodePtr
typedef Path<TaxiPathNodePtr, TaxiPathNodeEntry const> TaxiPathNodeList;
typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath;
-#define TaxiMaskSize 14
-typedef uint32 TaxiMask[TaxiMaskSize];
+#define TaxiMaskSize 114
+typedef uint8 TaxiMask[TaxiMaskSize];
#endif
-
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index a1ebaa70018..76dc9402fe5 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -19,115 +19,159 @@
#ifndef TRINITY_DBCSFRM_H
#define TRINITY_DBCSFRM_H
-char const Achievementfmt[] = "niixssssssssssssssssxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxii";
-const std::string CustomAchievementfmt = "pppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaapapaaaaaaaaaaaaaaaaaapp";
+// x - skip<uint32>, X - skip<uint8>, s - char*, f - float, i - uint32, b - uint8, d - index (not included)
+// n - index (included), l - bool, p - field present in sql dbc, a - field absent in sql dbc
+
+char const Achievementfmt[] = "niixsxiixixxii";
+const std::string CustomAchievementfmt = "pppaaaapapaapp";
const std::string CustomAchievementIndex = "ID";
-char const AchievementCriteriafmt[] = "niiiiiiiixxxxxxxxxxxxxxxxxiiiix";
-char const AreaTableEntryfmt[] = "iiinixxxxxissssssssssssssssxiiiiixxx";
+char const AchievementCriteriafmt[] = "niiiixiiiisiiiiixxiiiii";
+char const AreaTableEntryfmt[] = "iiinixxxxxisiiiiiffixxxxxx";
char const AreaGroupEntryfmt[] = "niiiiiii";
-char const AreaPOIEntryfmt[] = "niiiiiiiiiiifffixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix";
-char const AreaTriggerEntryfmt[] = "niffffffff";
-char const AuctionHouseEntryfmt[] = "niiixxxxxxxxxxxxxxxxx";
+char const AreaPOIEntryfmt[] = "niiiiiiiiiiiffixixxixx";
+char const AreaTriggerEntryfmt[] = "nifffxxxfffff";
+char const ArmorLocationfmt[] = "nfffff";
+char const AuctionHouseEntryfmt[] = "niiix";
char const BankBagSlotPricesEntryfmt[] = "ni";
char const BannedAddOnsfmt[] = "nxxxxxxxxxx";
-char const BarberShopStyleEntryfmt[] = "nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii";
-char const BattlemasterListEntryfmt[] = "niiiiiiiiixssssssssssssssssxiixx";
-char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
-char const CharTitlesEntryfmt[] = "nxssssssssssssssssxxxxxxxxxxxxxxxxxxi";
-char const ChatChannelsEntryfmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxx";
-char const ChrClassesEntryfmt[] = "nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";
-char const ChrRacesEntryfmt[] = "nxixiixixxxxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";
+char const BarberShopStyleEntryfmt[] = "nixxxiii";
+char const BattlemasterListEntryfmt[] = "niiiiiiiiixsiiiixxxx";
+char const CharStartOutfitEntryfmt[] = "dbbbXiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxii";
+char const CharTitlesEntryfmt[] = "nxsxix";
+char const ChatChannelsEntryfmt[] = "nixsx";
+char const ChrClassesEntryfmt[] = "nixsxxxixiiiii";
+char const ChrRacesEntryfmt[] = "nxixiixixxxxixsxxxxxixxx";
+char const ChrClassesXPowerTypesfmt[] = "nii";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
-char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxx";
-char const CreatureFamilyfmt[] = "nfifiiiiixssssssssssssssssxx";
-char const CreatureModelDatafmt[] = "nxxxfxxxxxxxxxxffxxxxxxxxxxx";
+char const CreatureDisplayInfofmt[] = "nixxfxxxxxxxxxxxx";
+char const CreatureModelDatafmt[] = "nxxxxxxxxxxxxxffxxxxxxxxxxxxxxx";
+char const CreatureFamilyfmt[] = "nfifiiiiixsx";
char const CreatureSpellDatafmt[] = "niiiixxxx";
-char const CreatureTypefmt[] = "nxxxxxxxxxxxxxxxxxx";
-char const CurrencyTypesfmt[] = "xnxi";
-char const DestructibleModelDatafmt[] = "nxxixxxixxxixxxixxx";
-char const DungeonEncounterfmt[] = "niixissssssssssssssssxx";
+char const CreatureTypefmt[] = "nxx";
+char const CurrencyTypesfmt[] = "nixxxiiiiix";
+char const DestructibleModelDatafmt[] = "ixxixxxixxxixxxixxxxxxxx";
+char const DungeonEncounterfmt[] = "iiixisxx";
char const DurabilityCostsfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiii";
char const DurabilityQualityfmt[] = "nf";
-char const EmotesEntryfmt[] = "nxxiiix";
+char const EmotesEntryfmt[] = "nxxiiixx";
char const EmotesTextEntryfmt[] = "nxixxxxxxxxxxxxxxxx";
-char const FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixssssssssssssssssxxxxxxxxxxxxxxxxxx";
+char const FactionEntryfmt[] = "niiiiiiiiiiiiiiiiiiffixsxi";
char const FactionTemplateEntryfmt[] = "niiiiiiiiiiiii";
-char const GameObjectDisplayInfofmt[] = "nsxxxxxxxxxxffffffx";
-char const GemPropertiesEntryfmt[] = "nixxi";
+char const GameObjectDisplayInfofmt[] = "nsxxxxxxxxxxffffffxxx";
+char const GemPropertiesEntryfmt[] = "nixxii";
char const GlyphPropertiesfmt[] = "niii";
char const GlyphSlotfmt[] = "nii";
-char const GtBarberShopCostBasefmt[] = "f";
-char const GtCombatRatingsfmt[] = "f";
-char const GtChanceToMeleeCritBasefmt[] = "f";
-char const GtChanceToMeleeCritfmt[] = "f";
-char const GtChanceToSpellCritBasefmt[] = "f";
-char const GtChanceToSpellCritfmt[] = "f";
-char const GtNPCManaCostScalerfmt[] = "f";
+char const GtBarberShopCostBasefmt[] = "xf";
+char const GtCombatRatingsfmt[] = "xf";
+char const GtOCTHpPerStaminafmt[] = "df";
+char const GtChanceToMeleeCritBasefmt[] = "xf";
+char const GtChanceToMeleeCritfmt[] = "xf";
+char const GtChanceToSpellCritBasefmt[] = "xf";
+char const GtChanceToSpellCritfmt[] = "xf";
+char const GtNPCManaCostScalerfmt[] = "xf";
char const GtOCTClassCombatRatingScalarfmt[] = "df";
char const GtOCTRegenHPfmt[] = "f";
//char const GtOCTRegenMPfmt[] = "f";
-char const GtRegenHPPerSptfmt[] = "f";
-char const GtRegenMPPerSptfmt[] = "f";
+char const GtRegenMPPerSptfmt[] = "xf";
+char const GtSpellScalingfmt[] = "df";
+char const GtOCTBaseHPByClassfmt[] = "df";
+char const GtOCTBaseMPByClassfmt[] = "df";
+char const GuildPerkSpellsfmt[] = "dii";
char const Holidaysfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiixxsiix";
-char const Itemfmt[] = "niiiiiii";
-char const ItemBagFamilyfmt[] = "nxxxxxxxxxxxxxxxxx";
+char const ImportPriceArmorfmt[] = "nffff";
+char const ImportPriceQualityfmt[] = "nf";
+char const ImportPriceShieldfmt[] = "nf";
+char const ImportPriceWeaponfmt[] = "nf";
+char const ItemPriceBasefmt[] = "diff";
+char const ItemReforgefmt[] = "nifif";
+char const ItemBagFamilyfmt[] = "nx";
+char const ItemArmorQualityfmt[] = "nfffffffi";
+char const ItemArmorShieldfmt[] = "nifffffff";
+char const ItemArmorTotalfmt[] = "niffff";
+char const ItemClassfmt[] = "dixxfx";
+char const ItemDamagefmt[] = "nfffffffi";
+char const ItemDisenchantLootfmt[] = "niiiiii";
//char const ItemDisplayTemplateEntryfmt[] = "nxxxxxxxxxxixxxxxxxxxxx";
-//char const ItemCondExtCostsEntryfmt[] = "xiii";
-char const ItemExtendedCostEntryfmt[] = "niiiiiiiiiiiiiix";
-char const ItemLimitCategoryEntryfmt[] = "nxxxxxxxxxxxxxxxxxii";
-char const ItemRandomPropertiesfmt[] = "nxiiixxssssssssssssssssx";
-char const ItemRandomSuffixfmt[] = "nssssssssssssssssxxiiixxiiixx";
-char const ItemSetEntryfmt[] = "dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
-char const LFGDungeonEntryfmt[] = "nssssssssssssssssxiiiiiiiiixxixixxxxxxxxxxxxxxxxx";
+char const ItemLimitCategoryEntryfmt[] = "nxii";
+char const ItemRandomPropertiesfmt[] = "nxiiixxs";
+char const ItemRandomSuffixfmt[] = "nsxiiiiiiiiii";
+char const ItemSetEntryfmt[] = "dsiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii";
+char const LFGDungeonEntryfmt[] = "nsiiiiiiiiixxixixixxx";
char const LiquidTypefmt[] = "nxxixixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char const LockEntryfmt[] = "niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";
-char const MailTemplateEntryfmt[] = "nxxxxxxxxxxxxxxxxxssssssssssssssssx";
-char const MapEntryfmt[] = "nxixxssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixiffxiix";
-char const MapDifficultyEntryfmt[] = "diisxxxxxxxxxxxxxxxxiix";
-char const MovieEntryfmt[] = "nxx";
-char const OverrideSpellDatafmt[] = "niiiiiiiiiix";
+char const PhaseEntryfmt[] = "nsi";
+char const MailTemplateEntryfmt[] = "nxs";
+char const MapEntryfmt[] = "nxixxxsixxixiffxiixi";
+char const MapDifficultyEntryfmt[] = "diisiix";
+char const MovieEntryfmt[] = "nxxx";
+char const MountCapabilityfmt[] = "niiiiiii";
+char const MountTypefmt[] = "niiiiiiiiiiiiiiiiiiiiiiii";
+char const NameGenfmt[] = "dsii";
+char const NumTalentsAtLevelfmt[] = "df";
+char const OverrideSpellDatafmt[] = "niiiiiiiiiixx";
char const QuestFactionRewardfmt[] = "niiiiiiiiii";
-char const QuestSortEntryfmt[] = "nxxxxxxxxxxxxxxxxx";
+char const QuestSortEntryfmt[] = "nx";
char const QuestXPfmt[] = "niiiiiiiiii";
char const PvPDifficultyfmt[] = "diiiii";
char const RandomPropertiesPointsfmt[] = "niiiiiiiiiiiiiii";
-char const ScalingStatDistributionfmt[] = "niiiiiiiiiiiiiiiiiiiii";
-char const ScalingStatValuesfmt[] = "iniiiiiiiiiiiiiiiiiiiiii";
-char const SkillLinefmt[] = "nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxi";
-char const SkillLineAbilityfmt[] = "niiiixxiiiiixx";
-char const SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+char const ScalingStatDistributionfmt[] = "niiiiiiiiiiiiiiiiiiiixi";
+char const ScalingStatValuesfmt[] = "iniiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii";
+char const SkillLinefmt[] = "nisxixi";
+char const SkillLineAbilityfmt[] = "niiiixxiiiiiii";
+char const SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char const SpellCastTimefmt[] = "nixx";
-char const SpellCategoryfmt[] = "ni";
+char const SpellCategoriesEntryfmt[] = "diiiiii";
+char const SpellCategoryfmt[] = "nixx";
char const SpellDifficultyfmt[] = "niiii";
const std::string CustomSpellDifficultyfmt = "ppppp";
const std::string CustomSpellDifficultyIndex = "id";
char const SpellDurationfmt[] = "niii";
-char const SpellEntryfmt[] = "niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxfffxx";
-const std::string CustomSpellEntryfmt = "papppppppppppapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa";
+// 0 10 20 26
+char const SpellEffectEntryfmt[] = "nifiiiffiiiiiifiifiiiiiiiix";
+const std::string CustomSpellEffectEntryfmt = "ppppppppppapppappppppppppp";
+const std::string CustomSpellEffectEntryIndex = "Id";
+// 0 10 20 30 40 47
+char const SpellEntryfmt[] = "niiiiiiiiiiiiiiifiiiissxxiixxifiiiiiiixiiiiiiiix";
+const std::string CustomSpellEntryfmt = "ppppppppppppppapaaaaaaaaapaaaaaapapppaapppaaapa";
const std::string CustomSpellEntryIndex = "Id";
-char const SpellFocusObjectfmt[] = "nxxxxxxxxxxxxxxxxx";
-char const SpellItemEnchantmentfmt[] = "nxiiiiiixxxiiissssssssssssssssxiiiiiii";
+char const SpellFocusObjectfmt[] = "nx";
+char const SpellItemEnchantmentfmt[] = "nxiiiiiixxxiiisiiiiiiix";
char const SpellItemEnchantmentConditionfmt[] = "nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
char const SpellRadiusfmt[] = "nfff";
-char const SpellRangefmt[] = "nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+char const SpellRangefmt[] = "nffffixx";
+char const SpellReagentsEntryfmt[] = "diiiiiiiiiiiiiiii";
+char const SpellScalingEntryfmt[] = "diiiiffffffffffi";
+char const SpellTotemsEntryfmt[] = "niiii";
+char const SpellTargetRestrictionsEntryfmt[] = "nxiiii";
+char const SpellPowerEntryfmt[] = "diiiiixf";
+char const SpellInterruptsEntryfmt[] = "dixixi";
+char const SpellEquippedItemsEntryfmt[] = "diii";
+char const SpellAuraOptionsEntryfmt[] = "niiii";
+char const SpellAuraRestrictionsEntryfmt[] = "diiiiiiii";
+char const SpellCastingRequirementsEntryfmt[] = "dixxixi";
+char const SpellClassOptionsEntryfmt[] = "dxiiiix";
+char const SpellCooldownsEntryfmt[] = "diii";
+char const SpellLevelsEntryfmt[] = "diii";
char const SpellRuneCostfmt[] = "niiii";
-char const SpellShapeshiftfmt[] = "nxxxxxxxxxxxxxxxxxxiixiiixxiiiiiiii";
+char const SpellShapeshiftEntryfmt[] = "nixixx";
+char const SpellShapeshiftFormfmt[] = "nxxiixiiixxiiiiiiiixx";
char const StableSlotPricesfmt[] = "ni";
char const SummonPropertiesfmt[] = "niiiii";
-char const TalentEntryfmt[] = "niiiiiiiixxxxixxixxxxxx";
-char const TalentTabEntryfmt[] = "nxxxxxxxxxxxxxxxxxxxiiix";
-char const TaxiNodesEntryfmt[] = "nifffssssssssssssssssxii";
+char const TalentEntryfmt[] = "niiiiiiiiixxixxxxxx";
+char const TalentTabEntryfmt[] = "nxxiiixxxii";
+char const TalentTreePrimarySpellsfmt[] = "diix";
+char const TaxiNodesEntryfmt[] = "nifffsiiixx";
char const TaxiPathEntryfmt[] = "niii";
char const TaxiPathNodeEntryfmt[] = "diiifffiiii";
-char const TeamContributionPointsfmt[] = "df";
-char const TotemCategoryEntryfmt[] = "nxxxxxxxxxxxxxxxxxii";
+char const TotemCategoryEntryfmt[] = "nxii";
+char const UnitPowerBarfmt[] = "niixxxxxxxxxxxxxxxxxxxxxxxx";
char const TransportAnimationfmt[] = "diifffx";
char const TransportRotationfmt[] = "diiffff";
char const VehicleEntryfmt[] = "niffffiiiiiiiifffffffffffffffssssfifiixx";
-char const VehicleSeatEntryfmt[] = "niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx";
-char const WMOAreaTableEntryfmt[] = "niiixxxxxiixxxxxxxxxxxxxxxxx";
-char const WorldMapAreaEntryfmt[] = "xinxffffixx";
-char const WorldMapOverlayEntryfmt[] = "nxiiiixxxxxxxxxxx";
-char const WorldSafeLocsEntryfmt[] = "nifffxxxxxxxxxxxxxxxxx";
+char const VehicleSeatEntryfmt[] = "niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxxxxxxxxxx";
+char const WMOAreaTableEntryfmt[] = "niiixxxxxiixxxx";
+char const WorldMapAreaEntryfmt[] = "xinxffffixxxxx";
+char const WorldMapOverlayEntryfmt[] = "nxiiiixxxxxxxxx";
+char const WorldSafeLocsEntryfmt[] = "nifffx";
#endif
diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h
index 0030dfa6c4b..84f5a5ae821 100644
--- a/src/server/game/DungeonFinding/LFG.h
+++ b/src/server/game/DungeonFinding/LFG.h
@@ -44,17 +44,21 @@ enum LfgUpdateType
LFG_UPDATETYPE_DEFAULT = 0, // Internal Use
LFG_UPDATETYPE_LEADER_UNK1 = 1, // FIXME: At group leave
LFG_UPDATETYPE_ROLECHECK_ABORTED = 4,
- LFG_UPDATETYPE_JOIN_QUEUE = 5,
- LFG_UPDATETYPE_ROLECHECK_FAILED = 6,
- LFG_UPDATETYPE_REMOVED_FROM_QUEUE = 7,
- LFG_UPDATETYPE_PROPOSAL_FAILED = 8,
- LFG_UPDATETYPE_PROPOSAL_DECLINED = 9,
- LFG_UPDATETYPE_GROUP_FOUND = 10,
- LFG_UPDATETYPE_ADDED_TO_QUEUE = 12,
- LFG_UPDATETYPE_PROPOSAL_BEGIN = 13,
- LFG_UPDATETYPE_UPDATE_STATUS = 14,
- LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 15,
- LFG_UPDATETYPE_GROUP_DISBAND_UNK16 = 16, // FIXME: Sometimes at group disband
+ LFG_UPDATETYPE_JOIN_QUEUE = 6,
+ LFG_UPDATETYPE_ROLECHECK_FAILED = 7,
+ LFG_UPDATETYPE_REMOVED_FROM_QUEUE = 8,
+ LFG_UPDATETYPE_PROPOSAL_FAILED = 9,
+ LFG_UPDATETYPE_PROPOSAL_DECLINED = 10,
+ LFG_UPDATETYPE_GROUP_FOUND = 11,
+ LFG_UPDATETYPE_ADDED_TO_QUEUE = 13,
+ LFG_UPDATETYPE_PROPOSAL_BEGIN = 14,
+ LFG_UPDATETYPE_UPDATE_STATUS = 15,
+ LFG_UPDATETYPE_GROUP_MEMBER_OFFLINE = 16,
+ LFG_UPDATETYPE_GROUP_DISBAND_UNK16 = 17, // FIXME: Sometimes at group disband
+ LFG_UPDATETYPE_JOIN_QUEUE_INITIAL = 24,
+ LFG_UPDATETYPE_DUNGEON_FINISHED = 25,
+ LFG_UPDATETYPE_PARTY_ROLE_NOT_AVAILABLE = 43,
+ LFG_UPDATETYPE_JOIN_LFG_OBJECT_FAILED = 45,
};
enum LfgState
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 2dcba7b6a76..61fb6191710 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -195,7 +195,6 @@ void LFGMgr::LoadLFGDungeons(bool reload /* = false */)
// Fill teleport locations from DB
QueryResult result = WorldDatabase.Query("SELECT dungeonId, position_x, position_y, position_z, orientation FROM lfg_entrances");
-
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 lfg entrance positions. DB table `lfg_entrances` is empty!");
@@ -235,10 +234,10 @@ void LFGMgr::LoadLFGDungeons(bool reload /* = false */)
// No teleport coords in database, load from areatriggers
if (dungeon.type != LFG_TYPE_RANDOM && dungeon.x == 0.0f && dungeon.y == 0.0f && dungeon.z == 0.0f)
{
- AreaTrigger const* at = sObjectMgr->GetMapEntranceTrigger(dungeon.map);
+ AreaTriggerStruct const* at = sObjectMgr->GetMapEntranceTrigger(dungeon.map);
if (!at)
{
- TC_LOG_ERROR("sql.sql", "Failed to load dungeon %s, cant find areatrigger for map %u", dungeon.name.c_str(), dungeon.map);
+ TC_LOG_ERROR("sql.sql", "Failed to load dungeon %s (Id: %u), cant find areatrigger for map %u", dungeon.name.c_str(), dungeon.id, dungeon.map);
continue;
}
@@ -286,7 +285,7 @@ void LFGMgr::Update(uint32 diff)
RestoreState(guid, "Remove Obsolete RoleCheck");
SendLfgRoleCheckUpdate(guid, roleCheck);
if (guid == roleCheck.leader)
- SendLfgJoinResult(guid, LfgJoinResultData(LFG_JOIN_FAILED, LFG_ROLECHECK_MISSING_ROLE));
+ SendLfgJoinResult(guid, LfgJoinResultData(LFG_JOIN_ROLE_CHECK_FAILED, LFG_ROLECHECK_MISSING_ROLE));
}
RestoreState(itRoleCheck->first, "Remove Obsolete RoleCheck");
@@ -343,10 +342,10 @@ void LFGMgr::Update(uint32 diff)
if (uint64 gguid = GetGroup(guid))
{
SetState(gguid, LFG_STATE_PROPOSAL);
- SendLfgUpdateParty(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)), true);
}
else
- SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_PROPOSAL_BEGIN, GetSelectedDungeons(guid), GetComment(guid)), false);
SendLfgUpdateProposal(guid, proposal);
}
@@ -361,7 +360,7 @@ void LFGMgr::Update(uint32 diff)
m_QueueTimer = 0;
time_t currTime = time(NULL);
for (LfgQueueContainer::iterator it = QueuesStore.begin(); it != QueuesStore.end(); ++it)
- it->second.UpdateQueueTimers(currTime);
+ it->second.UpdateQueueTimers(it->first, currTime);
}
else
m_QueueTimer += diff;
@@ -495,7 +494,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
if (Player* plrg = itr->GetSource())
{
if (!plrg->GetSession()->HasPermission(rbac::RBAC_PERM_JOIN_DUNGEON_FINDER))
- joinData.result = LFG_JOIN_PARTY_NOT_MEET_REQS;
+ joinData.result = LFG_JOIN_INTERNAL_ERROR;
if (plrg->HasAura(LFG_SPELL_DUNGEON_DESERTER))
joinData.result = LFG_JOIN_PARTY_DESERTER;
else if (plrg->HasAura(LFG_SPELL_DUNGEON_COOLDOWN))
@@ -557,7 +556,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
// if we have lockmap then there are no compatible dungeons
GetCompatibleDungeons(dungeons, players, joinData.lockmap);
if (dungeons.empty())
- joinData.result = grp ? LFG_JOIN_PARTY_NOT_MEET_REQS : LFG_JOIN_NOT_MEET_REQS;
+ joinData.result = grp ? LFG_JOIN_INTERNAL_ERROR : LFG_JOIN_NOT_MEET_REQS;
}
}
@@ -606,7 +605,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
if (Player* plrg = itr->GetSource())
{
uint64 pguid = plrg->GetGUID();
- plrg->GetSession()->SendLfgUpdateParty(updateData);
+ plrg->GetSession()->SendLfgUpdateStatus(updateData, true);
SetState(pguid, LFG_STATE_ROLECHECK);
if (!isContinue)
SetSelectedDungeons(pguid, dungeons);
@@ -637,7 +636,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const
}
// Send update to player
player->GetSession()->SendLfgJoinResult(joinData);
- player->GetSession()->SendLfgUpdatePlayer(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment));
+ player->GetSession()->SendLfgUpdateStatus(LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment), false);
SetState(gguid, LFG_STATE_QUEUED);
SetRoles(guid, roles);
debugNames.append(player->GetName());
@@ -672,14 +671,14 @@ void LFGMgr::LeaveLfg(uint64 guid)
for (LfgGuidSet::const_iterator it = players.begin(); it != players.end(); ++it)
{
SetState(*it, LFG_STATE_NONE);
- SendLfgUpdateParty(*it, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE));
+ SendLfgUpdateStatus(*it, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE), true);
}
}
else
{
LFGQueue& queue = GetQueue(guid);
queue.RemoveFromQueue(guid);
- SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE), false);
SetState(guid, LFG_STATE_NONE);
}
break;
@@ -768,7 +767,11 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /*
else
dungeons = roleCheck.dungeons;
- LfgJoinResultData joinData = LfgJoinResultData(LFG_JOIN_FAILED, roleCheck.state);
+ LfgJoinResult joinResult = LFG_JOIN_FAILED;
+ if (roleCheck.state == LFG_ROLECHECK_MISSING_ROLE || roleCheck.state == LFG_ROLECHECK_WRONG_ROLES)
+ joinResult = LFG_JOIN_ROLE_CHECK_FAILED;
+
+ LfgJoinResultData joinData = LfgJoinResultData(joinResult, roleCheck.state);
for (LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
{
uint64 pguid = it->first;
@@ -784,12 +787,12 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /*
case LFG_ROLECHECK_FINISHED:
SetState(pguid, LFG_STATE_QUEUED);
SetRoles(pguid, it->second);
- SendLfgUpdateParty(pguid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, GetComment(pguid)));
+ SendLfgUpdateStatus(pguid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, dungeons, GetComment(pguid)), true);
break;
default:
if (roleCheck.leader == pguid)
SendLfgJoinResult(pguid, joinData);
- SendLfgUpdateParty(pguid, LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED));
+ SendLfgUpdateStatus(pguid, LfgUpdateData(LFG_UPDATETYPE_ROLECHECK_FAILED), true);
RestoreState(pguid, "Rolecheck Failed");
break;
}
@@ -1053,16 +1056,16 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
if (gguid)
{
waitTime = int32((joinTime - queue.GetJoinTime(gguid)) / IN_MILLISECONDS);
- SendLfgUpdateParty(pguid, updateData);
+ SendLfgUpdateStatus(pguid, updateData, false);
}
else
{
waitTime = int32((joinTime - queue.GetJoinTime(pguid)) / IN_MILLISECONDS);
- SendLfgUpdatePlayer(pguid, updateData);
+ SendLfgUpdateStatus(pguid, updateData, false);
}
updateData.updateType = LFG_UPDATETYPE_REMOVED_FROM_QUEUE;
- SendLfgUpdatePlayer(pguid, updateData);
- SendLfgUpdateParty(pguid, updateData);
+ SendLfgUpdateStatus(pguid, updateData, true);
+ SendLfgUpdateStatus(pguid, updateData, false);
// Update timers
uint8 role = GetRoles(pguid);
@@ -1154,10 +1157,10 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
if (gguid != guid)
{
RestoreState(it->second.group, "Proposal Fail (someone in group didn't accepted)");
- SendLfgUpdateParty(guid, updateData);
+ SendLfgUpdateStatus(guid, updateData, true);
}
else
- SendLfgUpdatePlayer(guid, updateData);
+ SendLfgUpdateStatus(guid, updateData, false);
}
else
{
@@ -1166,10 +1169,10 @@ void LFGMgr::RemoveProposal(LfgProposalContainer::iterator itProposal, LfgUpdate
if (gguid != guid)
{
SetState(gguid, LFG_STATE_QUEUED);
- SendLfgUpdateParty(guid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)), true);
}
else
- SendLfgUpdatePlayer(guid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_ADDED_TO_QUEUE, GetSelectedDungeons(guid), GetComment(guid)), false);
}
}
@@ -1726,7 +1729,7 @@ void LFGMgr::RemoveGroupData(uint64 guid)
if (state != LFG_STATE_PROPOSAL)
{
SetState(*it, LFG_STATE_NONE);
- SendLfgUpdateParty(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE));
+ SendLfgUpdateStatus(guid, LfgUpdateData(LFG_UPDATETYPE_REMOVED_FROM_QUEUE), true);
}
}
GroupsStore.erase(it);
@@ -1808,16 +1811,10 @@ void LFGMgr::SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck)
player->GetSession()->SendLfgRoleCheckUpdate(roleCheck);
}
-void LFGMgr::SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data)
+void LFGMgr::SendLfgUpdateStatus(uint64 guid, LfgUpdateData const& data, bool party)
{
if (Player* player = ObjectAccessor::FindPlayer(guid))
- player->GetSession()->SendLfgUpdatePlayer(data);
-}
-
-void LFGMgr::SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data)
-{
- if (Player* player = ObjectAccessor::FindPlayer(guid))
- player->GetSession()->SendLfgUpdateParty(data);
+ player->GetSession()->SendLfgUpdateStatus(data, party);
}
void LFGMgr::SendLfgJoinResult(uint64 guid, LfgJoinResultData const& data)
@@ -1849,18 +1846,22 @@ bool LFGMgr::IsLfgGroup(uint64 guid)
return guid && IS_GROUP_GUID(guid) && GroupsStore[guid].IsLfgGroup();
}
-LFGQueue& LFGMgr::GetQueue(uint64 guid)
+uint8 LFGMgr::GetQueueId(uint64 guid)
{
- uint8 queueId = 0;
if (IS_GROUP_GUID(guid))
{
LfgGuidSet const& players = GetPlayers(guid);
uint64 pguid = players.empty() ? 0 : (*players.begin());
if (pguid)
- queueId = GetTeam(pguid);
+ return GetTeam(pguid);
}
- else
- queueId = GetTeam(guid);
+
+ return GetTeam(guid);
+}
+
+LFGQueue& LFGMgr::GetQueue(uint64 guid)
+{
+ uint8 queueId = GetQueueId(guid);
return QueuesStore[queueId];
}
@@ -1875,6 +1876,16 @@ bool LFGMgr::AllQueued(LfgGuidList const& check)
return true;
}
+time_t LFGMgr::GetQueueJoinTime(uint64 guid)
+{
+ uint8 queueId = GetQueueId(guid);
+ LfgQueueContainer::const_iterator itr = QueuesStore.find(queueId);
+ if (itr != QueuesStore.end())
+ return itr->second.GetJoinTime(guid);
+
+ return 0;
+}
+
// Only for debugging purposes
void LFGMgr::Clean()
{
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 8e33ba0a2f6..34e3fdd9670 100644
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -94,23 +94,24 @@ enum LfgTeleportError
enum LfgJoinResult
{
// 3 = No client reaction | 18 = "Rolecheck failed"
- LFG_JOIN_OK = 0, // Joined (no client msg)
- LFG_JOIN_FAILED = 1, // RoleCheck Failed
- LFG_JOIN_GROUPFULL = 2, // Your group is full
- LFG_JOIN_INTERNAL_ERROR = 4, // Internal LFG Error
- LFG_JOIN_NOT_MEET_REQS = 5, // You do not meet the requirements for the chosen dungeons
- LFG_JOIN_PARTY_NOT_MEET_REQS = 6, // One or more party members do not meet the requirements for the chosen dungeons
- LFG_JOIN_MIXED_RAID_DUNGEON = 7, // You cannot mix dungeons, raids, and random when picking dungeons
- LFG_JOIN_MULTI_REALM = 8, // The dungeon you chose does not support players from multiple realms
- LFG_JOIN_DISCONNECTED = 9, // One or more party members are pending invites or disconnected
- LFG_JOIN_PARTY_INFO_FAILED = 10, // Could not retrieve information about some party members
- LFG_JOIN_DUNGEON_INVALID = 11, // One or more dungeons was not valid
- LFG_JOIN_DESERTER = 12, // You can not queue for dungeons until your deserter debuff wears off
- LFG_JOIN_PARTY_DESERTER = 13, // One or more party members has a deserter debuff
- LFG_JOIN_RANDOM_COOLDOWN = 14, // You can not queue for random dungeons while on random dungeon cooldown
- LFG_JOIN_PARTY_RANDOM_COOLDOWN = 15, // One or more party members are on random dungeon cooldown
- LFG_JOIN_TOO_MUCH_MEMBERS = 16, // You can not enter dungeons with more that 5 party members
- LFG_JOIN_USING_BG_SYSTEM = 17 // You can not use the dungeon system while in BG or arenas
+ LFG_JOIN_OK = 0x00, // Joined (no client msg)
+ LFG_JOIN_FAILED = 0x1B, // RoleCheck Failed
+ LFG_JOIN_GROUPFULL = 0x1C, // Your group is full
+ LFG_JOIN_INTERNAL_ERROR = 0x1E, // Internal LFG Error
+ LFG_JOIN_NOT_MEET_REQS = 0x1F, // You do not meet the requirements for the chosen dungeons
+ //LFG_JOIN_PARTY_NOT_MEET_REQS = 6, // One or more party members do not meet the requirements for the chosen dungeons
+ LFG_JOIN_MIXED_RAID_DUNGEON = 0x20, // You cannot mix dungeons, raids, and random when picking dungeons
+ LFG_JOIN_MULTI_REALM = 0x21, // The dungeon you chose does not support players from multiple realms
+ LFG_JOIN_DISCONNECTED = 0x22, // One or more party members are pending invites or disconnected
+ LFG_JOIN_PARTY_INFO_FAILED = 0x23, // Could not retrieve information about some party members
+ LFG_JOIN_DUNGEON_INVALID = 0x24, // One or more dungeons was not valid
+ LFG_JOIN_DESERTER = 0x25, // You can not queue for dungeons until your deserter debuff wears off
+ LFG_JOIN_PARTY_DESERTER = 0x26, // One or more party members has a deserter debuff
+ LFG_JOIN_RANDOM_COOLDOWN = 0x27, // You can not queue for random dungeons while on random dungeon cooldown
+ LFG_JOIN_PARTY_RANDOM_COOLDOWN = 0x28, // One or more party members are on random dungeon cooldown
+ LFG_JOIN_TOO_MUCH_MEMBERS = 0x29, // You can not enter dungeons with more that 5 party members
+ LFG_JOIN_USING_BG_SYSTEM = 0x2A, // You can not use the dungeon system while in BG or arenas
+ LFG_JOIN_ROLE_CHECK_FAILED = 0x2B // Role check failed, client shows special error
};
/// Role check states
@@ -157,7 +158,7 @@ struct LfgJoinResultData
LfgLockPartyMap lockmap;
};
-// Data needed by SMSG_LFG_UPDATE_PARTY and SMSG_LFG_UPDATE_PLAYER
+// Data needed by SMSG_LFG_UPDATE_STATUS
struct LfgUpdateData
{
LfgUpdateData(LfgUpdateType _type = LFG_UPDATETYPE_DEFAULT): updateType(_type), state(LFG_STATE_NONE), comment("") { }
@@ -175,12 +176,14 @@ struct LfgUpdateData
// Data needed by SMSG_LFG_QUEUE_STATUS
struct LfgQueueStatusData
{
- LfgQueueStatusData(uint32 _dungeonId = 0, int32 _waitTime = -1, int32 _waitTimeAvg = -1, int32 _waitTimeTank = -1, int32 _waitTimeHealer = -1,
+ LfgQueueStatusData(uint8 _queueId = 0, uint32 _dungeonId = 0, time_t _joinTime = 0, int32 _waitTime = -1, int32 _waitTimeAvg = -1, int32 _waitTimeTank = -1, int32 _waitTimeHealer = -1,
int32 _waitTimeDps = -1, uint32 _queuedTime = 0, uint8 _tanks = 0, uint8 _healers = 0, uint8 _dps = 0) :
- dungeonId(_dungeonId), waitTime(_waitTime), waitTimeAvg(_waitTimeAvg), waitTimeTank(_waitTimeTank), waitTimeHealer(_waitTimeHealer),
- waitTimeDps(_waitTimeDps), queuedTime(_queuedTime), tanks(_tanks), healers(_healers), dps(_dps) { }
+ queueId(_queueId), dungeonId(_dungeonId), joinTime(_joinTime), waitTime(_waitTime), waitTimeAvg(_waitTimeAvg), waitTimeTank(_waitTimeTank),
+ waitTimeHealer(_waitTimeHealer), waitTimeDps(_waitTimeDps), queuedTime(_queuedTime), tanks(_tanks), healers(_healers), dps(_dps) { }
+ uint8 queueId;
uint32 dungeonId;
+ time_t joinTime;
int32 waitTime;
int32 waitTimeAvg;
int32 waitTimeTank;
@@ -268,7 +271,7 @@ 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)
{ }
- LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name[0]), map(dbc->map),
+ LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name), map(dbc->map),
type(dbc->type), expansion(dbc->expansion), group(dbc->grouptype),
minlevel(dbc->minlevel), maxlevel(dbc->maxlevel), difficulty(Difficulty(dbc->difficulty)),
seasonal(dbc->flags & LFG_FLAG_SEASONAL), x(0.0f), y(0.0f), z(0.0f), o(0.0f)
@@ -407,8 +410,12 @@ class LFGMgr
uint8 GetPlayerCount(uint64 guid);
/// Add a new Proposal
uint32 AddProposal(LfgProposal& proposal);
+ /// Returns queue id
+ uint8 GetQueueId(uint64 guid);
/// Checks if all players are queued
bool AllQueued(LfgGuidList const& check);
+ /// Gets queue join time
+ time_t GetQueueJoinTime(uint64 guid);
/// Checks if given roles match, modifies given roles map with new roles
static bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true);
/// Checks if given players are ignoring each other
@@ -435,7 +442,8 @@ class LFGMgr
void MakeNewGroup(LfgProposal const& proposal);
// Generic
- LFGQueue &GetQueue(uint64 guid);
+ LFGQueue& GetQueue(uint64 guid);
+
LfgDungeonSet const& GetDungeonsByRandom(uint32 randomdungeon);
LfgType GetDungeonType(uint32 dungeon);
@@ -443,8 +451,7 @@ class LFGMgr
void SendLfgJoinResult(uint64 guid, LfgJoinResultData const& data);
void SendLfgRoleChosen(uint64 guid, uint64 pguid, uint8 roles);
void SendLfgRoleCheckUpdate(uint64 guid, LfgRoleCheck const& roleCheck);
- void SendLfgUpdateParty(uint64 guid, LfgUpdateData const& data);
- void SendLfgUpdatePlayer(uint64 guid, LfgUpdateData const& data);
+ void SendLfgUpdateStatus(uint64 guid, LfgUpdateData const& data, bool party);
void SendLfgUpdateProposal(uint64 guid, LfgProposal const& proposal);
LfgGuidSet const& GetPlayers(uint64 guid);
diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp
index 67a9f0afc69..a44c7780c6b 100644
--- a/src/server/game/DungeonFinding/LFGQueue.cpp
+++ b/src/server/game/DungeonFinding/LFGQueue.cpp
@@ -537,7 +537,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(LfgGuidList check)
return LFG_COMPATIBLES_MATCH;
}
-void LFGQueue::UpdateQueueTimers(time_t currTime)
+void LFGQueue::UpdateQueueTimers(uint8 queueId, time_t currTime)
{
TC_LOG_TRACE("lfg.queue.timers.update", "Updating queue timers...");
for (LfgQueueDataContainer::iterator itQueue = QueueDataStore.begin(); itQueue != QueueDataStore.end(); ++itQueue)
@@ -578,7 +578,7 @@ void LFGQueue::UpdateQueueTimers(time_t currTime)
if (queueinfo.bestCompatible.empty())
FindBestCompatibleInQueue(itQueue);
- LfgQueueStatusData queueData(dungeonId, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps);
+ LfgQueueStatusData queueData(queueId, dungeonId, queueinfo.joinTime, waitTime, wtAvg, wtTank, wtHealer, wtDps, queuedTime, queueinfo.tanks, queueinfo.healers, queueinfo.dps);
for (LfgRolesMap::const_iterator itPlayer = queueinfo.roles.begin(); itPlayer != queueinfo.roles.end(); ++itPlayer)
{
uint64 pguid = itPlayer->first;
@@ -587,9 +587,13 @@ void LFGQueue::UpdateQueueTimers(time_t currTime)
}
}
-time_t LFGQueue::GetJoinTime(uint64 guid)
+time_t LFGQueue::GetJoinTime(uint64 guid) const
{
- return QueueDataStore[guid].joinTime;
+ LfgQueueDataContainer::const_iterator itr = QueueDataStore.find(guid);
+ if (itr != QueueDataStore.end())
+ return itr->second.joinTime;
+
+ return 0;
}
std::string LFGQueue::DumpQueueInfo() const
diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h
index b66121802c6..0312c926991 100644
--- a/src/server/game/DungeonFinding/LFGQueue.h
+++ b/src/server/game/DungeonFinding/LFGQueue.h
@@ -100,8 +100,8 @@ class LFGQueue
void UpdateWaitTimeDps(int32 waitTime, uint32 dungeonId);
// Update Queue timers
- void UpdateQueueTimers(time_t currTime);
- time_t GetJoinTime(uint64 guid);
+ void UpdateQueueTimers(uint8 queueId, time_t currTime);
+ time_t GetJoinTime(uint64 guid) const;
// Find new group
uint8 FindGroups();
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 1f182ce0761..45c8c1b8bb2 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -193,7 +193,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth
//else if (state == LFG_STATE_BOOT)
// Update internal kick cooldown of kicked
- player->GetSession()->SendLfgUpdateParty(LfgUpdateData(LFG_UPDATETYPE_LEADER_UNK1));
+ player->GetSession()->SendLfgUpdateStatus(LfgUpdateData(LFG_UPDATETYPE_LEADER_UNK1), true);
if (isLFG && player->GetMap()->IsDungeon()) // Teleport player out the dungeon
sLFGMgr->TeleportPlayer(player, true);
}
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
new file mode 100644
index 00000000000..f399686d5d5
--- /dev/null
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "ObjectAccessor.h"
+#include "Unit.h"
+#include "SpellInfo.h"
+#include "Log.h"
+#include "AreaTrigger.h"
+
+AreaTrigger::AreaTrigger() : WorldObject(false), _duration(0)
+{
+ m_objectType |= TYPEMASK_AREATRIGGER;
+ m_objectTypeId = TYPEID_AREATRIGGER;
+
+ m_updateFlag = UPDATEFLAG_STATIONARY_POSITION;
+
+ m_valuesCount = AREATRIGGER_END;
+}
+
+AreaTrigger::~AreaTrigger()
+{
+}
+
+void AreaTrigger::AddToWorld()
+{
+ ///- Register the AreaTrigger for guid lookup and for caster
+ if (!IsInWorld())
+ {
+ sObjectAccessor->AddObject(this);
+ WorldObject::AddToWorld();
+ }
+}
+
+void AreaTrigger::RemoveFromWorld()
+{
+ ///- Remove the AreaTrigger from the accessor and from all lists of objects in world
+ if (IsInWorld())
+ {
+ if (!IsInWorld())
+ return;
+
+ WorldObject::RemoveFromWorld();
+ sObjectAccessor->RemoveObject(this);
+ }
+}
+
+bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* caster, SpellInfo const* spell, Position const& pos)
+{
+ SetMap(caster->GetMap());
+ Relocate(pos);
+ if (!IsPositionValid())
+ {
+ TC_LOG_ERROR("misc", "AreaTrigger (spell %u) not created. Invalid coordinates (X: %f Y: %f)", spell->Id, GetPositionX(), GetPositionY());
+ return false;
+ }
+
+ WorldObject::_Create(guidlow, HIGHGUID_AREATRIGGER, caster->GetPhaseMask());
+
+ SetEntry(triggerEntry);
+ SetDuration(spell->GetDuration());
+ SetObjectScale(1);
+
+ SetUInt32Value(AREATRIGGER_SPELLID, spell->Id);
+ SetUInt32Value(AREATRIGGER_SPELLVISUALID, spell->SpellVisual[0]);
+ SetUInt32Value(AREATRIGGER_DURATION, spell->GetDuration());
+ SetFloatValue(AREATRIGGER_FINAL_POS + 0, pos.GetPositionX());
+ SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY());
+ SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ());
+
+ if (!GetMap()->AddToMap(this))
+ return false;
+
+ return true;
+}
+
+void AreaTrigger::Update(uint32 p_time)
+{
+ if (GetDuration() > int32(p_time))
+ _duration -= p_time;
+ else
+ Remove(); // expired
+
+ WorldObject::Update(p_time);
+}
+
+void AreaTrigger::Remove()
+{
+ if (IsInWorld())
+ {
+ SendObjectDeSpawnAnim(GetGUID());
+ RemoveFromWorld();
+ AddObjectToRemoveList();
+ }
+}
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h
new file mode 100644
index 00000000000..cbfa4405b0e
--- /dev/null
+++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h
@@ -0,0 +1,46 @@
+/*
+ * 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 TRINITYCORE_AREATRIGGER_H
+#define TRINITYCORE_AREATRIGGER_H
+
+#include "Object.h"
+
+class Unit;
+class SpellInfo;
+
+class AreaTrigger : public WorldObject, public GridObject<AreaTrigger>
+{
+ public:
+ AreaTrigger();
+ ~AreaTrigger();
+
+ void AddToWorld();
+ void RemoveFromWorld();
+
+ bool CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* caster, SpellInfo const* spell, Position const& pos);
+ void Update(uint32 p_time);
+ void Remove();
+ uint32 GetSpellId() const { return GetUInt32Value(AREATRIGGER_SPELLID); }
+ int32 GetDuration() const { return _duration; }
+ void SetDuration(int32 newDuration) { _duration = newDuration; }
+ void Delay(int32 delaytime) { SetDuration(GetDuration() - delaytime); }
+
+ protected:
+ int32 _duration;
+};
+#endif
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index e41426edb3d..2fa82acdaf5 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -31,7 +31,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type
m_objectType |= TYPEMASK_CORPSE;
m_objectTypeId = TYPEID_CORPSE;
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION);
+ m_updateFlag = UPDATEFLAG_STATIONARY_POSITION;
m_valuesCount = CORPSE_END;
@@ -114,7 +114,6 @@ void Corpse::SaveToDB()
stmt->setString(index++, _ConcatFields(CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END)); // itemCache
stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_BYTES_1)); // bytes1
stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_BYTES_2)); // bytes2
- stmt->setUInt32(index++, GetUInt32Value(CORPSE_FIELD_GUILD)); // guildId
stmt->setUInt8 (index++, GetUInt32Value(CORPSE_FIELD_FLAGS)); // flags
stmt->setUInt8 (index++, GetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS)); // dynFlags
stmt->setUInt32(index++, uint32(m_time)); // time
@@ -160,10 +159,10 @@ void Corpse::DeleteFromDB(SQLTransaction& trans)
bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields)
{
- // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
- // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
- uint32 ownerGuid = fields[17].GetUInt32();
+ uint32 ownerGuid = fields[16].GetUInt32();
float posX = fields[0].GetFloat();
float posY = fields[1].GetFloat();
float posZ = fields[2].GetFloat();
@@ -176,15 +175,14 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields)
_LoadIntoDataField(fields[6].GetCString(), CORPSE_FIELD_ITEM, EQUIPMENT_SLOT_END);
SetUInt32Value(CORPSE_FIELD_BYTES_1, fields[7].GetUInt32());
SetUInt32Value(CORPSE_FIELD_BYTES_2, fields[8].GetUInt32());
- SetUInt32Value(CORPSE_FIELD_GUILD, fields[9].GetUInt32());
- SetUInt32Value(CORPSE_FIELD_FLAGS, fields[10].GetUInt8());
- SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[11].GetUInt8());
+ SetUInt32Value(CORPSE_FIELD_FLAGS, fields[9].GetUInt8());
+ SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[10].GetUInt8());
SetUInt64Value(CORPSE_FIELD_OWNER, MAKE_NEW_GUID(ownerGuid, 0, HIGHGUID_PLAYER));
- m_time = time_t(fields[12].GetUInt32());
+ m_time = time_t(fields[11].GetUInt32());
- uint32 instanceId = fields[14].GetUInt32();
- uint32 phaseMask = fields[15].GetUInt32();
+ uint32 instanceId = fields[13].GetUInt32();
+ uint32 phaseMask = fields[14].GetUInt32();
// place
SetLocationInstanceId(instanceId);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index e4bdc2d58fe..40a09114935 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -63,12 +63,12 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
return NULL;
}
-bool VendorItemData::RemoveItem(uint32 item_id)
+bool VendorItemData::RemoveItem(uint32 item_id, uint8 type)
{
bool found = false;
for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();)
{
- if ((*i)->item == item_id)
+ if ((*i)->item == item_id && (*i)->Type == type)
{
i = m_items.erase(i++);
found = true;
@@ -79,10 +79,10 @@ bool VendorItemData::RemoveItem(uint32 item_id)
return found;
}
-VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const
+VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const
{
for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i)
- if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost)
+ if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost && (*i)->Type == type)
return *i;
return NULL;
}
@@ -332,6 +332,7 @@ bool Creature::InitEntry(uint32 entry, uint32 /*team*/, const CreatureData* data
SetName(normalInfo->Name); // at normal entry always
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
+ SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f);
SetSpeed(MOVE_WALK, cinfo->speed_walk);
SetSpeed(MOVE_RUN, cinfo->speed_run);
@@ -607,13 +608,10 @@ void Creature::RegenerateMana()
// Combat and any controlled creature
if (IsInCombat() || GetCharmerOrOwnerGUID())
{
- if (!IsUnderLastManaUseEffect())
- {
- float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
- float Spirit = GetStat(STAT_SPIRIT);
+ float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
+ float Spirit = GetStat(STAT_SPIRIT);
- addvalue = uint32((Spirit / 5.0f + 17.0f) * ManaIncreaseRate);
- }
+ addvalue = uint32((Spirit / 5.0f + 17.0f) * ManaIncreaseRate);
}
else
addvalue = maxValue / 3;
@@ -1066,12 +1064,21 @@ void Creature::SelectLevel()
// mana
uint32 mana = stats->GenerateMana(cInfo);
-
SetCreateMana(mana);
- SetMaxPower(POWER_MANA, mana); // MAX Mana
- SetPower(POWER_MANA, mana);
- /// @todo set UNIT_FIELD_POWER*, for some creature class case (energy, etc)
+ switch (getClass())
+ {
+ case CLASS_WARRIOR:
+ setPowerType(POWER_RAGE);
+ break;
+ case CLASS_ROGUE:
+ setPowerType(POWER_ENERGY);
+ break;
+ default:
+ SetMaxPower(POWER_MANA, mana); // MAX Mana
+ SetPower(POWER_MANA, mana);
+ break;
+ }
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, (float)health);
SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana);
@@ -1677,7 +1684,7 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
if (bcontinue)
continue;
- if (spellInfo->ManaCost > GetPower(POWER_MANA))
+ if (spellInfo->ManaCost > (uint32)GetPower(POWER_MANA))
continue;
float range = spellInfo->GetMaxRange(false);
float minrange = spellInfo->GetMinRange(false);
@@ -1721,7 +1728,7 @@ SpellInfo const* Creature::reachWithSpellCure(Unit* victim)
if (bcontinue)
continue;
- if (spellInfo->ManaCost > GetPower(POWER_MANA))
+ if (spellInfo->ManaCost > (uint32)GetPower(POWER_MANA))
continue;
float range = spellInfo->GetMaxRange(true);
@@ -2132,11 +2139,6 @@ void Creature::SetInCombatWithZone()
}
}
-uint32 Creature::GetShieldBlockValue() const //dunno mob block value
-{
- return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
-}
-
void Creature::_AddCreatureSpellCooldown(uint32 spell_id, time_t end_time)
{
m_CreatureSpellCooldowns[spell_id] = end_time;
@@ -2451,110 +2453,6 @@ bool Creature::IsDungeonBoss() const
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
-bool Creature::SetWalk(bool enable)
-{
- if (!Unit::SetWalk(enable))
- return false;
-
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
- data.append(GetPackGUID());
- SendMessageToSet(&data, false);
- return true;
-}
-
-bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
-{
- //! It's possible only a packet is sent but moveflags are not updated
- //! Need more research on this
- if (!packetOnly && !Unit::SetDisableGravity(disable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
- data.append(GetPackGUID());
- SendMessageToSet(&data, false);
- return true;
-}
-
-bool Creature::SetSwim(bool enable)
-{
- if (!Unit::SetSwim(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_START_SWIM : SMSG_SPLINE_MOVE_STOP_SWIM);
- data.append(GetPackGUID());
- SendMessageToSet(&data, true);
- return true;
-}
-
-bool Creature::SetCanFly(bool enable)
-{
- if (!Unit::SetCanFly(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_FLYING : SMSG_SPLINE_MOVE_UNSET_FLYING, 9);
- data.append(GetPackGUID());
- SendMessageToSet(&data, false);
- return true;
-}
-
-bool Creature::SetWaterWalking(bool enable, bool packetOnly /* = false */)
-{
- if (!packetOnly && !Unit::SetWaterWalking(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_WATER_WALK : SMSG_SPLINE_MOVE_LAND_WALK);
- data.append(GetPackGUID());
- SendMessageToSet(&data, true);
- return true;
-}
-
-bool Creature::SetFeatherFall(bool enable, bool packetOnly /* = false */)
-{
- if (!packetOnly && !Unit::SetFeatherFall(enable))
- return false;
-
- if (!movespline->Initialized())
- return true;
-
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_FEATHER_FALL : SMSG_SPLINE_MOVE_NORMAL_FALL);
- data.append(GetPackGUID());
- SendMessageToSet(&data, true);
- return true;
-}
-
-bool Creature::SetHover(bool enable, bool packetOnly /*= false*/)
-{
- if (!packetOnly && !Unit::SetHover(enable))
- return false;
-
- //! Unconfirmed for players:
- if (enable)
- SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
- else
- RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
-
- if (!movespline->Initialized())
- return true;
-
- //! Not always a packet is sent
- WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);
- data.append(GetPackGUID());
- SendMessageToSet(&data, false);
- return true;
-}
-
float Creature::GetAggroRange(Unit const* target) const
{
// Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection.
@@ -2646,7 +2544,7 @@ void Creature::UpdateMovementFlags()
}
if (!isInAir)
- RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ SetFall(false);
SetSwim(GetCreatureTemplate()->InhabitType & INHABIT_WATER && IsInWater());
}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 737e3072091..d9236bbfb8e 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -88,6 +88,7 @@ struct CreatureTemplate
uint8 minlevel;
uint8 maxlevel;
uint32 expansion;
+ uint32 expansionUnknown; // either 0 or 3, sent to the client / wdb
uint32 faction_A;
uint32 faction_H;
uint32 npcflag;
@@ -108,7 +109,6 @@ struct CreatureTemplate
uint32 dynamicflags;
uint32 family; // enum CreatureFamily values (optional)
uint32 trainer_type;
- uint32 trainer_spell;
uint32 trainer_class;
uint32 trainer_race;
float minrangedmg;
@@ -116,6 +116,7 @@ struct CreatureTemplate
uint32 rangedattackpower;
uint32 type; // enum CreatureType values
uint32 type_flags; // enum CreatureTypeFlags mask values
+ uint32 type_flags2; // unknown enum, only set for 4 creatures (with value 1)
uint32 lootid;
uint32 pickpocketLootId;
uint32 SkinLootId;
@@ -131,6 +132,7 @@ struct CreatureTemplate
float HoverHeight;
float ModHealth;
float ModMana;
+ float ModManaExtra; // Added in 4.x, this value is usually 2 for a small group of creatures with double mana
float ModArmor;
bool RacialLeader;
uint32 questItems[MAX_CREATURE_QUEST_ITEMS];
@@ -203,7 +205,7 @@ struct CreatureBaseStats
if (!BaseMana)
return 0;
- return uint32(ceil(BaseMana * info->ModMana));
+ return uint32(ceil(BaseMana * info->ModMana * info->ModManaExtra));
}
uint32 GenerateArmor(CreatureTemplate const* info) const
@@ -331,13 +333,14 @@ typedef UNORDERED_MAP<uint32, CreatureAddon> CreatureAddonContainer;
// Vendors
struct VendorItem
{
- VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
- : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) { }
+ VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost, uint8 _Type)
+ : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost), Type(_Type) { }
uint32 item;
uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
+ uint8 Type;
//helpers
bool IsGoldRequired(ItemTemplate const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; }
@@ -356,13 +359,13 @@ struct VendorItemData
return m_items[slot];
}
bool Empty() const { return m_items.empty(); }
- uint8 GetItemCount() const { return m_items.size(); }
- void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost)
+ uint32 GetItemCount() const { return m_items.size(); }
+ void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type)
{
- m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
+ m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost, type));
}
- bool RemoveItem(uint32 item_id);
- VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const;
+ bool RemoveItem(uint32 item_id, uint8 type);
+ VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost, uint8 type) const;
void Clear()
{
for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
@@ -420,7 +423,7 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns;
// max different by z coordinate for creature aggro reaction
#define CREATURE_Z_ATTACK_RANGE 3
-#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY
+#define MAX_VENDOR_ITEMS 150 // Limitation in 4.x.x item count in SMSG_LIST_INVENTORY
class Creature : public Unit, public GridObject<Creature>, public MapObject
{
@@ -482,16 +485,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
- bool SetWalk(bool enable);
- bool SetDisableGravity(bool disable, bool packetOnly = false);
- bool SetSwim(bool enable);
- bool SetCanFly(bool enable);
- bool SetWaterWalking(bool enable, bool packetOnly = false);
- bool SetFeatherFall(bool enable, bool packetOnly = false);
- bool SetHover(bool enable, bool packetOnly = false);
-
- uint32 GetShieldBlockValue() const;
-
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index ffb28849925..497b3a44b4f 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -345,11 +345,11 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_LIST NPC Guid=%u", GUID_LOPART(npcGUID));
}
-void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const
+void PlayerMenu::SendQuestGiverStatus(uint32 questStatus, uint64 npcGUID) const
{
- WorldPacket data(SMSG_QUESTGIVER_STATUS, 9);
+ WorldPacket data(SMSG_QUESTGIVER_STATUS, 8 + 4);
data << uint64(npcGUID);
- data << uint8(questStatus);
+ data << uint32(questStatus);
_session->SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC Guid=%u, status=%u", GUID_LOPART(npcGUID), questStatus);
@@ -357,10 +357,14 @@ void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const
void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID, bool activateAccept) const
{
- std::string questTitle = quest->GetTitle();
- std::string questDetails = quest->GetDetails();
- std::string questObjectives = quest->GetObjectives();
- std::string questEndText = quest->GetEndText();
+ std::string questTitle = quest->GetTitle();
+ std::string questDetails = quest->GetDetails();
+ std::string questObjectives = quest->GetObjectives();
+ std::string questEndText = quest->GetEndText();
+ std::string questGiverTextWindow = quest->GetQuestGiverTextWindow();
+ std::string questGiverTargetName = quest->GetQuestGiverTargetName();
+ std::string questTurnTextWindow = quest->GetQuestTurnTextWindow();
+ std::string questTurnTargetName = quest->GetQuestTurnTargetName();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
@@ -371,6 +375,10 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails);
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName);
}
}
@@ -384,76 +392,23 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
data << questTitle;
data << questDetails;
data << questObjectives;
+ data << questGiverTextWindow; // 4.x
+ data << questGiverTargetName; // 4.x
+ data << questTurnTextWindow; // 4.x
+ data << questTurnTargetName; // 4.x
+ data << uint32(quest->GetQuestGiverPortrait()); // 4.x
+ data << uint32(quest->GetQuestTurnInPortrait()); // 4.x
data << uint8(activateAccept ? 1 : 0); // auto finish
data << uint32(quest->GetFlags()); // 3.3.3 questFlags
data << uint32(quest->GetSuggestedPlayers());
data << uint8(0); // IsFinished? value is sent back to server in quest accept packet
+ data << uint8(0); // 4.x FIXME: Starts at AreaTrigger
+ data << uint32(quest->GetRequiredSpell()); // 4.x
- if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
- {
- data << uint32(0); // Rewarded chosen items hidden
- data << uint32(0); // Rewarded items hidden
- data << uint32(0); // Rewarded money hidden
- data << uint32(0); // Rewarded XP hidden
- }
- else
- {
- data << uint32(quest->GetRewChoiceItemsCount());
- for (uint32 i=0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- {
- if (!quest->RewardChoiceItemId[i])
- continue;
-
- data << uint32(quest->RewardChoiceItemId[i]);
- data << uint32(quest->RewardChoiceItemCount[i]);
-
- if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[i]))
- data << uint32(itemTemplate->DisplayInfoID);
- else
- data << uint32(0x00);
- }
-
- data << uint32(quest->GetRewItemsCount());
-
- for (uint32 i=0; i < QUEST_REWARDS_COUNT; ++i)
- {
- if (!quest->RewardItemId[i])
- continue;
-
- data << uint32(quest->RewardItemId[i]);
- data << uint32(quest->RewardItemIdCount[i]);
-
- if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardItemId[i]))
- data << uint32(itemTemplate->DisplayInfoID);
- else
- data << uint32(0);
- }
-
- data << uint32(quest->GetRewOrReqMoney());
- data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));
- }
-
- // rewarded honor points. Multiply with 10 to satisfy client
- data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest)));
- data << float(0.0f); // unk, honor multiplier?
- data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (cast if RewSpellCast == 0)
- data << int32(quest->GetRewSpellCast()); // cast spell
- data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
- data << uint32(quest->GetBonusTalents()); // bonus talents
- data << uint32(quest->GetRewArenaPoints()); // reward arena points
- data << uint32(0); // unk
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- data << uint32(quest->RewardFactionId[i]);
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- data << int32(quest->RewardFactionValueId[i]);
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- data << int32(quest->RewardFactionValueIdOverride[i]);
+ quest->BuildExtraQuestInfo(data, _session->GetPlayer());
data << uint32(QUEST_EMOTE_COUNT);
- for (uint32 i = 0; i < QUEST_EMOTE_COUNT; ++i)
+ for (uint8 i = 0; i < QUEST_EMOTE_COUNT; ++i)
{
data << uint32(quest->DetailsEmote[i]);
data << uint32(quest->DetailsEmoteDelay[i]); // DetailsEmoteDelay (in ms)
@@ -470,6 +425,10 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
std::string questObjectives = quest->GetObjectives();
std::string questEndText = quest->GetEndText();
std::string questCompletedText = quest->GetCompletedText();
+ std::string questGiverTextWindow = quest->GetQuestGiverTextWindow();
+ std::string questGiverTargetName = quest->GetQuestGiverTargetName();
+ std::string questTurnTextWindow = quest->GetQuestTurnTextWindow();
+ std::string questTurnTargetName = quest->GetQuestTurnTargetName();
std::string questObjectiveText[QUEST_OBJECTIVES_COUNT];
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
@@ -485,6 +444,10 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives);
ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText);
ObjectMgr::GetLocaleString(localeData->CompletedText, locale, questCompletedText);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName);
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ObjectMgr::GetLocaleString(localeData->ObjectiveText[i], locale, questObjectiveText[i]);
@@ -525,11 +488,16 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << float(quest->GetRewHonorMultiplier());
data << uint32(quest->GetSrcItemId()); // source item id
data << uint32(quest->GetFlags() & 0xFFFF); // quest flags
+ data << uint32(quest->GetMinimapTargetMark()); // minimap target mark (skull, etc. missing enum)
data << uint32(quest->GetCharTitleId()); // CharTitleId, new 2.4.0, player gets this title (id from CharTitles)
data << uint32(quest->GetPlayersSlain()); // players slain
data << uint32(quest->GetBonusTalents()); // bonus talents
- data << uint32(quest->GetRewArenaPoints()); // bonus arena points
- data << uint32(0); // review rep show mask
+ data << uint32(quest->GetRewArenaPoints()); // bonus arena points FIXME: arena points were removed, right?
+ data << uint32(quest->GetRewardSkillId()); // reward skill id
+ data << uint32(quest->GetRewardSkillPoints()); // reward skill points
+ data << uint32(quest->GetRewardReputationMask()); // rep mask (unsure on what it does)
+ data << uint32(quest->GetQuestGiverPortrait()); // quest giver entry ?
+ data << uint32(quest->GetQuestTurnInPortrait()); // quest turnin entry ?
if (quest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))
{
@@ -558,7 +526,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid+1 QuestFactionReward.dbc?
data << int32(quest->RewardFactionValueId[i]);
- for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0)
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unknown usage
data << int32(quest->RewardFactionValueIdOverride[i]);
data << uint32(quest->GetPointMapId());
@@ -573,7 +541,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << questObjectives;
data << questDetails;
data << questEndText;
- data << questCompletedText; // display in quest objectives window once all objectives are completed
+ data << questCompletedText;
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
{
@@ -584,7 +552,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << uint32(quest->RequiredNpcOrGoCount[i]);
data << uint32(quest->RequiredSourceItemId[i]);
- data << uint32(0); // req source count?
+ data << uint32(quest->RequiredSourceItemCount[i]);
}
for (uint8 i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
@@ -593,9 +561,30 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const
data << uint32(quest->RequiredItemCount[i]);
}
+ data << uint32(quest->GetRequiredSpell()); // Is it required to be cast, learned or what?
+
for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
data << questObjectiveText[i];
+ for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ {
+ data << uint32(quest->RewardCurrencyId[i]);
+ data << uint32(quest->RewardCurrencyCount[i]);
+ }
+
+ for (uint32 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ {
+ data << uint32(quest->RequiredCurrencyId[i]);
+ data << uint32(quest->RequiredCurrencyCount[i]);
+ }
+
+ data << questGiverTextWindow;
+ data << questGiverTargetName;
+ data << questTurnTextWindow;
+ data << questTurnTargetName;
+ data << uint32(quest->GetSoundAccept());
+ data << uint32(quest->GetSoundTurnIn());
+
_session->SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", quest->GetQuestId());
}
@@ -604,6 +593,10 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
{
std::string questTitle = quest->GetTitle();
std::string questOfferRewardText = quest->GetOfferRewardText();
+ std::string questGiverTextWindow = quest->GetQuestGiverTextWindow();
+ std::string questGiverTargetName = quest->GetQuestGiverTargetName();
+ std::string questTurnTextWindow = quest->GetQuestTurnTextWindow();
+ std::string questTurnTargetName = quest->GetQuestTurnTargetName();
int32 locale = _session->GetSessionDbLocaleIndex();
if (locale >= 0)
@@ -612,6 +605,10 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
{
ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle);
ObjectMgr::GetLocaleString(localeData->OfferRewardText, locale, questOfferRewardText);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTextWindow, locale, questGiverTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestGiverTargetName, locale, questGiverTargetName);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTextWindow, locale, questTurnTextWindow);
+ ObjectMgr::GetLocaleString(localeData->QuestTurnTargetName, locale, questTurnTargetName);
}
}
@@ -624,6 +621,13 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
data << questTitle;
data << questOfferRewardText;
+ data << questGiverTextWindow;
+ data << questGiverTargetName;
+ data << questTurnTextWindow;
+ data << questTurnTargetName;
+ data << uint32(quest->GetQuestGiverPortrait());
+ data << uint32(quest->GetQuestTurnInPortrait());
+
data << uint8(enableNext ? 1 : 0); // Auto Finish
data << uint32(quest->GetFlags()); // 3.3.3 questFlags
data << uint32(quest->GetSuggestedPlayers()); // SuggestedGroupNum
@@ -643,52 +647,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, uint64 npcGUID, b
data << uint32(quest->OfferRewardEmote[i]);
}
- data << uint32(quest->GetRewChoiceItemsCount());
- for (uint32 i=0; i < quest->GetRewChoiceItemsCount(); ++i)
- {
- data << uint32(quest->RewardChoiceItemId[i]);
- data << uint32(quest->RewardChoiceItemCount[i]);
-
- if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardChoiceItemId[i]))
- data << uint32(itemTemplate->DisplayInfoID);
- else
- data << uint32(0);
- }
-
- data << uint32(quest->GetRewItemsCount());
- for (uint32 i = 0; i < quest->GetRewItemsCount(); ++i)
- {
- data << uint32(quest->RewardItemId[i]);
- data << uint32(quest->RewardItemIdCount[i]);
-
- if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(quest->RewardItemId[i]))
- data << uint32(itemTemplate->DisplayInfoID);
- else
- data << uint32(0);
- }
-
- data << uint32(quest->GetRewOrReqMoney());
- data << uint32(quest->XPValue(_session->GetPlayer()) * sWorld->getRate(RATE_XP_QUEST));
-
- // rewarded honor points. Multiply with 10 to satisfy client
- data << uint32(10 * quest->CalculateHonorGain(_session->GetPlayer()->GetQuestLevel(quest)));
- data << float(0.0f); // unk, honor multiplier?
- data << uint32(0x08); // unused by client?
- data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (cast if RewSpellCast == 0)
- data << int32(quest->GetRewSpellCast()); // cast spell
- data << uint32(0); // unknown
- data << uint32(quest->GetBonusTalents()); // bonus talents
- data << uint32(quest->GetRewArenaPoints()); // arena points
- data << uint32(0);
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
- data << uint32(quest->RewardFactionId[i]);
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid in QuestFactionReward.dbc (zero based)?
- data << int32(quest->RewardFactionValueId[i]);
-
- for (uint32 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward reputation override?
- data << uint32(quest->RewardFactionValueIdOverride[i]);
+ quest->BuildExtraQuestInfo(data, _session->GetPlayer());
_session->SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId());
@@ -758,14 +717,25 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, uint64 npcGUID,
data << uint32(0);
}
- if (!canComplete)
- data << uint32(0x00);
+ data << uint32(quest->GetReqCurrencyCount());
+ for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ {
+ if (!quest->RequiredCurrencyId[i])
+ continue;
+
+ data << uint32(quest->RequiredCurrencyId[i]);
+ data << uint32(quest->RequiredCurrencyCount[i]);
+ }
+
+ if (!canComplete) // Experimental; there are 6 similar flags, if any of them
+ data << uint32(0x00); // of them is 0 player can't complete quest (still unknown meaning)
else
- data << uint32(0x03);
+ data << uint32(0x02);
data << uint32(0x04);
data << uint32(0x08);
data << uint32(0x10);
+ data << uint32(0x40);
_session->SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_REQUEST_ITEMS NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), quest->GetQuestId());
diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h
index 9a30fdeee2b..47711993005 100644
--- a/src/server/game/Entities/Creature/GossipDef.h
+++ b/src/server/game/Entities/Creature/GossipDef.h
@@ -271,7 +271,7 @@ class PlayerMenu
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
- void SendQuestGiverStatus(uint8 questStatus, uint64 npcGUID) const;
+ void SendQuestGiverStatus(uint32 questStatus, uint64 npcGUID) const;
void SendQuestGiverQuestList(QEmote const& eEmote, const std::string& Title, uint64 npcGUID);
diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp
index d31117c8381..b982de1289d 100644
--- a/src/server/game/Entities/Creature/TemporarySummon.cpp
+++ b/src/server/game/Entities/Creature/TemporarySummon.cpp
@@ -196,7 +196,8 @@ void TempSummon::InitStats(uint32 duration)
if (owner)
{
- if (uint32 slot = m_Properties->Slot)
+ int32 slot = m_Properties->Slot;
+ if (slot > 0)
{
if (owner->m_SummonSlot[slot] && owner->m_SummonSlot[slot] != GetGUID())
{
@@ -268,10 +269,13 @@ void TempSummon::RemoveFromWorld()
return;
if (m_Properties)
- if (uint32 slot = m_Properties->Slot)
+ {
+ int32 slot = m_Properties->Slot;
+ if (slot > 0)
if (Unit* owner = GetSummoner())
if (owner->m_SummonSlot[slot] == GetGUID())
owner->m_SummonSlot[slot] = 0;
+ }
//if (GetOwnerGUID())
// TC_LOG_ERROR("entities.unit", "Unit %u has owner guid when removed from world", GetEntry());
@@ -285,6 +289,8 @@ Minion::Minion(SummonPropertiesEntry const* properties, Unit* owner, bool isWorl
ASSERT(m_owner);
m_unitTypeMask |= UNIT_MASK_MINION;
m_followAngle = PET_FOLLOW_ANGLE;
+ /// @todo: Find correct way
+ InitCharmInfo();
}
void Minion::InitStats(uint32 duration)
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
index f4e956e8839..53e4e92d6cd 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp
@@ -33,7 +33,7 @@ DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject),
m_objectType |= TYPEMASK_DYNAMICOBJECT;
m_objectTypeId = TYPEID_DYNAMICOBJECT;
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION);
+ m_updateFlag = UPDATEFLAG_STATIONARY_POSITION;
m_valuesCount = DYNAMICOBJECT_END;
}
@@ -79,29 +79,23 @@ void DynamicObject::RemoveFromWorld()
}
}
-bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type)
+bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, SpellInfo const* spell, Position const& pos, float radius, DynamicObjectType type)
{
SetMap(caster->GetMap());
Relocate(pos);
if (!IsPositionValid())
{
- TC_LOG_ERROR("misc", "DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", spellId, GetPositionX(), GetPositionY());
+ TC_LOG_ERROR("misc", "DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", spell->Id, GetPositionX(), GetPositionY());
return false;
}
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask());
- SetEntry(spellId);
+ SetEntry(spell->Id);
SetObjectScale(1);
SetUInt64Value(DYNAMICOBJECT_CASTER, caster->GetGUID());
-
- // The lower word of DYNAMICOBJECT_BYTES must be 0x0001. This value means that the visual radius will be overriden
- // by client for most of the "ground patch" visual effect spells and a few "skyfall" ones like Hurricane.
- // If any other value is used, the client will _always_ use the radius provided in DYNAMICOBJECT_RADIUS, but
- // precompensation is necessary (eg radius *= 2) for many spells. Anyway, blizz sends 0x0001 for all the spells
- // I saw sniffed...
- SetByteValue(DYNAMICOBJECT_BYTES, 0, type);
- SetUInt32Value(DYNAMICOBJECT_SPELLID, spellId);
+ SetUInt32Value(DYNAMICOBJECT_BYTES, spell->SpellVisual[0] | (type << 28));
+ SetUInt32Value(DYNAMICOBJECT_SPELLID, spell->Id);
SetFloatValue(DYNAMICOBJECT_RADIUS, radius);
SetUInt32Value(DYNAMICOBJECT_CASTTIME, getMSTime());
diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h
index 5b68bf377b9..66e3a2cff02 100644
--- a/src/server/game/Entities/DynamicObject/DynamicObject.h
+++ b/src/server/game/Entities/DynamicObject/DynamicObject.h
@@ -41,7 +41,7 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>
void AddToWorld();
void RemoveFromWorld();
- bool CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spellId, Position const& pos, float radius, DynamicObjectType type);
+ bool CreateDynamicObject(uint32 guidlow, Unit* caster, SpellInfo const* spell, Position const& pos, float radius, DynamicObjectType type);
void Update(uint32 p_time);
void Remove();
void SetDuration(int32 newDuration);
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index e326e0155c1..01bdf63d464 100644
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -41,7 +41,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(),
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
- m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION);
+ m_updateFlag = (UPDATEFLAG_STATIONARY_POSITION | UPDATEFLAG_ROTATION);
m_valuesCount = GAMEOBJECT_END;
m_respawnTime = 0;
@@ -205,7 +205,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
}
if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
- m_updateFlag = (m_updateFlag | UPDATEFLAG_TRANSPORT) & ~UPDATEFLAG_POSITION;
+ m_updateFlag |= UPDATEFLAG_TRANSPORT;
Object::_Create(guidlow, goinfo->entry, HIGHGUID_GAMEOBJECT);
@@ -250,6 +250,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
m_goValue.Building.Health = goinfo->building.intactNumHits + goinfo->building.damagedNumHits;
m_goValue.Building.MaxHealth = m_goValue.Building.Health;
SetGoAnimProgress(255);
+ SetUInt32Value(GAMEOBJECT_PARENTROTATION, m_goInfo->building.destructibleData);
break;
case GAMEOBJECT_TYPE_TRANSPORT:
SetUInt32Value(GAMEOBJECT_LEVEL, goinfo->transport.pause);
@@ -361,7 +362,7 @@ void GameObject::Update(uint32 diff)
SetGoState(GO_STATE_ACTIVE);
SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
- UpdateData udata;
+ UpdateData udata(caster->GetMapId());
WorldPacket packet;
BuildValuesUpdateBlockForPlayer(&udata, caster->ToPlayer());
udata.BuildPacket(&packet);
@@ -2210,7 +2211,7 @@ void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /*
*ori = GetOrientation();
}
-float GameObject::GetInteractionDistance()
+float GameObject::GetInteractionDistance() const
{
switch (GetGoType())
{
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 84abc391bc6..8f32f5fe080 100644
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -46,6 +46,7 @@ struct GameObjectTemplate
uint32 flags;
float size;
uint32 questItems[MAX_GAMEOBJECT_QUEST_ITEMS];
+ int32 unkInt32;
union // different GO types have different data field
{
//0 GAMEOBJECT_TYPE_DOOR
@@ -830,7 +831,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map
float GetStationaryZ() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); }
float GetStationaryO() const { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); }
- float GetInteractionDistance();
+ float GetInteractionDistance() const;
protected:
bool AIM_Initialize();
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index ee389ed7311..2c12c82b80a 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -28,6 +28,7 @@
#include "ConditionMgr.h"
#include "Player.h"
#include "Opcodes.h"
+#include "WorldSession.h"
void AddItemsSetItem(Player* player, Item* item)
{
@@ -213,6 +214,10 @@ bool ItemCanGoIntoBag(ItemTemplate const* pProto, ItemTemplate const* pBagProto)
if (!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP))
return false;
return true;
+ case ITEM_SUBCLASS_TACKLE_CONTAINER:
+ if (!(pProto->BagFamily & BAG_FAMILY_MASK_FISHING_SUPP))
+ return false;
+ return true;
default:
return false;
}
@@ -239,7 +244,7 @@ Item::Item()
m_objectType |= TYPEMASK_ITEM;
m_objectTypeId = TYPEID_ITEM;
- m_updateFlag = UPDATEFLAG_LOWGUID;
+ m_updateFlag = 0;
m_valuesCount = ITEM_END;
m_slot = 0;
@@ -553,46 +558,6 @@ uint32 Item::GetSkill()
}
}
-uint32 Item::GetSpell()
-{
- ItemTemplate const* proto = GetTemplate();
-
- switch (proto->Class)
- {
- case ITEM_CLASS_WEAPON:
- switch (proto->SubClass)
- {
- case ITEM_SUBCLASS_WEAPON_AXE: return 196;
- case ITEM_SUBCLASS_WEAPON_AXE2: return 197;
- case ITEM_SUBCLASS_WEAPON_BOW: return 264;
- case ITEM_SUBCLASS_WEAPON_GUN: return 266;
- case ITEM_SUBCLASS_WEAPON_MACE: return 198;
- case ITEM_SUBCLASS_WEAPON_MACE2: return 199;
- case ITEM_SUBCLASS_WEAPON_POLEARM: return 200;
- case ITEM_SUBCLASS_WEAPON_SWORD: return 201;
- case ITEM_SUBCLASS_WEAPON_SWORD2: return 202;
- case ITEM_SUBCLASS_WEAPON_STAFF: return 227;
- case ITEM_SUBCLASS_WEAPON_DAGGER: return 1180;
- case ITEM_SUBCLASS_WEAPON_THROWN: return 2567;
- case ITEM_SUBCLASS_WEAPON_SPEAR: return 3386;
- case ITEM_SUBCLASS_WEAPON_CROSSBOW:return 5011;
- case ITEM_SUBCLASS_WEAPON_WAND: return 5009;
- default: return 0;
- }
- case ITEM_CLASS_ARMOR:
- switch (proto->SubClass)
- {
- case ITEM_SUBCLASS_ARMOR_CLOTH: return 9078;
- case ITEM_SUBCLASS_ARMOR_LEATHER: return 9077;
- case ITEM_SUBCLASS_ARMOR_MAIL: return 8737;
- case ITEM_SUBCLASS_ARMOR_PLATE: return 750;
- case ITEM_SUBCLASS_ARMOR_SHIELD: return 9116;
- default: return 0;
- }
- }
- return 0;
-}
-
int32 Item::GenerateItemRandomPropertyId(uint32 item_id)
{
ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
@@ -654,8 +619,8 @@ void Item::SetItemRandomProperties(int32 randomPropId)
SetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID, item_rand->ID);
SetState(ITEM_CHANGED, GetOwner());
}
- for (uint32 i = PROP_ENCHANTMENT_SLOT_2; i < PROP_ENCHANTMENT_SLOT_2 + 3; ++i)
- SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_2], 0, 0);
+ for (uint32 i = PROP_ENCHANTMENT_SLOT_1; i < PROP_ENCHANTMENT_SLOT_1 + 3; ++i)
+ SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_1], 0, 0);
}
}
else
@@ -671,7 +636,7 @@ void Item::SetItemRandomProperties(int32 randomPropId)
SetState(ITEM_CHANGED, GetOwner());
}
- for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i < PROP_ENCHANTMENT_SLOT_0 + 3; ++i)
+ for (uint32 i = PROP_ENCHANTMENT_SLOT_0; i <= PROP_ENCHANTMENT_SLOT_4; ++i)
SetEnchantment(EnchantmentSlot(i), item_rand->enchant_id[i - PROP_ENCHANTMENT_SLOT_0], 0, 0);
}
}
@@ -791,10 +756,15 @@ bool Item::HasEnchantRequiredSkill(const Player* player) const
{
// Check all enchants for required skill
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT && enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->requiredSkill && player->GetSkillValue(enchantEntry->requiredSkill) < enchantEntry->requiredSkillValue)
return false;
+ }
return true;
}
@@ -805,10 +775,15 @@ uint32 Item::GetEnchantRequiredLevel() const
// Check all enchants for required level
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT && enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->requiredLevel > level)
level = enchantEntry->requiredLevel;
+ }
return level;
}
@@ -817,10 +792,16 @@ bool Item::IsBoundByEnchant() const
{
// Check all enchants for soulbound
for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
+ {
+ if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT && enchant_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot)))
if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id))
if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
return true;
+ }
+
return false;
}
@@ -828,15 +809,15 @@ InventoryResult Item::CanBeMergedPartlyWith(ItemTemplate const* proto) const
{
// not allow merge looting currently items
if (m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
// check item type
if (GetEntry() != proto->ItemId)
- return EQUIP_ERR_ITEM_CANT_STACK;
+ return EQUIP_ERR_CANT_STACK;
// check free space (full stacks can't be target of merge
if (GetCount() >= proto->GetMaxStackSize())
- return EQUIP_ERR_ITEM_CANT_STACK;
+ return EQUIP_ERR_CANT_STACK;
return EQUIP_ERR_OK;
}
@@ -848,8 +829,8 @@ bool Item::IsFitToSpellRequirements(SpellInfo const* spellInfo) const
if (spellInfo->EquippedItemClass != -1) // -1 == any item class
{
// Special case - accept vellum for armor/weapon requirements
- if ((spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && proto->IsArmorVellum())
- ||(spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && proto->IsWeaponVellum()))
+ if ((spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR ||
+ spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON) && proto->IsVellum())
if (spellInfo->IsAbilityOfSkillType(SKILL_ENCHANTING)) // only for enchanting spells
return true;
@@ -1227,6 +1208,305 @@ bool Item::CheckSoulboundTradeExpire()
return false;
}
+bool Item::CanBeTransmogrified() const
+{
+ ItemTemplate const* proto = GetTemplate();
+
+ if (!proto)
+ return false;
+
+ if (proto->Quality == ITEM_QUALITY_LEGENDARY)
+ return false;
+
+ if (proto->Class != ITEM_CLASS_ARMOR &&
+ proto->Class != ITEM_CLASS_WEAPON)
+ return false;
+
+ if (proto->Class == ITEM_CLASS_WEAPON && proto->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE)
+ return false;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_CANNOT_BE_TRANSMOG)
+ return false;
+
+ if (!HasStats())
+ return false;
+
+ return true;
+}
+
+bool Item::CanTransmogrify() const
+{
+ ItemTemplate const* proto = GetTemplate();
+
+ if (!proto)
+ return false;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_CANNOT_TRANSMOG)
+ return false;
+
+ if (proto->Quality == ITEM_QUALITY_LEGENDARY)
+ return false;
+
+ if (proto->Class != ITEM_CLASS_ARMOR &&
+ proto->Class != ITEM_CLASS_WEAPON)
+ return false;
+
+ if (proto->Class == ITEM_CLASS_WEAPON && proto->SubClass == ITEM_SUBCLASS_WEAPON_FISHING_POLE)
+ return false;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_CAN_TRANSMOG)
+ return true;
+
+ if (!HasStats())
+ return false;
+
+ return true;
+}
+
+bool Item::CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* transmogrifier)
+{
+ if (!transmogrifier || !transmogrified)
+ return false;
+
+ ItemTemplate const* proto1 = transmogrifier->GetTemplate(); // source
+ ItemTemplate const* proto2 = transmogrified->GetTemplate(); // dest
+
+ if (proto1->ItemId == proto2->ItemId)
+ return false;
+
+ if (!transmogrified->CanTransmogrify() || !transmogrifier->CanBeTransmogrified())
+ return false;
+
+ if (proto1->InventoryType == INVTYPE_BAG ||
+ proto1->InventoryType == INVTYPE_RELIC ||
+ proto1->InventoryType == INVTYPE_BODY ||
+ proto1->InventoryType == INVTYPE_FINGER ||
+ proto1->InventoryType == INVTYPE_TRINKET ||
+ proto1->InventoryType == INVTYPE_AMMO ||
+ proto1->InventoryType == INVTYPE_QUIVER)
+ return false;
+
+ if (proto1->SubClass != proto2->SubClass && (proto1->Class != ITEM_CLASS_WEAPON || !proto2->IsRangedWeapon() || !proto1->IsRangedWeapon()))
+ return false;
+
+ if (proto1->InventoryType != proto2->InventoryType &&
+ (proto1->Class != ITEM_CLASS_WEAPON || (proto2->InventoryType != INVTYPE_WEAPONMAINHAND && proto2->InventoryType != INVTYPE_WEAPONOFFHAND)) &&
+ (proto1->Class != ITEM_CLASS_ARMOR || (proto1->InventoryType != INVTYPE_CHEST && proto2->InventoryType != INVTYPE_ROBE && proto1->InventoryType != INVTYPE_ROBE && proto2->InventoryType != INVTYPE_CHEST)))
+ return false;
+
+ return true;
+}
+
+bool Item::HasStats() const
+{
+ if (GetItemRandomPropertyId() != 0)
+ return true;
+
+ ItemTemplate const* proto = GetTemplate();
+ for (uint8 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
+ if (proto->ItemStat[i].ItemStatValue != 0)
+ return true;
+
+ return false;
+}
+
+// used by mail items, transmog cost, stationeryinfo and others
+uint32 Item::GetSellPrice(ItemTemplate const* proto, bool& normalSellPrice)
+{
+ normalSellPrice = true;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE)
+ {
+ return proto->BuyPrice;
+ }
+ else
+ {
+ ImportPriceQualityEntry const* qualityPrice = sImportPriceQualityStore.LookupEntry(proto->Quality + 1);
+ ItemPriceBaseEntry const* basePrice = sItemPriceBaseStore.LookupEntry(proto->ItemLevel);
+
+ if (!qualityPrice || !basePrice)
+ return 0;
+
+ float qualityFactor = qualityPrice->Factor;
+ float baseFactor = 0.0f;
+
+ uint32 inventoryType = proto->InventoryType;
+
+ if (inventoryType == INVTYPE_WEAPON ||
+ inventoryType == INVTYPE_2HWEAPON ||
+ inventoryType == INVTYPE_WEAPONMAINHAND ||
+ inventoryType == INVTYPE_WEAPONOFFHAND ||
+ inventoryType == INVTYPE_RANGED ||
+ inventoryType == INVTYPE_THROWN ||
+ inventoryType == INVTYPE_RANGEDRIGHT)
+ baseFactor = basePrice->WeaponFactor;
+ else
+ baseFactor = basePrice->ArmorFactor;
+
+ if (inventoryType == INVTYPE_ROBE)
+ inventoryType = INVTYPE_CHEST;
+
+ float typeFactor = 0.0f;
+ int8 weapType = -1;
+
+ switch (inventoryType)
+ {
+ case INVTYPE_HEAD:
+ case INVTYPE_SHOULDERS:
+ case INVTYPE_CHEST:
+ case INVTYPE_WAIST:
+ case INVTYPE_LEGS:
+ case INVTYPE_FEET:
+ case INVTYPE_WRISTS:
+ case INVTYPE_HANDS:
+ case INVTYPE_CLOAK:
+ {
+ ImportPriceArmorEntry const* armorPrice = sImportPriceArmorStore.LookupEntry(inventoryType);
+ if (!armorPrice)
+ return 0;
+
+ switch (proto->SubClass)
+ {
+ case ITEM_SUBCLASS_ARMOR_MISCELLANEOUS:
+ case ITEM_SUBCLASS_ARMOR_CLOTH:
+ typeFactor = armorPrice->ClothFactor;
+ break;
+ case ITEM_SUBCLASS_ARMOR_LEATHER:
+ typeFactor = armorPrice->LeatherFactor;
+ break;
+ case ITEM_SUBCLASS_ARMOR_MAIL:
+ typeFactor = armorPrice->MailFactor;
+ break;
+ case ITEM_SUBCLASS_ARMOR_PLATE:
+ typeFactor = armorPrice->PlateFactor;
+ break;
+ default:
+ return 0;
+ }
+
+ break;
+ }
+ case INVTYPE_SHIELD:
+ {
+ ImportPriceShieldEntry const* shieldPrice = sImportPriceShieldStore.LookupEntry(1); // it only has two rows, it's unclear which is the one used
+ if (!shieldPrice)
+ return 0;
+
+ typeFactor = shieldPrice->Factor;
+ break;
+ }
+ case INVTYPE_WEAPONMAINHAND:
+ weapType = 0;
+ break;
+ case INVTYPE_WEAPONOFFHAND:
+ weapType = 1;
+ break;
+ case INVTYPE_WEAPON:
+ weapType = 2;
+ break;
+ case INVTYPE_2HWEAPON:
+ weapType = 3;
+ break;
+ case INVTYPE_RANGED:
+ case INVTYPE_RANGEDRIGHT:
+ case INVTYPE_RELIC:
+ weapType = 4;
+ break;
+ default:
+ return proto->BuyPrice;
+ }
+
+ if (weapType != -1)
+ {
+ ImportPriceWeaponEntry const* weaponPrice = sImportPriceWeaponStore.LookupEntry(weapType + 1);
+ if (!weaponPrice)
+ return 0;
+
+ typeFactor = weaponPrice->Factor;
+ }
+
+ normalSellPrice = false;
+ return uint32(qualityFactor * proto->Unk430_2 * proto->Unk430_1 * typeFactor * baseFactor);
+ }
+}
+
+uint32 Item::GetSpecialPrice(ItemTemplate const* proto, uint32 minimumPrice /*= 10000*/)
+{
+ uint32 cost = 0;
+
+ if (proto->Flags2 & ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE)
+ cost = proto->SellPrice;
+ else
+ {
+ bool normalPrice;
+ cost = Item::GetSellPrice(proto, normalPrice);
+
+ if (!normalPrice)
+ {
+ if (proto->BuyCount <= 1)
+ {
+ ItemClassEntry const* classEntry = sItemClassStore.LookupEntry(proto->Class);
+ if (classEntry)
+ cost *= classEntry->PriceFactor;
+ else
+ cost = 0;
+ }
+ else
+ cost /= 4 * proto->BuyCount;
+ }
+ else
+ cost = proto->SellPrice;
+ }
+
+ if (cost < minimumPrice)
+ cost = minimumPrice;
+
+ return cost;
+}
+
+int32 Item::GetReforgableStat(ItemModType statType) const
+{
+ ItemTemplate const* proto = GetTemplate();
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
+ if (ItemModType(proto->ItemStat[i].ItemStatType) == statType)
+ return proto->ItemStat[i].ItemStatValue;
+
+ int32 randomPropId = GetItemRandomPropertyId();
+ if (!randomPropId)
+ return 0;
+
+ if (randomPropId < 0)
+ {
+ ItemRandomSuffixEntry const* randomSuffix = sItemRandomSuffixStore.LookupEntry(-randomPropId);
+ if (!randomSuffix)
+ return 0;
+
+ for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
+ if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
+ for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f)
+ if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && ItemModType(enchant->spellid[f]) == statType)
+ for (int k = 0; k < 5; ++k)
+ if (randomSuffix->enchant_id[k] == enchant->ID)
+ return int32((randomSuffix->prefix[k] * GetItemSuffixFactor()) / 10000);
+ }
+ else
+ {
+ ItemRandomPropertiesEntry const* randomProp = sItemRandomPropertiesStore.LookupEntry(randomPropId);
+ if (!randomProp)
+ return 0;
+
+ for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
+ if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
+ for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f)
+ if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && ItemModType(enchant->spellid[f]) == statType)
+ for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ if (randomProp->enchant_id[k] == enchant->ID)
+ return int32(enchant->amount[k]);
+ }
+
+ return 0;
+}
+
void Item::ItemContainerSaveLootToDB()
{
// Saves the money and item loot associated with an openable item to the DB
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index a65579cc134..8a10784b3c2 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -38,95 +38,99 @@ struct ItemSetEffect
enum InventoryResult
{
- EQUIP_ERR_OK = 0,
- EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1,
- EQUIP_ERR_CANT_EQUIP_SKILL = 2,
- EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3,
- EQUIP_ERR_BAG_FULL = 4,
- EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5,
- EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6,
- EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7,
- EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8,
- EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9,
- EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10,
- EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11,
- EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12,
- EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13,
- EQUIP_ERR_CANT_DUAL_WIELD = 14,
- EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15,
- EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16,
- EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17,
- EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18,
- EQUIP_ERR_ITEM_CANT_STACK = 19,
- EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20,
- EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21,
- EQUIP_ERR_SLOT_IS_EMPTY = 22,
- EQUIP_ERR_ITEM_NOT_FOUND = 23,
- EQUIP_ERR_CANT_DROP_SOULBOUND = 24,
- EQUIP_ERR_OUT_OF_RANGE = 25,
- EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26,
- EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27,
- EQUIP_ERR_MISSING_REAGENT = 28,
- EQUIP_ERR_NOT_ENOUGH_MONEY = 29,
- EQUIP_ERR_NOT_A_BAG = 30,
- EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31,
- EQUIP_ERR_DONT_OWN_THAT_ITEM = 32,
- EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33,
- EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34,
- EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35,
- EQUIP_ERR_ITEM_LOCKED = 36,
- EQUIP_ERR_YOU_ARE_STUNNED = 37,
- EQUIP_ERR_YOU_ARE_DEAD = 38,
- EQUIP_ERR_CANT_DO_RIGHT_NOW = 39,
- EQUIP_ERR_INT_BAG_ERROR = 40,
- EQUIP_ERR_CAN_EQUIP_ONLY1_BOLT = 41,
- EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42,
- EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43,
- EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44,
- EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45,
- EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46,
- EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47,
- EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48,
- EQUIP_ERR_ALREADY_LOOTED = 49,
- EQUIP_ERR_INVENTORY_FULL = 50,
- EQUIP_ERR_BANK_FULL = 51,
- EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52,
- EQUIP_ERR_BAG_FULL3 = 53,
- EQUIP_ERR_ITEM_NOT_FOUND2 = 54,
- EQUIP_ERR_ITEM_CANT_STACK2 = 55,
- EQUIP_ERR_BAG_FULL4 = 56,
- EQUIP_ERR_ITEM_SOLD_OUT = 57,
- EQUIP_ERR_OBJECT_IS_BUSY = 58,
- EQUIP_ERR_NONE = 59,
- EQUIP_ERR_NOT_IN_COMBAT = 60,
- EQUIP_ERR_NOT_WHILE_DISARMED = 61,
- EQUIP_ERR_BAG_FULL6 = 62,
- EQUIP_ERR_CANT_EQUIP_RANK = 63,
- EQUIP_ERR_CANT_EQUIP_REPUTATION = 64,
- EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65,
- EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66,
- EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67,
- EQUIP_ERR_VENDOR_MISSING_TURNINS = 68,
- EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69,
- EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70,
- EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71,
- EQUIP_ERR_MAIL_BOUND_ITEM = 72,
- EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73,
- EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75,
- EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76,
- EQUIP_ERR_TOO_MUCH_GOLD = 77,
- EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78,
- EQUIP_ERR_CANNOT_TRADE_THAT = 79,
- EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80,
- EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM = 81,
- EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82,
- // no output = 83,
- EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED = 84,
- EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED = 85,
- EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 86,
- EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW = 87,
- EQUIP_ERR_CANT_EQUIP_NEED_TALENT = 88,
- EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED = 89
+ EQUIP_ERR_OK = 0,
+ EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1, // You must reach level %d to use that item.
+ EQUIP_ERR_CANT_EQUIP_SKILL = 2, // You aren't skilled enough to use that item.
+ EQUIP_ERR_WRONG_SLOT = 3, // That item does not go in that slot.
+ EQUIP_ERR_BAG_FULL = 4, // That bag is full.
+ EQUIP_ERR_BAG_IN_BAG = 5, // Can't put non-empty bags in other bags.
+ EQUIP_ERR_TRADE_EQUIPPED_BAG = 6, // You can't trade equipped bags.
+ EQUIP_ERR_AMMO_ONLY = 7, // Only ammo can go there.
+ EQUIP_ERR_PROFICIENCY_NEEDED = 8, // You do not have the required proficiency for that item.
+ EQUIP_ERR_NO_SLOT_AVAILABLE = 9, // No equipment slot is available for that item.
+ EQUIP_ERR_CANT_EQUIP_EVER = 10, // You can never use that item.
+ EQUIP_ERR_CANT_EQUIP_EVER_2 = 11, // You can never use that item.
+ EQUIP_ERR_NO_SLOT_AVAILABLE_2 = 12, // No equipment slot is available for that item.
+ EQUIP_ERR_2HANDED_EQUIPPED = 13, // Cannot equip that with a two-handed weapon.
+ EQUIP_ERR_2HSKILLNOTFOUND = 14, // You cannot dual-wield
+ EQUIP_ERR_WRONG_BAG_TYPE = 15, // That item doesn't go in that container.
+ EQUIP_ERR_WRONG_BAG_TYPE_2 = 16, // That item doesn't go in that container.
+ EQUIP_ERR_ITEM_MAX_COUNT = 17, // You can't carry any more of those items.
+ EQUIP_ERR_NO_SLOT_AVAILABLE_3 = 18, // No equipment slot is available for that item.
+ EQUIP_ERR_CANT_STACK = 19, // This item cannot stack.
+ EQUIP_ERR_NOT_EQUIPPABLE = 20, // This item cannot be equipped.
+ EQUIP_ERR_CANT_SWAP = 21, // These items can't be swapped.
+ EQUIP_ERR_SLOT_EMPTY = 22, // That slot is empty.
+ EQUIP_ERR_ITEM_NOT_FOUND = 23, // The item was not found.
+ EQUIP_ERR_DROP_BOUND_ITEM = 24, // You can't drop a soulbound item.
+ EQUIP_ERR_OUT_OF_RANGE = 25, // Out of range.
+ EQUIP_ERR_TOO_FEW_TO_SPLIT = 26, // Tried to split more than number in stack.
+ EQUIP_ERR_SPLIT_FAILED = 27, // Couldn't split those items.
+ EQUIP_ERR_SPELL_FAILED_REAGENTS_GENERIC = 28, // Missing reagent
+ EQUIP_ERR_NOT_ENOUGH_MONEY = 29, // You don't have enough money.
+ EQUIP_ERR_NOT_A_BAG = 30, // Not a bag.
+ EQUIP_ERR_DESTROY_NONEMPTY_BAG = 31, // You can only do that with empty bags.
+ EQUIP_ERR_NOT_OWNER = 32, // You don't own that item.
+ EQUIP_ERR_ONLY_ONE_QUIVER = 33, // You can only equip one quiver.
+ EQUIP_ERR_NO_BANK_SLOT = 34, // You must purchase that bag slot first
+ EQUIP_ERR_NO_BANK_HERE = 35, // You are too far away from a bank.
+ EQUIP_ERR_ITEM_LOCKED = 36, // Item is locked.
+ EQUIP_ERR_GENERIC_STUNNED = 37, // You are stunned
+ EQUIP_ERR_PLAYER_DEAD = 38, // You can't do that when you're dead.
+ EQUIP_ERR_CLIENT_LOCKED_OUT = 39, // You can't do that right now.
+ EQUIP_ERR_INTERNAL_BAG_ERROR = 40, // Internal Bag Error
+ EQUIP_ERR_ONLY_ONE_BOLT = 41, // You can only equip one quiver.
+ EQUIP_ERR_ONLY_ONE_AMMO = 42, // You can only equip one ammo pouch.
+ EQUIP_ERR_CANT_WRAP_STACKABLE = 43, // Stackable items can't be wrapped.
+ EQUIP_ERR_CANT_WRAP_EQUIPPED = 44, // Equipped items can't be wrapped.
+ EQUIP_ERR_CANT_WRAP_WRAPPED = 45, // Wrapped items can't be wrapped.
+ EQUIP_ERR_CANT_WRAP_BOUND = 46, // Bound items can't be wrapped.
+ EQUIP_ERR_CANT_WRAP_UNIQUE = 47, // Unique items can't be wrapped.
+ EQUIP_ERR_CANT_WRAP_BAGS = 48, // Bags can't be wrapped.
+ EQUIP_ERR_LOOT_GONE = 49, // Already looted
+ EQUIP_ERR_INV_FULL = 50, // Inventory is full.
+ EQUIP_ERR_BANK_FULL = 51, // Your bank is full
+ EQUIP_ERR_VENDOR_SOLD_OUT = 52, // That item is currently sold out.
+ EQUIP_ERR_BAG_FULL_2 = 53, // That bag is full.
+ EQUIP_ERR_ITEM_NOT_FOUND_2 = 54, // The item was not found.
+ EQUIP_ERR_CANT_STACK_2 = 55, // This item cannot stack.
+ EQUIP_ERR_BAG_FULL_3 = 56, // That bag is full.
+ EQUIP_ERR_VENDOR_SOLD_OUT_2 = 57, // That item is currently sold out.
+ EQUIP_ERR_OBJECT_IS_BUSY = 58, // That object is busy.
+ EQUIP_ERR_CANT_BE_DISENCHANTED = 59,
+ EQUIP_ERR_NOT_IN_COMBAT = 60, // You can't do that while in combat
+ EQUIP_ERR_NOT_WHILE_DISARMED = 61, // You can't do that while disarmed
+ EQUIP_ERR_BAG_FULL_4 = 62, // That bag is full.
+ EQUIP_ERR_CANT_EQUIP_RANK = 63, // You don't have the required rank for that item
+ EQUIP_ERR_CANT_EQUIP_REPUTATION = 64, // You don't have the required reputation for that item
+ EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65, // You cannot equip another bag of that type
+ EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66, // You can't loot that item now.
+ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE = 67, // You cannot equip more than one of those.
+ EQUIP_ERR_VENDOR_MISSING_TURNINS = 68, // You do not have the required items for that purchase
+ EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69, // You don't have enough honor points
+ EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70, // You don't have enough arena points
+ EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71, // You have the maximum number of those gems in your inventory or socketed into items.
+ EQUIP_ERR_MAIL_BOUND_ITEM = 72, // You can't mail soulbound items.
+ EQUIP_ERR_INTERNAL_BAG_ERROR_2 = 73, // Internal Bag Error
+ EQUIP_ERR_BAG_FULL_5 = 74, // That bag is full.
+ EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75, // You have the maximum number of those gems socketed into equipped items.
+ EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76, // You cannot socket more than one of those gems into a single item.
+ EQUIP_ERR_TOO_MUCH_GOLD = 77, // At gold limit
+ EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, // You can't do that while in an arena match
+ EQUIP_ERR_TRADE_BOUND_ITEM = 79, // You can't trade a soulbound item.
+ EQUIP_ERR_CANT_EQUIP_RATING = 80, // You don't have the personal, team, or battleground rating required to buy that item
+ EQUIP_ERR_NO_OUTPUT = 81,
+ EQUIP_ERR_NOT_SAME_ACCOUNT = 82, // Account-bound items can only be given to your own characters.
+ EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS = 84, // You can only carry %d %s
+ EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS = 85, // You can only equip %d |4item:items in the %s category
+ EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 86, // Your level is too high to use that item
+ EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW = 87, // You must reach level %d to purchase that item.
+ EQUIP_ERR_CANT_EQUIP_NEED_TALENT = 88, // You do not have the required talent to equip that.
+ EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS = 89, // You can only equip %d |4item:items in the %s category
+ EQUIP_ERR_SHAPESHIFT_FORM_CANNOT_EQUIP = 90, // Cannot equip item in this form
+ EQUIP_ERR_ITEM_INVENTORY_FULL_SATCHEL = 91, // Your inventory is full. Your satchel has been delivered to your mailbox.
+ EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_TOO_LOW = 92, // Your level is too low to use that item
+ EQUIP_ERR_CANT_BUY_QUANTITY = 93, // You can't buy the specified quantity of that item.
};
enum BuyResult
@@ -162,14 +166,17 @@ enum EnchantmentSlot
SOCK_ENCHANTMENT_SLOT_3 = 4,
BONUS_ENCHANTMENT_SLOT = 5,
PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment
- MAX_INSPECTED_ENCHANTMENT_SLOT = 7,
-
- PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix
- PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty
- PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty
- PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty
- MAX_ENCHANTMENT_SLOT = 12
+ //TODO: 7,
+ REFORGE_ENCHANTMENT_SLOT = 8,
+ TRANSMOGRIFY_ENCHANTMENT_SLOT = 9,
+ MAX_INSPECTED_ENCHANTMENT_SLOT = 10,
+
+ PROP_ENCHANTMENT_SLOT_0 = 10, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_1 = 11, // used with RandomSuffix
+ PROP_ENCHANTMENT_SLOT_2 = 12, // used with RandomSuffix and RandomProperty
+ PROP_ENCHANTMENT_SLOT_3 = 13, // used with RandomProperty
+ PROP_ENCHANTMENT_SLOT_4 = 14, // used with RandomProperty
+ MAX_ENCHANTMENT_SLOT = 15
};
#define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment)
@@ -281,7 +288,6 @@ class Item : public Object
bool IsEquipped() const;
uint32 GetSkill();
- uint32 GetSpell();
// RandomPropertyId (signed but stored as unsigned)
int32 GetItemRandomPropertyId() const { return GetInt32Value(ITEM_FIELD_RANDOM_PROPERTIES_ID); }
@@ -326,10 +332,11 @@ class Item : public Object
bool hasQuest(uint32 quest_id) const { return GetTemplate()->StartQuest == quest_id; }
bool hasInvolvedQuest(uint32 /*quest_id*/) const { return false; }
+ bool HasStats() const;
bool IsPotion() const { return GetTemplate()->IsPotion(); }
- bool IsWeaponVellum() const { return GetTemplate()->IsWeaponVellum(); }
- bool IsArmorVellum() const { return GetTemplate()->IsArmorVellum(); }
+ bool IsVellum() const { return GetTemplate()->IsVellum(); }
bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); }
+ bool IsRangedWeapon() const { return GetTemplate()->IsRangedWeapon(); }
// Item Refund system
void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = NULL);
@@ -353,6 +360,24 @@ class Item : public Object
void BuildUpdate(UpdateDataMapType&);
uint32 GetScriptId() const { return GetTemplate()->ScriptId; }
+
+ bool CanBeTransmogrified() const;
+ bool CanTransmogrify() const;
+ static bool CanTransmogrifyItemWithItem(Item const* transmogrified, Item const* transmogrifier);
+ static uint32 GetSpecialPrice(ItemTemplate const* proto, uint32 minimumPrice = 10000);
+ uint32 GetSpecialPrice(uint32 minimumPrice = 10000) const { return Item::GetSpecialPrice(GetTemplate(), minimumPrice); }
+
+ uint32 GetVisibleEntry() const
+ {
+ if (uint32 transmogrification = GetEnchantmentId(TRANSMOGRIFY_ENCHANTMENT_SLOT))
+ return transmogrification;
+ return GetEntry();
+ }
+
+ static uint32 GetSellPrice(ItemTemplate const* proto, bool& success);
+
+ int32 GetReforgableStat(ItemModType statType) const;
+
private:
std::string m_text;
uint8 m_slot;
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index d411af218b1..4535ae57474 100644
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -59,18 +59,23 @@ enum ItemModType
ITEM_MOD_EXPERTISE_RATING = 37,
ITEM_MOD_ATTACK_POWER = 38,
ITEM_MOD_RANGED_ATTACK_POWER = 39,
- //ITEM_MOD_FERAL_ATTACK_POWER = 40, not in 3.3
- ITEM_MOD_SPELL_HEALING_DONE = 41, // deprecated
- ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated
ITEM_MOD_MANA_REGENERATION = 43,
ITEM_MOD_ARMOR_PENETRATION_RATING = 44,
ITEM_MOD_SPELL_POWER = 45,
ITEM_MOD_HEALTH_REGEN = 46,
ITEM_MOD_SPELL_PENETRATION = 47,
- ITEM_MOD_BLOCK_VALUE = 48
+ ITEM_MOD_BLOCK_VALUE = 48,
+ ITEM_MOD_MASTERY_RATING = 49,
+ ITEM_MOD_EXTRA_ARMOR = 50,
+ ITEM_MOD_FIRE_RESISTANCE = 51,
+ ITEM_MOD_FROST_RESISTANCE = 52,
+ ITEM_MOD_HOLY_RESISTANCE = 53,
+ ITEM_MOD_SHADOW_RESISTANCE = 54,
+ ITEM_MOD_NATURE_RESISTANCE = 55,
+ ITEM_MOD_ARCANE_RESISTANCE = 56,
};
-#define MAX_ITEM_MOD 49
+#define MAX_ITEM_MOD 57
enum ItemSpelltriggerType
{
@@ -138,7 +143,7 @@ enum ItemProtoFlags
ITEM_PROTO_FLAG_TRIGGERED_CAST = 0x10000000, // Spell is cast with triggered flag
ITEM_PROTO_FLAG_MILLABLE = 0x20000000, // Item can be milled
ITEM_PROTO_FLAG_UNK11 = 0x40000000, // ?
- ITEM_PROTO_FLAG_UNK12 = 0x80000000 // ?
+ ITEM_PROTO_FLAG_BOP_TRADEABLE = 0x80000000 // bound item that can be traded
};
enum ItemFieldFlags
@@ -184,7 +189,13 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001,
ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002,
ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required
- ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100
+ ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100,
+ ITEM_FLAGS_EXTRA_CASTER_WEAPON = 0x00000200,
+ ITEM_FLAGS_EXTRA_HAS_NORMAL_PRICE = 0x00004000,
+ ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000,
+ ITEM_FLAGS_EXTRA_CANNOT_BE_TRANSMOG = 0x00200000,
+ ITEM_FLAGS_EXTRA_CANNOT_TRANSMOG = 0x00400000,
+ ITEM_FLAGS_EXTRA_CAN_TRANSMOG = 0x00800000,
};
enum ItemFlagsCustom
@@ -194,6 +205,28 @@ enum ItemFlagsCustom
ITEM_FLAGS_CU_FOLLOW_LOOT_RULES = 0x0004 // Item will always follow group/master/need before greed looting rules
};
+enum CurrencyFlags
+{
+ CURRENCY_FLAG_TRADEABLE = 0x01,
+ // ...
+ CURRENCY_FLAG_HIGH_PRECISION = 0x08,
+ // ...
+ CURRENCY_FLAG_COUNT_SEASON_TOTAL = 0x80,
+};
+
+enum CurrencyCategory
+{
+ // ...
+ CURRENCY_CATEGORY_META_CONQUEST = 89,
+ // ...
+};
+
+enum ItemVendorType
+{
+ ITEM_VENDOR_TYPE_ITEM = 1,
+ ITEM_VENDOR_TYPE_CURRENCY = 2,
+};
+
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_NONE = 0x00000000,
@@ -211,7 +244,8 @@ enum BAG_FAMILY_MASK
BAG_FAMILY_MASK_SOULBOUND_EQUIPMENT = 0x00000800,
BAG_FAMILY_MASK_VANITY_PETS = 0x00001000,
BAG_FAMILY_MASK_CURRENCY_TOKENS = 0x00002000,
- BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000
+ BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000,
+ BAG_FAMILY_MASK_FISHING_SUPP = 0x00008000,
};
enum SocketColor
@@ -219,10 +253,12 @@ enum SocketColor
SOCKET_COLOR_META = 1,
SOCKET_COLOR_RED = 2,
SOCKET_COLOR_YELLOW = 4,
- SOCKET_COLOR_BLUE = 8
+ SOCKET_COLOR_BLUE = 8,
+ SOCKET_COLOR_HYDRAULIC = 16, // not used
+ SOCKET_COLOR_COGWHEEL = 32,
};
-#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE)
+#define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE | SOCKET_COLOR_COGWHEEL)
enum InventoryType
{
@@ -269,14 +305,14 @@ enum ItemClass
ITEM_CLASS_REAGENT = 5,
ITEM_CLASS_PROJECTILE = 6,
ITEM_CLASS_TRADE_GOODS = 7,
- ITEM_CLASS_GENERIC = 8,
+ ITEM_CLASS_GENERIC = 8, // OBSOLETE
ITEM_CLASS_RECIPE = 9,
- ITEM_CLASS_MONEY = 10,
+ ITEM_CLASS_MONEY = 10, // OBSOLETE
ITEM_CLASS_QUIVER = 11,
ITEM_CLASS_QUEST = 12,
ITEM_CLASS_KEY = 13,
- ITEM_CLASS_PERMANENT = 14,
- ITEM_CLASS_MISC = 15,
+ ITEM_CLASS_PERMANENT = 14, // OBSOLETE
+ ITEM_CLASS_MISCELLANEOUS = 15,
ITEM_CLASS_GLYPH = 16
};
@@ -289,7 +325,7 @@ enum ItemSubclassConsumable
ITEM_SUBCLASS_ELIXIR = 2,
ITEM_SUBCLASS_FLASK = 3,
ITEM_SUBCLASS_SCROLL = 4,
- ITEM_SUBCLASS_FOOD = 5,
+ ITEM_SUBCLASS_FOOD_DRINK = 5,
ITEM_SUBCLASS_ITEM_ENHANCEMENT = 6,
ITEM_SUBCLASS_BANDAGE = 7,
ITEM_SUBCLASS_CONSUMABLE_OTHER = 8
@@ -307,28 +343,29 @@ enum ItemSubclassContainer
ITEM_SUBCLASS_GEM_CONTAINER = 5,
ITEM_SUBCLASS_MINING_CONTAINER = 6,
ITEM_SUBCLASS_LEATHERWORKING_CONTAINER = 7,
- ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8
+ ITEM_SUBCLASS_INSCRIPTION_CONTAINER = 8,
+ ITEM_SUBCLASS_TACKLE_CONTAINER = 9
};
-#define MAX_ITEM_SUBCLASS_CONTAINER 9
+#define MAX_ITEM_SUBCLASS_CONTAINER 10
enum ItemSubclassWeapon
{
- ITEM_SUBCLASS_WEAPON_AXE = 0,
- ITEM_SUBCLASS_WEAPON_AXE2 = 1,
+ ITEM_SUBCLASS_WEAPON_AXE = 0, // One-Handed Axes
+ ITEM_SUBCLASS_WEAPON_AXE2 = 1, // Two-Handed Axes
ITEM_SUBCLASS_WEAPON_BOW = 2,
ITEM_SUBCLASS_WEAPON_GUN = 3,
- ITEM_SUBCLASS_WEAPON_MACE = 4,
- ITEM_SUBCLASS_WEAPON_MACE2 = 5,
+ ITEM_SUBCLASS_WEAPON_MACE = 4, // One-Handed Maces
+ ITEM_SUBCLASS_WEAPON_MACE2 = 5, // Two-Handed Maces
ITEM_SUBCLASS_WEAPON_POLEARM = 6,
- ITEM_SUBCLASS_WEAPON_SWORD = 7,
- ITEM_SUBCLASS_WEAPON_SWORD2 = 8,
- ITEM_SUBCLASS_WEAPON_obsolete = 9,
+ ITEM_SUBCLASS_WEAPON_SWORD = 7, // One-Handed Swords
+ ITEM_SUBCLASS_WEAPON_SWORD2 = 8, // Two-Handed Swords
+ ITEM_SUBCLASS_WEAPON_Obsolete = 9,
ITEM_SUBCLASS_WEAPON_STAFF = 10,
- ITEM_SUBCLASS_WEAPON_EXOTIC = 11,
- ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12,
- ITEM_SUBCLASS_WEAPON_FIST = 13,
- ITEM_SUBCLASS_WEAPON_MISC = 14,
+ ITEM_SUBCLASS_WEAPON_EXOTIC = 11, // One-Handed Exotics
+ ITEM_SUBCLASS_WEAPON_EXOTIC2 = 12, // Two-Handed Exotics
+ ITEM_SUBCLASS_WEAPON_FIST_WEAPON = 13,
+ ITEM_SUBCLASS_WEAPON_MISCELLANEOUS = 14,
ITEM_SUBCLASS_WEAPON_DAGGER = 15,
ITEM_SUBCLASS_WEAPON_THROWN = 16,
ITEM_SUBCLASS_WEAPON_SPEAR = 17,
@@ -353,27 +390,30 @@ enum ItemSubclassGem
ITEM_SUBCLASS_GEM_ORANGE = 5,
ITEM_SUBCLASS_GEM_META = 6,
ITEM_SUBCLASS_GEM_SIMPLE = 7,
- ITEM_SUBCLASS_GEM_PRISMATIC = 8
+ ITEM_SUBCLASS_GEM_PRISMATIC = 8,
+ ITEM_SUBCLASS_GEM_HYDRAULIC = 9,
+ ITEM_SUBCLASS_GEM_COGWHEEL = 10
};
-#define MAX_ITEM_SUBCLASS_GEM 9
+#define MAX_ITEM_SUBCLASS_GEM 11
enum ItemSubclassArmor
{
- ITEM_SUBCLASS_ARMOR_MISC = 0,
+ ITEM_SUBCLASS_ARMOR_MISCELLANEOUS = 0,
ITEM_SUBCLASS_ARMOR_CLOTH = 1,
ITEM_SUBCLASS_ARMOR_LEATHER = 2,
ITEM_SUBCLASS_ARMOR_MAIL = 3,
ITEM_SUBCLASS_ARMOR_PLATE = 4,
- ITEM_SUBCLASS_ARMOR_BUCKLER = 5,
+ ITEM_SUBCLASS_ARMOR_BUCKLER = 5, // OBSOLETE
ITEM_SUBCLASS_ARMOR_SHIELD = 6,
ITEM_SUBCLASS_ARMOR_LIBRAM = 7,
ITEM_SUBCLASS_ARMOR_IDOL = 8,
ITEM_SUBCLASS_ARMOR_TOTEM = 9,
- ITEM_SUBCLASS_ARMOR_SIGIL = 10
+ ITEM_SUBCLASS_ARMOR_SIGIL = 10,
+ ITEM_SUBCLASS_ARMOR_RELIC = 11,
};
-#define MAX_ITEM_SUBCLASS_ARMOR 11
+#define MAX_ITEM_SUBCLASS_ARMOR 12
enum ItemSubclassReagent
{
@@ -384,11 +424,11 @@ enum ItemSubclassReagent
enum ItemSubclassProjectile
{
- ITEM_SUBCLASS_WAND = 0, // ABS
- ITEM_SUBCLASS_BOLT = 1, // ABS
+ ITEM_SUBCLASS_WAND = 0, // OBSOLETE
+ ITEM_SUBCLASS_BOLT = 1, // OBSOLETE
ITEM_SUBCLASS_ARROW = 2,
ITEM_SUBCLASS_BULLET = 3,
- ITEM_SUBCLASS_THROWN = 4 // ABS
+ ITEM_SUBCLASS_THROWN = 4 // OBSOLETE
};
#define MAX_ITEM_SUBCLASS_PROJECTILE 5
@@ -409,15 +449,14 @@ enum ItemSubclassTradeGoods
ITEM_SUBCLASS_TRADE_GOODS_OTHER = 11,
ITEM_SUBCLASS_ENCHANTING = 12,
ITEM_SUBCLASS_MATERIAL = 13,
- ITEM_SUBCLASS_ARMOR_ENCHANTMENT = 14,
- ITEM_SUBCLASS_WEAPON_ENCHANTMENT = 15
+ ITEM_SUBCLASS_ENCHANTMENT = 14,
};
-#define MAX_ITEM_SUBCLASS_TRADE_GOODS 16
+#define MAX_ITEM_SUBCLASS_TRADE_GOODS 15
enum ItemSubclassGeneric
{
- ITEM_SUBCLASS_GENERIC = 0
+ ITEM_SUBCLASS_GENERIC = 0 // OBSOLETE
};
#define MAX_ITEM_SUBCLASS_GENERIC 1
@@ -434,22 +473,24 @@ enum ItemSubclassRecipe
ITEM_SUBCLASS_FIRST_AID_MANUAL = 7,
ITEM_SUBCLASS_ENCHANTING_FORMULA = 8,
ITEM_SUBCLASS_FISHING_MANUAL = 9,
- ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10
+ ITEM_SUBCLASS_JEWELCRAFTING_RECIPE = 10,
+ ITEM_SUBCLASS_INSCRIPTION_TECHNIQUE = 11
};
-#define MAX_ITEM_SUBCLASS_RECIPE 11
+#define MAX_ITEM_SUBCLASS_RECIPE 12
enum ItemSubclassMoney
{
- ITEM_SUBCLASS_MONEY = 0
+ ITEM_SUBCLASS_MONEY = 0, // OBSOLETE
+ ITEM_SUBCLASS_MONEY_UNK_7 = 7, // OBSOLETE, 1 item (41749)
};
-#define MAX_ITEM_SUBCLASS_MONEY 1
+#define MAX_ITEM_SUBCLASS_MONEY 8
enum ItemSubclassQuiver
{
- ITEM_SUBCLASS_QUIVER0 = 0, // ABS
- ITEM_SUBCLASS_QUIVER1 = 1, // ABS
+ ITEM_SUBCLASS_QUIVER0 = 0, // OBSOLETE
+ ITEM_SUBCLASS_QUIVER1 = 1, // OBSOLETE
ITEM_SUBCLASS_QUIVER = 2,
ITEM_SUBCLASS_AMMO_POUCH = 3
};
@@ -458,10 +499,12 @@ enum ItemSubclassQuiver
enum ItemSubclassQuest
{
- ITEM_SUBCLASS_QUEST = 0
+ ITEM_SUBCLASS_QUEST = 0,
+ ITEM_SUBCLASS_QUEST_UNK3 = 3, // 1 item (33604)
+ ITEM_SUBCLASS_QUEST_UNK8 = 8, // 2 items (37445, 49700)
};
-#define MAX_ITEM_SUBCLASS_QUEST 1
+#define MAX_ITEM_SUBCLASS_QUEST 9
enum ItemSubclassKey
{
@@ -485,10 +528,11 @@ enum ItemSubclassJunk
ITEM_SUBCLASS_JUNK_PET = 2,
ITEM_SUBCLASS_JUNK_HOLIDAY = 3,
ITEM_SUBCLASS_JUNK_OTHER = 4,
- ITEM_SUBCLASS_JUNK_MOUNT = 5
+ ITEM_SUBCLASS_JUNK_MOUNT = 5,
+ ITEM_SUBCLASS_JUNK_UNK12 = 12, // 1 item (37677)
};
-#define MAX_ITEM_SUBCLASS_JUNK 6
+#define MAX_ITEM_SUBCLASS_JUNK 13
enum ItemSubclassGlyph
{
@@ -544,24 +588,19 @@ inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemS
#pragma pack(push, 1)
#endif
-struct _Damage
-{
- float DamageMin;
- float DamageMax;
- uint32 DamageType; // id from Resistances.dbc
-};
-
struct _ItemStat
{
uint32 ItemStatType;
int32 ItemStatValue;
+ int32 ItemStatUnk1;
+ int32 ItemStatUnk2;
};
+
struct _Spell
{
int32 SpellId; // id from Spell.dbc
uint32 SpellTrigger;
int32 SpellCharges;
- float SpellPPMRate;
int32 SpellCooldown;
uint32 SpellCategory; // id from SpellCategory.dbc
int32 SpellCategoryCooldown;
@@ -596,6 +635,8 @@ struct ItemTemplate
uint32 Quality;
uint32 Flags;
uint32 Flags2;
+ float Unk430_1;
+ float Unk430_2;
uint32 BuyCount;
int32 BuyPrice;
uint32 SellPrice;
@@ -614,24 +655,14 @@ struct ItemTemplate
int32 MaxCount; // <= 0: no limit
int32 Stackable; // 0: not allowed, -1: put in player coin info tab and don't limit stacking (so 1 slot)
uint32 ContainerSlots;
- uint32 StatsCount;
_ItemStat ItemStat[MAX_ITEM_PROTO_STATS];
uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc
- uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc
- _Damage Damage[MAX_ITEM_PROTO_DAMAGES];
- uint32 Armor;
- uint32 HolyRes;
- uint32 FireRes;
- uint32 NatureRes;
- uint32 FrostRes;
- uint32 ShadowRes;
- uint32 ArcaneRes;
+ uint32 DamageType; // id from Resistances.dbc
uint32 Delay;
- uint32 AmmoType;
float RangedModRange;
_Spell Spells[MAX_ITEM_PROTO_SPELLS];
uint32 Bonding;
- std::string Description;
+ std::string Description;
uint32 PageText;
uint32 LanguageID;
uint32 PageMaterial;
@@ -641,7 +672,6 @@ struct ItemTemplate
uint32 Sheath;
int32 RandomProperty; // id from ItemRandomProperties.dbc
int32 RandomSuffix; // id from ItemRandomSuffix.dbc
- uint32 Block;
uint32 ItemSet; // id from ItemSet.dbc
uint32 MaxDurability;
uint32 Area; // id from AreaTable.dbc
@@ -651,13 +681,23 @@ struct ItemTemplate
_Socket Socket[MAX_ITEM_PROTO_SOCKETS];
uint32 socketBonus; // id from SpellItemEnchantment.dbc
uint32 GemProperties; // id from GemProperties.dbc
- uint32 RequiredDisenchantSkill;
float ArmorDamageModifier;
uint32 Duration;
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 HolidayId; // id from Holidays.dbc
+ float StatScalingFactor;
+ uint32 CurrencySubstitutionId; // May be used instead of a currency
+ uint32 CurrencySubstitutionCount;
+
+ // extra fields, not part of db2 files
+ float DamageMin;
+ float DamageMax;
+ float DPS;
+ uint32 Armor;
+ float SpellPPMRate;
uint32 ScriptId;
uint32 DisenchantID;
+ uint32 RequiredDisenchantSkill;
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
@@ -691,29 +731,6 @@ struct ItemTemplate
return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable);
}
- float getDPS() const
- {
- if (Delay == 0)
- return 0;
- float temp = 0;
- for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
- temp+=Damage[i].DamageMin + Damage[i].DamageMax;
- return temp*500/Delay;
- }
-
- int32 getFeralBonus(int32 extraDPS = 0) const
- {
- // 0x02A5F3 - is mask for Melee weapon from ItemSubClassMask.dbc
- if (Class == ITEM_CLASS_WEAPON && (1<<SubClass)&0x02A5F3)
- {
- int32 bonus = int32((extraDPS + getDPS())*14.0f) - 767;
- if (bonus < 0)
- return 0;
- return bonus;
- }
- return 0;
- }
-
float GetItemLevelIncludingQuality() const
{
float itemLevel = (float)ItemLevel;
@@ -738,9 +755,16 @@ struct ItemTemplate
}
bool IsPotion() const { return Class == ITEM_CLASS_CONSUMABLE && SubClass == ITEM_SUBCLASS_POTION; }
- bool IsWeaponVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT; }
- bool IsArmorVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT; }
+ bool IsVellum() const { return Class == ITEM_CLASS_TRADE_GOODS && SubClass == ITEM_SUBCLASS_ENCHANTMENT; }
bool IsConjuredConsumable() const { return Class == ITEM_CLASS_CONSUMABLE && (Flags & ITEM_PROTO_FLAG_CONJURED); }
+
+ bool IsRangedWeapon() const
+ {
+ return Class == ITEM_CLASS_WEAPON ||
+ SubClass == ITEM_SUBCLASS_WEAPON_BOW ||
+ SubClass == ITEM_SUBCLASS_WEAPON_GUN ||
+ SubClass == ITEM_SUBCLASS_WEAPON_CROSSBOW;
+ }
};
// Benchmarked: Faster than std::map (insert/find)
@@ -752,15 +776,4 @@ struct ItemLocale
StringVector Description;
};
-struct ItemSetNameEntry
-{
- std::string name;
- uint32 InventoryType;
-};
-
-struct ItemSetNameLocale
-{
- StringVector Name;
-};
-
#endif
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 8af48f277bd..da22204a4e1 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -47,6 +47,7 @@
#include "OutdoorPvPMgr.h"
#include "MovementPacketBuilder.h"
#include "DynamicTree.h"
+#include "Unit.h"
#include "Group.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
@@ -64,6 +65,7 @@ uint32 GuidHigh2TypeId(uint32 guid_hi)
case HIGHGUID_GAMEOBJECT: return TYPEID_GAMEOBJECT;
case HIGHGUID_DYNAMICOBJECT:return TYPEID_DYNAMICOBJECT;
case HIGHGUID_CORPSE: return TYPEID_CORPSE;
+ case HIGHGUID_AREATRIGGER: return TYPEID_AREATRIGGER;
case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT;
case HIGHGUID_VEHICLE: return TYPEID_UNIT;
}
@@ -138,8 +140,8 @@ void Object::_Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
uint64 guid = MAKE_NEW_GUID(guidlow, entry, guidhigh);
SetUInt64Value(OBJECT_FIELD_GUID, guid);
- SetUInt32Value(OBJECT_FIELD_TYPE, m_objectType);
- m_PackGUID.wpos(0);
+ SetUInt16Value(OBJECT_FIELD_TYPE, 0, m_objectType);
+ m_PackGUID.clear();
m_PackGUID.appendPackGUID(GetGUID());
}
@@ -175,18 +177,6 @@ void Object::RemoveFromWorld()
ClearUpdateMask(true);
}
-void Object::BuildMovementUpdateBlock(UpdateData* data, uint32 flags) const
-{
- ByteBuffer buf(500);
-
- buf << uint8(UPDATETYPE_MOVEMENT);
- buf.append(GetPackGUID());
-
- BuildMovementUpdate(&buf, flags);
-
- data->AddUpdateBlock(buf);
-}
-
void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const
{
if (!target)
@@ -199,16 +189,36 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
if (target == this) // building packet for yourself
flags |= UPDATEFLAG_SELF;
- if (flags & UPDATEFLAG_STATIONARY_POSITION)
+ switch (GetGUIDHigh())
{
- // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...
- if (isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER))
+ case HIGHGUID_PLAYER:
+ case HIGHGUID_PET:
+ case HIGHGUID_CORPSE:
+ case HIGHGUID_DYNAMICOBJECT:
+ case HIGHGUID_AREATRIGGER:
updateType = UPDATETYPE_CREATE_OBJECT2;
+ break;
+ case HIGHGUID_UNIT:
+ case HIGHGUID_VEHICLE:
+ {
+ if (TempSummon const* summon = ToUnit()->ToTempSummon())
+ if (IS_PLAYER_GUID(summon->GetSummonerGUID()))
+ updateType = UPDATETYPE_CREATE_OBJECT2;
- // UPDATETYPE_CREATE_OBJECT2 for pets...
- if (target->GetPetGUID() == GetGUID())
- updateType = UPDATETYPE_CREATE_OBJECT2;
+ break;
+ }
+ case HIGHGUID_GAMEOBJECT:
+ {
+ if (IS_PLAYER_GUID(ToGameObject()->GetOwnerGUID()))
+ updateType = UPDATETYPE_CREATE_OBJECT2;
+ break;
+ }
+ default:
+ break;
+ }
+ if (flags & UPDATEFLAG_STATIONARY_POSITION)
+ {
// UPDATETYPE_CREATE_OBJECT2 for some gameobject types...
if (isType(TYPEMASK_GAMEOBJECT))
{
@@ -224,15 +234,11 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
break;
}
}
-
- if (isType(TYPEMASK_UNIT))
- {
- if (ToUnit()->GetVictim())
- flags |= UPDATEFLAG_HAS_TARGET;
- }
}
- //TC_LOG_DEBUG("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updateType, m_objectTypeId, flags, flags2);
+ if (Unit const* unit = ToUnit())
+ if (unit->GetVictim())
+ flags |= UPDATEFLAG_HAS_TARGET;
ByteBuffer buf(500);
buf << uint8(updateType);
@@ -247,7 +253,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
void Object::SendUpdateToPlayer(Player* player)
{
// send create update to player
- UpdateData upd;
+ UpdateData upd(player->GetMapId());
WorldPacket packet;
BuildCreateUpdateBlockForPlayer(&upd, player);
@@ -337,135 +343,315 @@ uint16 Object::GetUInt16Value(uint16 index, uint8 offset) const
void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
{
- Unit const* unit = NULL;
- WorldObject const* object = NULL;
+ Unit const* self = NULL;
+ ObjectGuid guid = GetGUID();
+ uint32 movementFlags = 0;
+ uint16 movementFlagsExtra = 0;
+
+ bool hasTransportTime2 = false;
+ bool hasTransportTime3 = false;
+ bool hasFallDirection = false;
+ bool hasFallData = false;
+ bool hasPitch = false;
+ bool hasSpline = false;
+ bool hasSplineElevation = false;
+
+ uint32 unkLoopCounter = 0;
+ // Bit content
+ data->WriteBit(0);
+ data->WriteBit(0);
+ data->WriteBit(flags & UPDATEFLAG_ROTATION);
+ data->WriteBit(flags & UPDATEFLAG_ANIMKITS);
+ data->WriteBit(flags & UPDATEFLAG_HAS_TARGET);
+ data->WriteBit(flags & UPDATEFLAG_SELF);
+ data->WriteBit(flags & UPDATEFLAG_VEHICLE);
+ data->WriteBit(flags & UPDATEFLAG_LIVING);
+ data->WriteBits(unkLoopCounter, 24);
+ data->WriteBit(0);
+ data->WriteBit(flags & UPDATEFLAG_GO_TRANSPORT_POSITION);
+ data->WriteBit(flags & UPDATEFLAG_STATIONARY_POSITION);
+ data->WriteBit(flags & UPDATEFLAG_UNK5);
+ data->WriteBit(0);
+ data->WriteBit(flags & UPDATEFLAG_TRANSPORT);
- if (isType(TYPEMASK_UNIT))
- unit = ToUnit();
- else
- object = ((WorldObject*)this);
-
- *data << uint16(flags); // update flags
-
- // 0x20
if (flags & UPDATEFLAG_LIVING)
{
- unit->BuildMovementPacket(data);
+ self = ToUnit();
+ movementFlags = self->m_movementInfo.GetMovementFlags();
+ movementFlagsExtra = self->m_movementInfo.GetExtraMovementFlags();
+ hasSpline = self->IsSplineEnabled();
+
+ hasTransportTime2 = self->m_movementInfo.transport.guid != 0 && self->m_movementInfo.transport.time2 != 0;
+ hasTransportTime3 = false;
+ hasPitch = self->HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || self->HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
+ hasFallDirection = self->HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ hasFallData = hasFallDirection || self->m_movementInfo.jump.fallTime != 0;
+ hasSplineElevation = self->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ if (GetTypeId() == TYPEID_UNIT)
+ movementFlags &= MOVEMENTFLAG_MASK_CREATURE_ALLOWED;
+
+ data->WriteBit(!movementFlags);
+ data->WriteBit(G3D::fuzzyEq(self->GetOrientation(), 0.0f)); // Has Orientation
+ data->WriteBit(guid[7]);
+ data->WriteBit(guid[3]);
+ data->WriteBit(guid[2]);
+ if (movementFlags)
+ data->WriteBits(movementFlags, 30);
+
+ data->WriteBit(hasSpline && GetTypeId() == TYPEID_PLAYER); // Has spline (from MovementInfo)
+ data->WriteBit(!hasPitch); // Has pitch
+ data->WriteBit(hasSpline); // Has spline data (independent)
+ data->WriteBit(hasFallData); // Has fall data
+ data->WriteBit(!hasSplineElevation); // Has spline elevation
+ data->WriteBit(guid[5]);
+ data->WriteBit(self->m_movementInfo.transport.guid); // Has transport data
+ data->WriteBit(0); // Is missing time
+
+ if (self->m_movementInfo.transport.guid)
+ {
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
+
+ data->WriteBit(transGuid[1]);
+ data->WriteBit(hasTransportTime2); // Has transport time 2
+ data->WriteBit(transGuid[4]);
+ data->WriteBit(transGuid[0]);
+ data->WriteBit(transGuid[6]);
+ data->WriteBit(hasTransportTime3); // Has transport time 3
+ data->WriteBit(transGuid[7]);
+ data->WriteBit(transGuid[5]);
+ data->WriteBit(transGuid[3]);
+ data->WriteBit(transGuid[2]);
+ }
+
+ data->WriteBit(guid[4]);
- *data << unit->GetSpeed(MOVE_WALK)
- << unit->GetSpeed(MOVE_RUN)
- << unit->GetSpeed(MOVE_RUN_BACK)
- << unit->GetSpeed(MOVE_SWIM)
- << unit->GetSpeed(MOVE_SWIM_BACK)
- << unit->GetSpeed(MOVE_FLIGHT)
- << unit->GetSpeed(MOVE_FLIGHT_BACK)
- << unit->GetSpeed(MOVE_TURN_RATE)
- << unit->GetSpeed(MOVE_PITCH_RATE);
+ if (hasSpline)
+ Movement::PacketBuilder::WriteCreateBits(*self->movespline, *data);
- // 0x08000000
- if (unit->m_movementInfo.GetMovementFlags() & MOVEMENTFLAG_SPLINE_ENABLED)
- Movement::PacketBuilder::WriteCreate(*unit->movespline, *data);
+ data->WriteBit(guid[6]);
+ if (hasFallData)
+ data->WriteBit(hasFallDirection);
+
+ data->WriteBit(guid[0]);
+ data->WriteBit(guid[1]);
+ data->WriteBit(0);
+ data->WriteBit(!movementFlagsExtra);
+ if (movementFlagsExtra)
+ data->WriteBits(movementFlagsExtra, 12);
}
- else
+
+ if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
- if (flags & UPDATEFLAG_POSITION)
- {
- Transport* transport = object->GetTransport();
+ WorldObject const* self = static_cast<WorldObject const*>(this);
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
+ data->WriteBit(transGuid[5]);
+ data->WriteBit(0); // Has GO transport time 3
+ data->WriteBit(transGuid[0]);
+ data->WriteBit(transGuid[3]);
+ data->WriteBit(transGuid[6]);
+ data->WriteBit(transGuid[1]);
+ data->WriteBit(transGuid[4]);
+ data->WriteBit(transGuid[2]);
+ data->WriteBit(0); // Has GO transport time 2
+ data->WriteBit(transGuid[7]);
+ }
- if (transport)
- data->append(transport->GetPackGUID());
- else
- *data << uint8(0);
+ if (flags & UPDATEFLAG_HAS_TARGET)
+ {
+ ObjectGuid victimGuid = self->GetVictim()->GetGUID(); // checked in BuildCreateUpdateBlockForPlayer
+ data->WriteBit(victimGuid[2]);
+ data->WriteBit(victimGuid[7]);
+ data->WriteBit(victimGuid[0]);
+ data->WriteBit(victimGuid[4]);
+ data->WriteBit(victimGuid[5]);
+ data->WriteBit(victimGuid[6]);
+ data->WriteBit(victimGuid[1]);
+ data->WriteBit(victimGuid[3]);
+ }
- *data << object->GetPositionX();
- *data << object->GetPositionY();
- if (isType(TYPEMASK_UNIT))
- *data << unit->GetPositionZMinusOffset();
- else
- *data << object->GetPositionZ();
+ if (flags & UPDATEFLAG_ANIMKITS)
+ {
+ data->WriteBit(1); // Missing AnimKit1
+ data->WriteBit(1); // Missing AnimKit2
+ data->WriteBit(1); // Missing AnimKit3
+ }
- if (transport)
- {
- *data << object->GetTransOffsetX();
- *data << object->GetTransOffsetY();
- *data << object->GetTransOffsetZ();
- }
- else
- {
- *data << object->GetPositionX();
- *data << object->GetPositionY();
- if (isType(TYPEMASK_UNIT))
- *data << unit->GetPositionZMinusOffset();
- else
- *data << object->GetPositionZ();
- }
+ data->FlushBits();
+
+ // Data
+ for (uint32 i = 0; i < unkLoopCounter; ++i)
+ *data << uint32(0);
- *data << object->GetOrientation();
+ if (flags & UPDATEFLAG_LIVING)
+ {
+ data->WriteByteSeq(guid[4]);
+ *data << self->GetSpeed(MOVE_RUN_BACK);
- if (GetTypeId() == TYPEID_CORPSE)
- *data << float(object->GetOrientation());
- else
- *data << float(0);
- }
- else
+ if (hasFallData)
{
- // 0x40
- if (flags & UPDATEFLAG_STATIONARY_POSITION)
+ if (hasFallDirection)
{
- *data << object->GetStationaryX();
- *data << object->GetStationaryY();
- *data << object->GetStationaryZ();
- *data << object->GetStationaryO();
+ *data << float(self->m_movementInfo.jump.xyspeed);
+ *data << float(self->m_movementInfo.jump.sinAngle);
+ *data << float(self->m_movementInfo.jump.cosAngle);
}
+
+ *data << uint32(self->m_movementInfo.jump.fallTime);
+ *data << float(self->m_movementInfo.jump.zspeed);
}
+
+ *data << self->GetSpeed(MOVE_SWIM_BACK);
+ if (hasSplineElevation)
+ *data << float(self->m_movementInfo.splineElevation);
+
+ if (hasSpline)
+ Movement::PacketBuilder::WriteCreateData(*self->movespline, *data);
+
+ *data << float(self->GetPositionZMinusOffset());
+ data->WriteByteSeq(guid[5]);
+
+ if (self->m_movementInfo.transport.guid)
+ {
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
+
+ data->WriteByteSeq(transGuid[5]);
+ data->WriteByteSeq(transGuid[7]);
+ *data << uint32(self->GetTransTime());
+ *data << float(self->GetTransOffsetO());
+ if (hasTransportTime2)
+ *data << uint32(self->m_movementInfo.transport.time2);
+
+ *data << float(self->GetTransOffsetY());
+ *data << float(self->GetTransOffsetX());
+ data->WriteByteSeq(transGuid[3]);
+ *data << float(self->GetTransOffsetZ());
+ data->WriteByteSeq(transGuid[0]);
+ if (hasTransportTime3)
+ *data << uint32(self->m_movementInfo.transport.time3);
+
+ *data << int8(self->GetTransSeat());
+ data->WriteByteSeq(transGuid[1]);
+ data->WriteByteSeq(transGuid[6]);
+ data->WriteByteSeq(transGuid[2]);
+ data->WriteByteSeq(transGuid[4]);
+ }
+
+ *data << float(self->GetPositionX());
+ *data << self->GetSpeed(MOVE_PITCH_RATE);
+ data->WriteByteSeq(guid[3]);
+ data->WriteByteSeq(guid[0]);
+ *data << self->GetSpeed(MOVE_SWIM);
+ *data << float(self->GetPositionY());
+ data->WriteByteSeq(guid[7]);
+ data->WriteByteSeq(guid[1]);
+ data->WriteByteSeq(guid[2]);
+ *data << self->GetSpeed(MOVE_WALK);
+
+ //if (true) // Has time, controlled by bit just after HasTransport
+ *data << uint32(getMSTime());
+
+ *data << self->GetSpeed(MOVE_FLIGHT_BACK);
+ data->WriteByteSeq(guid[6]);
+ *data << self->GetSpeed(MOVE_TURN_RATE);
+ if (!G3D::fuzzyEq(self->GetOrientation(), 0.0f))
+ *data << float(self->GetOrientation());
+
+ *data << self->GetSpeed(MOVE_RUN);
+ if (hasPitch)
+ *data << float(self->m_movementInfo.pitch);
+
+ *data << self->GetSpeed(MOVE_FLIGHT);
}
- // 0x8
- if (flags & UPDATEFLAG_UNKNOWN)
+ if (flags & UPDATEFLAG_VEHICLE)
{
- *data << uint32(0);
+ *data << float(self->GetOrientation());
+ *data << uint32(self->GetVehicleKit()->GetVehicleInfo()->m_ID);
}
- // 0x10
- if (flags & UPDATEFLAG_LOWGUID)
+ if (flags & UPDATEFLAG_GO_TRANSPORT_POSITION)
{
- switch (GetTypeId())
- {
- case TYPEID_OBJECT:
- case TYPEID_ITEM:
- case TYPEID_CONTAINER:
- case TYPEID_GAMEOBJECT:
- case TYPEID_DYNAMICOBJECT:
- case TYPEID_CORPSE:
- *data << uint32(GetGUIDLow()); // GetGUIDLow()
- break;
- //! Unit, Player and default here are sending wrong values.
- /// @todo Research the proper formula
- case TYPEID_UNIT:
- *data << uint32(0x0000000B); // unk
- break;
- case TYPEID_PLAYER:
- if (flags & UPDATEFLAG_SELF)
- *data << uint32(0x0000002F); // unk
- else
- *data << uint32(0x00000008); // unk
- break;
- default:
- *data << uint32(0x00000000); // unk
- break;
- }
+ WorldObject const* self = static_cast<WorldObject const*>(this);
+ ObjectGuid transGuid = self->m_movementInfo.transport.guid;
+
+ data->WriteBit(transGuid[0]);
+ data->WriteBit(transGuid[5]);
+ if (hasTransportTime3)
+ *data << uint32(self->m_movementInfo.transport.time3);
+
+ data->WriteBit(transGuid[3]);
+ *data << float(self->GetTransOffsetX());
+ data->WriteBit(transGuid[4]);
+ data->WriteBit(transGuid[6]);
+ data->WriteBit(transGuid[1]);
+ *data << uint32(self->GetTransTime());
+ *data << float(self->GetTransOffsetY());
+ data->WriteBit(transGuid[2]);
+ data->WriteBit(transGuid[7]);
+ *data << float(self->GetTransOffsetZ());
+ *data << int8(self->GetTransSeat());
+ *data << float(self->GetTransOffsetO());
+ if (hasTransportTime2)
+ *data << uint32(self->m_movementInfo.transport.time2);
}
- // 0x4
- if (flags & UPDATEFLAG_HAS_TARGET)
+ if (flags & UPDATEFLAG_ROTATION)
+ *data << uint64(ToGameObject()->GetRotation());
+
+ if (flags & UPDATEFLAG_UNK5)
+ {
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << uint8(0);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ *data << float(0.0f);
+ }
+
+ if (flags & UPDATEFLAG_STATIONARY_POSITION)
{
- if (Unit* victim = unit->GetVictim())
- data->append(victim->GetPackGUID());
- else
- *data << uint8(0);
+ WorldObject const* self = static_cast<WorldObject const*>(this);
+ *data << float(self->GetStationaryO());
+ *data << float(self->GetStationaryX());
+ *data << float(self->GetStationaryY());
+ *data << float(self->GetStationaryZ());
}
- // 0x2
+ if (flags & UPDATEFLAG_HAS_TARGET)
+ {
+ ObjectGuid victimGuid = self->GetVictim()->GetGUID(); // checked in BuildCreateUpdateBlockForPlayer
+ data->WriteByteSeq(victimGuid[4]);
+ data->WriteByteSeq(victimGuid[0]);
+ data->WriteByteSeq(victimGuid[3]);
+ data->WriteByteSeq(victimGuid[5]);
+ data->WriteByteSeq(victimGuid[7]);
+ data->WriteByteSeq(victimGuid[6]);
+ data->WriteByteSeq(victimGuid[2]);
+ data->WriteByteSeq(victimGuid[1]);
+ }
+
+ //if (flags & UPDATEFLAG_ANIMKITS)
+ //{
+ // if (hasAnimKit1)
+ // *data << uint16(animKit1);
+ // if (hasAnimKit2)
+ // *data << uint16(animKit2);
+ // if (hasAnimKit3)
+ // *data << uint16(animKit3);
+ //}
+
if (flags & UPDATEFLAG_TRANSPORT)
{
GameObject const* go = ToGameObject();
@@ -474,21 +660,6 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const
else
*data << uint32(getMSTime());
}
-
- // 0x80
- if (flags & UPDATEFLAG_VEHICLE)
- {
- /// @todo Allow players to aquire this updateflag.
- *data << uint32(unit->GetVehicleKit()->GetVehicleInfo()->m_ID);
- if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
- *data << float(unit->GetTransOffsetO());
- else
- *data << float(unit->GetOrientation());
- }
-
- // 0x200
- if (flags & UPDATEFLAG_ROTATION)
- *data << int64(ToGameObject()->GetRotation());
}
void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
@@ -536,7 +707,7 @@ void Object::BuildFieldsUpdate(Player* player, UpdateDataMapType& data_map) cons
if (iter == data_map.end())
{
- std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData()));
+ std::pair<UpdateDataMapType::iterator, bool> p = data_map.insert(UpdateDataMapType::value_type(player, UpdateData(player->GetMapId())));
ASSERT(p.second);
iter = p.first;
}
@@ -590,6 +761,9 @@ uint32 Object::GetUpdateFieldData(Player const* target, uint32*& flags) const
if (ToCorpse()->GetOwnerGUID() == target->GetGUID())
visibleFlag |= UF_FLAG_OWNER;
break;
+ case TYPEID_AREATRIGGER:
+ flags = AreaTriggerUpdateFieldFlags;
+ break;
case TYPEID_OBJECT:
break;
}
@@ -1060,11 +1234,11 @@ void MovementInfo::OutDebug()
{
TC_LOG_INFO("misc", "MOVEMENT INFO");
TC_LOG_INFO("misc", "guid " UI64FMTD, guid);
- TC_LOG_INFO("misc", "flags %u", flags);
- TC_LOG_INFO("misc", "flags2 %u", flags2);
- TC_LOG_INFO("misc", "time %u current time " UI64FMTD "", flags2, uint64(::time(NULL)));
+ TC_LOG_INFO("misc", "flags %s (%u)", Movement::MovementFlags_ToString(flags).c_str(), flags);
+ TC_LOG_INFO("misc", "flags2 %s (%u)", Movement::MovementFlagsExtra_ToString(flags2).c_str(), flags2);
+ TC_LOG_INFO("misc", "time %u current time %u", time, getMSTime());
TC_LOG_INFO("misc", "position: `%s`", pos.ToString().c_str());
- if (flags & MOVEMENTFLAG_ONTRANSPORT)
+ if (transport.guid)
{
TC_LOG_INFO("misc", "TRANSPORT:");
TC_LOG_INFO("misc", "guid: " UI64FMTD, transport.guid);
@@ -1073,14 +1247,19 @@ void MovementInfo::OutDebug()
TC_LOG_INFO("misc", "time: %u", transport.time);
if (flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
TC_LOG_INFO("misc", "time2: %u", transport.time2);
+ if (transport.time3)
+ TC_LOG_INFO("misc", "time3: %u", transport.time3);
}
if ((flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
TC_LOG_INFO("misc", "pitch: %f", pitch);
- TC_LOG_INFO("misc", "fallTime: %u", fallTime);
- if (flags & MOVEMENTFLAG_FALLING)
- TC_LOG_INFO("misc", "j_zspeed: %f j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.zspeed, jump.sinAngle, jump.cosAngle, jump.xyspeed);
+ if (flags & MOVEMENTFLAG_FALLING || jump.fallTime)
+ {
+ TC_LOG_INFO("misc", "fallTime: %u j_zspeed: %f", jump.fallTime, jump.zspeed);
+ if (flags & MOVEMENTFLAG_FALLING)
+ TC_LOG_INFO("misc", "j_sinAngle: %f j_cosAngle: %f j_xyspeed: %f", jump.sinAngle, jump.cosAngle, jump.xyspeed);
+ }
if (flags & MOVEMENTFLAG_SPLINE_ELEVATION)
TC_LOG_INFO("misc", "splineElevation: %f", splineElevation);
@@ -1780,13 +1959,6 @@ bool WorldObject::CanDetectInvisibilityOf(WorldObject const* obj) const
if (mask != obj->m_invisibility.GetFlags())
return false;
- // It isn't possible in invisibility to detect something that can't detect the invisible object
- // (it's at least true for spell: 66)
- // It seems like that only Units are affected by this check (couldn't see arena doors with preparation invisibility)
- if (obj->ToUnit())
- if ((m_invisibility.GetFlags() & obj->m_invisibilityDetect.GetFlags()) != m_invisibility.GetFlags())
- return false;
-
for (uint32 i = 0; i < TOTAL_INVISIBILITY_TYPES; ++i)
{
if (!(mask & (1 << i)))
@@ -1866,7 +2038,8 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj) const
void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf)
{
WorldPacket data(SMSG_PLAY_SOUND, 4);
- data << Sound;
+ data << uint32(Sound);
+ data << uint64(GetGUID());
if (OnlySelf && GetTypeId() == TYPEID_PLAYER)
this->ToPlayer()->GetSession()->SendPacket(&data);
else
@@ -2026,13 +2199,6 @@ void WorldObject::MonsterWhisper(int32 textId, Player const* target, bool IsBoss
target->GetSession()->SendPacket(&data);
}
-void Unit::BuildHeartBeatMsg(WorldPacket* data) const
-{
- data->Initialize(MSG_MOVE_HEARTBEAT, 32);
- data->append(GetPackGUID());
- BuildMovementPacket(data);
-}
-
void WorldObject::SendMessageToSet(WorldPacket* data, bool self)
{
if (IsInWorld())
@@ -2775,6 +2941,7 @@ void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/)
{
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(sound_id);
+ data << uint64(GetGUID());
if (target)
target->SendDirectMessage(&data);
else
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 8d3b1ff9554..0c99fac09be 100644
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -54,6 +54,7 @@ enum TypeMask
TYPEMASK_GAMEOBJECT = 0x0020,
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080,
+ TYPEMASK_AREATRIGGER = 0x0100,
TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT
};
@@ -66,10 +67,11 @@ enum TypeID
TYPEID_PLAYER = 4,
TYPEID_GAMEOBJECT = 5,
TYPEID_DYNAMICOBJECT = 6,
- TYPEID_CORPSE = 7
+ TYPEID_CORPSE = 7,
+ TYPEID_AREATRIGGER = 8
};
-#define NUM_CLIENT_OBJECT_TYPES 8
+#define NUM_CLIENT_OBJECT_TYPES 9
uint32 GuidHigh2TypeId(uint32 guid_hi);
@@ -116,6 +118,62 @@ class ZoneScript;
typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;
+//! Structure to ease conversions from single 64 bit integer guid into individual bytes, for packet sending purposes
+//! Nuke this out when porting ObjectGuid from MaNGOS, but preserve the per-byte storage
+struct ObjectGuid
+{
+ public:
+ ObjectGuid() { _data.u64 = UI64LIT(0); }
+ ObjectGuid(uint64 guid) { _data.u64 = guid; }
+ ObjectGuid(ObjectGuid const& other) { _data.u64 = other._data.u64; }
+
+ uint8& operator[](uint32 index)
+ {
+ ASSERT(index < sizeof(uint64));
+
+#if TRINITY_ENDIAN == TRINITY_LITTLEENDIAN
+ return _data.byte[index];
+#else
+ return _data.byte[7 - index];
+#endif
+ }
+
+ uint8 const& operator[](uint32 index) const
+ {
+ ASSERT(index < sizeof(uint64));
+
+#if TRINITY_ENDIAN == TRINITY_LITTLEENDIAN
+ return _data.byte[index];
+#else
+ return _data.byte[7 - index];
+#endif
+ }
+
+ operator uint64()
+ {
+ return _data.u64;
+ }
+
+ ObjectGuid& operator=(uint64 guid)
+ {
+ _data.u64 = guid;
+ return *this;
+ }
+
+ ObjectGuid& operator=(ObjectGuid const& other)
+ {
+ _data.u64 = other._data.u64;
+ return *this;
+ }
+
+ private:
+ union
+ {
+ uint64 u64;
+ uint8 byte[8];
+ } _data;
+};
+
class Object
{
public:
@@ -145,7 +203,6 @@ class Object
void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const;
void BuildOutOfRangeUpdateBlock(UpdateData* data) const;
- void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const;
virtual void DestroyForPlayer(Player* target, bool onDeath = false) const;
@@ -227,6 +284,9 @@ class Object
DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(this); else return NULL; }
DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(this); else return NULL; }
+ AreaTrigger* ToAreaTrigger() { if (GetTypeId() == TYPEID_AREATRIGGER) return reinterpret_cast<AreaTrigger*>(this); else return NULL; }
+ AreaTrigger const* ToAreaTrigger() const { if (GetTypeId() == TYPEID_AREATRIGGER) return reinterpret_cast<AreaTrigger const*>(this); else return NULL; }
+
protected:
Object();
@@ -419,6 +479,7 @@ struct MovementInfo
seat = -1;
time = 0;
time2 = 0;
+ time3 = 0;
}
uint64 guid;
@@ -426,22 +487,23 @@ struct MovementInfo
int8 seat;
uint32 time;
uint32 time2;
+ uint32 time3;
} transport;
// swimming/flying
float pitch;
- // falling
- uint32 fallTime;
-
- // jumping
+ // jumping
struct JumpInfo
{
void Reset()
{
+ fallTime = 0;
zspeed = sinAngle = cosAngle = xyspeed = 0.0f;
}
+ uint32 fallTime;
+
float zspeed, sinAngle, cosAngle, xyspeed;
} jump;
@@ -450,7 +512,7 @@ struct MovementInfo
float splineElevation;
MovementInfo() :
- guid(0), flags(0), flags2(0), time(0), pitch(0.0f), fallTime(0), splineElevation(0.0f)
+ guid(0), flags(0), flags2(0), time(0), pitch(0.0f), splineElevation(0.0f)
{
pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
transport.Reset();
@@ -464,10 +526,22 @@ struct MovementInfo
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
uint16 GetExtraMovementFlags() const { return flags2; }
+ void SetExtraMovementFlags(uint16 flag) { flags2 = flag; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
+ void RemoveExtraMovementFlag(uint16 flag) { flags2 &= ~flag; }
bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
- void SetFallTime(uint32 time) { fallTime = time; }
+ void SetFallTime(uint32 time) { jump.fallTime = time; }
+
+ void ResetTransport()
+ {
+ transport.Reset();
+ }
+
+ void ResetJump()
+ {
+ jump.Reset();
+ }
void OutDebug();
};
diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h
index 236f77caf5a..03a4f80bf60 100644
--- a/src/server/game/Entities/Object/ObjectDefines.h
+++ b/src/server/game/Entities/Object/ObjectDefines.h
@@ -23,18 +23,21 @@
enum HighGuid
{
- HIGHGUID_ITEM = 0x4000, // blizz 4000
- HIGHGUID_CONTAINER = 0x4000, // blizz 4000
- HIGHGUID_PLAYER = 0x0000, // blizz 0000
- HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110
- HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
- HIGHGUID_UNIT = 0xF130, // blizz F130
- HIGHGUID_PET = 0xF140, // blizz F140
- HIGHGUID_VEHICLE = 0xF150, // blizz F550
- HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100
+ HIGHGUID_ITEM = 0x400, // blizz 4000
+ HIGHGUID_CONTAINER = 0x400, // blizz 4000
+ HIGHGUID_PLAYER = 0x000, // blizz 0000
+ HIGHGUID_GAMEOBJECT = 0xF11, // blizz F110
+ HIGHGUID_TRANSPORT = 0xF12, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)
+ HIGHGUID_UNIT = 0xF13, // blizz F130
+ HIGHGUID_PET = 0xF14, // blizz F140
+ HIGHGUID_VEHICLE = 0xF15, // blizz F550
+ HIGHGUID_DYNAMICOBJECT = 0xF10, // blizz F100
HIGHGUID_CORPSE = 0xF101, // blizz F100
- HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
- HIGHGUID_GROUP = 0x1F50
+ HIGHGUID_AREATRIGGER = 0xF102, // blizz F100
+ HIGHGUID_BATTLEGROUND = 0x1F1, // new 4.x
+ HIGHGUID_MO_TRANSPORT = 0x1FC, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT)
+ HIGHGUID_GROUP = 0x1F5,
+ HIGHGUID_GUILD = 0x1FF // new 4.x
};
// used for creating values for respawn for example
@@ -53,6 +56,7 @@ inline bool IS_VEHICLE_GUID(uint64 guid);
inline bool IS_CRE_OR_VEH_GUID(uint64 guid);
inline bool IS_CRE_OR_VEH_OR_PET_GUID(uint64 guid);
inline bool IS_PLAYER_GUID(uint64 guid);
+inline bool IS_GUILD_GUID(uint64 guid);
inline bool IS_UNIT_GUID(uint64 guid);
inline bool IS_ITEM_GUID(uint64 guid);
inline bool IS_GAMEOBJECT_GUID(uint64 guid);
@@ -61,6 +65,7 @@ inline bool IS_CORPSE_GUID(uint64 guid);
inline bool IS_TRANSPORT_GUID(uint64 guid);
inline bool IS_MO_TRANSPORT_GUID(uint64 guid);
inline bool IS_GROUP_GUID(uint64 guid);
+inline bool IS_AREATRIGGER_GUID(uint64 guid);
// l - OBJECT_FIELD_GUID
// e - OBJECT_FIELD_ENTRY for GO (except GAMEOBJECT_TYPE_MO_TRANSPORT) and creatures or UNIT_FIELD_PETNUMBER for pets
@@ -145,6 +150,11 @@ bool IS_PLAYER_GUID(uint64 guid)
return guid != 0 && GUID_HIPART(guid) == HIGHGUID_PLAYER;
}
+bool IS_GUILD_GUID(uint64 guid)
+{
+ return GUID_HIPART(guid) == HIGHGUID_GUILD;
+}
+
bool IS_UNIT_GUID(uint64 guid)
{
return IS_CRE_OR_VEH_OR_PET_GUID(guid) || IS_PLAYER_GUID(guid);
@@ -185,28 +195,33 @@ bool IS_GROUP_GUID(uint64 guid)
return GUID_HIPART(guid) == HIGHGUID_GROUP;
}
+bool IS_AREATRIGGER_GUID(uint64 guid)
+{
+ return GUID_HIPART(guid) == HIGHGUID_AREATRIGGER;
+}
+
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
{
- return uint64(uint64(l) | (uint64(e) << 24) | (uint64(h) << 48));
+ return uint64(uint64(l) | (uint64(e) << 32) | (uint64(h) << ((h == HIGHGUID_CORPSE || h == HIGHGUID_AREATRIGGER) ? 48 : 52)));
}
uint32 GUID_HIPART(uint64 guid)
{
- return (uint32)((uint64(guid) >> 48) & 0x0000FFFF);
+ uint32 t = ((uint64(guid) >> 48) & 0x0000FFFF);
+ return (t == HIGHGUID_CORPSE || t == HIGHGUID_AREATRIGGER) ? t : ((t >> 4) & 0x00000FFF);
}
uint32 GUID_ENPART(uint64 x)
{
return IsGuidHaveEnPart(x)
- ? (uint32)((x >> 24) & UI64LIT(0x0000000000FFFFFF))
+ ? ((uint32)((x >> 32) & UI64LIT(0x00000000000FFFFF)))
: 0;
}
uint32 GUID_LOPART(uint64 x)
{
- return IsGuidHaveEnPart(x)
- ? (uint32)(x & UI64LIT(0x0000000000FFFFFF))
- : (uint32)(x & UI64LIT(0x00000000FFFFFFFF));
+ // _GUID_LOPART_3 and _GUID_LOPART_2 were both equal to PAIR64_LOPART
+ return PAIR64_LOPART(x);
}
bool IsGuidHaveEnPart(uint64 guid)
@@ -218,6 +233,7 @@ bool IsGuidHaveEnPart(uint64 guid)
case HIGHGUID_DYNAMICOBJECT:
case HIGHGUID_CORPSE:
case HIGHGUID_GROUP:
+ case HIGHGUID_GUILD:
return false;
case HIGHGUID_GAMEOBJECT:
case HIGHGUID_TRANSPORT:
@@ -225,6 +241,7 @@ bool IsGuidHaveEnPart(uint64 guid)
case HIGHGUID_PET:
case HIGHGUID_VEHICLE:
case HIGHGUID_MO_TRANSPORT:
+ case HIGHGUID_AREATRIGGER:
default:
return true;
}
@@ -245,6 +262,8 @@ char const* GetLogNameForGuid(uint64 guid)
case HIGHGUID_CORPSE: return "corpse";
case HIGHGUID_MO_TRANSPORT: return "mo_transport";
case HIGHGUID_GROUP: return "group";
+ case HIGHGUID_GUILD: return "guild";
+ case HIGHGUID_AREATRIGGER: return "areatrigger";
default:
return "<unknown>";
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp
index e996db52c38..ee84b01e175 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp
@@ -25,7 +25,7 @@
#include "World.h"
#include "zlib.h"
-UpdateData::UpdateData() : m_blockCount(0) { }
+UpdateData::UpdateData(uint16 map) : m_map(map), m_blockCount(0) { }
void UpdateData::AddOutOfRangeGUID(std::set<uint64>& guids)
{
@@ -43,104 +43,24 @@ void UpdateData::AddUpdateBlock(const ByteBuffer &block)
++m_blockCount;
}
-void UpdateData::Compress(void* dst, uint32 *dst_size, void* src, int src_size)
-{
- z_stream c_stream;
-
- c_stream.zalloc = (alloc_func)0;
- c_stream.zfree = (free_func)0;
- c_stream.opaque = (voidpf)0;
-
- // default Z_BEST_SPEED (1)
- int z_res = deflateInit(&c_stream, sWorld->getIntConfig(CONFIG_COMPRESSION));
- if (z_res != Z_OK)
- {
- TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
- *dst_size = 0;
- return;
- }
-
- c_stream.next_out = (Bytef*)dst;
- c_stream.avail_out = *dst_size;
- c_stream.next_in = (Bytef*)src;
- c_stream.avail_in = (uInt)src_size;
-
- z_res = deflate(&c_stream, Z_NO_FLUSH);
- if (z_res != Z_OK)
- {
- TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate) Error code: %i (%s)", z_res, zError(z_res));
- *dst_size = 0;
- return;
- }
-
- if (c_stream.avail_in != 0)
- {
- TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate not greedy)");
- *dst_size = 0;
- return;
- }
-
- z_res = deflate(&c_stream, Z_FINISH);
- if (z_res != Z_STREAM_END)
- {
- TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflate should report Z_STREAM_END instead %i (%s)", z_res, zError(z_res));
- *dst_size = 0;
- return;
- }
-
- z_res = deflateEnd(&c_stream);
- if (z_res != Z_OK)
- {
- TC_LOG_ERROR("misc", "Can't compress update packet (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res));
- *dst_size = 0;
- return;
- }
-
- *dst_size = c_stream.total_out;
-}
-
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());
- ByteBuffer buf(4 + (m_outOfRangeGUIDs.empty() ? 0 : 1 + 4 + 9 * m_outOfRangeGUIDs.size()) + m_data.wpos());
-
- buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount);
+ *packet << uint16(m_map);
+ *packet << uint32(m_blockCount + (m_outOfRangeGUIDs.empty() ? 0 : 1));
if (!m_outOfRangeGUIDs.empty())
{
- buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
- buf << (uint32) m_outOfRangeGUIDs.size();
+ *packet << uint8(UPDATETYPE_OUT_OF_RANGE_OBJECTS);
+ *packet << uint32(m_outOfRangeGUIDs.size());
for (std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
- {
- buf.appendPackGUID(*i);
- }
- }
-
- buf.append(m_data);
-
- size_t pSize = buf.wpos(); // use real used data size
-
- if (pSize > 100) // compress large packets
- {
- uint32 destsize = compressBound(pSize);
- packet->resize(destsize + sizeof(uint32));
-
- packet->put<uint32>(0, pSize);
- Compress(const_cast<uint8*>(packet->contents()) + sizeof(uint32), &destsize, (void*)buf.contents(), pSize);
- if (destsize == 0)
- return false;
-
- packet->resize(destsize + sizeof(uint32));
- packet->SetOpcode(SMSG_COMPRESSED_UPDATE_OBJECT);
- }
- else // send small packets without compression
- {
- packet->append(buf);
- packet->SetOpcode(SMSG_UPDATE_OBJECT);
+ packet->appendPackGUID(*i);
}
+ packet->append(m_data);
return true;
}
@@ -149,5 +69,6 @@ void UpdateData::Clear()
m_data.clear();
m_outOfRangeGUIDs.clear();
m_blockCount = 0;
+ m_map = 0;
}
diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h
index 16bdec46aba..1deccfa237b 100644
--- a/src/server/game/Entities/Object/Updates/UpdateData.h
+++ b/src/server/game/Entities/Object/Updates/UpdateData.h
@@ -27,32 +27,34 @@ class WorldPacket;
enum OBJECT_UPDATE_TYPE
{
UPDATETYPE_VALUES = 0,
- UPDATETYPE_MOVEMENT = 1,
- UPDATETYPE_CREATE_OBJECT = 2,
- UPDATETYPE_CREATE_OBJECT2 = 3,
- UPDATETYPE_OUT_OF_RANGE_OBJECTS = 4,
- UPDATETYPE_NEAR_OBJECTS = 5
+ UPDATETYPE_CREATE_OBJECT = 1,
+ UPDATETYPE_CREATE_OBJECT2 = 2,
+ UPDATETYPE_OUT_OF_RANGE_OBJECTS = 3,
};
enum OBJECT_UPDATE_FLAGS
{
- UPDATEFLAG_NONE = 0x0000,
- UPDATEFLAG_SELF = 0x0001,
- UPDATEFLAG_TRANSPORT = 0x0002,
- UPDATEFLAG_HAS_TARGET = 0x0004,
- UPDATEFLAG_UNKNOWN = 0x0008,
- UPDATEFLAG_LOWGUID = 0x0010,
- UPDATEFLAG_LIVING = 0x0020,
- UPDATEFLAG_STATIONARY_POSITION = 0x0040,
- UPDATEFLAG_VEHICLE = 0x0080,
- UPDATEFLAG_POSITION = 0x0100,
- UPDATEFLAG_ROTATION = 0x0200
+ UPDATEFLAG_NONE = 0x0000,
+ UPDATEFLAG_SELF = 0x0001,
+ UPDATEFLAG_TRANSPORT = 0x0002,
+ UPDATEFLAG_HAS_TARGET = 0x0004,
+ UPDATEFLAG_UNKNOWN = 0x0008,
+ UPDATEFLAG_LOWGUID = 0x0010,
+ UPDATEFLAG_LIVING = 0x0020,
+ UPDATEFLAG_STATIONARY_POSITION = 0x0040,
+ UPDATEFLAG_VEHICLE = 0x0080,
+ UPDATEFLAG_GO_TRANSPORT_POSITION = 0x0100,
+ UPDATEFLAG_ROTATION = 0x0200,
+ UPDATEFLAG_UNK3 = 0x0400,
+ UPDATEFLAG_ANIMKITS = 0x0800,
+ UPDATEFLAG_UNK5 = 0x1000,
+ UPDATEFLAG_UNK6 = 0x2000,
};
class UpdateData
{
public:
- UpdateData();
+ UpdateData(uint16 map);
void AddOutOfRangeGUID(std::set<uint64>& guids);
void AddOutOfRangeGUID(uint64 guid);
@@ -64,11 +66,10 @@ class UpdateData
std::set<uint64> const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; }
protected:
+ uint16 m_map;
uint32 m_blockCount;
std::set<uint64> m_outOfRangeGUIDs;
ByteBuffer m_data;
-
- void Compress(void* dst, uint32 *dst_size, void* src, int src_size);
};
#endif
diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
index 5629fef7d0c..0db2a312c9a 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
+++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp
@@ -21,6 +21,8 @@ uint32 ItemUpdateFieldFlags[CONTAINER_END] =
{
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
@@ -77,12 +79,20 @@ uint32 ItemUpdateFieldFlags[CONTAINER_END] =
UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_1
UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_1+1
UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_12_3
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_1+1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_13_3
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_1+1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_14_3
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_1+1
+ UF_FLAG_PUBLIC, // ITEM_FIELD_ENCHANTMENT_15_3
UF_FLAG_PUBLIC, // ITEM_FIELD_PROPERTY_SEED
UF_FLAG_PUBLIC, // ITEM_FIELD_RANDOM_PROPERTIES_ID
UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER, // ITEM_FIELD_DURABILITY
UF_FLAG_OWNER | UF_FLAG_ITEM_OWNER, // ITEM_FIELD_MAXDURABILITY
UF_FLAG_PUBLIC, // ITEM_FIELD_CREATE_PLAYED_TIME
- UF_FLAG_NONE, // ITEM_FIELD_PAD
UF_FLAG_PUBLIC, // CONTAINER_FIELD_NUM_SLOTS
UF_FLAG_NONE, // CONTAINER_ALIGN_PAD
UF_FLAG_PUBLIC, // CONTAINER_FIELD_SLOT_1
@@ -163,6 +173,8 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
{
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
@@ -191,30 +203,22 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PUBLIC, // UNIT_FIELD_POWER3
UF_FLAG_PUBLIC, // UNIT_FIELD_POWER4
UF_FLAG_PUBLIC, // UNIT_FIELD_POWER5
- UF_FLAG_PUBLIC, // UNIT_FIELD_POWER6
- UF_FLAG_PUBLIC, // UNIT_FIELD_POWER7
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXHEALTH
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER1
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER2
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER3
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER4
UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER5
- UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER6
- UF_FLAG_PUBLIC, // UNIT_FIELD_MAXPOWER7
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+1
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+2
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+3
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+4
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+5
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+6
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+1
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+2
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+3
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+4
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+5
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+6
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+1
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+2
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+3
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER+4
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+1
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+2
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+3
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNUSED2, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+4
UF_FLAG_PUBLIC, // UNIT_FIELD_LEVEL
UF_FLAG_PUBLIC, // UNIT_FIELD_FACTIONTEMPLATE
UF_FLAG_PUBLIC, // UNIT_VIRTUAL_ITEM_SLOT_ID
@@ -228,7 +232,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // UNIT_FIELD_RANGEDATTACKTIME
UF_FLAG_PUBLIC, // UNIT_FIELD_BOUNDINGRADIUS
UF_FLAG_PUBLIC, // UNIT_FIELD_COMBATREACH
- UF_FLAG_PUBLIC, // UNIT_FIELD_DISPLAYID
+ UF_FLAG_DYNAMIC, // UNIT_FIELD_DISPLAYID
UF_FLAG_PUBLIC, // UNIT_FIELD_NATIVEDISPLAYID
UF_FLAG_PUBLIC, // UNIT_FIELD_MOUNTDISPLAYID
UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_SPECIAL_INFO, // UNIT_FIELD_MINDAMAGE
@@ -242,6 +246,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_OWNER, // UNIT_FIELD_PETNEXTLEVELEXP
UF_FLAG_DYNAMIC, // UNIT_DYNAMIC_FLAGS
UF_FLAG_PUBLIC, // UNIT_MOD_CAST_SPEED
+ UF_FLAG_PUBLIC, // UNIT_MOD_CAST_HASTE
UF_FLAG_PUBLIC, // UNIT_CREATED_BY_SPELL
UF_FLAG_DYNAMIC, // UNIT_NPC_FLAGS
UF_FLAG_PUBLIC, // UNIT_NPC_EMOTESTATE
@@ -285,10 +290,12 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_BASE_HEALTH
UF_FLAG_PUBLIC, // UNIT_FIELD_BYTES_2
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MODS
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MOD_POS
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MOD_NEG
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_ATTACK_POWER_MULTIPLIER
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER
- UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MODS
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS
+ UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MINRANGEDDAMAGE
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MAXRANGEDDAMAGE
@@ -308,142 +315,269 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_POWER_COST_MULTIPLIER+6
UF_FLAG_PRIVATE | UF_FLAG_OWNER, // UNIT_FIELD_MAXHEALTHMODIFIER
UF_FLAG_PUBLIC, // UNIT_FIELD_HOVERHEIGHT
+ UF_FLAG_PUBLIC, // UNIT_FIELD_MAXITEMLEVEL
UF_FLAG_NONE, // UNIT_FIELD_PADDING
UF_FLAG_PUBLIC, // PLAYER_DUEL_ARBITER
UF_FLAG_PUBLIC, // PLAYER_DUEL_ARBITER+1
UF_FLAG_PUBLIC, // PLAYER_FLAGS
- UF_FLAG_PUBLIC, // PLAYER_GUILDID
UF_FLAG_PUBLIC, // PLAYER_GUILDRANK
+ UF_FLAG_PUBLIC, // PLAYER_GUILDDELETE_DATE
+ UF_FLAG_PUBLIC, // PLAYER_GUILDLEVEL
UF_FLAG_PUBLIC, // PLAYER_BYTES
UF_FLAG_PUBLIC, // PLAYER_BYTES_2
UF_FLAG_PUBLIC, // PLAYER_BYTES_3
UF_FLAG_PUBLIC, // PLAYER_DUEL_TEAM
UF_FLAG_PUBLIC, // PLAYER_GUILD_TIMESTAMP
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_1_4
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_1_4
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_2_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_2_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_3_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_3_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_4_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_4_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_5_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_5_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_6_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_6_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_7_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_7_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_8_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_8_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_9_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_9_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_10_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_10_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_11_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_11_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_12_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_12_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_13_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_13_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_14_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_14_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_15_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_15_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_16_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_16_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_17_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_17_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_18_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_18_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_19_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_19_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_20_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_20_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_21_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_21_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_22_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_22_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_23_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_23_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_24_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_24_5
UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_2
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_3
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_3+1
- UF_FLAG_PRIVATE, // PLAYER_QUEST_LOG_25_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_25_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_26_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_27_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_28_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_29_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_30_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_31_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_32_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_33_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_34_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_35_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_36_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_37_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_38_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_39_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_40_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_41_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_42_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_43_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_44_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_45_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_46_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_47_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_48_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_49_5
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_2
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_3
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_3+1
+ UF_FLAG_PARTY_MEMBER, // PLAYER_QUEST_LOG_50_5
UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_1_ENTRYID
UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_1_ENCHANTMENT
UF_FLAG_PUBLIC, // PLAYER_VISIBLE_ITEM_2_ENTRYID
@@ -657,134 +791,6 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+21
UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+22
UF_FLAG_PRIVATE, // PLAYER_FIELD_VENDORBUYBACK_SLOT_1+23
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+1
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+2
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+3
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+4
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+5
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+6
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+7
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+8
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+9
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+10
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+11
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+12
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+13
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+14
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+15
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+16
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+17
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+18
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+19
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+20
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+21
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+22
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+23
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+24
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+25
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+26
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+27
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+28
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+29
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+30
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+31
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+32
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+33
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+34
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+35
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+36
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+37
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+38
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+39
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+40
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+41
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+42
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+43
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+44
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+45
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+46
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+47
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+48
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+49
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+50
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+51
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+52
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+53
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+54
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+55
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+56
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+57
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+58
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+59
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+60
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+61
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+62
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KEYRING_SLOT_1+63
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+1
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+2
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+3
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+4
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+5
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+6
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+7
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+8
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+9
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+10
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+11
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+12
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+13
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+14
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+15
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+16
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+17
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+18
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+19
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+20
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+21
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+22
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+23
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+24
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+25
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+26
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+27
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+28
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+29
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+30
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+31
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+32
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+33
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+34
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+35
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+36
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+37
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+38
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+39
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+40
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+41
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+42
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+43
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+44
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+45
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+46
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+47
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+48
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+49
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+50
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+51
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+52
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+53
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+54
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+55
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+56
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+57
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+58
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+59
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+60
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+61
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+62
- UF_FLAG_PRIVATE, // PLAYER_FIELD_CURRENCYTOKEN_SLOT_1+63
UF_FLAG_PRIVATE, // PLAYER_FARSIGHT
UF_FLAG_PRIVATE, // PLAYER_FARSIGHT+1
UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES
@@ -793,403 +799,402 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES1+1
UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES2
UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES2+1
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KNOWN_CURRENCIES
- UF_FLAG_PRIVATE, // PLAYER_FIELD_KNOWN_CURRENCIES+1
+ UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES3
+ UF_FLAG_PRIVATE, // PLAYER__FIELD_KNOWN_TITLES3+1
UF_FLAG_PRIVATE, // PLAYER_XP
UF_FLAG_PRIVATE, // PLAYER_NEXT_LEVEL_XP
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+1
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+2
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+3
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+4
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+5
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+6
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+7
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+8
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+9
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+10
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+11
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+12
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+13
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+14
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+15
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+16
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+17
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+18
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+19
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+20
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+21
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+22
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+23
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+24
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+25
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+26
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+27
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+28
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+29
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+30
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+31
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+32
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+33
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+34
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+35
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+36
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+37
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+38
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+39
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+40
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+41
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+42
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+43
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+44
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+45
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+46
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+47
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+48
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+49
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+50
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+51
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+52
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+53
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+54
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+55
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+56
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+57
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+58
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+59
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+60
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+61
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+62
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+63
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+64
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+65
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+66
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+67
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+68
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+69
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+70
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+71
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+72
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+73
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+74
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+75
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+76
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+77
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+78
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+79
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+80
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+81
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+82
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+83
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+84
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+85
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+86
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+87
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+88
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+89
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+90
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+91
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+92
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+93
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+94
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+95
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+96
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+97
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+98
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+99
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+100
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+101
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+102
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+103
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+104
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+105
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+106
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+107
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+108
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+109
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+110
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+111
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+112
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+113
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+114
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+115
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+116
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+117
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+118
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+119
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+120
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+121
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+122
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+123
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+124
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+125
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+126
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+127
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+128
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+129
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+130
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+131
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+132
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+133
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+134
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+135
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+136
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+137
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+138
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+139
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+140
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+141
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+142
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+143
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+144
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+145
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+146
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+147
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+148
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+149
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+150
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+151
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+152
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+153
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+154
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+155
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+156
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+157
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+158
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+159
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+160
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+161
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+162
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+163
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+164
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+165
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+166
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+167
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+168
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+169
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+170
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+171
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+172
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+173
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+174
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+175
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+176
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+177
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+178
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+179
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+180
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+181
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+182
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+183
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+184
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+185
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+186
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+187
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+188
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+189
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+190
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+191
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+192
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+193
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+194
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+195
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+196
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+197
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+198
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+199
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+200
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+201
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+202
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+203
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+204
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+205
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+206
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+207
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+208
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+209
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+210
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+211
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+212
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+213
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+214
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+215
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+216
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+217
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+218
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+219
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+220
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+221
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+222
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+223
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+224
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+225
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+226
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+227
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+228
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+229
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+230
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+231
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+232
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+233
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+234
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+235
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+236
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+237
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+238
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+239
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+240
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+241
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+242
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+243
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+244
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+245
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+246
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+247
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+248
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+249
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+250
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+251
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+252
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+253
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+254
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+255
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+256
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+257
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+258
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+259
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+260
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+261
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+262
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+263
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+264
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+265
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+266
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+267
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+268
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+269
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+270
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+271
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+272
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+273
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+274
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+275
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+276
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+277
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+278
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+279
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+280
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+281
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+282
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+283
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+284
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+285
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+286
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+287
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+288
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+289
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+290
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+291
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+292
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+293
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+294
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+295
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+296
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+297
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+298
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+299
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+300
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+301
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+302
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+303
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+304
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+305
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+306
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+307
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+308
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+309
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+310
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+311
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+312
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+313
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+314
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+315
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+316
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+317
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+318
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+319
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+320
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+321
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+322
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+323
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+324
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+325
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+326
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+327
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+328
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+329
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+330
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+331
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+332
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+333
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+334
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+335
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+336
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+337
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+338
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+339
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+340
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+341
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+342
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+343
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+344
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+345
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+346
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+347
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+348
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+349
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+350
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+351
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+352
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+353
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+354
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+355
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+356
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+357
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+358
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+359
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+360
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+361
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+362
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+363
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+364
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+365
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+366
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+367
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+368
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+369
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+370
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+371
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+372
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+373
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+374
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+375
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+376
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+377
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+378
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+379
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+380
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+381
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+382
- UF_FLAG_PRIVATE, // PLAYER_SKILL_INFO_1_1+383
- UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS1
- UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID_0+63
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_STEP_0+63
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_RANK_0+63
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MAX_RANK_0+63
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_MODIFIER_0+63
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+1
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+2
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+3
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+4
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+5
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+6
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+7
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+8
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+9
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+10
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+11
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+12
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+13
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+14
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+15
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+16
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+17
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+18
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+19
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+20
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+21
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+22
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+23
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+24
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+25
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+26
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+27
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+28
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+29
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+30
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+31
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+32
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+33
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+34
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+35
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+36
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+37
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+38
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+39
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+40
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+41
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+42
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+43
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+44
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+45
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+46
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+47
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+48
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+49
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+50
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+51
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+52
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+53
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+54
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+55
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+56
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+57
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+58
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+59
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+60
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+61
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+62
+ UF_FLAG_PRIVATE, // PLAYER_SKILL_TALENT_0+63
+ UF_FLAG_PRIVATE, // PLAYER_CHARACTER_POINTS
UF_FLAG_PRIVATE, // PLAYER_TRACK_CREATURES
UF_FLAG_PRIVATE, // PLAYER_TRACK_RESOURCES
+ UF_FLAG_PRIVATE, // PLAYER_EXPERTISE
+ UF_FLAG_PRIVATE, // PLAYER_OFFHAND_EXPERTISE
UF_FLAG_PRIVATE, // PLAYER_BLOCK_PERCENTAGE
UF_FLAG_PRIVATE, // PLAYER_DODGE_PERCENTAGE
UF_FLAG_PRIVATE, // PLAYER_PARRY_PERCENTAGE
- UF_FLAG_PRIVATE, // PLAYER_EXPERTISE
- UF_FLAG_PRIVATE, // PLAYER_OFFHAND_EXPERTISE
UF_FLAG_PRIVATE, // PLAYER_CRIT_PERCENTAGE
UF_FLAG_PRIVATE, // PLAYER_RANGED_CRIT_PERCENTAGE
UF_FLAG_PRIVATE, // PLAYER_OFFHAND_CRIT_PERCENTAGE
@@ -1202,6 +1207,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_SPELL_CRIT_PERCENTAGE1+6
UF_FLAG_PRIVATE, // PLAYER_SHIELD_BLOCK
UF_FLAG_PRIVATE, // PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE
+ UF_FLAG_PRIVATE, // PLAYER_MASTERY
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+1
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+2
@@ -1330,8 +1336,37 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+125
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+126
UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+127
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+128
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+129
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+130
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+131
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+132
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+133
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+134
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+135
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+136
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+137
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+138
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+139
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+140
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+141
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+142
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+143
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+144
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+145
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+146
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+147
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+148
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+149
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+150
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+151
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+152
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+153
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+154
+ UF_FLAG_PRIVATE, // PLAYER_EXPLORED_ZONES_1+155
UF_FLAG_PRIVATE, // PLAYER_REST_STATE_EXPERIENCE
UF_FLAG_PRIVATE, // PLAYER_FIELD_COINAGE
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_COINAGE+1
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS+1
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_DAMAGE_DONE_POS+2
@@ -1356,10 +1391,14 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_DONE_POS
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_PCT
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HEALING_DONE_PCT
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS+1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS+2
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_SPELL_POWER_PCT
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_TARGET_RESISTANCE
UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE
UF_FLAG_PRIVATE, // PLAYER_FIELD_BYTES
- UF_FLAG_PRIVATE, // PLAYER_AMMO_ID
UF_FLAG_PRIVATE, // PLAYER_SELF_RES_SPELL
UF_FLAG_PRIVATE, // PLAYER_FIELD_PVP_MEDALS
UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_PRICE_1
@@ -1387,8 +1426,6 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_TIMESTAMP_1+10
UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_TIMESTAMP_1+11
UF_FLAG_PRIVATE, // PLAYER_FIELD_KILLS
- UF_FLAG_PRIVATE, // PLAYER_FIELD_TODAY_CONTRIBUTION
- UF_FLAG_PRIVATE, // PLAYER_FIELD_YESTERDAY_CONTRIBUTION
UF_FLAG_PRIVATE, // PLAYER_FIELD_LIFETIME_HONORBALE_KILLS
UF_FLAG_PRIVATE, // PLAYER_FIELD_BYTES2
UF_FLAG_PRIVATE, // PLAYER_FIELD_WATCHED_FACTION_INDEX
@@ -1417,6 +1454,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+22
UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+23
UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+24
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_COMBAT_RATING_1+25
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+1
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+2
@@ -1438,8 +1476,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+18
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+19
UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_TEAM_INFO_1_1+20
- UF_FLAG_PRIVATE, // PLAYER_FIELD_HONOR_CURRENCY
- UF_FLAG_PRIVATE, // PLAYER_FIELD_ARENA_CURRENCY
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_BATTLEGROUND_RATING
UF_FLAG_PRIVATE, // PLAYER_FIELD_MAX_LEVEL
UF_FLAG_PRIVATE, // PLAYER_FIELD_DAILY_QUESTS_1
UF_FLAG_PRIVATE, // PLAYER_FIELD_DAILY_QUESTS_1+1
@@ -1479,20 +1516,53 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] =
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+3
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+4
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+5
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+6
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+7
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPH_SLOTS_1+8
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+1
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+2
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+3
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+4
UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+5
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+6
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+7
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_GLYPHS_1+8
UF_FLAG_PRIVATE, // PLAYER_GLYPHS_ENABLED
UF_FLAG_PRIVATE, // PLAYER_PET_SPELL_POWER
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+2
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+3
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+4
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+5
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+6
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESEARCHING_1+7
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+2
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+3
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+4
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+5
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+6
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_RESERACH_SITE_1+7
+ UF_FLAG_PRIVATE, // PLAYER_PROFESSION_SKILL_LINE_1
+ UF_FLAG_PRIVATE, // PLAYER_PROFESSION_SKILL_LINE_1+1
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_UI_HIT_MODIFIER
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_UI_SPELL_HIT_MODIFIER
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_HOME_REALM_TIME_OFFSET
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HASTE
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_RANGED_HASTE
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_PET_HASTE
+ UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_HASTE_REGEN
};
uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END] =
{
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
@@ -1515,13 +1585,15 @@ uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END] =
{
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
UF_FLAG_NONE, // OBJECT_FIELD_PADDING
UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTER
UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTER+1
- UF_FLAG_PUBLIC, // DYNAMICOBJECT_BYTES
+ UF_FLAG_DYNAMIC, // DYNAMICOBJECT_BYTES
UF_FLAG_PUBLIC, // DYNAMICOBJECT_SPELLID
UF_FLAG_PUBLIC, // DYNAMICOBJECT_RADIUS
UF_FLAG_PUBLIC, // DYNAMICOBJECT_CASTTIME
@@ -1531,6 +1603,8 @@ uint32 CorpseUpdateFieldFlags[CORPSE_END] =
{
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
@@ -1561,8 +1635,24 @@ uint32 CorpseUpdateFieldFlags[CORPSE_END] =
UF_FLAG_PUBLIC, // CORPSE_FIELD_ITEM+18
UF_FLAG_PUBLIC, // CORPSE_FIELD_BYTES_1
UF_FLAG_PUBLIC, // CORPSE_FIELD_BYTES_2
- UF_FLAG_PUBLIC, // CORPSE_FIELD_GUILD
UF_FLAG_PUBLIC, // CORPSE_FIELD_FLAGS
UF_FLAG_DYNAMIC, // CORPSE_FIELD_DYNAMIC_FLAGS
- UF_FLAG_NONE, // CORPSE_FIELD_PAD
+};
+
+uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END] =
+{
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_GUID+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_DATA+1
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_TYPE
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_ENTRY
+ UF_FLAG_PUBLIC, // OBJECT_FIELD_SCALE_X
+ UF_FLAG_NONE, // OBJECT_FIELD_PADDING
+ UF_FLAG_PUBLIC, // AREATRIGGER_SPELLID
+ UF_FLAG_PUBLIC, // AREATRIGGER_SPELLVISUALID
+ UF_FLAG_PUBLIC, // AREATRIGGER_DURATION
+ UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS
+ UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS+1
+ UF_FLAG_PUBLIC, // AREATRIGGER_FINAL_POS+2
};
diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
index 6d168cd56c4..b0e6bb6afa2 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.h
@@ -40,5 +40,6 @@ extern uint32 UnitUpdateFieldFlags[PLAYER_END];
extern uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END];
extern uint32 DynamicObjectUpdateFieldFlags[DYNAMICOBJECT_END];
extern uint32 CorpseUpdateFieldFlags[CORPSE_END];
+extern uint32 AreaTriggerUpdateFieldFlags[AREATRIGGER_END];
#endif // _UPDATEFIELDFLAGS_H
diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h
index 2838ee31d81..880eb68bb89 100644
--- a/src/server/game/Entities/Object/Updates/UpdateFields.h
+++ b/src/server/game/Entities/Object/Updates/UpdateFields.h
@@ -16,418 +16,550 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _UPDATEFIELDS_AUTO_H
-#define _UPDATEFIELDS_AUTO_H
+#ifndef _UPDATEFIELDS_H
+#define _UPDATEFIELDS_H
-// Auto generated for version 3, 3, 5, 12340
+// Auto generated for version 4, 3, 4, 15595
enum EObjectFields
{
- OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- OBJECT_FIELD_TYPE = 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- OBJECT_FIELD_ENTRY = 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- OBJECT_FIELD_SCALE_X = 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
- OBJECT_FIELD_PADDING = 0x0005, // Size: 1, Type: INT, Flags: NONE
- OBJECT_END = 0x0006
+ OBJECT_FIELD_GUID = 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ OBJECT_FIELD_DATA = 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ OBJECT_FIELD_TYPE = 0x0004, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ OBJECT_FIELD_ENTRY = 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
+ OBJECT_FIELD_SCALE_X = 0x0006, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ OBJECT_FIELD_PADDING = 0x0007, // Size: 1, Type: INT, Flags: NONE
+ OBJECT_END = 0x0008
};
enum EItemFields
{
- ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
- ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_DURABILITY = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
- ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: PUBLIC
- ITEM_FIELD_PAD = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE
- ITEM_END = OBJECT_END + 0x003A
+ ITEM_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_CONTAINED = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_CREATOR = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_GIFTCREATOR = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
+ ITEM_FIELD_STACK_COUNT = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_DURATION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_SPELL_CHARGES = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_FLAGS = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_1_1 = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_1_3 = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_1 = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_2_3 = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_1 = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_3_3 = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_1 = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_4_3 = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_1 = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_5_3 = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_1 = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_6_3 = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_1 = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_7_3 = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_1 = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_8_3 = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_1 = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_9_3 = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_1 = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_10_3 = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_1 = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_11_3 = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_1 = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_12_3 = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_13_1 = OBJECT_END + 0x0034, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_13_3 = OBJECT_END + 0x0036, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_14_1 = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_14_3 = OBJECT_END + 0x0039, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_15_1 = OBJECT_END + 0x003A, // Size: 2, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_ENCHANTMENT_15_3 = OBJECT_END + 0x003C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ ITEM_FIELD_PROPERTY_SEED = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_RANDOM_PROPERTIES_ID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_FIELD_DURABILITY = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_MAXDURABILITY = OBJECT_END + 0x0040, // Size: 1, Type: INT, Flags: OWNER, ITEM_OWNER
+ ITEM_FIELD_CREATE_PLAYED_TIME = OBJECT_END + 0x0041, // Size: 1, Type: INT, Flags: PUBLIC
+ ITEM_END = OBJECT_END + 0x0042,
};
enum EContainerFields
{
- CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
- CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE
- CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC
- CONTAINER_END = ITEM_END + 0x004A
+ CONTAINER_FIELD_NUM_SLOTS = ITEM_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
+ CONTAINER_ALIGN_PAD = ITEM_END + 0x0001, // Size: 1, Type: BYTES, Flags: NONE
+ CONTAINER_FIELD_SLOT_1 = ITEM_END + 0x0002, // Size: 72, Type: LONG, Flags: PUBLIC
+ CONTAINER_END = ITEM_END + 0x004A
};
enum EUnitFields
{
- UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
- UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
- UNIT_CHANNEL_SPELL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_HEALTH = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER1 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER2 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER3 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER4 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER6 = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER7 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER6 = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MAXPOWER7 = OBJECT_END + 0x0021, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x0022, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0029, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_LEVEL = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x0032, // Size: 3, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_AURASTATE = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0038, // Size: 2, Type: INT, Flags: PUBLIC
- UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x003A, // Size: 1, Type: INT, Flags: PRIVATE
- UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_COMBATREACH = OBJECT_END + 0x003C, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_DISPLAYID = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_BYTES_1 = OBJECT_END + 0x0044, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_PETNUMBER = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER
- UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: OWNER
- UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_MOD_CAST_SPEED = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_CREATED_BY_SPELL = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_NPC_FLAGS = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC
- UNIT_NPC_EMOTESTATE = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_STAT0 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT1 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT2 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT3 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_STAT4 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RESISTANCES = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, PARTY_LEADER
- UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_BASE_MANA = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC
- UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_BYTES_2 = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC
- UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_ATTACK_POWER_MODS = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
- UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RANGED_ATTACK_POWER_MODS = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER
- UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
- UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
- UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC
- UNIT_FIELD_PADDING = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE
- UNIT_END = OBJECT_END + 0x008E,
+ UNIT_FIELD_CHARM = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_SUMMON = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CRITTER = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE
+ UNIT_FIELD_CHARMEDBY = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_SUMMONEDBY = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CREATEDBY = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_TARGET = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_FIELD_CHANNEL_OBJECT = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC
+ UNIT_CHANNEL_SPELL = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BYTES_0 = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_HEALTH = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER1 = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER2 = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER3 = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER4 = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER5 = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXHEALTH = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER1 = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER2 = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER3 = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER4 = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MAXPOWER5 = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER = OBJECT_END + 0x001E, // Size: 5, Type: FLOAT, Flags: PRIVATE, OWNER, UNUSED2
+ UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0023, // Size: 5, Type: FLOAT, Flags: PRIVATE, OWNER, UNUSED2
+ UNIT_FIELD_LEVEL = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x002A, // Size: 3, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS = OBJECT_END + 0x002D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x002E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_AURASTATE = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x0030, // Size: 2, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PRIVATE
+ UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x0033, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_COMBATREACH = OBJECT_END + 0x0034, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_DISPLAYID = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x0038, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO
+ UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x0039, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO
+ UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO
+ UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER, SPECIAL_INFO
+ UNIT_FIELD_BYTES_1 = OBJECT_END + 0x003C, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_PETNUMBER = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x003F, // Size: 1, Type: INT, Flags: OWNER
+ UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x0040, // Size: 1, Type: INT, Flags: OWNER
+ UNIT_DYNAMIC_FLAGS = OBJECT_END + 0x0041, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_MOD_CAST_SPEED = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_MOD_CAST_HASTE = OBJECT_END + 0x0043, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_CREATED_BY_SPELL = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_NPC_FLAGS = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: DYNAMIC
+ UNIT_NPC_EMOTESTATE = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_STAT0 = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT1 = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT2 = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT3 = OBJECT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_STAT4 = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT0 = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT1 = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT2 = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT3 = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POSSTAT4 = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT0 = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT1 = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT2 = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT3 = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_NEGSTAT4 = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RESISTANCES = OBJECT_END + 0x0056, // Size: 7, Type: INT, Flags: PRIVATE, OWNER, SPECIAL_INFO
+ UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_BASE_MANA = OBJECT_END + 0x006B, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x006C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_BYTES_2 = OBJECT_END + 0x006D, // Size: 1, Type: BYTES, Flags: PUBLIC
+ UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x006E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_ATTACK_POWER_MOD_POS = OBJECT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x0070, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0071, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0075, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x0076, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x0078, // Size: 7, Type: INT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x007F, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x0086, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER
+ UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x0087, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x0088, // Size: 1, Type: INT, Flags: PUBLIC
+ UNIT_FIELD_PADDING = OBJECT_END + 0x0089, // Size: 1, Type: INT, Flags: NONE
+ UNIT_END = OBJECT_END + 0x008A
+};
+
+enum EPlayerFields
+{
+ PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILDRANK = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILDDELETE_DATE = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILDLEVEL = UNIT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_BYTES = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_BYTES_2 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_BYTES_3 = UNIT_END + 0x0008, // Size: 1, Type: BYTES, Flags: PUBLIC
+ PLAYER_DUEL_TEAM = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0011, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0012, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0016, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0017, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x0020, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0021, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0025, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0026, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x002A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x0030, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0034, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0035, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0039, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x003A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0043, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0044, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0048, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0049, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0052, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0053, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0057, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0058, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005D, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0061, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0062, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0066, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0067, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006C, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x0070, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0071, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0075, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0076, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x007A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007B, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x0080, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0084, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0085, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_26_1 = UNIT_END + 0x0088, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_26_2 = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_26_3 = UNIT_END + 0x008A, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_26_5 = UNIT_END + 0x008C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_27_1 = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_27_2 = UNIT_END + 0x008E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_27_3 = UNIT_END + 0x008F, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_27_5 = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_28_1 = UNIT_END + 0x0092, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_28_2 = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_28_3 = UNIT_END + 0x0094, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_28_5 = UNIT_END + 0x0096, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_29_1 = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_29_2 = UNIT_END + 0x0098, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_29_3 = UNIT_END + 0x0099, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_29_5 = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_30_1 = UNIT_END + 0x009C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_30_2 = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_30_3 = UNIT_END + 0x009E, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_30_5 = UNIT_END + 0x00A0, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_31_1 = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_31_2 = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_31_3 = UNIT_END + 0x00A3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_31_5 = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_32_1 = UNIT_END + 0x00A6, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_32_2 = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_32_3 = UNIT_END + 0x00A8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_32_5 = UNIT_END + 0x00AA, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_33_1 = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_33_2 = UNIT_END + 0x00AC, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_33_3 = UNIT_END + 0x00AD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_33_5 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_34_1 = UNIT_END + 0x00B0, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_34_2 = UNIT_END + 0x00B1, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_34_3 = UNIT_END + 0x00B2, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_34_5 = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_35_1 = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_35_2 = UNIT_END + 0x00B6, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_35_3 = UNIT_END + 0x00B7, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_35_5 = UNIT_END + 0x00B9, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_36_1 = UNIT_END + 0x00BA, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_36_2 = UNIT_END + 0x00BB, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_36_3 = UNIT_END + 0x00BC, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_36_5 = UNIT_END + 0x00BE, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_37_1 = UNIT_END + 0x00BF, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_37_2 = UNIT_END + 0x00C0, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_37_3 = UNIT_END + 0x00C1, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_37_5 = UNIT_END + 0x00C3, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_38_1 = UNIT_END + 0x00C4, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_38_2 = UNIT_END + 0x00C5, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_38_3 = UNIT_END + 0x00C6, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_38_5 = UNIT_END + 0x00C8, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_39_1 = UNIT_END + 0x00C9, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_39_2 = UNIT_END + 0x00CA, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_39_3 = UNIT_END + 0x00CB, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_39_5 = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_40_1 = UNIT_END + 0x00CE, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_40_2 = UNIT_END + 0x00CF, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_40_3 = UNIT_END + 0x00D0, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_40_5 = UNIT_END + 0x00D2, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_41_1 = UNIT_END + 0x00D3, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_41_2 = UNIT_END + 0x00D4, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_41_3 = UNIT_END + 0x00D5, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_41_5 = UNIT_END + 0x00D7, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_42_1 = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_42_2 = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_42_3 = UNIT_END + 0x00DA, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_42_5 = UNIT_END + 0x00DC, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_43_1 = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_43_2 = UNIT_END + 0x00DE, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_43_3 = UNIT_END + 0x00DF, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_43_5 = UNIT_END + 0x00E1, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_44_1 = UNIT_END + 0x00E2, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_44_2 = UNIT_END + 0x00E3, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_44_3 = UNIT_END + 0x00E4, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_44_5 = UNIT_END + 0x00E6, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_45_1 = UNIT_END + 0x00E7, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_45_2 = UNIT_END + 0x00E8, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_45_3 = UNIT_END + 0x00E9, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_45_5 = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_46_1 = UNIT_END + 0x00EC, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_46_2 = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_46_3 = UNIT_END + 0x00EE, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_46_5 = UNIT_END + 0x00F0, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_47_1 = UNIT_END + 0x00F1, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_47_2 = UNIT_END + 0x00F2, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_47_3 = UNIT_END + 0x00F3, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_47_5 = UNIT_END + 0x00F5, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_48_1 = UNIT_END + 0x00F6, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_48_2 = UNIT_END + 0x00F7, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_48_3 = UNIT_END + 0x00F8, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_48_5 = UNIT_END + 0x00FA, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_49_1 = UNIT_END + 0x00FB, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_49_2 = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_49_3 = UNIT_END + 0x00FD, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_49_5 = UNIT_END + 0x00FF, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_50_1 = UNIT_END + 0x0100, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_50_2 = UNIT_END + 0x0101, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_50_3 = UNIT_END + 0x0102, // Size: 2, Type: TWO_SHORT, Flags: PARTY_MEMBER
+ PLAYER_QUEST_LOG_50_5 = UNIT_END + 0x0104, // Size: 1, Type: INT, Flags: PARTY_MEMBER
+ PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0105, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0106, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0107, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x0108, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x0109, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x010A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x010B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x010E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0110, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0111, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0112, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0113, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0114, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0115, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0116, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0117, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x0118, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x0119, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x011A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x011B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x011E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x011F, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x0120, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x0122, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x0123, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x0124, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x0125, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x0126, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x0127, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x0128, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x0129, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x012A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
+ PLAYER_CHOSEN_TITLE = UNIT_END + 0x012B, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FAKE_INEBRIATION = UNIT_END + 0x012C, // Size: 1, Type: INT, Flags: PUBLIC
+ PLAYER_FIELD_PAD_0 = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: NONE
+ PLAYER_END_NOT_SELF = UNIT_END + 0x012E,
- PLAYER_DUEL_ARBITER = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- PLAYER_FLAGS = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILDID = UNIT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILDRANK = UNIT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_BYTES = UNIT_END + 0x0005, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_BYTES_2 = UNIT_END + 0x0006, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_BYTES_3 = UNIT_END + 0x0007, // Size: 1, Type: BYTES, Flags: PUBLIC
- PLAYER_DUEL_TEAM = UNIT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_GUILD_TIMESTAMP = UNIT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_QUEST_LOG_1_1 = UNIT_END + 0x000A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_1_2 = UNIT_END + 0x000B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_1_3 = UNIT_END + 0x000C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_1_4 = UNIT_END + 0x000E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_1 = UNIT_END + 0x000F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_2_2 = UNIT_END + 0x0010, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_3 = UNIT_END + 0x0011, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_2_5 = UNIT_END + 0x0013, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_1 = UNIT_END + 0x0014, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_3_2 = UNIT_END + 0x0015, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_3 = UNIT_END + 0x0016, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_3_5 = UNIT_END + 0x0018, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_1 = UNIT_END + 0x0019, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_4_2 = UNIT_END + 0x001A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_3 = UNIT_END + 0x001B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_4_5 = UNIT_END + 0x001D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_1 = UNIT_END + 0x001E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_5_2 = UNIT_END + 0x001F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_3 = UNIT_END + 0x0020, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_5_5 = UNIT_END + 0x0022, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_1 = UNIT_END + 0x0023, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_6_2 = UNIT_END + 0x0024, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_3 = UNIT_END + 0x0025, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_6_5 = UNIT_END + 0x0027, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_1 = UNIT_END + 0x0028, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_7_2 = UNIT_END + 0x0029, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_3 = UNIT_END + 0x002A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_7_5 = UNIT_END + 0x002C, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_1 = UNIT_END + 0x002D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_8_2 = UNIT_END + 0x002E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_3 = UNIT_END + 0x002F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_8_5 = UNIT_END + 0x0031, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_1 = UNIT_END + 0x0032, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_9_2 = UNIT_END + 0x0033, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_3 = UNIT_END + 0x0034, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_9_5 = UNIT_END + 0x0036, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_1 = UNIT_END + 0x0037, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_10_2 = UNIT_END + 0x0038, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_3 = UNIT_END + 0x0039, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_10_5 = UNIT_END + 0x003B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_1 = UNIT_END + 0x003C, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_11_2 = UNIT_END + 0x003D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_3 = UNIT_END + 0x003E, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_11_5 = UNIT_END + 0x0040, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_1 = UNIT_END + 0x0041, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_12_2 = UNIT_END + 0x0042, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_3 = UNIT_END + 0x0043, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_12_5 = UNIT_END + 0x0045, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_1 = UNIT_END + 0x0046, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_13_2 = UNIT_END + 0x0047, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_3 = UNIT_END + 0x0048, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_13_5 = UNIT_END + 0x004A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_1 = UNIT_END + 0x004B, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_14_2 = UNIT_END + 0x004C, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_3 = UNIT_END + 0x004D, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_14_5 = UNIT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_1 = UNIT_END + 0x0050, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_15_2 = UNIT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_3 = UNIT_END + 0x0052, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_15_5 = UNIT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_1 = UNIT_END + 0x0055, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_16_2 = UNIT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_3 = UNIT_END + 0x0057, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_16_5 = UNIT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_1 = UNIT_END + 0x005A, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_17_2 = UNIT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_3 = UNIT_END + 0x005C, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_17_5 = UNIT_END + 0x005E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_1 = UNIT_END + 0x005F, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_18_2 = UNIT_END + 0x0060, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_3 = UNIT_END + 0x0061, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_18_5 = UNIT_END + 0x0063, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_1 = UNIT_END + 0x0064, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_19_2 = UNIT_END + 0x0065, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_3 = UNIT_END + 0x0066, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_19_5 = UNIT_END + 0x0068, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_1 = UNIT_END + 0x0069, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_20_2 = UNIT_END + 0x006A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_3 = UNIT_END + 0x006B, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_20_5 = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_1 = UNIT_END + 0x006E, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_21_2 = UNIT_END + 0x006F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_3 = UNIT_END + 0x0070, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_21_5 = UNIT_END + 0x0072, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_1 = UNIT_END + 0x0073, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_22_2 = UNIT_END + 0x0074, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_3 = UNIT_END + 0x0075, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_22_5 = UNIT_END + 0x0077, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_1 = UNIT_END + 0x0078, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_23_2 = UNIT_END + 0x0079, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_3 = UNIT_END + 0x007A, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_23_5 = UNIT_END + 0x007C, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_1 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_24_2 = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_3 = UNIT_END + 0x007F, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_24_5 = UNIT_END + 0x0081, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_1 = UNIT_END + 0x0082, // Size: 1, Type: INT, Flags: PARTY_MEMBER
- PLAYER_QUEST_LOG_25_2 = UNIT_END + 0x0083, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_3 = UNIT_END + 0x0084, // Size: 2, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_QUEST_LOG_25_5 = UNIT_END + 0x0086, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_VISIBLE_ITEM_1_ENTRYID = UNIT_END + 0x0087, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_1_ENCHANTMENT = UNIT_END + 0x0088, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_ENTRYID = UNIT_END + 0x0089, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_2_ENCHANTMENT = UNIT_END + 0x008A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_ENTRYID = UNIT_END + 0x008B, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_3_ENCHANTMENT = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_ENTRYID = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_4_ENCHANTMENT = UNIT_END + 0x008E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_ENTRYID = UNIT_END + 0x008F, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_5_ENCHANTMENT = UNIT_END + 0x0090, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_ENTRYID = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_6_ENCHANTMENT = UNIT_END + 0x0092, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_ENTRYID = UNIT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_7_ENCHANTMENT = UNIT_END + 0x0094, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_ENTRYID = UNIT_END + 0x0095, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_8_ENCHANTMENT = UNIT_END + 0x0096, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_ENTRYID = UNIT_END + 0x0097, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_9_ENCHANTMENT = UNIT_END + 0x0098, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_ENTRYID = UNIT_END + 0x0099, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_10_ENCHANTMENT = UNIT_END + 0x009A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_ENTRYID = UNIT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_11_ENCHANTMENT = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_ENTRYID = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_12_ENCHANTMENT = UNIT_END + 0x009E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_ENTRYID = UNIT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_13_ENCHANTMENT = UNIT_END + 0x00A0, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_ENTRYID = UNIT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_14_ENCHANTMENT = UNIT_END + 0x00A2, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_ENTRYID = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_15_ENCHANTMENT = UNIT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_ENTRYID = UNIT_END + 0x00A5, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_16_ENCHANTMENT = UNIT_END + 0x00A6, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_ENTRYID = UNIT_END + 0x00A7, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_17_ENCHANTMENT = UNIT_END + 0x00A8, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_ENTRYID = UNIT_END + 0x00A9, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_18_ENCHANTMENT = UNIT_END + 0x00AA, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_ENTRYID = UNIT_END + 0x00AB, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_VISIBLE_ITEM_19_ENCHANTMENT = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC
- PLAYER_CHOSEN_TITLE = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FAKE_INEBRIATION = UNIT_END + 0x00AE, // Size: 1, Type: INT, Flags: PUBLIC
- PLAYER_FIELD_PAD_0 = UNIT_END + 0x00AF, // Size: 1, Type: INT, Flags: NONE
- PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x00B0, // Size: 46, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x00DE, // Size: 32, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x00FE, // Size: 56, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x0136, // Size: 14, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x0144, // Size: 24, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KEYRING_SLOT_1 = UNIT_END + 0x015C, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_CURRENCYTOKEN_SLOT_1 = UNIT_END + 0x019C, // Size: 64, Type: LONG, Flags: PRIVATE
- PLAYER_FARSIGHT = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_FIELD_KNOWN_CURRENCIES = UNIT_END + 0x01E4, // Size: 2, Type: LONG, Flags: PRIVATE
- PLAYER_XP = UNIT_END + 0x01E6, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E7, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SKILL_INFO_1_1 = UNIT_END + 0x01E8, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS1 = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CHARACTER_POINTS2 = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_CREATURES = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_TRACK_RESOURCES = UNIT_END + 0x036B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPERTISE = UNIT_END + 0x036F, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x0370, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x0371, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x0372, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0373, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0374, // Size: 7, Type: FLOAT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK = UNIT_END + 0x037B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x037C, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037D, // Size: 128, Type: BYTES, Flags: PRIVATE
- PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x03FD, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COINAGE = UNIT_END + 0x03FE, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x03FF, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0406, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x040D, // Size: 7, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x0414, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0415, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0416, // Size: 1, Type: FLOAT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0418, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES = UNIT_END + 0x0419, // Size: 1, Type: BYTES, Flags: PRIVATE
- PLAYER_AMMO_ID = UNIT_END + 0x041A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_SELF_RES_SPELL = UNIT_END + 0x041B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x041C, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x041D, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0429, // Size: 12, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_KILLS = UNIT_END + 0x0435, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
- PLAYER_FIELD_TODAY_CONTRIBUTION = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_YESTERDAY_CONTRIBUTION = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_BYTES2 = UNIT_END + 0x0439, // Size: 1, Type: 6, Flags: PRIVATE
- PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x043B, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0454, // Size: 21, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_HONOR_CURRENCY = UNIT_END + 0x0469, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_ARENA_CURRENCY = UNIT_END + 0x046A, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x046B, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x046C, // Size: 25, Type: INT, Flags: PRIVATE
- PLAYER_RUNE_REGEN_1 = UNIT_END + 0x0485, // Size: 4, Type: FLOAT, Flags: PRIVATE
- PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x0489, // Size: 3, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x048C, // Size: 6, Type: INT, Flags: PRIVATE
- PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x0492, // Size: 6, Type: INT, Flags: PRIVATE
- PLAYER_GLYPHS_ENABLED = UNIT_END + 0x0498, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_PET_SPELL_POWER = UNIT_END + 0x0499, // Size: 1, Type: INT, Flags: PRIVATE
- PLAYER_END = UNIT_END + 0x049A
+ PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x012E, // Size: 46, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_PACK_SLOT_1 = UNIT_END + 0x015C, // Size: 32, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANK_SLOT_1 = UNIT_END + 0x017C, // Size: 56, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_BANKBAG_SLOT_1 = UNIT_END + 0x01B4, // Size: 14, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_VENDORBUYBACK_SLOT_1 = UNIT_END + 0x01C2, // Size: 24, Type: LONG, Flags: PRIVATE
+ PLAYER_FARSIGHT = UNIT_END + 0x01DA, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x01DC, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES1 = UNIT_END + 0x01DE, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES2 = UNIT_END + 0x01E0, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER__FIELD_KNOWN_TITLES3 = UNIT_END + 0x01E2, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_XP = UNIT_END + 0x01E4, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x01E5, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SKILL_LINEID_0 = UNIT_END + 0x01E6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_SKILL_STEP_0 = UNIT_END + 0x0226, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_SKILL_RANK_0 = UNIT_END + 0x0266, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_SKILL_MAX_RANK_0 = UNIT_END + 0x02A6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_SKILL_MODIFIER_0 = UNIT_END + 0x02E6, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_SKILL_TALENT_0 = UNIT_END + 0x0326, // Size: 64, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_CHARACTER_POINTS = UNIT_END + 0x0366, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_CREATURES = UNIT_END + 0x0367, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_TRACK_RESOURCES = UNIT_END + 0x0368, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_EXPERTISE = UNIT_END + 0x0369, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x036A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x036B, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x036C, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x036D, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x036E, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x036F, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x0370, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x0371, // Size: 7, Type: FLOAT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK = UNIT_END + 0x0378, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x0379, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_MASTERY = UNIT_END + 0x037A, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x037B, // Size: 156, Type: BYTES, Flags: PRIVATE
+ PLAYER_REST_STATE_EXPERIENCE = UNIT_END + 0x0417, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COINAGE = UNIT_END + 0x0418, // Size: 2, Type: LONG, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x041A, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x0421, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x0428, // Size: 7, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x042F, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x0430, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x0431, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS = UNIT_END + 0x0432, // Size: 3, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_SPELL_POWER_PCT = UNIT_END + 0x0435, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT = UNIT_END + 0x0436, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES = UNIT_END + 0x0439, // Size: 1, Type: BYTES, Flags: PRIVATE
+ PLAYER_SELF_RES_SPELL = UNIT_END + 0x043A, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x043B, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x043C, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x0448, // Size: 12, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_KILLS = UNIT_END + 0x0454, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x0455, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BYTES2 = UNIT_END + 0x0456, // Size: 1, Type: 6, Flags: PRIVATE
+ PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x0457, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x0458, // Size: 26, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x0472, // Size: 21, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_BATTLEGROUND_RATING = UNIT_END + 0x0487, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0x0488, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_DAILY_QUESTS_1 = UNIT_END + 0x0489, // Size: 25, Type: INT, Flags: PRIVATE
+ PLAYER_RUNE_REGEN_1 = UNIT_END + 0x04A2, // Size: 4, Type: FLOAT, Flags: PRIVATE
+ PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0x04A6, // Size: 3, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPH_SLOTS_1 = UNIT_END + 0x04A9, // Size: 9, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_GLYPHS_1 = UNIT_END + 0x04B2, // Size: 9, Type: INT, Flags: PRIVATE
+ PLAYER_GLYPHS_ENABLED = UNIT_END + 0x04BB, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_PET_SPELL_POWER = UNIT_END + 0x04BC, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_RESEARCHING_1 = UNIT_END + 0x04BD, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_FIELD_RESERACH_SITE_1 = UNIT_END + 0x04C5, // Size: 8, Type: TWO_SHORT, Flags: PRIVATE
+ PLAYER_PROFESSION_SKILL_LINE_1 = UNIT_END + 0x04CD, // Size: 2, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_UI_HIT_MODIFIER = UNIT_END + 0x04CF, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_UI_SPELL_HIT_MODIFIER = UNIT_END + 0x04D0, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_HOME_REALM_TIME_OFFSET = UNIT_END + 0x04D1, // Size: 1, Type: INT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HASTE = UNIT_END + 0x04D2, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_RANGED_HASTE = UNIT_END + 0x04D3, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_PET_HASTE = UNIT_END + 0x04D4, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_FIELD_MOD_HASTE_REGEN = UNIT_END + 0x04D5, // Size: 1, Type: FLOAT, Flags: PRIVATE
+ PLAYER_END = UNIT_END + 0x04D6
};
enum EGameObjectFields
{
- OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
- GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
- GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
- GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC
- GAMEOBJECT_END = OBJECT_END + 0x000C
+ OBJECT_FIELD_CREATED_BY = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ GAMEOBJECT_DISPLAYID = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_FLAGS = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_PARENTROTATION = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC
+ GAMEOBJECT_DYNAMIC = OBJECT_END + 0x0008, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC
+ GAMEOBJECT_FACTION = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_LEVEL = OBJECT_END + 0x000A, // Size: 1, Type: INT, Flags: PUBLIC
+ GAMEOBJECT_BYTES_1 = OBJECT_END + 0x000B, // Size: 1, Type: BYTES, Flags: PUBLIC
+ GAMEOBJECT_END = OBJECT_END + 0x000C
};
enum EDynamicObjectFields
{
- DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: BYTES, Flags: PUBLIC
- DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
- DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
- DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
- DYNAMICOBJECT_END = OBJECT_END + 0x0006
+ DYNAMICOBJECT_CASTER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ DYNAMICOBJECT_BYTES = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: DYNAMIC
+ DYNAMICOBJECT_SPELLID = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC
+ DYNAMICOBJECT_RADIUS = OBJECT_END + 0x0004, // Size: 1, Type: FLOAT, Flags: PUBLIC
+ DYNAMICOBJECT_CASTTIME = OBJECT_END + 0x0005, // Size: 1, Type: INT, Flags: PUBLIC
+ DYNAMICOBJECT_END = OBJECT_END + 0x0006
};
enum ECorpseFields
{
- CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
- CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
- CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC
- CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC
- CORPSE_FIELD_GUILD = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC
- CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: DYNAMIC
- CORPSE_FIELD_PAD = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: NONE
- CORPSE_END = OBJECT_END + 0x001E
+ CORPSE_FIELD_OWNER = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC
+ CORPSE_FIELD_PARTY = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC
+ CORPSE_FIELD_DISPLAY_ID = OBJECT_END + 0x0004, // Size: 1, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_ITEM = OBJECT_END + 0x0005, // Size: 19, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_BYTES_1 = OBJECT_END + 0x0018, // Size: 1, Type: BYTES, Flags: PUBLIC
+ CORPSE_FIELD_BYTES_2 = OBJECT_END + 0x0019, // Size: 1, Type: BYTES, Flags: PUBLIC
+ CORPSE_FIELD_FLAGS = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC
+ CORPSE_FIELD_DYNAMIC_FLAGS = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: DYNAMIC
+ CORPSE_END = OBJECT_END + 0x001C
};
-#endif
+
+enum EAreaTriggerFields
+{
+ AREATRIGGER_SPELLID = OBJECT_END + 0x0000, // Size: 1, Type: INT, Flags: PUBLIC
+ AREATRIGGER_SPELLVISUALID = OBJECT_END + 0x0001, // Size: 1, Type: INT, Flags: PUBLIC
+ AREATRIGGER_DURATION = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC
+ AREATRIGGER_FINAL_POS = OBJECT_END + 0x0003, // Size: 3, Type: FLOAT, Flags: PUBLIC
+ AREATRIGGER_END = OBJECT_END + 0x0006
+};
+
+#endif // _UPDATEFIELDS_H
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index c218c3c645f..13d738887b5 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -31,15 +31,16 @@
#include "Util.h"
#include "Group.h"
#include "Opcodes.h"
+#include "WorldSession.h"
#define PET_XP_FACTOR 0.05f
Pet::Pet(Player* owner, PetType type) :
Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false),
- m_happinessTimer(7500), m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false),
+ m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false),
m_declinedname(NULL)
{
- ASSERT(GetOwner()->GetTypeId() == TYPEID_PLAYER);
+ ASSERT(m_owner->GetTypeId() == TYPEID_PLAYER);
m_unitTypeMask |= UNIT_MASK_PET;
if (type == HUNTER_PET)
@@ -150,14 +151,14 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
if (!petEntry)
return false;
- uint32 summonSpellId = fields[15].GetUInt32();
+ uint32 summonSpellId = fields[14].GetUInt32();
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(summonSpellId);
bool isTemporarySummon = spellInfo && spellInfo->GetDuration() > 0;
if (current && isTemporarySummon)
return false;
- PetType petType = PetType(fields[16].GetUInt8());
+ PetType petType = PetType(fields[15].GetUInt8());
if (petType == HUNTER_PET)
{
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
@@ -224,8 +225,6 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
// this enables popup window (pet abandon, cancel)
- SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
- SetPower(POWER_HAPPINESS, fields[12].GetUInt32());
setPowerType(POWER_FOCUS);
break;
default:
@@ -267,7 +266,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
else
{
SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth);
- SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana);
+ SetPower(POWER_MANA, savedmana > uint32(GetMaxPower(POWER_MANA)) ? GetMaxPower(POWER_MANA) : savedmana);
}
}
@@ -315,13 +314,13 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c
InitTalentForLevel(); // set original talents points before spell loading
- uint32 timediff = uint32(time(NULL) - fields[14].GetUInt32());
+ uint32 timediff = uint32(time(NULL) - fields[13].GetUInt32());
_LoadAuras(timediff);
// load action bar, if data broken will fill later by default spells.
if (!isTemporarySummon)
{
- m_charmInfo->LoadPetActionBar(fields[13].GetString());
+ m_charmInfo->LoadPetActionBar(fields[12].GetString());
_LoadSpells();
InitTalentForLevel(); // re-init to check talent count
@@ -449,7 +448,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
// save pet
std::ostringstream ss;
- ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType) "
+ ss << "INSERT INTO character_pet (id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType) "
<< "VALUES ("
<< m_charmInfo->GetPetNumber() << ','
<< GetEntry() << ','
@@ -462,8 +461,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< name.c_str() << "', "
<< uint32(HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) ? 0 : 1) << ','
<< curhealth << ','
- << curmana << ','
- << GetPower(POWER_HAPPINESS) << ", '";
+ << curmana << ", '";
for (uint32 i = ACTION_BAR_INDEX_START; i < ACTION_BAR_INDEX_END; ++i)
{
@@ -524,12 +522,6 @@ void Pet::setDeathState(DeathState s) // overwrite virtual
// pet corpse non lootable and non skinnable
SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
-
- //lose happiness when died and not in BG/Arena
- MapEntry const* mapEntry = sMapStore.LookupEntry(GetMapId());
- if (!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))
- ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE);
-
//SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
}
@@ -623,18 +615,6 @@ void Pet::Update(uint32 diff)
}
}
}
-
- if (getPetType() != HUNTER_PET)
- break;
-
- if (m_happinessTimer <= diff)
- {
- LoseHappiness();
- m_happinessTimer = 7500;
- }
- else
- m_happinessTimer -= diff;
-
break;
}
default:
@@ -682,27 +662,6 @@ void Creature::Regenerate(Powers power)
ModifyPower(power, int32(addvalue));
}
-void Pet::LoseHappiness()
-{
- uint32 curValue = GetPower(POWER_HAPPINESS);
- if (curValue <= 0)
- return;
- int32 addvalue = 670; //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)
- if (IsInCombat()) //we know in combat happiness fades faster, multiplier guess
- addvalue = int32(addvalue * 1.5f);
- ModifyPower(POWER_HAPPINESS, -addvalue);
-}
-
-HappinessState Pet::GetHappinessState()
-{
- if (GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE)
- return UNHAPPY;
- else if (GetPower(POWER_HAPPINESS) >= HAPPINESS_LEVEL_SIZE * 2)
- return HAPPY;
- else
- return CONTENT;
-}
-
void Pet::Remove(PetSaveMode mode, bool returnreagent)
{
GetOwner()->RemovePet(this, mode, returnreagent);
@@ -787,7 +746,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
SetDisplayId(creature->GetDisplayId());
if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
- SetName(cFamily->Name[sWorld->GetDefaultDbcLocale()]);
+ SetName(cFamily->Name);
else
SetName(creature->GetNameForLocaleIdx(sObjectMgr->GetDBCLocaleIndex()));
@@ -800,7 +759,7 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner)
return false;
if (CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family))
- SetName(cFamily->Name[sWorld->GetDefaultDbcLocale()]);
+ SetName(cFamily->Name);
Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
@@ -815,8 +774,6 @@ bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phas
if (!Create(guid, map, phaseMask, cinfo->Entry, petId))
return false;
- SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
- SetPower(POWER_HAPPINESS, 166500);
setPowerType(POWER_FOCUS);
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
@@ -874,6 +831,7 @@ bool Guardian::InitStatsForLevel(uint8 petlevel)
SetAttackTime(RANGED_ATTACK, BASE_ATTACK_TIME);
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
+ SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f);
//scale
CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family);
@@ -1907,6 +1865,8 @@ bool Pet::IsPermanentPetFor(Player* owner) const
return GetCreatureTemplate()->type == CREATURE_TYPE_DEMON;
case CLASS_DEATH_KNIGHT:
return GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD;
+ case CLASS_MAGE:
+ return GetCreatureTemplate()->type == CREATURE_TYPE_ELEMENTAL;
default:
return false;
}
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index ef5e792e939..d987e1a3fdc 100644
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -77,8 +77,6 @@ class Pet : public Guardian
return m_autospells[pos];
}
- void LoseHappiness();
- HappinessState GetHappinessState();
void GivePetXP(uint32 xp);
void GivePetLevel(uint8 level);
void SynchronizeLevelWithOwner();
@@ -149,7 +147,6 @@ class Pet : public Guardian
Player* GetOwner() const;
protected:
- uint32 m_happinessTimer;
PetType m_petType;
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
uint64 m_auraRaidUpdateMask;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 9ee7bc4b05a..2324057169a 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -35,6 +35,7 @@
#include "ConditionMgr.h"
#include "CreatureAI.h"
#include "DatabaseEnv.h"
+#include "DB2Stores.h"
#include "DisableMgr.h"
#include "Formulas.h"
#include "GameEventMgr.h"
@@ -77,22 +78,11 @@
#include "World.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "MovementStructures.h"
#include "GameObjectAI.h"
#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS)
-#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3))
-#define PLAYER_SKILL_VALUE_INDEX(x) (PLAYER_SKILL_INDEX(x)+1)
-#define PLAYER_SKILL_BONUS_INDEX(x) (PLAYER_SKILL_INDEX(x)+2)
-
-#define SKILL_VALUE(x) PAIR32_LOPART(x)
-#define SKILL_MAX(x) PAIR32_HIPART(x)
-#define MAKE_SKILL_VALUE(v, m) MAKE_PAIR32(v, m)
-
-#define SKILL_TEMP_BONUS(x) int16(PAIR32_LOPART(x))
-#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x))
-#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t, p)
-
enum CharacterFlags
{
CHARACTER_FLAG_NONE = 0x00000000,
@@ -144,6 +134,22 @@ enum CharacterCustomizeFlags
static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 };
+uint32 const MasterySpells[MAX_CLASSES] =
+{
+ 0,
+ 87500, // Warrior
+ 87494, // Paladin
+ 87493, // Hunter
+ 87496, // Rogue
+ 87495, // Priest
+ 87492, // Death Knight
+ 87497, // Shaman
+ 86467, // Mage
+ 87498, // Warlock
+ 0,
+ 87491, // Druid
+};
+
// == PlayerTaxi ================================================
PlayerTaxi::PlayerTaxi()
@@ -205,15 +211,16 @@ void PlayerTaxi::LoadTaxiMask(std::string const &data)
void PlayerTaxi::AppendTaximaskTo(ByteBuffer& data, bool all)
{
+ data << uint32(TaxiMaskSize);
if (all)
{
for (uint8 i = 0; i < TaxiMaskSize; ++i)
- data << uint32(sTaxiNodesMask[i]); // all existed nodes
+ data << uint8(sTaxiNodesMask[i]); // all existed nodes
}
else
{
for (uint8 i = 0; i < TaxiMaskSize; ++i)
- data << uint32(m_taximask[i]); // known nodes
+ data << uint8(m_taximask[i]); // known nodes
}
}
@@ -281,7 +288,7 @@ uint32 PlayerTaxi::GetCurrentTaxiPath() const
std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi)
{
for (uint8 i = 0; i < TaxiMaskSize; ++i)
- ss << taxi.m_taximask[i] << ' ';
+ ss << uint32(taxi.m_taximask[i]) << ' ';
return ss;
}
@@ -359,7 +366,7 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/)
Update(false); // send spell info to caster self
}
-void TradeData::SetMoney(uint32 money)
+void TradeData::SetMoney(uint64 money)
{
if (m_money == money)
return;
@@ -433,6 +440,7 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
// 4.3. Give reputation (player must not be on BG).
// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
// 5. Credit instance encounter.
+// 6. Update guild achievements.
KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) :
// 1. Initialize internal variables to default values.
_killer(killer), _victim(victim), _group(killer->GetGroup()),
@@ -521,10 +529,14 @@ inline void KillRewarder::_RewardXP(Player* player, float rate)
for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
AddPct(xp, (*i)->GetAmount());
- // 4.2.3. Give XP to player.
+ // 4.2.3. Calculate expansion penalty
+ if (_victim->GetTypeId() == TYPEID_UNIT && player->getLevel() >= GetMaxLevelForExpansion(_victim->ToCreature()->GetCreatureTemplate()->expansion))
+ xp = CalculatePct(xp, 10); // Players get only 10% xp for killing creatures of lower expansion levels than himself
+
+ // 4.2.4. Give XP to player.
player->GiveXP(xp, _victim, _groupRate);
if (Pet* pet = player->GetPet())
- // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
+ // 4.2.5. If player has pet, reward pet with XP (100% for single player, 50% for group case).
pet->GivePetXP(_group ? xp / 2 : xp);
}
}
@@ -543,7 +555,7 @@ inline void KillRewarder::_RewardKillCredit(Player* player)
if (Creature* target = _victim->ToCreature())
{
player->KilledMonster(target->GetCreatureTemplate(), target->GetGUID());
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, target);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, 0, target);
}
}
@@ -606,7 +618,7 @@ void KillRewarder::_RewardGroup()
if (member->IsAtGroupRewardDistance(_victim))
{
_RewardPlayer(member, isDungeon);
- member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, _victim);
+ member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, 0, _victim);
}
}
}
@@ -634,10 +646,18 @@ void KillRewarder::Reward()
}
// 5. Credit instance encounter.
+ // 6. Update guild achievements.
if (Creature* victim = _victim->ToCreature())
+ {
if (victim->IsDungeonBoss())
if (InstanceScript* instance = _victim->GetInstanceScript())
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim);
+
+ if (uint32 guildId = victim->GetMap()->GetOwnerGuildId())
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer);
+ }
+
}
// == Player ====================================================
@@ -647,7 +667,7 @@ void KillRewarder::Reward()
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
-Player::Player(WorldSession* session): Unit(true)
+Player::Player(WorldSession* session): Unit(true), phaseMgr(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -680,11 +700,10 @@ Player::Player(WorldSession* session): Unit(true)
m_comboTarget = 0;
m_comboPoints = 0;
- m_usedTalentCount = 0;
- m_questRewardTalentCount = 0;
-
m_regenTimer = 0;
m_regenTimerCount = 0;
+ m_holyPowerRegenTimerCount = 0;
+ m_focusRegenTimerCount = 0;
m_weaponChangeTimer = 0;
m_zoneUpdateId = 0;
@@ -695,7 +714,7 @@ Player::Player(WorldSession* session): Unit(true)
m_nextSave = sWorld->getIntConfig(CONFIG_INTERVAL_SAVE);
- clearResurrectRequestData();
+ _resurrectionData = NULL;
memset(m_items, 0, sizeof(Item*)*PLAYER_SLOTS_COUNT);
@@ -760,7 +779,6 @@ Player::Player(WorldSession* session): Unit(true)
m_canParry = false;
m_canBlock = false;
m_canTitanGrip = false;
- m_ammoDPS = 0.0f;
m_temporaryUnsummonedPetNumber = 0;
//cache for UNIT_CREATED_BY_SPELL to allow
@@ -784,8 +802,6 @@ Player::Player(WorldSession* session): Unit(true)
unReadMails = 0;
m_nextMailDelivereTime = 0;
- m_resetTalentsCost = 0;
- m_resetTalentsTime = 0;
m_itemUpdateQueueBlocked = false;
for (uint8 i = 0; i < MAX_MOVE_TYPE; ++i)
@@ -802,17 +818,7 @@ Player::Player(WorldSession* session): Unit(true)
m_raidMapDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
m_lastPotionId = 0;
-
- m_activeSpec = 0;
- m_specsCount = 1;
-
- for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
- {
- for (uint8 g = 0; g < MAX_GLYPH_SLOT_INDEX; ++g)
- m_Glyphs[i][g] = 0;
-
- m_talents[i] = new PlayerTalentMap();
- }
+ _talentMgr = new PlayerTalentInfo();
for (uint8 i = 0; i < BASEMOD_END; ++i)
{
@@ -824,7 +830,6 @@ Player::Player(WorldSession* session): Unit(true)
m_baseRatingValue[i] = 0;
m_baseSpellPower = 0;
- m_baseFeralAP = 0;
m_baseManaRegen = 0;
m_baseHealthRegen = 0;
m_spellPenetrationItemMod = 0;
@@ -876,12 +881,11 @@ Player::Player(WorldSession* session): Unit(true)
m_ChampioningFaction = 0;
- m_timeSyncCounter = 0;
m_timeSyncTimer = 0;
m_timeSyncClient = 0;
m_timeSyncServer = 0;
- for (uint8 i = 0; i < MAX_POWERS; ++i)
+ for (uint8 i = 0; i < MAX_POWERS_PER_CLASS; ++i)
m_powerFraction[i] = 0;
isDebugAreaTriggers = false;
@@ -895,7 +899,12 @@ Player::Player(WorldSession* session): Unit(true)
SetPendingBind(0, 0);
_activeCheats = CHEAT_NONE;
- m_achievementMgr = new AchievementMgr(this);
+ _maxPersonalArenaRate = 0;
+
+ memset(_voidStorageItems, 0, VOID_STORAGE_MAX_SLOT * sizeof(VoidStorageItem*));
+ memset(_CUFProfiles, 0, MAX_CUF_PROFILES * sizeof(CUFProfile*));
+
+ m_achievementMgr = new AchievementMgr<Player>(this);
m_reputationMgr = new ReputationMgr(this);
}
@@ -911,12 +920,7 @@ Player::~Player()
for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
delete itr->second;
- for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
- {
- for (PlayerTalentMap::const_iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end(); ++itr)
- delete itr->second;
- delete m_talents[i];
- }
+ delete _talentMgr;
//all mailed items should be deleted, also all mail should be deallocated
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -935,6 +939,14 @@ Player::~Player()
delete m_achievementMgr;
delete m_reputationMgr;
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ delete _voidStorageItems[i];
+
+ for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
+ delete _CUFProfiles[i];
+
+ ClearResurrectRequestData();
+
sWorld->DecreasePlayerCount();
}
@@ -1007,8 +1019,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
}
+
SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER);
- SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f); // fix cast time showed in spell tooltip on client
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); // default for players in 3.0.3
SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1)); // -1 is default value
@@ -1021,8 +1033,9 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
SetByteValue(PLAYER_BYTES_3, 0, createInfo->Gender);
SetByteValue(PLAYER_BYTES_3, 3, 0); // BattlefieldArenaFaction (0 or 1)
- SetUInt32Value(PLAYER_GUILDID, 0);
+ SetUInt64Value(OBJECT_FIELD_DATA, 0);
SetUInt32Value(PLAYER_GUILDRANK, 0);
+ SetGuildLevel(0);
SetUInt32Value(PLAYER_GUILD_TIMESTAMP, 0);
for (int i = 0; i < KNOWN_TITLES_SIZE; ++i)
@@ -1031,8 +1044,6 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
SetUInt32Value(PLAYER_FIELD_KILLS, 0);
SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
- SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
- SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
// set starting level
uint32 start_level = getClass() != CLASS_DEATH_KNIGHT
@@ -1051,8 +1062,9 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
InitRunes();
SetUInt32Value(PLAYER_FIELD_COINAGE, sWorld->getIntConfig(CONFIG_START_PLAYER_MONEY));
- SetHonorPoints(sWorld->getIntConfig(CONFIG_START_HONOR_POINTS));
- SetArenaPoints(sWorld->getIntConfig(CONFIG_START_ARENA_POINTS));
+ SetCurrency(CURRENCY_TYPE_HONOR_POINTS, sWorld->getIntConfig(CONFIG_CURRENCY_START_HONOR_POINTS));
+ SetCurrency(CURRENCY_TYPE_JUSTICE_POINTS, sWorld->getIntConfig(CONFIG_CURRENCY_START_JUSTICE_POINTS));
+ SetCurrency(CURRENCY_TYPE_CONQUEST_POINTS, sWorld->getIntConfig(CONFIG_CURRENCY_START_CONQUEST_POINTS));
// start with every map explored
if (sWorld->getBoolConfig(CONFIG_START_ALL_EXPLORED))
@@ -1127,8 +1139,8 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
if (getPowerType() == POWER_RUNIC_POWER)
{
- SetPower(POWER_RUNE, 8);
- SetMaxPower(POWER_RUNE, 8);
+ SetPower(POWER_RUNES, 8);
+ SetMaxPower(POWER_RUNES, 8);
SetPower(POWER_RUNIC_POWER, 0);
SetMaxPower(POWER_RUNIC_POWER, 1000);
}
@@ -1159,7 +1171,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
uint32 count = iProto->BuyCount;
// special amount for food/drink
- if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD)
+ if (iProto->Class == ITEM_CLASS_CONSUMABLE && iProto->SubClass == ITEM_SUBCLASS_FOOD_DRINK)
{
switch (iProto->Spells[0].SpellCategory)
{
@@ -1195,7 +1207,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
RemoveItem(INVENTORY_SLOT_BAG_0, i, true);
EquipItem(eDest, pItem, true);
}
- // move other items to more appropriate slots (ammo not equipped in special bag)
+ // move other items to more appropriate slots
else
{
ItemPosCountVec sDest;
@@ -1205,11 +1217,6 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo)
RemoveItem(INVENTORY_SLOT_BAG_0, i, true);
pItem = StoreItem(sDest, pItem, true);
}
-
- // if this is ammo then use it
- msg = CanUseAmmo(pItem->GetEntry());
- if (msg == EQUIP_ERR_OK)
- SetAmmo(pItem->GetEntry());
}
}
}
@@ -1319,8 +1326,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage)
TC_LOG_DEBUG("entities.player", "We are fall to death, loosing 10 percents durability");
DurabilityLossAll(0.10f, false);
// durability lost message
- WorldPacket data2(SMSG_DURABILITY_DAMAGE_DEATH, 0);
- GetSession()->SendPacket(&data2);
+ SendDurabilityLoss(this, 10);
}
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type);
@@ -1876,7 +1882,7 @@ void Player::setDeathState(DeathState s)
// lost combo points at any target (targeted combo points clear in Unit::setDeathState)
ClearComboPoints();
- clearResurrectRequestData();
+ ClearResurrectRequestData();
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
@@ -1915,100 +1921,70 @@ void Player::InnEnter(time_t time, uint32 mapid, float x, float y, float z)
time_inn_enter = time;
}
-bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
+bool Player::BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer)
{
// 0 1 2 3 4 5 6 7
// "SELECT characters.guid, characters.name, characters.race, characters.class, characters.gender, characters.playerBytes, characters.playerBytes2, characters.level, "
// 8 9 10 11 12 13 14
// "characters.zone, characters.map, characters.position_x, characters.position_y, characters.position_z, guild_member.guildid, characters.playerFlags, "
- // 15 16 17 18 19 20 21
- // "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, character_banned.guid, character_declinedname.genitive "
+ // 15 16 17 18 19 20 21 22
+ // "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, characters.data, character_banned.guid, characters.slot, character_declinedname.genitive"
Field* fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
+ ObjectGuid guid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ std::string name = fields[1].GetString();
uint8 plrRace = fields[2].GetUInt8();
uint8 plrClass = fields[3].GetUInt8();
uint8 gender = fields[4].GetUInt8();
-
- PlayerInfo const* info = sObjectMgr->GetPlayerInfo(plrRace, plrClass);
- if (!info)
- {
- TC_LOG_ERROR("entities.player.loading", "Player %u has incorrect race/class pair. Don't build enum.", guid);
- return false;
- }
- else if (!IsValidGender(gender))
- {
- TC_LOG_ERROR("entities.player.loading", "Player (%u) has incorrect gender (%u), don't build enum.", guid, gender);
- return false;
- }
-
- *data << uint64(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
- *data << fields[1].GetString(); // name
- *data << uint8(plrRace); // race
- *data << uint8(plrClass); // class
- *data << uint8(gender); // gender
-
- uint32 playerBytes = fields[5].GetUInt32();
- *data << uint8(playerBytes); // skin
- *data << uint8(playerBytes >> 8); // face
- *data << uint8(playerBytes >> 16); // hair style
- *data << uint8(playerBytes >> 24); // hair color
-
- uint32 playerBytes2 = fields[6].GetUInt32();
- *data << uint8(playerBytes2 & 0xFF); // facial hair
-
- *data << uint8(fields[7].GetUInt8()); // level
- *data << uint32(fields[8].GetUInt16()); // zone
- *data << uint32(fields[9].GetUInt16()); // map
-
- *data << fields[10].GetFloat(); // x
- *data << fields[11].GetFloat(); // y
- *data << fields[12].GetFloat(); // z
-
- *data << uint32(fields[13].GetUInt32()); // guild id
+ uint8 skin = uint8(fields[5].GetUInt32() & 0xFF);
+ uint8 face = uint8((fields[5].GetUInt32() >> 8) & 0xFF);
+ uint8 hairStyle = uint8((fields[5].GetUInt32() >> 16) & 0xFF);
+ uint8 hairColor = uint8((fields[5].GetUInt32() >> 24) & 0xFF);
+ uint8 facialHair = uint8(fields[6].GetUInt32() & 0xFF);
+ uint8 level = fields[7].GetUInt8();
+ uint32 zone = fields[8].GetUInt16();
+ uint32 mapId = uint32(fields[9].GetUInt16());
+ float x = fields[10].GetFloat();
+ float y = fields[11].GetFloat();
+ float z = fields[12].GetFloat();
+ uint32 guildId = fields[13].GetUInt32();
+ ObjectGuid guildGuid = MAKE_NEW_GUID(guildId, 0, guildId ? uint32(HIGHGUID_GUILD) : 0);
+ uint32 playerFlags = fields[14].GetUInt32();
+ uint32 atLoginFlags = fields[15].GetUInt16();
+ Tokenizer equipment(fields[19].GetString(), ' ');
+ uint8 slot = fields[21].GetUInt8();
uint32 charFlags = 0;
- uint32 playerFlags = fields[14].GetUInt32();
- uint16 atLoginFlags = fields[15].GetUInt16();
if (playerFlags & PLAYER_FLAGS_HIDE_HELM)
charFlags |= CHARACTER_FLAG_HIDE_HELM;
+
if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK)
charFlags |= CHARACTER_FLAG_HIDE_CLOAK;
+
if (playerFlags & PLAYER_FLAGS_GHOST)
charFlags |= CHARACTER_FLAG_GHOST;
+
if (atLoginFlags & AT_LOGIN_RENAME)
charFlags |= CHARACTER_FLAG_RENAME;
+
if (fields[20].GetUInt32())
charFlags |= CHARACTER_FLAG_LOCKED_BY_BILLING;
- if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED))
- {
- if (!fields[21].GetString().empty())
- charFlags |= CHARACTER_FLAG_DECLINED;
- }
- else
- charFlags |= CHARACTER_FLAG_DECLINED;
- *data << uint32(charFlags); // character flags
+ if (sWorld->getBoolConfig(CONFIG_DECLINED_NAMES_USED) && !fields[22].GetString().empty())
+ charFlags |= CHARACTER_FLAG_DECLINED;
- // character customize flags
+ uint32 customizationFlag = 0;
if (atLoginFlags & AT_LOGIN_CUSTOMIZE)
- *data << uint32(CHAR_CUSTOMIZE_FLAG_CUSTOMIZE);
+ customizationFlag = CHAR_CUSTOMIZE_FLAG_CUSTOMIZE;
else if (atLoginFlags & AT_LOGIN_CHANGE_FACTION)
- *data << uint32(CHAR_CUSTOMIZE_FLAG_FACTION);
+ customizationFlag = CHAR_CUSTOMIZE_FLAG_FACTION;
else if (atLoginFlags & AT_LOGIN_CHANGE_RACE)
- *data << uint32(CHAR_CUSTOMIZE_FLAG_RACE);
- else
- *data << uint32(CHAR_CUSTOMIZE_FLAG_NONE);
+ customizationFlag = CHAR_CUSTOMIZE_FLAG_RACE;
- // First login
- *data << uint8(atLoginFlags & AT_LOGIN_FIRST ? 1 : 0);
-
- // Pets info
uint32 petDisplayId = 0;
- uint32 petLevel = 0;
- uint32 petFamily = 0;
-
+ uint32 petLevel = 0;
+ uint32 petFamily = 0;
// show pet at selection character in character list only for non-ghost character
if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT))
{
@@ -2017,32 +1993,48 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
if (creatureInfo)
{
petDisplayId = fields[17].GetUInt32();
- petLevel = fields[18].GetUInt16();
- petFamily = creatureInfo->family;
- }
- }
-
- *data << uint32(petDisplayId);
- *data << uint32(petLevel);
- *data << uint32(petFamily);
-
- Tokenizer equipment(fields[19].GetString(), ' ');
+ petLevel = fields[18].GetUInt16();
+ petFamily = creatureInfo->family;
+ }
+ }
+
+ // Packet content flags
+ bitBuffer->WriteBit(guid[3]);
+ bitBuffer->WriteBit(guildGuid[1]);
+ bitBuffer->WriteBit(guildGuid[7]);
+ bitBuffer->WriteBit(guildGuid[2]);
+ bitBuffer->WriteBits(uint32(name.length()), 7);
+ bitBuffer->WriteBit(guid[4]);
+ bitBuffer->WriteBit(guid[7]);
+ bitBuffer->WriteBit(guildGuid[3]);
+ bitBuffer->WriteBit(guid[5]);
+ bitBuffer->WriteBit(guildGuid[6]);
+ bitBuffer->WriteBit(guid[1]);
+ bitBuffer->WriteBit(guildGuid[5]);
+ bitBuffer->WriteBit(guildGuid[4]);
+ bitBuffer->WriteBit(atLoginFlags & AT_LOGIN_FIRST);
+ bitBuffer->WriteBit(guid[0]);
+ bitBuffer->WriteBit(guid[2]);
+ bitBuffer->WriteBit(guid[6]);
+ bitBuffer->WriteBit(guildGuid[0]);
+
+ // Character data
+ *dataBuffer << uint8(plrClass); // Class
for (uint8 slot = 0; slot < INVENTORY_SLOT_BAG_END; ++slot)
{
- uint32 visualBase = slot * 2;
- uint32 itemId = GetUInt32ValueFromArray(equipment, visualBase);
+ uint32 visualbase = slot * 2;
+ uint32 itemId = GetUInt32ValueFromArray(equipment, visualbase);
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
if (!proto)
{
- *data << uint32(0);
- *data << uint8(0);
- *data << uint32(0);
+ *dataBuffer << uint8(0);
+ *dataBuffer << uint32(0);
+ *dataBuffer << uint32(0);
continue;
}
SpellItemEnchantmentEntry const* enchant = NULL;
-
- uint32 enchants = GetUInt32ValueFromArray(equipment, visualBase + 1);
+ uint32 enchants = GetUInt32ValueFromArray(equipment, visualbase + 1);
for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot)
{
// values stored in 2 uint16
@@ -2055,11 +2047,47 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data)
break;
}
- *data << uint32(proto->DisplayInfoID);
- *data << uint8(proto->InventoryType);
- *data << uint32(enchant ? enchant->aura_id : 0);
- }
-
+ *dataBuffer << uint8(proto->InventoryType);
+ *dataBuffer << uint32(proto->DisplayInfoID);
+ *dataBuffer << uint32(enchant ? enchant->aura_id : 0);
+ }
+
+ *dataBuffer << uint32(petFamily); // Pet family
+ dataBuffer->WriteByteSeq(guildGuid[2]);
+ *dataBuffer << uint8(slot); // List order
+ *dataBuffer << uint8(hairStyle); // Hair style
+ dataBuffer->WriteByteSeq(guildGuid[3]);
+ *dataBuffer << uint32(petDisplayId); // Pet DisplayID
+ *dataBuffer << uint32(charFlags); // Character flags
+ *dataBuffer << uint8(hairColor); // Hair color
+ dataBuffer->WriteByteSeq(guid[4]);
+ *dataBuffer << uint32(mapId); // Map Id
+ dataBuffer->WriteByteSeq(guildGuid[5]);
+ *dataBuffer << float(z); // Z
+ dataBuffer->WriteByteSeq(guildGuid[6]);
+ *dataBuffer << uint32(petLevel); // Pet level
+ dataBuffer->WriteByteSeq(guid[3]);
+ *dataBuffer << float(y); // Y
+ *dataBuffer << uint32(customizationFlag); // Character customization flags
+ *dataBuffer << uint8(facialHair); // Facial hair
+ dataBuffer->WriteByteSeq(guid[7]);
+ *dataBuffer << uint8(gender); // Gender
+ dataBuffer->append(name.c_str(), name.length()); // Name
+ *dataBuffer << uint8(face); // Face
+ dataBuffer->WriteByteSeq(guid[0]);
+ dataBuffer->WriteByteSeq(guid[2]);
+ dataBuffer->WriteByteSeq(guildGuid[1]);
+ dataBuffer->WriteByteSeq(guildGuid[7]);
+ *dataBuffer << float(x); // X
+ *dataBuffer << uint8(skin); // Skin
+ *dataBuffer << uint8(plrRace); // Race
+ *dataBuffer << uint8(level); // Level
+ dataBuffer->WriteByteSeq(guid[6]);
+ dataBuffer->WriteByteSeq(guildGuid[4]);
+ dataBuffer->WriteByteSeq(guildGuid[0]);
+ dataBuffer->WriteByteSeq(guid[5]);
+ dataBuffer->WriteByteSeq(guid[1]);
+ *dataBuffer << uint32(zone); // Zone id
return true;
}
@@ -2093,15 +2121,6 @@ uint8 Player::GetChatTag() const
return tag;
}
-void Player::SendTeleportAckPacket()
-{
- WorldPacket data(MSG_MOVE_TELEPORT_ACK, 41);
- data.append(GetPackGUID());
- data << uint32(0); // this value increments every time
- BuildMovementPacket(&data);
- GetSession()->SendPacket(&data);
-}
-
bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options)
{
if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation))
@@ -2137,7 +2156,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.transport.Reset();
+ m_movementInfo.ResetTransport();
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
}
@@ -2153,17 +2172,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// reset movement flags at teleport, because player will continue move with these flags after teleport
SetUnitMovementFlags(GetUnitMovementFlags() & MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE);
+ m_movementInfo.ResetJump();
DisableSpline();
if (m_transport)
{
- if (options & TELE_TO_NOT_LEAVE_TRANSPORT)
- AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
- else
+ if (!(options & TELE_TO_NOT_LEAVE_TRANSPORT))
{
m_transport->RemovePassenger(this);
m_transport = NULL;
- m_movementInfo.transport.Reset();
+ m_movementInfo.ResetTransport();
}
}
@@ -2205,9 +2223,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
SetFallInformation(0, z);
// code for finish transfer called in WorldSession::HandleMovementOpcodes()
- // at client packet MSG_MOVE_TELEPORT_ACK
+ // at client packet CMSG_MOVE_TELEPORT_ACK
SetSemaphoreTeleportNear(true);
- // near teleport, triggering send MSG_MOVE_TELEPORT_ACK from client at landing
+ // near teleport, triggering send CMSG_MOVE_TELEPORT_ACK from client at landing
if (!GetSession()->PlayerLogout())
{
Position oldPos;
@@ -2215,7 +2233,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
if (HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
z += GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
Relocate(x, y, z, orientation);
- SendTeleportAckPacket();
SendTeleportPacket(oldPos); // this automatically relocates to oldPos in order to broadcast the packet in the right place
}
}
@@ -2299,10 +2316,16 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
{
// send transfer packets
WorldPacket data(SMSG_TRANSFER_PENDING, 4 + 4 + 4);
- data << uint32(mapid);
+ data.WriteBit(0); // unknown
if (m_transport)
- data << m_transport->GetEntry() << GetMapId();
+ {
+ data.WriteBit(1); // has transport
+ data << GetMapId() << m_transport->GetEntry();
+ }
+ else
+ data.WriteBit(0); // has transport
+ data << uint32(mapid);
GetSession()->SendPacket(&data);
}
@@ -2318,11 +2341,11 @@ 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);
- if (m_transport)
- data << m_movementInfo.transport.pos.PositionXYZOStream();
- else
- data << m_teleport_dest.PositionXYZOStream();
+ data << float(m_teleport_dest.GetPositionY());
GetSession()->SendPacket(&data);
SendSavedInstances();
@@ -2363,18 +2386,22 @@ void Player::ProcessDelayedOperations()
{
ResurrectPlayer(0.0f, false);
- if (GetMaxHealth() > m_resurrectHealth)
- SetHealth(m_resurrectHealth);
+ if (GetMaxHealth() > _resurrectionData->Health)
+ SetHealth(_resurrectionData->Health);
else
SetFullHealth();
- if (GetMaxPower(POWER_MANA) > m_resurrectMana)
- SetPower(POWER_MANA, m_resurrectMana);
+ if (uint32(GetMaxPower(POWER_MANA)) > _resurrectionData->Mana)
+ SetPower(POWER_MANA, _resurrectionData->Mana);
else
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
SetPower(POWER_RAGE, 0);
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
+ SetPower(POWER_ECLIPSE, 0);
+
+ if (uint32 aura = _resurrectionData->Aura)
+ CastSpell(this, aura, true, NULL, NULL, _resurrectionData->GUID);
SpawnCorpseBones();
}
@@ -2473,15 +2500,40 @@ void Player::RegenerateAll()
m_regenTimerCount += m_regenTimer;
- Regenerate(POWER_ENERGY);
+ if (getClass() == CLASS_PALADIN)
+ m_holyPowerRegenTimerCount += m_regenTimer;
+ if (getClass() == CLASS_HUNTER)
+ m_focusRegenTimerCount += m_regenTimer;
+
+ Regenerate(POWER_ENERGY);
Regenerate(POWER_MANA);
// Runes act as cooldowns, and they don't need to send any data
if (getClass() == CLASS_DEATH_KNIGHT)
- for (uint8 i = 0; i < MAX_RUNES; ++i)
- if (uint32 cd = GetRuneCooldown(i))
- SetRuneCooldown(i, (cd > m_regenTimer) ? cd - m_regenTimer : 0);
+ {
+ for (uint8 i = 0; i < MAX_RUNES; i += 2)
+ {
+ uint8 runeToRegen = i;
+ uint32 cd = GetRuneCooldown(i);
+ uint32 secondRuneCd = GetRuneCooldown(i + 1);
+ // Regenerate second rune of the same type only after first rune is off the cooldown
+ if (secondRuneCd && (cd > secondRuneCd || !cd))
+ {
+ runeToRegen = i + 1;
+ cd = secondRuneCd;
+ }
+
+ if (cd)
+ SetRuneCooldown(runeToRegen, (cd > m_regenTimer) ? cd - m_regenTimer : 0);
+ }
+ }
+
+ if (m_focusRegenTimerCount >= 1000 && getClass() == CLASS_HUNTER)
+ {
+ Regenerate(POWER_FOCUS);
+ m_focusRegenTimerCount -= 1000;
+ }
if (m_regenTimerCount >= 2000)
{
@@ -2500,6 +2552,12 @@ void Player::RegenerateAll()
m_regenTimerCount -= 2000;
}
+ if (m_holyPowerRegenTimerCount >= 10000 && getClass() == CLASS_PALADIN)
+ {
+ Regenerate(POWER_HOLY_POWER);
+ m_holyPowerRegenTimerCount -= 10000;
+ }
+
m_regenTimer = 0;
}
@@ -2515,33 +2573,44 @@ void Player::Regenerate(Powers power)
if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power))
return;
+ // Skip regeneration for power type we cannot have
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS)
+ return;
+
float addvalue = 0.0f;
+ // Powers now benefit from haste.
+ float rangedHaste = GetFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE);
+ float meleeHaste = GetFloatValue(PLAYER_FIELD_MOD_HASTE);
+ float spellHaste = GetFloatValue(UNIT_MOD_CAST_SPEED);
+
switch (power)
{
case POWER_MANA:
{
- bool recentCast = IsUnderLastManaUseEffect();
float ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA);
- if (getLevel() < 15)
- ManaIncreaseRate = sWorld->getRate(RATE_POWER_MANA) * (2.066f - (getLevel() * 0.066f));
-
- if (recentCast) // Trinity Updates Mana in intervals of 2s, which is correct
- addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
+ if (IsInCombat()) // Trinity Updates Mana in intervals of 2s, which is correct
+ addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste));
else
- addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
- } break;
- case POWER_RAGE: // Regenerate rage
+ addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * ((0.001f * m_regenTimer) + CalculatePct(0.001f, spellHaste));
+ }
+ break;
+ case POWER_RAGE: // Regenerate rage
{
if (!IsInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
{
float RageDecreaseRate = sWorld->getRate(RATE_POWER_RAGE_LOSS);
- addvalue += -20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec)
+ addvalue += -25 * RageDecreaseRate / meleeHaste; // 2.5 rage by tick (= 2 seconds => 1.25 rage/sec)
}
- } break;
- case POWER_ENERGY: // Regenerate energy (rogue)
- addvalue += 0.01f * m_regenTimer * sWorld->getRate(RATE_POWER_ENERGY);
+ }
+ break;
+ case POWER_FOCUS:
+ addvalue += (6.0f + CalculatePct(6.0f, rangedHaste)) * sWorld->getRate(RATE_POWER_FOCUS);
+ break;
+ case POWER_ENERGY: // Regenerate energy (rogue)
+ addvalue += ((0.01f * m_regenTimer) + CalculatePct(0.01f, meleeHaste)) * sWorld->getRate(RATE_POWER_ENERGY);
break;
case POWER_RUNIC_POWER:
{
@@ -2550,10 +2619,15 @@ void Player::Regenerate(Powers power)
float RunicPowerDecreaseRate = sWorld->getRate(RATE_POWER_RUNICPOWER_LOSS);
addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
}
- } break;
- case POWER_RUNE:
- case POWER_FOCUS:
- case POWER_HAPPINESS:
+ }
+ break;
+ case POWER_HOLY_POWER: // Regenerate holy power
+ {
+ if (!IsInCombat())
+ addvalue += -1.0f; // remove 1 each 10 sec
+ }
+ break;
+ case POWER_RUNES:
break;
case POWER_HEALTH:
return;
@@ -2587,7 +2661,7 @@ void Player::Regenerate(Powers power)
else
return;
- addvalue += m_powerFraction[power];
+ addvalue += m_powerFraction[powerIndex];
uint32 integerValue = uint32(fabs(addvalue));
if (addvalue < 0.0f)
@@ -2595,12 +2669,12 @@ void Player::Regenerate(Powers power)
if (curValue > integerValue)
{
curValue -= integerValue;
- m_powerFraction[power] = addvalue + integerValue;
+ m_powerFraction[powerIndex] = addvalue + integerValue;
}
else
{
curValue = 0;
- m_powerFraction[power] = 0;
+ m_powerFraction[powerIndex] = 0;
}
}
else
@@ -2610,15 +2684,16 @@ void Player::Regenerate(Powers power)
if (curValue > maxValue)
{
curValue = maxValue;
- m_powerFraction[power] = 0;
+ m_powerFraction[powerIndex] = 0;
}
else
- m_powerFraction[power] = addvalue - integerValue;
+ m_powerFraction[powerIndex] = addvalue - integerValue;
}
+
if (m_regenTimerCount >= 2000)
SetPower(power, curValue);
else
- UpdateUInt32Value(UNIT_FIELD_POWER1 + power, curValue);
+ UpdateUInt32Value(UNIT_FIELD_POWER1 + powerIndex, curValue);
}
void Player::RegenerateHealth()
@@ -2630,10 +2705,6 @@ void Player::RegenerateHealth()
return;
float HealthIncreaseRate = sWorld->getRate(RATE_HEALTH);
-
- if (getLevel() < 15)
- HealthIncreaseRate = sWorld->getRate(RATE_HEALTH) * (2.066f - (getLevel() * 0.066f));
-
float addValue = 0.0f;
// polymorphed case
@@ -2642,9 +2713,15 @@ void Player::RegenerateHealth()
// normal regen case (maybe partly in combat case)
else if (!IsInCombat() || HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
{
- addValue = OCTRegenHPPerSpirit() * HealthIncreaseRate;
+ addValue = HealthIncreaseRate;
+
if (!IsInCombat())
{
+ if (getLevel() < 15)
+ addValue = (0.20f * ((float)GetMaxHealth()) / getLevel() * HealthIncreaseRate);
+ else
+ addValue = 0.015f * ((float)GetMaxHealth()) * HealthIncreaseRate;
+
AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
AddPct(addValue, (*i)->GetAmount());
@@ -2685,6 +2762,9 @@ void Player::ResetAllPowers()
case POWER_RUNIC_POWER:
SetPower(POWER_RUNIC_POWER, 0);
break;
+ case POWER_ECLIPSE:
+ SetPower(POWER_ECLIPSE, 0);
+ break;
default:
break;
}
@@ -2826,18 +2906,6 @@ void Player::SetGameMaster(bool on)
}
else
{
- // restore phase
- uint32 newPhase = 0;
- AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
- if (!phases.empty())
- for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
- newPhase |= (*itr)->GetMiscValue();
-
- if (!newPhase)
- newPhase = PHASEMASK_NORMAL;
-
- SetPhaseMask(newPhase, false);
-
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
setFactionForRace(getRace());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
@@ -2858,6 +2926,9 @@ void Player::SetGameMaster(bool on)
getHostileRefManager().setOnlineOfflineState(true);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER);
+
+ phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
+ phaseMgr.Update();
}
UpdateObjectVisibility();
@@ -3028,23 +3099,21 @@ void Player::GiveLevel(uint8 level)
PlayerLevelInfo info;
sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), level, &info);
- PlayerClassLevelInfo classInfo;
- sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, &classInfo);
+ uint32 basehp = 0, basemana = 0;
+ sObjectMgr->GetPlayerClassLevelInfo(getClass(), level, basehp, basemana);
// send levelup info to client
- WorldPacket data(SMSG_LEVELUP_INFO, (4+4+MAX_POWERS*4+MAX_STATS*4));
+ WorldPacket data(SMSG_LEVELUP_INFO, (4+4+MAX_POWERS_PER_CLASS*4+MAX_STATS*4));
data << uint32(level);
- data << uint32(int32(classInfo.basehealth) - int32(GetCreateHealth()));
- // for (int i = 0; i < MAX_POWERS; ++i) // Powers loop (0-6)
- data << uint32(int32(classInfo.basemana) - int32(GetCreateMana()));
- data << uint32(0);
- data << uint32(0);
+ data << uint32(int32(basehp) - int32(GetCreateHealth()));
+ // for (int i = 0; i < MAX_STORED_POWERS; ++i) // Powers loop (0-10)
+ data << uint32(int32(basemana) - int32(GetCreateMana()));
data << uint32(0);
data << uint32(0);
data << uint32(0);
data << uint32(0);
// end for
- for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4)
+ for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4)
data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i)));
GetSession()->SendPacket(&data);
@@ -3064,8 +3133,8 @@ void Player::GiveLevel(uint8 level)
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
SetCreateStat(Stats(i), info.stats[i]);
- SetCreateHealth(classInfo.basehealth);
- SetCreateMana(classInfo.basemana);
+ SetCreateHealth(basehp);
+ SetCreateMana(basemana);
InitTalentForLevel();
InitTaxiNodesForLevel();
@@ -3076,6 +3145,8 @@ void Player::GiveLevel(uint8 level)
if (sWorld->getBoolConfig(CONFIG_ALWAYS_MAXSKILL)) // Max weapon skill when leveling up
UpdateSkillsToMaxSkillsForLevel();
+ _ApplyAllLevelScaleItemMods(true); // Moved to above SetFullHealth so player will have full health from Heirlooms
+
// set current level health and mana/energy to maximum after applying all mods.
SetFullHealth();
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
@@ -3083,9 +3154,6 @@ void Player::GiveLevel(uint8 level)
if (GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE))
SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE));
SetPower(POWER_FOCUS, 0);
- SetPower(POWER_HAPPINESS, 0);
-
- _ApplyAllLevelScaleItemMods(true);
// update level to hunter/summon pet
if (Pet* pet = GetPet())
@@ -3101,6 +3169,11 @@ void Player::GiveLevel(uint8 level)
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
+ PhaseUpdateData phaseUpdateData;
+ phaseUpdateData.AddConditionType(CONDITION_LEVEL);
+
+ phaseMgr.NotifyConditionChanged(phaseUpdateData);
+
// Refer-A-Friend
if (GetSession()->GetRecruiterId())
if (level < sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
@@ -3122,33 +3195,33 @@ void Player::InitTalentForLevel()
if (level < 10)
{
// Remove all talent points
- if (m_usedTalentCount > 0) // Free any used talents
+ if (GetUsedTalentCount() > 0) // Free any used talents
{
- resetTalents(true); /// @todo: Has to (collectively) be renamed to ResetTalents
+ ResetTalents(true);
SetFreeTalentPoints(0);
}
}
else
{
- if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || m_specsCount == 0)
+ if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || GetSpecsCount() == 0)
{
- m_specsCount = 1;
- m_activeSpec = 0;
+ SetSpecsCount(1);
+ SetActiveSpec(0);
}
uint32 talentPointsForLevel = CalculateTalentsPoints();
// if used more that have then reset
- if (m_usedTalentCount > talentPointsForLevel)
+ if (GetUsedTalentCount() > talentPointsForLevel)
{
if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED))
- resetTalents(true);
+ ResetTalents(true);
else
SetFreeTalentPoints(0);
}
// else update amount of free points
else
- SetFreeTalentPoints(talentPointsForLevel - m_usedTalentCount);
+ SetFreeTalentPoints(talentPointsForLevel - GetUsedTalentCount());
}
if (!GetSession()->PlayerLoading())
@@ -3160,8 +3233,8 @@ void Player::InitStatsForLevel(bool reapplyMods)
if (reapplyMods) //reapply stats values only on .reset stats (level) command
_RemoveAllStatBonuses();
- PlayerClassLevelInfo classInfo;
- sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), &classInfo);
+ uint32 basehp = 0, basemana = 0;
+ sObjectMgr->GetPlayerClassLevelInfo(getClass(), getLevel(), basehp, basemana);
PlayerLevelInfo info;
sObjectMgr->GetPlayerLevelInfo(getRace(), getClass(), getLevel(), &info);
@@ -3176,6 +3249,9 @@ void Player::InitStatsForLevel(bool reapplyMods)
// set default cast time multiplier
SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);
+ SetFloatValue(UNIT_MOD_CAST_HASTE, 1.0f);
+ SetFloatValue(PLAYER_FIELD_MOD_HASTE, 1.0f);
+ SetFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE, 1.0f);
// reset size before reapply auras
SetObjectScale(1.0f);
@@ -3187,10 +3263,10 @@ void Player::InitStatsForLevel(bool reapplyMods)
for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i)
SetStat(Stats(i), info.stats[i]);
- SetCreateHealth(classInfo.basehealth);
+ SetCreateHealth(basehp);
//set create powers
- SetCreateMana(classInfo.basemana);
+ SetCreateMana(basemana);
SetArmor(int32(m_createStats[STAT_AGILITY]*2));
@@ -3201,13 +3277,17 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetUInt32Value(index, 0);
SetUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, 0);
+ SetFloatValue(PLAYER_FIELD_MOD_HEALING_PCT, 1.0f);
+ SetFloatValue(PLAYER_FIELD_MOD_HEALING_DONE_PCT, 1.0f);
for (uint8 i = 0; i < 7; ++i)
{
SetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i, 0);
SetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i, 0);
- SetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i, 1.00f);
+ SetFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i, 1.0f);
}
+ SetFloatValue(PLAYER_FIELD_MOD_SPELL_POWER_PCT, 1.0f);
+
//reset attack power, damage and attack speed fields
SetFloatValue(UNIT_FIELD_BASEATTACKTIME, 2000.0f);
SetFloatValue(UNIT_FIELD_BASEATTACKTIME + 1, 2000.0f); // offhand attack time
@@ -3219,12 +3299,11 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(UNIT_FIELD_MAXOFFHANDDAMAGE, 0.0f);
SetFloatValue(UNIT_FIELD_MINRANGEDDAMAGE, 0.0f);
SetFloatValue(UNIT_FIELD_MAXRANGEDDAMAGE, 0.0f);
+ SetFloatValue(PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS, 1.0f);
SetInt32Value(UNIT_FIELD_ATTACK_POWER, 0);
- SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, 0);
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, 0.0f);
SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0);
- SetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS, 0);
SetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER, 0.0f);
// Base crit values (will be recalculated in UpdateAllStats() at loading and in _ApplyAllStatBonuses() at reset
@@ -3238,7 +3317,9 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetFloatValue(PLAYER_PARRY_PERCENTAGE, 0.0f);
SetFloatValue(PLAYER_BLOCK_PERCENTAGE, 0.0f);
- SetUInt32Value(PLAYER_SHIELD_BLOCK, 0);
+
+ // Static 30% damage blocked
+ SetUInt32Value(PLAYER_SHIELD_BLOCK, 30);
// Dodge percentage
SetFloatValue(PLAYER_DODGE_PERCENTAGE, 0.0f);
@@ -3270,9 +3351,9 @@ void Player::InitStatsForLevel(bool reapplyMods)
// save new stats
for (uint8 i = POWER_MANA; i < MAX_POWERS; ++i)
- SetMaxPower(Powers(i), uint32(GetCreatePowers(Powers(i))));
+ SetMaxPower(Powers(i), GetCreatePowers(Powers(i)));
- SetMaxHealth(classInfo.basehealth); // stamina bonus will applied later
+ SetMaxHealth(basehp); // stamina bonus will applied later
// cleanup mounted state (it will set correctly at aura loading if player saved at mount.
SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
@@ -3307,8 +3388,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
if (GetPower(POWER_RAGE) > GetMaxPower(POWER_RAGE))
SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE));
- SetPower(POWER_FOCUS, 0);
- SetPower(POWER_HAPPINESS, 0);
+ SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS));
SetPower(POWER_RUNIC_POWER, 0);
// update level to hunter/summon pet
@@ -3340,7 +3420,7 @@ void Player::SendInitialSpells()
data << uint32(itr->first);
data << uint16(0); // it's not slot id
- spellCount +=1;
+ ++spellCount;
}
data.put<uint16>(countPos, spellCount); // write real count value
@@ -3355,7 +3435,7 @@ void Player::SendInitialSpells()
data << uint32(itr->first);
- data << uint16(itr->second.itemid); // cast item id
+ data << uint32(itr->second.itemid); // cast item id
data << uint16(sEntry->GetCategory()); // spell category
// send infinity cooldown in special format
@@ -3401,15 +3481,15 @@ void Player::RemoveMail(uint32 id)
void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError, uint32 item_guid, uint32 item_count)
{
WorldPacket data(SMSG_SEND_MAIL_RESULT, (4+4+4+(mailError == MAIL_ERR_EQUIP_ERROR?4:(mailAction == MAIL_ITEM_TAKEN?4+4:0))));
- data << (uint32) mailId;
- data << (uint32) mailAction;
- data << (uint32) mailError;
+ data << uint32(mailId);
+ data << uint32(mailAction);
+ data << uint32(mailError);
if (mailError == MAIL_ERR_EQUIP_ERROR)
- data << (uint32) equipError;
+ data << uint32(equipError);
else if (mailAction == MAIL_ITEM_TAKEN)
{
- data << (uint32) item_guid; // item guid low?
- data << (uint32) item_count; // item count?
+ data << uint32(item_guid); // item guid low?
+ data << uint32(item_count); // item count?
}
GetSession()->SendPacket(&data);
}
@@ -3501,8 +3581,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
return false;
}
- PlayerTalentMap::iterator itr = m_talents[spec]->find(spellId);
- if (itr != m_talents[spec]->end())
+ PlayerTalentMap::iterator itr = GetTalentMap(spec)->find(spellId);
+ if (itr != GetTalentMap(spec)->end())
itr->second->state = PLAYERSPELL_UNCHANGED;
else if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
{
@@ -3515,8 +3595,8 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
if (!rankSpellId || rankSpellId == spellId)
continue;
- itr = m_talents[spec]->find(rankSpellId);
- if (itr != m_talents[spec]->end())
+ itr = GetTalentMap(spec)->find(rankSpellId);
+ if (itr != GetTalentMap(spec)->end())
itr->second->state = PLAYERSPELL_REMOVED;
}
}
@@ -3527,7 +3607,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
newtalent->state = state;
newtalent->spec = spec;
- (*m_talents[spec])[spellId] = newtalent;
+ (*GetTalentMap(spec))[spellId] = newtalent;
return true;
}
return false;
@@ -3796,7 +3876,7 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent
}
// update used talent points count
- m_usedTalentCount += talentCost;
+ SetUsedTalentCount(GetUsedTalentCount() + talentCost);
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
@@ -3836,12 +3916,6 @@ bool Player::addSpell(uint32 spellId, bool active, bool learning, bool dependent
if (!pSkill)
continue;
- if (!Has310Flyer(false) && pSkill->id == SKILL_MOUNTS)
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED &&
- spellInfo->Effects[i].CalcValue() == 310)
- SetHas310Flyer(true);
-
if (HasSkill(pSkill->id))
continue;
@@ -3932,10 +4006,21 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const
bool need_cast = (!spellInfo->Stances || (form && (spellInfo->Stances & (1 << (form - 1)))) ||
(!form && (spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT)));
+ if (spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION)
+ need_cast &= IsCurrentSpecMasterySpell(spellInfo);
+
//Check CasterAuraStates
return need_cast && (!spellInfo->CasterAuraState || HasAuraState(AuraStateType(spellInfo->CasterAuraState)));
}
+bool Player::IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const
+{
+ if (TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ return spellInfo->Id == talentTab->MasterySpellId[0] || spellInfo->Id == talentTab->MasterySpellId[1];
+
+ return false;
+}
+
void Player::learnSpell(uint32 spell_id, bool dependent)
{
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
@@ -3948,9 +4033,9 @@ void Player::learnSpell(uint32 spell_id, bool dependent)
// prevent duplicated entires in spell book, also not send if not in world (loading)
if (learning && IsInWorld())
{
- WorldPacket data(SMSG_LEARNED_SPELL, 6);
+ WorldPacket data(SMSG_LEARNED_SPELL, 8);
data << uint32(spell_id);
- data << uint16(0);
+ data << uint32(0);
GetSession()->SendPacket(&data);
}
@@ -4032,10 +4117,10 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
uint32 talentCosts = GetTalentSpellCost(spell_id);
if (talentCosts > 0 && giveTalentPoints)
{
- if (talentCosts < m_usedTalentCount)
- m_usedTalentCount -= talentCosts;
+ if (talentCosts < GetUsedTalentCount())
+ SetUsedTalentCount(GetUsedTalentCount() - talentCosts);
else
- m_usedTalentCount = 0;
+ SetUsedTalentCount(0);
}
// update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning)
@@ -4106,16 +4191,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
SetSkill(pSkill->id, GetSkillStep(pSkill->id), 0, 0);
}
-
- // most likely will never be used, haven't heard of cases where players unlearn a mount
- if (Has310Flyer(false) && _spell_idx->second->skillId == SKILL_MOUNTS)
- {
- if (spellInfo)
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED &&
- spellInfo->Effects[i].CalcValue() == 310)
- Has310Flyer(true, spell_id); // with true as first argument its also used to set/remove the flag
- }
}
}
@@ -4171,8 +4246,19 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
if (spell_id == 46917 && m_canTitanGrip)
SetCanTitanGrip(false);
- if (spell_id == 674 && m_canDualWield)
- SetCanDualWield(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 (sWorld->getBoolConfig(CONFIG_OFFHAND_CHECK_AT_SPELL_UNLEARN))
AutoUnequipOffhandIfNeed();
@@ -4186,40 +4272,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
}
}
-bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId)
-{
- if (!checkAllSpells)
- return m_ExtraFlags & PLAYER_EXTRA_HAS_310_FLYER;
- else
- {
- SetHas310Flyer(false);
- SpellInfo const* spellInfo;
- for (PlayerSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
- {
- if (itr->first == excludeSpellId)
- continue;
-
- SkillLineAbilityMapBounds bounds = sSpellMgr->GetSkillLineAbilityMapBounds(itr->first);
- for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx)
- {
- if (_spell_idx->second->skillId != SKILL_MOUNTS)
- break; // We can break because mount spells belong only to one skillline (at least 310 flyers do)
-
- spellInfo = sSpellMgr->GetSpellInfo(itr->first);
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED &&
- spellInfo->Effects[i].CalcValue() == 310)
- {
- SetHas310Flyer(true);
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
void Player::RemoveSpellCooldown(uint32 spell_id, bool update /* = false */)
{
m_spellCooldowns.erase(spell_id);
@@ -4290,9 +4342,7 @@ void Player::RemoveAllSpellCooldown()
{
if (!m_spellCooldowns.empty())
{
- for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
- SendClearCooldown(itr->first, this);
-
+ SendClearAllCooldowns(this);
m_spellCooldowns.clear();
}
}
@@ -4370,31 +4420,31 @@ void Player::_SaveSpellCooldowns(SQLTransaction& trans)
trans->Append(ss.str().c_str());
}
-uint32 Player::resetTalentsCost() const
+uint32 Player::GetNextResetTalentsCost() const
{
// The first time reset costs 1 gold
- if (m_resetTalentsCost < 1*GOLD)
+ if (GetTalentResetCost() < 1*GOLD)
return 1*GOLD;
// then 5 gold
- else if (m_resetTalentsCost < 5*GOLD)
+ else if (GetTalentResetCost() < 5*GOLD)
return 5*GOLD;
// After that it increases in increments of 5 gold
- else if (m_resetTalentsCost < 10*GOLD)
+ else if (GetTalentResetCost() < 10*GOLD)
return 10*GOLD;
else
{
- uint64 months = (sWorld->GetGameTime() - m_resetTalentsTime)/MONTH;
+ uint64 months = (sWorld->GetGameTime() - GetTalentResetTime())/MONTH;
if (months > 0)
{
// This cost will be reduced by a rate of 5 gold per month
- int32 new_cost = int32(m_resetTalentsCost - 5*GOLD*months);
+ int32 new_cost = int32(GetTalentResetCost() - 5*GOLD*months);
// to a minimum of 10 gold.
return (new_cost < 10*GOLD ? 10*GOLD : new_cost);
}
else
{
// After that it increases in increments of 5 gold
- int32 new_cost = m_resetTalentsCost + 5*GOLD;
+ int32 new_cost = GetTalentResetCost() + 5*GOLD;
// until it hits a cap of 50 gold.
if (new_cost > 50*GOLD)
new_cost = 50*GOLD;
@@ -4403,7 +4453,7 @@ uint32 Player::resetTalentsCost() const
}
}
-bool Player::resetTalents(bool no_cost)
+bool Player::ResetTalents(bool no_cost)
{
sScriptMgr->OnPlayerTalentsReset(this, no_cost);
@@ -4413,7 +4463,7 @@ bool Player::resetTalents(bool no_cost)
uint32 talentPointsForLevel = CalculateTalentsPoints();
- if (m_usedTalentCount == 0)
+ if (!GetUsedTalentCount())
{
SetFreeTalentPoints(talentPointsForLevel);
return false;
@@ -4423,9 +4473,9 @@ bool Player::resetTalents(bool no_cost)
if (!no_cost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST))
{
- cost = resetTalentsCost();
+ cost = GetNextResetTalentsCost();
- if (!HasEnoughMoney(cost))
+ if (!HasEnoughMoney(uint64(cost)))
{
SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
return false;
@@ -4466,27 +4516,43 @@ bool Player::resetTalents(bool no_cost)
if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
removeSpell(_spellEntry->Effects[i].TriggerSpell, true);
// if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
- PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
- if (plrTalent != m_talents[m_activeSpec]->end())
+ PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->RankID[rank]);
+ if (plrTalent != GetTalentMap(GetActiveSpec())->end())
plrTalent->second->state = PLAYERSPELL_REMOVED;
}
}
+ // Remove spec specific spells
+ uint32 const* talentTabs = GetTalentTabPages(getClass());
+ for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
+ {
+ if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentTabs[i]))
+ for (size_t j = 0; j < specSpells->size(); ++j)
+ removeSpell(specSpells->at(j), true);
+
+ TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabs[i]);
+ for (uint32 j = 0; j < MAX_MASTERY_SPELLS; ++j)
+ if (uint32 mastery = talentTabInfo->MasterySpellId[j])
+ RemoveAurasDueToSpell(mastery);
+ }
+
+
+ SetPrimaryTalentTree(GetActiveSpec(), 0);
+ SetFreeTalentPoints(talentPointsForLevel);
+
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveTalents(trans);
_SaveSpells(trans);
CharacterDatabase.CommitTransaction(trans);
- SetFreeTalentPoints(talentPointsForLevel);
-
if (!no_cost)
{
- ModifyMoney(-(int32)cost);
+ ModifyMoney(-(int64)cost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS, cost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1);
- m_resetTalentsCost = cost;
- m_resetTalentsTime = time(NULL);
+ SetTalentResetCost(cost);
+ SetTalentResetTime(time(NULL));
}
/* when prev line will dropped use next line
@@ -4500,12 +4566,6 @@ bool Player::resetTalents(bool no_cost)
return true;
}
-void Player::SetFreeTalentPoints(uint32 points)
-{
- sScriptMgr->OnPlayerFreeTalentPointsChanged(this, points);
- SetUInt32Value(PLAYER_CHARACTER_POINTS1, points);
-}
-
Mail* Player::GetMail(uint32 id)
{
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
@@ -4534,13 +4594,6 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
}
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- {
- if (m_items[i] == NULL)
- continue;
-
- m_items[i]->BuildCreateUpdateBlockForPlayer(data, target);
- }
}
Unit::BuildCreateUpdateBlockForPlayer(data, target);
@@ -4567,13 +4620,6 @@ void Player::DestroyForPlayer(Player* target, bool onDeath) const
m_items[i]->DestroyForPlayer(target);
}
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- {
- if (m_items[i] == NULL)
- continue;
-
- m_items[i]->DestroyForPlayer(target);
- }
}
}
@@ -4586,8 +4632,8 @@ bool Player::HasSpell(uint32 spell) const
bool Player::HasTalent(uint32 spell, uint8 spec) const
{
- PlayerTalentMap::const_iterator itr = m_talents[spec]->find(spell);
- return (itr != m_talents[spec]->end() && itr->second->state != PLAYERSPELL_REMOVED);
+ PlayerTalentMap::const_iterator itr = GetTalentMap(spec)->find(spell);
+ return (itr != GetTalentMap(spec)->end() && itr->second->state != PLAYERSPELL_REMOVED);
}
bool Player::HasActiveSpell(uint32 spell) const
@@ -4746,7 +4792,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
uint32 sender = mailFields[3].GetUInt32();
std::string subject = mailFields[4].GetString();
std::string body = mailFields[5].GetString();
- uint32 money = mailFields[6].GetUInt32();
+ uint64 money = mailFields[6].GetUInt64();
bool has_items = mailFields[7].GetBool();
// We can return mail now
@@ -5048,24 +5094,6 @@ void Player::DeleteOldCharacters(uint32 keepDays)
}
}
-void Player::SetMovement(PlayerMovementType pType)
-{
- WorldPacket data;
- switch (pType)
- {
- case MOVE_ROOT: data.Initialize(SMSG_FORCE_MOVE_ROOT, GetPackGUID().size()+4); break;
- case MOVE_UNROOT: data.Initialize(SMSG_FORCE_MOVE_UNROOT, GetPackGUID().size()+4); break;
- case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_WATER_WALK, GetPackGUID().size()+4); break;
- case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_LAND_WALK, GetPackGUID().size()+4); break;
- default:
- TC_LOG_ERROR("entities.player", "Player::SetMovement: Unsupported move type (%d), data not sent to client.", pType);
- return;
- }
- data.append(GetPackGUID());
- data << uint32(0);
- GetSession()->SendPacket(&data);
-}
-
/* Preconditions:
- a resurrectable corpse must not be loaded for the player (only bones)
- the player must be in world
@@ -5104,9 +5132,9 @@ void Player::BuildPlayerRepop()
// convert player body to ghost
SetHealth(1);
- SetMovement(MOVE_WATER_WALK);
- if (!GetSession()->isLogingOut())
- SetMovement(MOVE_UNROOT);
+ SetWaterWalking(true);
+ if (!GetSession()->isLogingOut() && !HasUnitState(UNIT_STATE_STUNNED))
+ SetRooted(false);
// BG - remove insignia related
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
@@ -5147,8 +5175,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
setDeathState(ALIVE);
- SetMovement(MOVE_LAND_WALK);
- SetMovement(MOVE_UNROOT);
+ SetWaterWalking(false);
+ if (!HasUnitState(UNIT_STATE_STUNNED))
+ SetRooted(false);
m_deathTimer = 0;
@@ -5159,6 +5188,8 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
SetPower(POWER_MANA, uint32(GetMaxPower(POWER_MANA)*restore_percent));
SetPower(POWER_RAGE, 0);
SetPower(POWER_ENERGY, uint32(GetMaxPower(POWER_ENERGY)*restore_percent));
+ SetPower(POWER_FOCUS, uint32(GetMaxPower(POWER_FOCUS)*restore_percent));
+ SetPower(POWER_ECLIPSE, 0);
}
// trigger update zone for alive state zone updates
@@ -5208,7 +5239,7 @@ void Player::KillPlayer()
if (IsFlying() && !GetTransport())
GetMotionMaster()->MoveFall();
- SetMovement(MOVE_ROOT);
+ SetRooted(true);
StopMirrorTimers(); //disable timers(bars)
@@ -5274,12 +5305,10 @@ void Player::CreateCorpse()
flags |= CORPSE_FLAG_HIDE_CLOAK;
if (InBattleground() && !InArena())
flags |= CORPSE_FLAG_LOOTABLE; // to be able to remove insignia
- corpse->SetUInt32Value(CORPSE_FIELD_FLAGS, flags);
+ corpse->SetUInt32Value(CORPSE_FIELD_FLAGS, flags);
corpse->SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, GetNativeDisplayId());
- corpse->SetUInt32Value(CORPSE_FIELD_GUILD, GetGuildId());
-
uint32 iDisplayID;
uint32 iIventoryType;
uint32 _cfi;
@@ -5330,9 +5359,6 @@ void Player::DurabilityLossAll(double percent, bool inventory)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
DurabilityLoss(pItem, percent);
- // keys not have durability
- //for (int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
-
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
@@ -5351,6 +5377,8 @@ void Player::DurabilityLoss(Item* item, double percent)
if (!pMaxDurability)
return;
+ percent /= GetTotalAuraMultiplier(SPELL_AURA_MOD_DURABILITY_LOSS);
+
uint32 pDurabilityLoss = uint32(pMaxDurability*percent);
if (pDurabilityLoss < 1)
@@ -5374,9 +5402,6 @@ void Player::DurabilityPointsLossAll(int32 points, bool inventory)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
DurabilityPointsLoss(pItem, points);
- // keys not have durability
- //for (int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
-
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
if (Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
@@ -5495,13 +5520,13 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
TotalCost = costs;
}
- else if (!HasEnoughMoney(costs))
+ else if (!HasEnoughMoney(uint64(costs)))
{
TC_LOG_DEBUG("entities.player.items", "You do not have enough money");
return TotalCost;
}
else
- ModifyMoney(-int32(costs));
+ ModifyMoney(-int64(costs));
}
}
@@ -5522,7 +5547,7 @@ void Player::RepopAtGraveyard()
AreaTableEntry const* zone = GetAreaEntryByAreaID(GetAreaId());
// Such zones are considered unreachable as a ghost and the player must be automatically revived
- if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < -500.0f)
+ if ((!IsAlive() && zone && zone->flags & AREA_FLAG_NEED_FLY) || GetTransport() || GetPositionZ() < (zone ? zone->MaxDepth : -500.0f))
{
ResurrectPlayer(0.5f);
SpawnCorpseBones();
@@ -5548,7 +5573,8 @@ void Player::RepopAtGraveyard()
// and don't show spirit healer location
if (ClosestGrave)
{
- TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, GetOrientation());
+ float const* orientation = sObjectMgr->GetGraveyardOrientation(ClosestGrave->ID);
+ TeleportTo(ClosestGrave->map_id, ClosestGrave->x, ClosestGrave->y, ClosestGrave->z, orientation ? *orientation : GetOrientation());
if (isDead()) // not send if alive, because it used in TeleportTo()
{
WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // show spirit healer position on minimap
@@ -5559,7 +5585,7 @@ void Player::RepopAtGraveyard()
GetSession()->SendPacket(&data);
}
}
- else if (GetPositionZ() < -500.0f)
+ else if (GetPositionZ() < zone->MaxDepth)
TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation());
}
@@ -5613,7 +5639,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
if (!cMgr)
return;
- std::string current_zone_name = current_zone->area_name[GetSession()->GetSessionDbcLocale()];
+ std::string current_zone_name = current_zone->area_name;
for (uint32 i = 0; i < sChatChannelsStore.GetNumRows(); ++i)
{
@@ -5649,7 +5675,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
else
currentNameExt = current_zone_name.c_str();
- snprintf(new_channel_name_buf, 100, channel->pattern[m_session->GetSessionDbcLocale()], currentNameExt);
+ snprintf(new_channel_name_buf, 100, channel->pattern, currentNameExt);
joinChannel = cMgr->GetJoinChannel(new_channel_name_buf, channel->ChannelID);
if (usedChannel)
@@ -5664,7 +5690,7 @@ void Player::UpdateLocalChannels(uint32 newZone)
}
}
else
- joinChannel = cMgr->GetJoinChannel(channel->pattern[m_session->GetSessionDbcLocale()], channel->ChannelID);
+ joinChannel = cMgr->GetJoinChannel(channel->pattern, channel->ChannelID);
}
else
removeChannel = usedChannel;
@@ -5695,12 +5721,6 @@ void Player::LeaveLFGChannel()
}
}
-void Player::UpdateDefense()
-{
- if (UpdateSkill(SKILL_DEFENSE, sWorld->getIntConfig(CONFIG_SKILL_GAIN_DEFENSE)))
- UpdateDefenseBonusesMod(); // update dependent from defense skill part
-}
-
void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, float amount, bool apply)
{
if (modGroup >= BASEMOD_END || modType >= MOD_END)
@@ -5722,7 +5742,6 @@ void Player::HandleBaseModValue(BaseModGroup modGroup, BaseModType modType, floa
case CRIT_PERCENTAGE: UpdateCritPercentage(BASE_ATTACK); break;
case RANGED_CRIT_PERCENTAGE: UpdateCritPercentage(RANGED_ATTACK); break;
case OFFHAND_CRIT_PERCENTAGE: UpdateCritPercentage(OFF_ATTACK); break;
- case SHIELD_BLOCK_VALUE: UpdateShieldBlockValue(); break;
default: break;
}
}
@@ -5755,15 +5774,6 @@ float Player::GetTotalBaseModValue(BaseModGroup modGroup) const
return m_auraBaseMod[modGroup][FLAT_MOD] * m_auraBaseMod[modGroup][PCT_MOD];
}
-uint32 Player::GetShieldBlockValue() const
-{
- float value = (m_auraBaseMod[SHIELD_BLOCK_VALUE][FLAT_MOD] + GetStat(STAT_STRENGTH) * 0.5f - 10)*m_auraBaseMod[SHIELD_BLOCK_VALUE][PCT_MOD];
-
- value = (value < 0) ? 0 : value;
-
- return uint32(value);
-}
-
float Player::GetMeleeCritFromAgility()
{
uint8 level = getLevel();
@@ -5786,17 +5796,17 @@ void Player::GetDodgeFromAgility(float &diminishing, float &nondiminishing)
// Table for base dodge values
const float dodge_base[MAX_CLASSES] =
{
- 0.036640f, // Warrior
- 0.034943f, // Paladin
- -0.040873f, // Hunter
- 0.020957f, // Rogue
- 0.034178f, // Priest
+ 0.037580f, // Warrior
+ 0.036520f, // Paladin
+ -0.054500f, // Hunter
+ -0.005900f, // Rogue
+ 0.031830f, // Priest
0.036640f, // DK
- 0.021080f, // Shaman
- 0.036587f, // Mage
- 0.024211f, // Warlock
+ 0.016750f, // Shaman
+ 0.034575f, // Mage
+ 0.020350f, // Warlock
0.0f, // ??
- 0.056097f // Druid
+ 0.049510f // Druid
};
// Crit/agility to dodge/agility coefficient multipliers; 3.2.0 increased required agility by 15%
const float crit_to_dodge[MAX_CLASSES] =
@@ -5842,13 +5852,13 @@ float Player::GetSpellCritFromIntellect()
if (level > GT_MAX_LEVEL)
level = GT_MAX_LEVEL;
- GtChanceToSpellCritBaseEntry const* critBase = sGtChanceToSpellCritBaseStore.LookupEntry(pclass-1);
- GtChanceToSpellCritEntry const* critRatio = sGtChanceToSpellCritStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
+ GtChanceToSpellCritBaseEntry const* critBase = sGtChanceToSpellCritBaseStore.LookupEntry(pclass - 1);
+ GtChanceToSpellCritEntry const* critRatio = sGtChanceToSpellCritStore.LookupEntry((pclass - 1) * GT_MAX_LEVEL + level - 1);
if (critBase == NULL || critRatio == NULL)
return 0.0f;
- float crit=critBase->base + GetStat(STAT_INTELLECT)*critRatio->ratio;
- return crit*100.0f;
+ float crit = critBase->base + GetStat(STAT_INTELLECT) * critRatio->ratio;
+ return crit * 100.0f;
}
float Player::GetRatingMultiplier(CombatRating cr) const
@@ -5869,7 +5879,10 @@ float Player::GetRatingMultiplier(CombatRating cr) const
float Player::GetRatingBonusValue(CombatRating cr) const
{
- return float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) * GetRatingMultiplier(cr);
+ float baseResult = float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) * GetRatingMultiplier(cr);
+ if (cr != CR_RESILIENCE_PLAYER_DAMAGE_TAKEN)
+ return baseResult;
+ return float(1.0f - pow(0.99f, baseResult)) * 100.0f;
}
float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
@@ -5886,29 +5899,6 @@ float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
return 0.0f;
}
-float Player::OCTRegenHPPerSpirit()
-{
- uint8 level = getLevel();
- uint32 pclass = getClass();
-
- if (level > GT_MAX_LEVEL)
- level = GT_MAX_LEVEL;
-
- GtOCTRegenHPEntry const* baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- GtRegenHPPerSptEntry const* moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1);
- if (baseRatio == NULL || moreRatio == NULL)
- return 0.0f;
-
- // Formula from PaperDollFrame script
- float spirit = GetStat(STAT_SPIRIT);
- float baseSpirit = spirit;
- if (baseSpirit > 50)
- baseSpirit = 50;
- float moreSpirit = spirit - baseSpirit;
- float regen = baseSpirit * baseRatio->ratio + moreSpirit * moreRatio->ratio;
- return regen;
-}
-
float Player::OCTRegenMPPerSpirit()
{
uint8 level = getLevel();
@@ -5930,7 +5920,7 @@ float Player::OCTRegenMPPerSpirit()
void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
{
- m_baseRatingValue[cr]+=(apply ? value : -value);
+ m_baseRatingValue[cr] +=(apply ? value : -value);
// explicit affected values
switch (cr)
@@ -5940,18 +5930,18 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
float RatingChange = value * GetRatingMultiplier(cr);
ApplyAttackTimePercentMod(BASE_ATTACK, RatingChange, apply);
ApplyAttackTimePercentMod(OFF_ATTACK, RatingChange, apply);
+ if (getClass() == CLASS_DEATH_KNIGHT)
+ UpdateAllRunesRegen();
break;
}
case CR_HASTE_RANGED:
{
- float RatingChange = value * GetRatingMultiplier(cr);
- ApplyAttackTimePercentMod(RANGED_ATTACK, RatingChange, apply);
+ ApplyAttackTimePercentMod(RANGED_ATTACK, value * GetRatingMultiplier(cr), apply);
break;
}
case CR_HASTE_SPELL:
{
- float RatingChange = value * GetRatingMultiplier(cr);
- ApplyCastTimePercentMod(RatingChange, apply);
+ ApplyCastTimePercentMod(value * GetRatingMultiplier(cr), apply);
break;
}
default:
@@ -5978,9 +5968,8 @@ void Player::UpdateRating(CombatRating cr)
switch (cr)
{
- case CR_WEAPON_SKILL: // Implemented in Unit::RollMeleeOutcomeAgainst
+ case CR_WEAPON_SKILL:
case CR_DEFENSE_SKILL:
- UpdateDefenseBonusesMod();
break;
case CR_DODGE:
UpdateDodgePercentage();
@@ -6015,15 +6004,12 @@ void Player::UpdateRating(CombatRating cr)
if (affectStats)
UpdateAllSpellCritChances();
break;
- case CR_HIT_TAKEN_MELEE: // Implemented in Unit::MeleeMissChanceCalc
- case CR_HIT_TAKEN_RANGED:
- break;
- case CR_HIT_TAKEN_SPELL: // Implemented in Unit::MagicSpellHitResult
- break;
- case CR_CRIT_TAKEN_MELEE: // Implemented in Unit::RollMeleeOutcomeAgainst (only for chance to crit)
- case CR_CRIT_TAKEN_RANGED:
- break;
- case CR_CRIT_TAKEN_SPELL: // Implemented in Unit::SpellCriticalBonus (only for chance to crit)
+ case CR_HIT_TAKEN_MELEE: // Deprecated since Cataclysm
+ case CR_HIT_TAKEN_RANGED: // Deprecated since Cataclysm
+ case CR_HIT_TAKEN_SPELL: // Deprecated since Cataclysm
+ case CR_RESILIENCE_PLAYER_DAMAGE_TAKEN:
+ case CR_RESILIENCE_CRIT_TAKEN:
+ case CR_CRIT_TAKEN_SPELL: // Deprecated since Cataclysm
break;
case CR_HASTE_MELEE: // Implemented in Player::ApplyRatingMod
case CR_HASTE_RANGED:
@@ -6044,6 +6030,9 @@ void Player::UpdateRating(CombatRating cr)
if (affectStats)
UpdateArmorPenetration(amount);
break;
+ case CR_MASTERY:
+ UpdateMastery();
+ break;
}
}
@@ -6082,23 +6071,25 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return false;
- uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
- uint32 data = GetUInt32Value(valueIndex);
- uint32 value = SKILL_VALUE(data);
- uint32 max = SKILL_MAX(data);
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
+
+ uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
+ uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
- if ((!max) || (!value) || (value >= max))
+ if (!max || !value || value >= max)
return false;
if (value < max)
{
- uint32 new_value = value+step;
+ uint16 new_value = value + step;
if (new_value > max)
new_value = max;
- SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(new_value, max));
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, new_value);
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_CHANGED;
+
UpdateSkillEnchantments(skill_id, value, new_value);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skill_id);
return true;
@@ -6191,129 +6182,65 @@ bool Player::UpdateFishingSkill()
return UpdateSkillPro(SKILL_FISHING, chance*10, gathering_skill_gain);
}
-// levels sync. with spell requirement for skill levels to learn
-// bonus abilities in sSkillLineAbilityStore
-// Used only to avoid scan DBC at each skill grow
-static uint32 bonusSkillLevels[ ] = {75, 150, 225, 300, 375, 450};
-static const size_t bonusSkillLevelsSize = sizeof(bonusSkillLevels) / sizeof(uint32);
-
-bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)
+bool Player::UpdateSkillPro(uint16 skillId, int32 chance, uint32 step)
{
- TC_LOG_DEBUG("entities.player.skills", "UpdateSkillPro(SkillId %d, Chance %3.1f%%)", SkillId, Chance / 10.0f);
- if (!SkillId)
+ // levels sync. with spell requirement for skill levels to learn
+ // bonus abilities in sSkillLineAbilityStore
+ // Used only to avoid scan DBC at each skill grow
+ static uint32 bonusSkillLevels[] = { 75, 150, 225, 300, 375, 450, 525 };
+ static const size_t bonusSkillLevelsSize = sizeof(bonusSkillLevels) / sizeof(uint32);
+
+ TC_LOG_DEBUG("entities.player.skills", "UpdateSkillPro(SkillId %d, Chance %3.1f%%)", skillId, chance / 10.0f);
+ if (!skillId)
return false;
- if (Chance <= 0) // speedup in 0 chance case
+ if (chance <= 0) // speedup in 0 chance case
{
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", Chance / 10.0f);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", chance / 10.0f);
return false;
}
- SkillStatusMap::iterator itr = mSkillStatus.find(SkillId);
+ SkillStatusMap::iterator itr = mSkillStatus.find(skillId);
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return false;
- uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
- uint32 data = GetUInt32Value(valueIndex);
- uint16 SkillValue = SKILL_VALUE(data);
- uint16 MaxValue = SKILL_MAX(data);
+ uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
+ uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
- if (!MaxValue || !SkillValue || SkillValue >= MaxValue)
+ if (!max || !value || value >= max)
return false;
- int32 Roll = irand(1, 1000);
-
- if (Roll <= Chance)
+ if (irand(1, 1000) > chance)
{
- uint32 new_value = SkillValue+step;
- if (new_value > MaxValue)
- new_value = MaxValue;
-
- SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(new_value, MaxValue));
- if (itr->second.uState != SKILL_NEW)
- itr->second.uState = SKILL_CHANGED;
- for (size_t i = 0; i < bonusSkillLevelsSize; ++i)
- {
- uint32 bsl = bonusSkillLevels[i];
- if (SkillValue < bsl && new_value >= bsl)
- {
- learnSkillRewardedSpells(SkillId, new_value);
- break;
- }
- }
- UpdateSkillEnchantments(SkillId, SkillValue, new_value);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, SkillId);
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% taken", Chance / 10.0f);
- return true;
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", chance / 10.0f);
+ return false;
}
- TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% missed", Chance / 10.0f);
- return false;
-}
-
-void Player::UpdateWeaponSkill(WeaponAttackType attType)
-{
- // no skill gain in pvp
- Unit* victim = GetVictim();
- if (victim && victim->GetTypeId() == TYPEID_PLAYER)
- return;
+ uint16 new_value = value + step;
+ if (new_value > max)
+ new_value = max;
- if (IsInFeralForm())
- return; // always maximized SKILL_FERAL_COMBAT in fact
-
- if (GetShapeshiftForm() == FORM_TREE)
- return; // use weapon but not skill up
-
- if (victim && victim->GetTypeId() == TYPEID_UNIT && (victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_SKILLGAIN))
- return;
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, new_value);
+ if (itr->second.uState != SKILL_NEW)
+ itr->second.uState = SKILL_CHANGED;
- uint32 weapon_skill_gain = sWorld->getIntConfig(CONFIG_SKILL_GAIN_WEAPON);
-
- Item* tmpitem = GetWeaponForAttack(attType, true);
- if (!tmpitem && attType == BASE_ATTACK)
- UpdateSkill(SKILL_UNARMED, weapon_skill_gain);
- else if (tmpitem && tmpitem->GetTemplate()->SubClass != ITEM_SUBCLASS_WEAPON_FISHING_POLE)
- UpdateSkill(tmpitem->GetSkill(), weapon_skill_gain);
-
- UpdateAllCritPercentages();
-}
-
-void Player::UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence)
-{
- uint8 plevel = getLevel(); // if defense than victim == attacker
- uint8 greylevel = Trinity::XP::GetGrayLevel(plevel);
- uint8 moblevel = victim->getLevelForTarget(this);
- if (moblevel < greylevel)
- return;
-
- if (moblevel > plevel + 5)
- moblevel = plevel + 5;
-
- uint8 lvldif = moblevel - greylevel;
- if (lvldif < 3)
- lvldif = 3;
-
- uint32 skilldif = 5 * plevel - (defence ? GetBaseDefenseSkillValue() : GetBaseWeaponSkillValue(attType));
- if (skilldif <= 0)
- return;
-
- float chance = float(3 * lvldif * skilldif) / plevel;
- if (!defence)
- if (getClass() == CLASS_WARRIOR || getClass() == CLASS_ROGUE)
- chance += chance * 0.02f * GetStat(STAT_INTELLECT);
-
- chance = chance < 1.0f ? 1.0f : chance; //minimum chance to increase skill is 1%
-
- if (roll_chance_f(chance))
+ for (size_t i = 0; i < bonusSkillLevelsSize; ++i)
{
- if (defence)
- UpdateDefense();
- else
- UpdateWeaponSkill(attType);
+ uint32 bsl = bonusSkillLevels[i];
+ if (value < bsl && new_value >= bsl)
+ {
+ learnSkillRewardedSpells(skillId, new_value);
+ break;
+ }
}
- else
- return;
+
+ UpdateSkillEnchantments(skillId, value, new_value);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, skillId);
+ TC_LOG_DEBUG("entities.player.skills", "Player::UpdateSkillPro Chance=%3.1f%% taken", chance / 10.0f);
+ return true;
}
void Player::ModifySkillBonus(uint32 skillid, int32 val, bool talent)
@@ -6322,25 +6249,18 @@ void Player::ModifySkillBonus(uint32 skillid, int32 val, bool talent)
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return;
- uint32 bonusIndex = PLAYER_SKILL_BONUS_INDEX(itr->second.pos);
+ uint16 field = itr->second.pos / 2 + (talent ? PLAYER_SKILL_TALENT_0 : PLAYER_SKILL_MODIFIER_0);
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
- uint32 bonus_val = GetUInt32Value(bonusIndex);
- int16 temp_bonus = SKILL_TEMP_BONUS(bonus_val);
- int16 perm_bonus = SKILL_PERM_BONUS(bonus_val);
+ uint16 bonus = GetUInt16Value(field, offset);
- if (talent) // permanent bonus stored in high part
- SetUInt32Value(bonusIndex, MAKE_SKILL_BONUS(temp_bonus, perm_bonus+val));
- else // temporary/item bonus stored in low part
- SetUInt32Value(bonusIndex, MAKE_SKILL_BONUS(temp_bonus+val, perm_bonus));
+ SetUInt16Value(field, offset, bonus + val);
}
void Player::UpdateSkillsForLevel()
{
- uint16 maxconfskill = sWorld->GetConfigMaxSkillValue();
uint32 maxSkill = GetMaxSkillValueForLevel();
- bool alwaysMaxSkill = sWorld->getBoolConfig(CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL);
-
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end(); ++itr)
{
if (itr->second.uState == SKILL_DELETED)
@@ -6354,27 +6274,22 @@ void Player::UpdateSkillsForLevel()
if (GetSkillRangeType(pSkill, false) != SKILL_RANGE_LEVEL)
continue;
- uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
- uint32 data = GetUInt32Value(valueIndex);
- uint32 max = SKILL_MAX(data);
- uint32 val = SKILL_VALUE(data);
+ if (IsWeaponSkill(pSkill->id))
+ continue;
+
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
+
+ //uint16 val = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
+ uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
/// update only level dependent max skill values
if (max != 1)
{
- /// maximize skill always
- if (alwaysMaxSkill)
- {
- SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(maxSkill, maxSkill));
- if (itr->second.uState != SKILL_NEW)
- itr->second.uState = SKILL_CHANGED;
- }
- else if (max != maxconfskill) /// update max skill value if current max skill not maximized
- {
- SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(val, maxSkill));
- if (itr->second.uState != SKILL_NEW)
- itr->second.uState = SKILL_CHANGED;
- }
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, maxSkill);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxSkill);
+ if (itr->second.uState != SKILL_NEW)
+ itr->second.uState = SKILL_CHANGED;
}
}
}
@@ -6389,18 +6304,22 @@ void Player::UpdateSkillsToMaxSkillsForLevel()
uint32 pskill = itr->first;
if (IsProfessionOrRidingSkill(pskill))
continue;
- uint32 valueIndex = PLAYER_SKILL_VALUE_INDEX(itr->second.pos);
- uint32 data = GetUInt32Value(valueIndex);
- uint32 max = SKILL_MAX(data);
+
+ if (IsWeaponSkill(pskill))
+ continue;
+
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
+
+ uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
if (max > 1)
{
- SetUInt32Value(valueIndex, MAKE_SKILL_VALUE(max, max));
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, max);
+
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_CHANGED;
}
- if (pskill == SKILL_DEFENSE)
- UpdateDefenseBonusesMod();
}
}
@@ -6417,22 +6336,29 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
//has skill
if (itr != mSkillStatus.end() && itr->second.uState != SKILL_DELETED)
{
- currVal = SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1; // itr->second.pos % 2
+ currVal = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
if (newVal)
{
// if skill value is going down, update enchantments before setting the new value
if (newVal < currVal)
UpdateSkillEnchantments(id, currVal, newVal);
+
// update step
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_PAIR32(id, step));
+ SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step);
// update value
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), MAKE_SKILL_VALUE(newVal, maxVal));
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, newVal);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxVal);
+
if (itr->second.uState != SKILL_NEW)
itr->second.uState = SKILL_CHANGED;
+
learnSkillRewardedSpells(id, newVal);
// if skill value is going up, update enchantments after setting the new value
if (newVal > currVal)
UpdateSkillEnchantments(id, currVal, newVal);
+
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
}
@@ -6441,9 +6367,12 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
//remove enchantments needing this skill
UpdateSkillEnchantments(id, currVal, 0);
// clear skill fields
- SetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos), 0);
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos), 0);
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos), 0);
+ SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0);
// mark as deleted or simply remove from map if not saved yet
if (itr->second.uState != SKILL_NEW)
@@ -6456,54 +6385,77 @@ void Player::SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal)
if (SkillLineAbilityEntry const* pAbility = sSkillLineAbilityStore.LookupEntry(j))
if (pAbility->skillId == id)
removeSpell(sSpellMgr->GetFirstSpellInChain(pAbility->spellId));
+
+ // Clear profession lines
+ if (GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1) == id)
+ SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1, 0);
+ else if (GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + 1) == id)
+ SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + 1, 0);
}
}
else if (newVal) //add
{
currVal = 0;
- for (int i=0; i < PLAYER_MAX_SKILLS; ++i)
- if (!GetUInt32Value(PLAYER_SKILL_INDEX(i)))
+ for (uint32 i = 0; i < PLAYER_MAX_SKILLS; ++i)
{
- SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(id);
- if (!pSkill)
+ uint16 field = i / 2;
+ uint8 offset = i & 1; // i % 2
+
+ if (!GetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset))
{
- TC_LOG_ERROR("entities.player.skills", "Skill not found in SkillLineStore: skill #%u", id);
- return;
- }
+ SkillLineEntry const* skillEntry = sSkillLineStore.LookupEntry(id);
+ if (!skillEntry)
+ {
+ TC_LOG_ERROR("misc", "Skill not found in SkillLineStore: skill #%u", id);
+ return;
+ }
- SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id, step));
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i), MAKE_SKILL_VALUE(newVal, maxVal));
- UpdateSkillEnchantments(id, currVal, newVal);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
+ SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, id);
+ if (skillEntry->categoryId == SKILL_CATEGORY_PROFESSION)
+ {
+ if (!GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1))
+ SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1, id);
+ else if (!GetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + 1))
+ SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + 1, id);
+ }
- // insert new entry or update if not deleted old entry yet
- if (itr != mSkillStatus.end())
- {
- itr->second.pos = i;
- itr->second.uState = SKILL_CHANGED;
- }
- else
- mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW)));
+ SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step);
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, newVal);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, maxVal);
+
+ UpdateSkillEnchantments(id, currVal, newVal);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL, id);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL, id);
- // apply skill bonuses
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i), 0);
+ // insert new entry or update if not deleted old entry yet
+ if (itr != mSkillStatus.end())
+ {
+ itr->second.pos = i;
+ itr->second.uState = SKILL_CHANGED;
+ }
+ else
+ mSkillStatus.insert(SkillStatusMap::value_type(id, SkillStatusData(i, SKILL_NEW)));
+
+ // apply skill bonuses
+ SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0);
- // temporary bonuses
- AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL);
- for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j)
- if ((*j)->GetMiscValue() == int32(id))
+ // temporary bonuses
+ AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL);
+ for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j)
+ if ((*j)->GetMiscValue() == int32(id))
(*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
- // permanent bonuses
- AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT);
- for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j)
- if ((*j)->GetMiscValue() == int32(id))
+ // permanent bonuses
+ AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT);
+ for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j)
+ if ((*j)->GetMiscValue() == int32(id))
(*j)->HandleEffect(this, AURA_EFFECT_HANDLE_SKILL, true);
- // Learn all spells for skill
- learnSkillRewardedSpells(id, newVal);
- return;
+ // Learn all spells for skill
+ learnSkillRewardedSpells(id, newVal);
+ return;
+ }
}
}
}
@@ -6526,7 +6478,7 @@ uint16 Player::GetSkillStep(uint16 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- return PAIR32_HIPART(GetUInt32Value(PLAYER_SKILL_INDEX(itr->second.pos)));
+ return GetUInt16Value(PLAYER_SKILL_STEP_0 + itr->second.pos / 2, itr->second.pos & 1);
}
uint16 Player::GetSkillValue(uint32 skill) const
@@ -6538,11 +6490,12 @@ uint16 Player::GetSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
- int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
- result += SKILL_TEMP_BONUS(bonus);
- result += SKILL_PERM_BONUS(bonus);
+ int32 result = int32(GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset));
+ result += int32(GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset));
+ result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset));
return result < 0 ? 0 : result;
}
@@ -6555,11 +6508,12 @@ uint16 Player::GetMaxSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- uint32 bonus = GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
- int32 result = int32(SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
- result += SKILL_TEMP_BONUS(bonus);
- result += SKILL_PERM_BONUS(bonus);
+ int32 result = int32(GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset));
+ result += int32(GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset));
+ result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset));
return result < 0 ? 0 : result;
}
@@ -6572,7 +6526,10 @@ uint16 Player::GetPureMaxSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- return SKILL_MAX(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ return GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
}
uint16 Player::GetBaseSkillValue(uint32 skill) const
@@ -6584,8 +6541,11 @@ uint16 Player::GetBaseSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- int32 result = int32(SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos))));
- result += SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ int32 result = int32(GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset));
+ result += int32(GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset));
return result < 0 ? 0 : result;
}
@@ -6598,7 +6558,10 @@ uint16 Player::GetPureSkillValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- return SKILL_VALUE(GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ return GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
}
int16 Player::GetSkillPermBonusValue(uint32 skill) const
@@ -6610,7 +6573,10 @@ int16 Player::GetSkillPermBonusValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- return SKILL_PERM_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ return GetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset);
}
int16 Player::GetSkillTempBonusValue(uint32 skill) const
@@ -6622,17 +6588,19 @@ int16 Player::GetSkillTempBonusValue(uint32 skill) const
if (itr == mSkillStatus.end() || itr->second.uState == SKILL_DELETED)
return 0;
- return SKILL_TEMP_BONUS(GetUInt32Value(PLAYER_SKILL_BONUS_INDEX(itr->second.pos)));
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ return GetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset);
}
void Player::SendActionButtons(uint32 state) const
{
WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4));
- data << uint8(state);
/*
state can be 0, 1, 2
- 0 - Looks to be sent when initial action buttons get sent, however on Trinity we use 1 since 0 had some difficulties
- 1 - Used in any SMSG_ACTION_BUTTONS packet with button data on Trinity. Only used after spec swaps on retail.
+ 0 - Sends initial action buttons, client does not validate if we have the spell or not
+ 1 - Used used after spec swaps, client validates if a spell is known.
2 - Clears the action bars client sided. This is sent during spec swap before unlearning and before sending the new buttons
*/
if (state != 2)
@@ -6646,9 +6614,12 @@ void Player::SendActionButtons(uint32 state) const
data << uint32(0);
}
}
+ else
+ data.resize(MAX_ACTION_BUTTONS * 4); // insert crap, client doesnt even parse this for state == 2
+ data << uint8(state);
GetSession()->SendPacket(&data);
- TC_LOG_INFO("network", "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUIDLow(), m_activeSpec);
+ TC_LOG_INFO("network", "Action Buttons for '%u' spec '%u' Sent", GetGUIDLow(), GetActiveSpec());
}
bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
@@ -6691,6 +6662,7 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type)
case ACTION_BUTTON_CMACRO:
case ACTION_BUTTON_MACRO:
case ACTION_BUTTON_EQSET:
+ case ACTION_BUTTON_DROPDOWN:
break;
default:
TC_LOG_ERROR("entities.player", "Unknown action type %u", type);
@@ -7115,16 +7087,12 @@ void Player::UpdateHonorFields()
// update yesterday's contribution
if (m_lastHonorUpdateTime >= yesterday)
{
- SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION));
-
// this is the first update today, reset today's contribution
- SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
SetUInt32Value(PLAYER_FIELD_KILLS, MAKE_PAIR32(0, kills_today));
}
else
{
// no honor/kills yesterday or today, reset
- SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
SetUInt32Value(PLAYER_FIELD_KILLS, 0);
}
}
@@ -7216,7 +7184,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, 0, victim);
}
else
{
@@ -7253,9 +7221,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
GetSession()->SendPacket(&data);
// add honor points
- ModifyHonorPoints(honor);
-
- ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, honor, true);
+ ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, int32(honor));
if (InBattleground() && honor > 0)
{
@@ -7290,82 +7256,441 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
return true;
}
-void Player::SetHonorPoints(uint32 value)
+
+void Player::_LoadCurrency(PreparedQueryResult result)
{
- if (value > sWorld->getIntConfig(CONFIG_MAX_HONOR_POINTS))
- value = sWorld->getIntConfig(CONFIG_MAX_HONOR_POINTS);
- SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, value);
- if (value)
- AddKnownCurrency(ITEM_HONOR_POINTS_ID);
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint16 currencyID = fields[0].GetUInt16();
+
+ CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(currencyID);
+ if (!currency)
+ continue;
+
+ PlayerCurrency cur;
+ cur.state = PLAYERCURRENCY_UNCHANGED;
+ cur.weekCount = fields[1].GetUInt32();
+ cur.totalCount = fields[2].GetUInt32();
+
+ _currencyStorage.insert(PlayerCurrenciesMap::value_type(currencyID, cur));
+
+ } while (result->NextRow());
}
-void Player::SetArenaPoints(uint32 value)
+void Player::_SaveCurrency(SQLTransaction& trans)
{
- if (value > sWorld->getIntConfig(CONFIG_MAX_ARENA_POINTS))
- value = sWorld->getIntConfig(CONFIG_MAX_ARENA_POINTS);
- SetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY, value);
- if (value)
- AddKnownCurrency(ITEM_ARENA_POINTS_ID);
+ PreparedStatement* stmt = NULL;
+ for (PlayerCurrenciesMap::iterator itr = _currencyStorage.begin(); itr != _currencyStorage.end(); ++itr)
+ {
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(itr->first);
+ if (!entry) // should never happen
+ continue;
+
+ switch (itr->second.state)
+ {
+ case PLAYERCURRENCY_NEW:
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_PLAYER_CURRENCY);
+ stmt->setUInt32(0, GetGUIDLow());
+ stmt->setUInt16(1, itr->first);
+ stmt->setUInt32(2, itr->second.weekCount);
+ stmt->setUInt32(3, itr->second.totalCount);
+ trans->Append(stmt);
+ break;
+ case PLAYERCURRENCY_CHANGED:
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_PLAYER_CURRENCY);
+ stmt->setUInt32(0, itr->second.weekCount);
+ stmt->setUInt32(1, itr->second.totalCount);
+ stmt->setUInt32(2, GetGUIDLow());
+ stmt->setUInt16(3, itr->first);
+ trans->Append(stmt);
+ break;
+ default:
+ break;
+ }
+
+ itr->second.state = PLAYERCURRENCY_UNCHANGED;
+ }
}
-void Player::ModifyHonorPoints(int32 value, SQLTransaction* trans /*=NULL*/)
+void Player::SendNewCurrency(uint32 id) const
{
- int32 newValue = int32(GetHonorPoints()) + value;
- if (newValue < 0)
- newValue = 0;
- SetHonorPoints(uint32(newValue));
+ PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
+ if (itr == _currencyStorage.end())
+ return;
+
+ ByteBuffer currencyData;
+ WorldPacket packet(SMSG_INIT_CURRENCY, 4 + (5*4 + 1));
+ packet.WriteBits(1, 23);
- if (trans && !trans->null())
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(id);
+ if (!entry) // should never happen
+ return;
+
+ uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+ uint32 weekCount = itr->second.weekCount / precision;
+ uint32 weekCap = GetCurrencyWeekCap(entry) / precision;
+
+ packet.WriteBit(weekCount);
+ packet.WriteBits(0, 4); // some flags
+ packet.WriteBit(weekCap);
+ packet.WriteBit(0); // season total earned
+
+ currencyData << uint32(itr->second.totalCount / precision);
+ if (weekCap)
+ currencyData << uint32(weekCap);
+
+ //if (seasonTotal)
+ // currencyData << uint32(seasonTotal / precision);
+
+ currencyData << uint32(entry->ID);
+ if (weekCount)
+ currencyData << uint32(weekCount);
+
+ packet.FlushBits();
+ packet.append(currencyData);
+ GetSession()->SendPacket(&packet);
+}
+
+void Player::SendCurrencies() const
+{
+ ByteBuffer currencyData;
+ WorldPacket packet(SMSG_INIT_CURRENCY, 4 + _currencyStorage.size()*(5*4 + 1));
+ size_t count_pos = packet.bitwpos();
+ packet.WriteBits(_currencyStorage.size(), 23);
+
+ size_t count = 0;
+ for (PlayerCurrenciesMap::const_iterator itr = _currencyStorage.begin(); itr != _currencyStorage.end(); ++itr)
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_HONOR_POINTS);
- stmt->setUInt32(0, newValue);
- stmt->setUInt32(1, GetGUIDLow());
- (*trans)->Append(stmt);
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(itr->first);
+
+ // not send init meta currencies.
+ if (!entry || entry->Category == CURRENCY_CATEGORY_META_CONQUEST)
+ continue;
+
+ uint32 precision = (entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+ uint32 weekCount = itr->second.weekCount / precision;
+ uint32 weekCap = GetCurrencyWeekCap(entry) / precision;
+
+ packet.WriteBit(weekCount);
+ packet.WriteBits(0, 4); // some flags
+ packet.WriteBit(weekCap);
+ packet.WriteBit(0); // season total earned
+
+ currencyData << uint32(itr->second.totalCount / precision);
+ if (weekCap)
+ currencyData << uint32(weekCap);
+
+ //if (seasonTotal)
+ // currencyData << uint32(seasonTotal / precision);
+
+ currencyData << uint32(entry->ID);
+ if (weekCount)
+ currencyData << uint32(weekCount);
+
+ ++count;
}
+
+ packet.FlushBits();
+ packet.append(currencyData);
+ packet.PutBits(count_pos, count, 23);
+ GetSession()->SendPacket(&packet);
}
-void Player::ModifyArenaPoints(int32 value, SQLTransaction* trans /*=NULL*/)
+void Player::SendPvpRewards() const
{
- int32 newValue = int32(GetArenaPoints()) + value;
- if (newValue < 0)
- newValue = 0;
- SetArenaPoints(uint32(newValue));
+ WorldPacket packet(SMSG_REQUEST_PVP_REWARDS_RESPONSE, 24);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS, true);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_POINTS, true);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA, true);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_RBG, true);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_ARENA, true);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS, true);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, true);
+ GetSession()->SendPacket(&packet);
+}
- if (trans && !trans->null())
+uint32 Player::GetCurrency(uint32 id, bool usePrecision) const
+{
+ PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
+ if (itr == _currencyStorage.end())
+ return 0;
+
+ CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
+ uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+
+ return itr->second.totalCount / precision;
+}
+
+uint32 Player::GetCurrencyOnWeek(uint32 id, bool usePrecision) const
+{
+ PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
+ if (itr == _currencyStorage.end())
+ return 0;
+
+ CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
+ uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+
+ return itr->second.weekCount / precision;
+}
+
+bool Player::HasCurrency(uint32 id, uint32 count) const
+{
+ PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
+ return itr != _currencyStorage.end() && itr->second.totalCount >= count;
+}
+
+void Player::ModifyCurrency(uint32 id, int32 count, bool printLog/* = true*/, bool ignoreMultipliers/* = false*/)
+{
+ if (!count)
+ return;
+
+ CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
+ ASSERT(currency);
+
+ if (!ignoreMultipliers)
+ count *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_CURRENCY_GAIN, id);
+
+ int32 precision = currency->Flags & CURRENCY_FLAG_HIGH_PRECISION ? CURRENCY_PRECISION : 1;
+ uint32 oldTotalCount = 0;
+ uint32 oldWeekCount = 0;
+ PlayerCurrenciesMap::iterator itr = _currencyStorage.find(id);
+ if (itr == _currencyStorage.end())
{
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_ARENA_POINTS);
- stmt->setUInt32(0, newValue);
- stmt->setUInt32(1, GetGUIDLow());
- (*trans)->Append(stmt);
+ PlayerCurrency cur;
+ cur.state = PLAYERCURRENCY_NEW;
+ cur.totalCount = 0;
+ cur.weekCount = 0;
+ _currencyStorage[id] = cur;
+ itr = _currencyStorage.find(id);
+ }
+ else
+ {
+ oldTotalCount = itr->second.totalCount;
+ oldWeekCount = itr->second.weekCount;
+ }
+
+ // count can't be more then weekCap if used (weekCap > 0)
+ uint32 weekCap = GetCurrencyWeekCap(currency);
+ if (weekCap && count > int32(weekCap))
+ count = weekCap;
+
+ // count can't be more then totalCap if used (totalCap > 0)
+ uint32 totalCap = GetCurrencyTotalCap(currency);
+ if (totalCap && count > int32(totalCap))
+ count = totalCap;
+
+ int32 newTotalCount = int32(oldTotalCount) + count;
+ if (newTotalCount < 0)
+ newTotalCount = 0;
+
+ int32 newWeekCount = int32(oldWeekCount) + (count > 0 ? count : 0);
+ if (newWeekCount < 0)
+ newWeekCount = 0;
+
+ // if we get more then weekCap just set to limit
+ if (weekCap && int32(weekCap) < newWeekCount)
+ {
+ newWeekCount = int32(weekCap);
+ // weekCap - oldWeekCount always >= 0 as we set limit before!
+ newTotalCount = oldTotalCount + (weekCap - oldWeekCount);
+ }
+
+ // if we get more then totalCap set to maximum;
+ if (totalCap && int32(totalCap) < newTotalCount)
+ {
+ newTotalCount = int32(totalCap);
+ newWeekCount = weekCap;
+ }
+
+ if (uint32(newTotalCount) != oldTotalCount)
+ {
+ if (itr->second.state != PLAYERCURRENCY_NEW)
+ itr->second.state = PLAYERCURRENCY_CHANGED;
+
+ itr->second.totalCount = newTotalCount;
+ itr->second.weekCount = newWeekCount;
+
+ if (count > 0)
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CURRENCY, id, count);
+
+ if (currency->Category == CURRENCY_CATEGORY_META_CONQUEST)
+ {
+ // count was changed to week limit, now we can modify original points.
+ ModifyCurrency(CURRENCY_TYPE_CONQUEST_POINTS, count, printLog);
+ return;
+ }
+
+ WorldPacket packet(SMSG_UPDATE_CURRENCY, 12);
+
+ packet.WriteBit(weekCap != 0);
+ packet.WriteBit(0); // hasSeasonCount
+ packet.WriteBit(!printLog); // print in log
+
+ // if hasSeasonCount packet << uint32(seasontotalearned); TODO: save this in character DB and use it
+
+ packet << uint32(newTotalCount / precision);
+ packet << uint32(id);
+ if (weekCap)
+ packet << uint32(newWeekCount / precision);
+
+ GetSession()->SendPacket(&packet);
+ }
+}
+
+void Player::SetCurrency(uint32 id, uint32 count, bool /*printLog*/ /*= true*/)
+{
+ PlayerCurrenciesMap::iterator itr = _currencyStorage.find(id);
+ if (itr == _currencyStorage.end())
+ {
+ PlayerCurrency cur;
+ cur.state = PLAYERCURRENCY_NEW;
+ cur.totalCount = count;
+ cur.weekCount = 0;
+ _currencyStorage[id] = cur;
+ }
+}
+
+uint32 Player::GetCurrencyWeekCap(uint32 id, bool usePrecision) const
+{
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(id);
+ if (!entry)
+ return 0;
+
+ uint32 precision = (usePrecision && entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+
+ return GetCurrencyWeekCap(entry) / precision;
+}
+
+void Player::ResetCurrencyWeekCap()
+{
+ for (uint32 arenaSlot = 0; arenaSlot < MAX_ARENA_SLOT; arenaSlot++)
+ {
+ if (uint32 arenaTeamId = GetArenaTeamId(arenaSlot))
+ {
+ ArenaTeam* arenaTeam = sArenaTeamMgr->GetArenaTeamById(arenaTeamId);
+ arenaTeam->FinishWeek(); // set played this week etc values to 0 in memory, too
+ arenaTeam->SaveToDB(); // save changes
+ arenaTeam->NotifyStatsChanged(); // notify the players of the changes
+ }
+ }
+
+ for (PlayerCurrenciesMap::iterator itr = _currencyStorage.begin(); itr != _currencyStorage.end(); ++itr)
+ {
+ itr->second.weekCount = 0;
+ itr->second.state = PLAYERCURRENCY_CHANGED;
+ }
+
+ WorldPacket data(SMSG_WEEKLY_RESET_CURRENCY, 0);
+ SendDirectMessage(&data);
+}
+
+uint32 Player::GetCurrencyWeekCap(CurrencyTypesEntry const* currency) const
+{
+ switch (currency->ID)
+ {
+ //original conquest not have week cap
+ case CURRENCY_TYPE_CONQUEST_POINTS:
+ return std::max(GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA, false), GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, false));
+ case CURRENCY_TYPE_CONQUEST_META_ARENA:
+ // should add precision mod = 100
+ return Trinity::Currency::ConquestRatingCalculator(_maxPersonalArenaRate) * CURRENCY_PRECISION;
+ case CURRENCY_TYPE_CONQUEST_META_RBG:
+ // should add precision mod = 100
+ return Trinity::Currency::BgConquestRatingCalculator(GetRBGPersonalRating()) * CURRENCY_PRECISION;
+ }
+
+ return currency->WeekCap;
+}
+
+uint32 Player::GetCurrencyTotalCap(CurrencyTypesEntry const* currency) const
+{
+ uint32 cap = currency->TotalCap;
+
+ switch (currency->ID)
+ {
+ case CURRENCY_TYPE_HONOR_POINTS:
+ {
+ uint32 honorcap = sWorld->getIntConfig(CONFIG_CURRENCY_MAX_HONOR_POINTS);
+ if (honorcap > 0)
+ cap = honorcap;
+ break;
+ }
+ case CURRENCY_TYPE_JUSTICE_POINTS:
+ {
+ uint32 justicecap = sWorld->getIntConfig(CONFIG_CURRENCY_MAX_JUSTICE_POINTS);
+ if (justicecap > 0)
+ cap = justicecap;
+ break;
+ }
}
+
+ return cap;
+}
+
+void Player::UpdateConquestCurrencyCap(uint32 currency)
+{
+ uint32 currenciesToUpdate[2] = { currency, CURRENCY_TYPE_CONQUEST_POINTS };
+
+ for (uint32 i = 0; i < 2; ++i)
+ {
+ CurrencyTypesEntry const* currencyEntry = sCurrencyTypesStore.LookupEntry(currenciesToUpdate[i]);
+ if (!currencyEntry)
+ continue;
+
+ uint32 precision = (currencyEntry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1;
+ uint32 cap = GetCurrencyWeekCap(currencyEntry);
+
+ WorldPacket packet(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, 8);
+ packet << uint32(cap / precision);
+ packet << uint32(currenciesToUpdate[i]);
+ GetSession()->SendPacket(&packet);
+ }
+}
+
+void Player::SetInGuild(uint32 guildId)
+{
+ if (guildId)
+ SetUInt64Value(OBJECT_FIELD_DATA, MAKE_NEW_GUID(guildId, 0, HIGHGUID_GUILD));
+ else
+ SetUInt64Value(OBJECT_FIELD_DATA, 0);
+
+ ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_GUILD_LEVEL_ENABLED, guildId != 0 && sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED));
+ SetUInt16Value(OBJECT_FIELD_TYPE, 1, guildId != 0);
}
uint32 Player::GetGuildIdFromDB(uint64 guid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
stmt->setUInt32(0, GUID_LOPART(guid));
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ return result->Fetch()[0].GetUInt32();
- if (!result)
- return 0;
-
- uint32 id = result->Fetch()[0].GetUInt32();
- return id;
+ return 0;
}
uint8 Player::GetRankFromDB(uint64 guid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_MEMBER);
stmt->setUInt32(0, GUID_LOPART(guid));
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ return result->Fetch()[1].GetUInt8();
- if (result)
+ return 0;
+}
+
+void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value)
+{
+ SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
+ if (type == ARENA_TEAM_PERSONAL_RATING && value > _maxPersonalArenaRate)
{
- uint32 v = result->Fetch()[1].GetUInt8();
- return v;
+ _maxPersonalArenaRate = value;
+ UpdateConquestCurrencyCap(CURRENCY_TYPE_CONQUEST_META_ARENA);
}
- else
- return 0;
}
void Player::SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type)
@@ -7373,10 +7698,6 @@ void Player::SetInArenaTeam(uint32 ArenaTeamId, uint8 slot, uint8 type)
SetArenaTeamInfoField(slot, ARENA_TEAM_ID, ArenaTeamId);
SetArenaTeamInfoField(slot, ARENA_TEAM_TYPE, type);
}
-void Player::SetArenaTeamInfoField(uint8 slot, ArenaTeamInfoType type, uint32 value)
-{
- SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + type, value);
-}
uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)
{
@@ -7459,6 +7780,8 @@ void Player::UpdateArea(uint32 newArea)
// so apply them accordingly
m_areaUpdateId = newArea;
+ phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
+
AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);
pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
UpdatePvPState(true);
@@ -7475,10 +7798,14 @@ void Player::UpdateArea(uint32 newArea)
}
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
+
+ phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
}
void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
+ phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
+
if (m_zoneUpdateId != newZone)
{
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
@@ -7504,7 +7831,7 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
if (!zone)
return;
- if (sWorld->getBoolConfig(CONFIG_WEATHER))
+ if (sWorld->getBoolConfig(CONFIG_WEATHER) && !HasAuraType(SPELL_AURA_FORCE_WEATHER))
{
if (Weather* weather = WeatherMgr::FindWeather(zone->ID))
weather->SendWeatherUpdateToPlayer(this);
@@ -7582,6 +7909,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
UpdateLocalChannels(newZone);
UpdateZoneDependentAuras(newZone);
+
+ phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
}
//If players are too far away from the duel flag... they lose the duel
@@ -7765,10 +8094,6 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply)
_ApplyWeaponDependentAuraMods(item, WeaponAttackType(attacktype), apply);
_ApplyItemBonuses(proto, slot, apply);
-
- if (slot == EQUIPMENT_SLOT_RANGED)
- _ApplyAmmoBonuses();
-
ApplyItemEquipSpell(item, apply);
ApplyEnchantment(item, apply);
@@ -7789,7 +8114,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (ssd && ssd_level > ssd->MaxLevel)
ssd_level = ssd->MaxLevel;
- ScalingStatValuesEntry const* ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL;
+ ScalingStatValuesEntry const* ssv = ssd ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL;
if (only_level_scale && !ssv)
return;
@@ -7803,12 +8128,10 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (ssd->StatMod[i] < 0)
continue;
statType = ssd->StatMod[i];
- val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000;
+ val = (ssv->GetStatMultiplier(proto->InventoryType) * ssd->Modifier[i]) / 10000;
}
else
{
- if (i >= proto->StatsCount)
- continue;
statType = proto->ItemStat[i].ItemStatType;
val = proto->ItemStat[i].ItemStatValue;
}
@@ -7874,24 +8197,24 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
case ITEM_MOD_CRIT_SPELL_RATING:
ApplyRatingMod(CR_CRIT_SPELL, int32(val), apply);
break;
- case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
- ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply);
- break;
- case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
- ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply);
- break;
- case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
- ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply);
- break;
- case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply);
- break;
+ // case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply);
+ // break;
+ // case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply);
+ // break;
+ // case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
+ // ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply);
+ // break;
case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply);
- break;
- case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply);
+ ApplyRatingMod(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, int32(val), apply);
break;
+ // case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
+ // ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply);
+ // break;
case ITEM_MOD_HASTE_MELEE_RATING:
ApplyRatingMod(CR_HASTE_MELEE, int32(val), apply);
break;
@@ -7911,20 +8234,18 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
ApplyRatingMod(CR_CRIT_RANGED, int32(val), apply);
ApplyRatingMod(CR_CRIT_SPELL, int32(val), apply);
break;
- case ITEM_MOD_HIT_TAKEN_RATING:
- ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply);
- ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply);
- ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply);
- break;
- case ITEM_MOD_CRIT_TAKEN_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply);
- ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply);
- ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply);
- break;
+ // case ITEM_MOD_HIT_TAKEN_RATING: // Unused since 3.3.5
+ // ApplyRatingMod(CR_HIT_TAKEN_MELEE, int32(val), apply);
+ // ApplyRatingMod(CR_HIT_TAKEN_RANGED, int32(val), apply);
+ // ApplyRatingMod(CR_HIT_TAKEN_SPELL, int32(val), apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_RATING: // Unused since 3.3.5
+ // ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply);
+ // ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply);
+ // ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply);
+ // break;
case ITEM_MOD_RESILIENCE_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_MELEE, int32(val), apply);
- ApplyRatingMod(CR_CRIT_TAKEN_RANGED, int32(val), apply);
- ApplyRatingMod(CR_CRIT_TAKEN_SPELL, int32(val), apply);
+ ApplyRatingMod(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, int32(val), apply);
break;
case ITEM_MOD_HASTE_RATING:
ApplyRatingMod(CR_HASTE_MELEE, int32(val), apply);
@@ -7941,9 +8262,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
case ITEM_MOD_RANGED_ATTACK_POWER:
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(val), apply);
break;
-// case ITEM_MOD_FERAL_ATTACK_POWER:
-// ApplyFeralAPBonus(int32(val), apply);
-// break;
case ITEM_MOD_MANA_REGENERATION:
ApplyManaRegenBonus(int32(val), apply);
break;
@@ -7959,28 +8277,39 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
case ITEM_MOD_SPELL_PENETRATION:
ApplySpellPenetrationBonus(val, apply);
break;
- case ITEM_MOD_BLOCK_VALUE:
- HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(val), apply);
+ case ITEM_MOD_MASTERY_RATING:
+ ApplyRatingMod(CR_MASTERY, int32(val), apply);
+ break;
+ case ITEM_MOD_FIRE_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(val), apply);
break;
- // deprecated item mods
- case ITEM_MOD_SPELL_HEALING_DONE:
- case ITEM_MOD_SPELL_DAMAGE_DONE:
+ case ITEM_MOD_FROST_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_HOLY_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_SHADOW_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_NATURE_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(val), apply);
+ break;
+ case ITEM_MOD_ARCANE_RESISTANCE:
+ HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(val), apply);
break;
}
}
// Apply Spell Power from ScalingStatValue if set
- if (ssv)
- if (int32 spellbonus = ssv->getSpellBonus(proto->ScalingStatValue))
+ if (ssv && proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON)
+ if (int32 spellbonus = int32(ssv->Spellpower))
ApplySpellPowerBonus(spellbonus, apply);
// If set ScalingStatValue armor get it or use item armor
uint32 armor = proto->Armor;
- if (ssv)
- {
- if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue))
- armor = ssvarmor;
- }
+ if (ssv && proto->Class == ITEM_CLASS_ARMOR)
+ armor = ssv->GetArmor(proto->InventoryType, proto->SubClass - 1);
else if (armor && proto->ArmorDamageModifier)
armor -= uint32(proto->ArmorDamageModifier);
@@ -8007,27 +8336,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (proto->ArmorDamageModifier > 0)
HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(proto->ArmorDamageModifier), apply);
- if (proto->Block)
- HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(proto->Block), apply);
-
- if (proto->HolyRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(proto->HolyRes), apply);
-
- if (proto->FireRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(proto->FireRes), apply);
-
- if (proto->NatureRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(proto->NatureRes), apply);
-
- if (proto->FrostRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(proto->FrostRes), apply);
-
- if (proto->ShadowRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(proto->ShadowRes), apply);
-
- if (proto->ArcaneRes)
- HandleStatModifier(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(proto->ArcaneRes), apply);
-
WeaponAttackType attType = BASE_ATTACK;
if (slot == EQUIPMENT_SLOT_RANGED && (
@@ -8043,23 +8351,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (CanUseAttackType(attType))
_ApplyWeaponDamage(slot, proto, ssv, apply);
-
-
- // Druids get feral AP bonus from weapon dps (also use DPS from ScalingStatValue)
- if (getClass() == CLASS_DRUID)
- {
- int32 dpsMod = 0;
- int32 feral_bonus = 0;
- if (ssv)
- {
- dpsMod = ssv->getDPSMod(proto->ScalingStatValue);
- feral_bonus += ssv->getFeralBonus(proto->ScalingStatValue);
- }
-
- feral_bonus += proto->getFeralBonus(dpsMod);
- if (feral_bonus)
- ApplyFeralAPBonus(feral_bonus, apply);
- }
}
void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply)
@@ -8078,18 +8369,20 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
attType = OFF_ATTACK;
}
- float minDamage = proto->Damage[0].DamageMin;
- float maxDamage = proto->Damage[0].DamageMax;
+ float minDamage = proto->DamageMin;
+ float maxDamage = proto->DamageMax;
// If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage
+ int32 extraDPS = 0;
if (ssv)
{
- int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue);
+ float damageMultiplier = 0.0f;
+ extraDPS = ssv->GetDPSAndDamageMultiplier(proto->SubClass, proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON, &damageMultiplier);
if (extraDPS)
{
float average = extraDPS * proto->Delay / 1000.0f;
- minDamage = 0.7f * average;
- maxDamage = 1.3f * average;
+ minDamage = (1.0f - damageMultiplier) * average;
+ maxDamage = (1.0f + damageMultiplier) * average;
}
}
@@ -8115,10 +8408,6 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt
SetAttackTime(OFF_ATTACK, apply ? proto->Delay: BASE_ATTACK_TIME);
}
- // No need to modify any physical damage for ferals as it is calculated from stats only
- if (IsInFeralForm())
- return;
-
if (CanModifyStats() && (damage || proto->Delay))
UpdateDamagePhysical(attType);
}
@@ -8362,10 +8651,10 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
float chance = (float)spellInfo->ProcChance;
- if (spellData.SpellPPMRate)
+ if (proto->SpellPPMRate)
{
uint32 WeaponSpeed = GetAttackTime(attType);
- chance = GetPPMProcChance(WeaponSpeed, spellData.SpellPPMRate, spellInfo);
+ chance = GetPPMProcChance(WeaponSpeed, proto->SpellPPMRate, spellInfo);
}
else if (chance > 100.0f)
chance = GetWeaponProcChance();
@@ -8378,6 +8667,9 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32
// item combat enchantments
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
{
+ if (e_slot > PRISMATIC_ENCHANTMENT_SLOT && e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
@@ -8453,7 +8745,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
if (!spellInfo)
{
TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) in have wrong spell id %u, ignoring ", proto->ItemId, learn_spell_id);
- SendEquipError(EQUIP_ERR_NONE, item, NULL);
+ SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, item, NULL);
return;
}
@@ -8500,6 +8792,9 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8
// Item enchantments spells cast at use
for (uint8 e_slot = 0; e_slot < MAX_ENCHANTMENT_SLOT; ++e_slot)
{
+ if (e_slot > PRISMATIC_ENCHANTMENT_SLOT && e_slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 enchant_id = item->GetEnchantmentId(EnchantmentSlot(e_slot));
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
@@ -8566,9 +8861,6 @@ void Player::_RemoveAllItemMods()
_ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), false);
_ApplyItemBonuses(proto, i, false);
-
- if (i == EQUIPMENT_SLOT_RANGED)
- _ApplyAmmoBonuses();
}
}
@@ -8595,9 +8887,6 @@ void Player::_ApplyAllItemMods()
_ApplyWeaponDependentAuraMods(m_items[i], WeaponAttackType(attacktype), true);
_ApplyItemBonuses(proto, i, true);
-
- if (i == EQUIPMENT_SLOT_RANGED)
- _ApplyAmmoBonuses();
}
}
@@ -8642,63 +8931,6 @@ void Player::_ApplyAllLevelScaleItemMods(bool apply)
}
}
-void Player::_ApplyAmmoBonuses()
-{
- // check ammo
- uint32 ammo_id = GetUInt32Value(PLAYER_AMMO_ID);
- if (!ammo_id)
- return;
-
- float currentAmmoDPS;
-
- ItemTemplate const* ammo_proto = sObjectMgr->GetItemTemplate(ammo_id);
- if (!ammo_proto || ammo_proto->Class != ITEM_CLASS_PROJECTILE || !CheckAmmoCompatibility(ammo_proto))
- currentAmmoDPS = 0.0f;
- else
- currentAmmoDPS = (ammo_proto->Damage[0].DamageMin + ammo_proto->Damage[0].DamageMax) / 2;
-
- if (currentAmmoDPS == GetAmmoDPS())
- return;
-
- m_ammoDPS = currentAmmoDPS;
-
- if (CanModifyStats())
- UpdateDamagePhysical(RANGED_ATTACK);
-}
-
-bool Player::CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const
-{
- if (!ammo_proto)
- return false;
-
- // check ranged weapon
- Item* weapon = GetWeaponForAttack(RANGED_ATTACK);
- if (!weapon || weapon->IsBroken())
- return false;
-
- ItemTemplate const* weapon_proto = weapon->GetTemplate();
- if (!weapon_proto || weapon_proto->Class != ITEM_CLASS_WEAPON)
- return false;
-
- // check ammo ws. weapon compatibility
- switch (weapon_proto->SubClass)
- {
- case ITEM_SUBCLASS_WEAPON_BOW:
- case ITEM_SUBCLASS_WEAPON_CROSSBOW:
- if (ammo_proto->SubClass != ITEM_SUBCLASS_ARROW)
- return false;
- break;
- case ITEM_SUBCLASS_WEAPON_GUN:
- if (ammo_proto->SubClass != ITEM_SUBCLASS_BULLET)
- return false;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
/* If in a battleground a player dies, and an enemy removes the insignia, the player's bones is lootable
Called by remove insignia spell effect */
void Player::RemovedInsignia(Player* looterPlr)
@@ -9039,7 +9271,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
// need know merged fishing/corpse loot type for achievements
loot->loot_type = loot_type;
- WorldPacket data(SMSG_LOOT_RESPONSE, (9+50)); // we guess size
+ WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size
data << uint64(guid);
data << uint8(loot_type);
data << LootView(*loot, this, permission);
@@ -9069,9 +9301,10 @@ void Player::SendNotifyLootItemRemoved(uint8 lootSlot)
void Player::SendUpdateWorldState(uint32 Field, uint32 Value)
{
- WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8);
+ WorldPacket data(SMSG_UPDATE_WORLD_STATE, 4+4+1);
data << Field;
data << Value;
+ data << uint8(0);
GetSession()->SendPacket(&data);
}
@@ -9124,46 +9357,6 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
case 2257: // Deeprun Tram
case 3703: // Shattrath City
break;
- case 139: // Eastern Plaguelands
- if (pvp && pvp->GetTypeId() == OUTDOOR_PVP_EP)
- pvp->FillInitialWorldStates(data);
- else
- {
- data << uint32(0x97a) << uint32(0x0); // 10 2426
- data << uint32(0x917) << uint32(0x0); // 11 2327
- data << uint32(0x918) << uint32(0x0); // 12 2328
- data << uint32(0x97b) << uint32(0x32); // 13 2427
- data << uint32(0x97c) << uint32(0x32); // 14 2428
- data << uint32(0x933) << uint32(0x1); // 15 2355
- data << uint32(0x946) << uint32(0x0); // 16 2374
- data << uint32(0x947) << uint32(0x0); // 17 2375
- data << uint32(0x948) << uint32(0x0); // 18 2376
- data << uint32(0x949) << uint32(0x0); // 19 2377
- data << uint32(0x94a) << uint32(0x0); // 20 2378
- data << uint32(0x94b) << uint32(0x0); // 21 2379
- data << uint32(0x932) << uint32(0x0); // 22 2354
- data << uint32(0x934) << uint32(0x0); // 23 2356
- data << uint32(0x935) << uint32(0x0); // 24 2357
- data << uint32(0x936) << uint32(0x0); // 25 2358
- data << uint32(0x937) << uint32(0x0); // 26 2359
- data << uint32(0x938) << uint32(0x0); // 27 2360
- data << uint32(0x939) << uint32(0x1); // 28 2361
- data << uint32(0x930) << uint32(0x1); // 29 2352
- data << uint32(0x93a) << uint32(0x0); // 30 2362
- data << uint32(0x93b) << uint32(0x0); // 31 2363
- data << uint32(0x93c) << uint32(0x0); // 32 2364
- data << uint32(0x93d) << uint32(0x0); // 33 2365
- data << uint32(0x944) << uint32(0x0); // 34 2372
- data << uint32(0x945) << uint32(0x0); // 35 2373
- data << uint32(0x931) << uint32(0x1); // 36 2353
- data << uint32(0x93e) << uint32(0x0); // 37 2366
- data << uint32(0x931) << uint32(0x1); // 38 2367 ?? grey horde not in dbc! send for consistency's sake, and to match field count
- data << uint32(0x940) << uint32(0x0); // 39 2368
- data << uint32(0x941) << uint32(0x0); // 7 2369
- data << uint32(0x942) << uint32(0x0); // 8 2370
- data << uint32(0x943) << uint32(0x0); // 9 2371
- }
- break;
case 1377: // Silithus
if (pvp && pvp->GetTypeId() == OUTDOOR_PVP_SI)
pvp->FillInitialWorldStates(data);
@@ -9657,16 +9850,37 @@ 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)
+ // Zul Aman
+ case 3805:
+ if (instance && mapid == 568)
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
+ data << uint32(3104) << uint32(0); // 9 WORLD_STATE_ZULAMAN_TIMER_ENABLED
+ data << uint32(3106) << uint32(0); // 10 WORLD_STATE_ZULAMAN_TIMER
}
break;
+ // Twin Peaks
+ case 5031:
+ if (bg && bg->GetTypeID(true) == BATTLEGROUND_TP)
+ bg->FillInitialWorldStates(data);
+ else
+ {
+ data << uint32(0x62d) << uint32(0x0); // 7 1581 alliance flag captures
+ data << uint32(0x62e) << uint32(0x0); // 8 1582 horde flag captures
+ data << uint32(0x609) << uint32(0x0); // 9 1545 unk
+ data << uint32(0x60a) << uint32(0x0); // 10 1546 unk
+ data << uint32(0x60b) << uint32(0x2); // 11 1547 unk
+ data << uint32(0x641) << uint32(0x3); // 12 1601 unk
+ data << uint32(0x922) << uint32(0x1); // 13 2338 horde (0 - hide, 1 - flag ok, 2 - flag picked up (flashing), 3 - flag picked up (not flashing)
+ data << uint32(0x923) << uint32(0x1); // 14 2339 alliance (0 - hide, 1 - flag ok, 2 - flag picked up (flashing), 3 - flag picked up (not flashing)
+ }
+ break;
+ // Battle for Gilneas
+ case 5449:
+ if (bg && bg->GetTypeID(true) == BATTLEGROUND_BFG)
+ bg->FillInitialWorldStates(data);
+ break;
// Wintergrasp
case 4197:
if (bf && bf->GetTypeId() == BATTLEFIELD_WG)
@@ -9674,6 +9888,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
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
@@ -9711,7 +9935,7 @@ void Player::SendBattlefieldWorldStates()
/// Send misc stuff that needs to be sent on every login, like the battle timers.
if (sWorld->getBoolConfig(CONFIG_WINTERGRASP_ENABLE))
{
- if (BattlefieldWG* wg = (BattlefieldWG*)sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
+ if (Battlefield* wg = sBattlefieldMgr->GetBattlefieldByBattleId(BATTLEFIELD_BATTLEID_WG))
{
if (wg->IsWarTime())
SendUpdateWorldState(ClockWorldState[1], uint32(time(NULL)));
@@ -9748,7 +9972,7 @@ void Player::SendTalentWipeConfirm(uint64 guid)
{
WorldPacket data(MSG_TALENT_WIPE_CONFIRM, (8+4));
data << uint64(guid);
- uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : resetTalentsCost();
+ uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : GetNextResetTalentsCost();
data << cost;
GetSession()->SendPacket(&data);
}
@@ -9946,30 +10170,10 @@ uint8 Player::FindEquipSlot(ItemTemplate const* proto, uint32 slot, bool swap) c
break;
case INVTYPE_RELIC:
{
- switch (proto->SubClass)
- {
- case ITEM_SUBCLASS_ARMOR_LIBRAM:
- if (playerClass == CLASS_PALADIN)
- slots[0] = EQUIPMENT_SLOT_RANGED;
- break;
- case ITEM_SUBCLASS_ARMOR_IDOL:
- if (playerClass == CLASS_DRUID)
- slots[0] = EQUIPMENT_SLOT_RANGED;
- break;
- case ITEM_SUBCLASS_ARMOR_TOTEM:
- if (playerClass == CLASS_SHAMAN)
- slots[0] = EQUIPMENT_SLOT_RANGED;
- break;
- case ITEM_SUBCLASS_ARMOR_MISC:
- if (playerClass == CLASS_WARLOCK)
- slots[0] = EQUIPMENT_SLOT_RANGED;
- break;
- case ITEM_SUBCLASS_ARMOR_SIGIL:
- if (playerClass == CLASS_DEATH_KNIGHT)
- slots[0] = EQUIPMENT_SLOT_RANGED;
- break;
- }
- break;
+ if (playerClass == CLASS_PALADIN || playerClass == CLASS_DRUID ||
+ playerClass == CLASS_SHAMAN || playerClass == CLASS_DEATH_KNIGHT)
+ slots[0] = EQUIPMENT_SLOT_RANGED;
+ break;
}
default:
return NULL_SLOT;
@@ -10031,14 +10235,6 @@ InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const
return EQUIP_ERR_OK;
}
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem->GetEntry() == item)
- {
- tempcount += pItem->GetCount();
- if (tempcount >= count)
- return EQUIP_ERR_OK;
- }
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
@@ -10063,11 +10259,6 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const
if (pItem != skipItem && pItem->GetEntry() == item)
count += pItem->GetCount();
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem != skipItem && pItem->GetEntry() == item)
- count += pItem->GetCount();
-
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
count += pBag->GetItemCount(item, skipItem);
@@ -10110,13 +10301,6 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte
if (pProto->ItemLimitCategory == limitCategory)
count += pItem->GetCount();
- for (int i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem != skipItem)
- if (ItemTemplate const* pProto = pItem->GetTemplate())
- if (pProto->ItemLimitCategory == limitCategory)
- count += pItem->GetCount();
-
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
count += pBag->GetItemCountWithLimitCategory(limitCategory, skipItem);
@@ -10142,11 +10326,6 @@ Item* Player::GetItemByGuid(uint64 guid) const
if (pItem->GetGUID() == guid)
return pItem;
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem->GetGUID() == guid)
- return pItem;
-
for (int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_BAG_END; ++i)
if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
if (pItem->GetGUID() == guid)
@@ -10178,7 +10357,7 @@ Item* Player::GetItemByPos(uint16 pos) const
Item* Player::GetItemByPos(uint8 bag, uint8 slot) const
{
- if (bag == INVENTORY_SLOT_BAG_0 && (slot < BANK_SLOT_BAG_END || (slot >= KEYRING_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)))
+ if (bag == INVENTORY_SLOT_BAG_0 && slot < BANK_SLOT_BAG_END)
return m_items[slot];
else if (Bag* pBag = GetBagByPos(bag))
return pBag->GetItemByPos(slot);
@@ -10268,8 +10447,6 @@ bool Player::IsInventoryPos(uint8 bag, uint8 slot)
return true;
if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)
return true;
- if (bag == INVENTORY_SLOT_BAG_0 && (slot >= KEYRING_SLOT_START && slot < CURRENCYTOKEN_SLOT_END))
- return true;
return false;
}
@@ -10328,10 +10505,6 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos)
if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_END)
return true;
- // keyring slots
- if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END)
- return true;
-
// bank main slots
if (slot >= BANK_SLOT_ITEM_START && slot < BANK_SLOT_ITEM_END)
return true;
@@ -10371,16 +10544,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const
return true;
}
}
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- {
- Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade())
- {
- tempcount += pItem->GetCount();
- if (tempcount >= count)
- return true;
- }
- }
+
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
if (Bag* pBag = GetBagByPos(i))
@@ -10510,11 +10674,11 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
{
if (no_space_count)
*no_space_count = count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
if (pItem && pItem->m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
// no maximum
if ((pProto->MaxCount <= 0 && pProto->ItemLimitCategory == 0) || pProto->MaxCount == 2147483647)
@@ -10527,7 +10691,7 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
{
if (no_space_count)
*no_space_count = count + curcount - pProto->MaxCount;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
@@ -10539,7 +10703,7 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
{
if (no_space_count)
*no_space_count = count;
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
}
if (limitEntry->mode == ITEM_LIMIT_CATEGORY_MODE_HAVE)
@@ -10549,7 +10713,7 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
{
if (no_space_count)
*no_space_count = count + curcount - limitEntry->maxCount;
- return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED;
+ return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS;
}
}
}
@@ -10570,36 +10734,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des
return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, NULL);
}
-bool Player::HasItemTotemCategory(uint32 TotemCategory) const
-{
- Item* pItem;
- for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i)
- {
- pItem = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem && IsTotemCategoryCompatiableWith(pItem->GetTemplate()->TotemCategory, TotemCategory))
- return true;
- }
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- {
- pItem = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem && IsTotemCategoryCompatiableWith(pItem->GetTemplate()->TotemCategory, TotemCategory))
- return true;
- }
- for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
- {
- if (Bag* pBag = GetBagByPos(i))
- {
- for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
- {
- pItem = GetUseableItemByPos(i, j);
- if (pItem && IsTotemCategoryCompatiableWith(pItem->GetTemplate()->TotemCategory, TotemCategory))
- return true;
- }
- }
- }
- return false;
-}
-
InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec &dest, ItemTemplate const* pProto, uint32& count, bool swap, Item* pSrcItem) const
{
Item* pItem2 = GetItemByPos(bag, slot);
@@ -10611,40 +10745,32 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
uint32 need_space;
if (pSrcItem && pSrcItem->IsNotEmptyBag() && !IsBagPos(uint16(bag) << 8 | slot))
- return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+ return EQUIP_ERR_DESTROY_NONEMPTY_BAG;
// empty specific slot - check item fit to slot
if (!pItem2 || swap)
{
if (bag == INVENTORY_SLOT_BAG_0)
{
- // keyring case
- if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS))
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
-
- // currencytoken case
- if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken()))
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
-
// prevent cheating
if ((slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END) || slot >= PLAYER_SLOT_END)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
}
else
{
Bag* pBag = GetBagByPos(bag);
if (!pBag)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
ItemTemplate const* pBagProto = pBag->GetTemplate();
if (!pBagProto)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
if (slot >= pBagProto->ContainerSlots)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
if (!ItemCanGoIntoBag(pProto, pBagProto))
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
}
// non empty stack with space
@@ -10678,26 +10804,26 @@ InventoryResult Player::CanStoreItem_InBag(uint8 bag, ItemPosCountVec &dest, Ite
{
// skip specific bag already processed in first called CanStoreItem_InBag
if (bag == skip_bag)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
// skip not existed bag or self targeted bag
Bag* pBag = GetBagByPos(bag);
if (!pBag || pBag == pSrcItem)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
if (pSrcItem && pSrcItem->IsNotEmptyBag())
- return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+ return EQUIP_ERR_DESTROY_NONEMPTY_BAG;
ItemTemplate const* pBagProto = pBag->GetTemplate();
if (!pBagProto)
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
// specialized bag mode or non-specilized
if (non_specialized != (pBagProto->Class == ITEM_CLASS_CONTAINER && pBagProto->SubClass == ITEM_SUBCLASS_CONTAINER))
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
if (!ItemCanGoIntoBag(pProto, pBagProto))
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
{
@@ -10748,7 +10874,7 @@ InventoryResult Player::CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 sl
{
//this is never called for non-bag slots so we can do this
if (pSrcItem && pSrcItem->IsNotEmptyBag())
- return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+ return EQUIP_ERR_DESTROY_NONEMPTY_BAG;
for (uint32 j = slot_begin; j < slot_end; j++)
{
@@ -10804,7 +10930,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
{
if (no_space_count)
*no_space_count = count;
- return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
+ return swap ? EQUIP_ERR_CANT_SWAP : EQUIP_ERR_ITEM_NOT_FOUND;
}
if (pItem)
@@ -10814,14 +10940,14 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
{
if (no_space_count)
*no_space_count = count;
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
}
if (pItem->IsBindedNotWith(this))
{
if (no_space_count)
*no_space_count = count;
- return EQUIP_ERR_DONT_OWN_THAT_ITEM;
+ return EQUIP_ERR_NOT_OWNER;
}
}
@@ -10857,7 +10983,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
@@ -10871,24 +10997,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
{
if (bag == INVENTORY_SLOT_BAG_0) // inventory
{
- res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
-
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
{
@@ -10904,7 +11012,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
else // equipped bag
@@ -10928,7 +11036,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
}
@@ -10936,67 +11044,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
// search free slot in bag for place to
if (bag == INVENTORY_SLOT_BAG_0) // inventory
{
- // search free slot - keyring case
- if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS)
- {
- uint32 keyringSize = GetMaxKeyringSize();
- res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START+keyringSize, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
-
- res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
- else if (pProto->IsCurrencyToken())
- {
- res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
-
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
{
@@ -11012,7 +11059,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
else // equipped bag
@@ -11035,7 +11082,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
}
@@ -11045,24 +11092,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
// search stack for merge to
if (pProto->Stackable != 1)
{
- res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
-
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
{
@@ -11078,7 +11107,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
if (pProto->BagFamily)
@@ -11096,7 +11125,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
}
@@ -11114,7 +11143,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
}
@@ -11122,48 +11151,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
// search free slot - special bag case
if (pProto->BagFamily)
{
- if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS)
- {
- uint32 keyringSize = GetMaxKeyringSize();
- res = CanStoreItem_InInventorySlots(KEYRING_SLOT_START, KEYRING_SLOT_START+keyringSize, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
- else if (pProto->IsCurrencyToken())
- {
- res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
- }
- }
-
for (uint32 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
res = CanStoreItem_InBag(i, dest, pProto, count, false, false, pItem, bag, slot);
@@ -11177,13 +11164,13 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
}
if (pItem && pItem->IsNotEmptyBag())
- return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG;
+ return EQUIP_ERR_BAG_IN_BAG;
// search free slot
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot);
@@ -11201,7 +11188,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
@@ -11217,14 +11204,14 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
+ return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
if (no_space_count)
*no_space_count = count + no_similar_count;
- return EQUIP_ERR_INVENTORY_FULL;
+ return EQUIP_ERR_INV_FULL;
}
//////////////////////////////////////////////////////////////////////////
@@ -11235,13 +11222,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
// fill space table
int inv_slot_items[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START];
int inv_bags[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];
- int inv_keys[KEYRING_SLOT_END - KEYRING_SLOT_START];
- int inv_tokens[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START];
memset(inv_slot_items, 0, sizeof(int) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
memset(inv_bags, 0, sizeof(int) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE);
- memset(inv_keys, 0, sizeof(int) * (KEYRING_SLOT_END - KEYRING_SLOT_START));
- memset(inv_tokens, 0, sizeof(int) * (CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START));
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
{
@@ -11250,20 +11233,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
inv_slot_items[i - INVENTORY_SLOT_ITEM_START] = pItem2->GetCount();
}
- for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
- {
- pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem2 && !pItem2->IsInTrade())
- inv_keys[i - KEYRING_SLOT_START] = pItem2->GetCount();
- }
-
- for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
- {
- pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (pItem2 && !pItem2->IsInTrade())
- inv_tokens[i - CURRENCYTOKEN_SLOT_START] = pItem2->GetCount();
- }
-
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
@@ -11291,11 +11260,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
// item used
if (pItem->m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
// item it 'bind'
if (pItem->IsBindedNotWith(this))
- return EQUIP_ERR_DONT_OWN_THAT_ITEM;
+ return EQUIP_ERR_NOT_OWNER;
ItemTemplate const* pBagProto;
@@ -11309,32 +11278,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
{
bool b_found = false;
- for (uint8 t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t)
- {
- pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
- if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
- {
- inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount();
- b_found = true;
- break;
- }
- }
- if (b_found)
- continue;
-
- for (int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
- {
- pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
- if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
- {
- inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount();
- b_found = true;
- break;
- }
- }
- if (b_found)
- continue;
-
for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t)
{
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
@@ -11375,38 +11318,6 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
if (pProto->BagFamily)
{
bool b_found = false;
- if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS)
- {
- uint32 keyringSize = GetMaxKeyringSize();
- for (uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START+keyringSize; ++t)
- {
- if (inv_keys[t-KEYRING_SLOT_START] == 0)
- {
- inv_keys[t-KEYRING_SLOT_START] = 1;
- b_found = true;
- break;
- }
- }
- }
-
- if (b_found)
- continue;
-
- if (pProto->IsCurrencyToken())
- {
- for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
- {
- if (inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0)
- {
- inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1;
- b_found = true;
- break;
- }
- }
- }
-
- if (b_found)
- continue;
for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t)
{
@@ -11473,7 +11384,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
// no free slot found?
if (!b_found)
- return EQUIP_ERR_INVENTORY_FULL;
+ return EQUIP_ERR_INV_FULL;
}
return EQUIP_ERR_OK;
@@ -11505,10 +11416,10 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
{
// item used
if (pItem->m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
if (pItem->IsBindedNotWith(this))
- return EQUIP_ERR_DONT_OWN_THAT_ITEM;
+ return EQUIP_ERR_NOT_OWNER;
// check count of items (skip for auto move for same player from bank)
InventoryResult res = CanTakeMoreSimilarItems(pItem);
@@ -11521,7 +11432,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
// May be here should be more stronger checks; STUNNED checked
// ROOT, CONFUSED, DISTRACTED, FLEEING this needs to be checked.
if (HasUnitState(UNIT_STATE_STUNNED))
- return EQUIP_ERR_YOU_ARE_STUNNED;
+ return EQUIP_ERR_GENERIC_STUNNED;
// do not allow equipping gear except weapons, offhands, projectiles, relics in
// - combat
@@ -11537,27 +11448,27 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
}
if (IsInCombat()&& (pProto->Class == ITEM_CLASS_WEAPON || pProto->InventoryType == INVTYPE_RELIC) && m_weaponChangeTimer != 0)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW; // maybe exist better err
+ return EQUIP_ERR_CLIENT_LOCKED_OUT; // maybe exist better err
if (IsNonMeleeSpellCast(false))
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
ScalingStatDistributionEntry const* ssd = pProto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(pProto->ScalingStatDistribution) : 0;
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
if (ssd && ssd->MaxLevel < DEFAULT_MAX_LEVEL && ssd->MaxLevel < getLevel())
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
uint8 eslot = FindEquipSlot(pProto, slot, swap);
if (eslot == NULL_SLOT)
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
res = CanUseItem(pItem, not_loading);
if (res != EQUIP_ERR_OK)
return res;
if (!swap && GetItemByPos(INVENTORY_SLOT_BAG_0, eslot))
- return EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE;
+ return EQUIP_ERR_NO_SLOT_AVAILABLE;
// if we are swapping 2 equiped items, CanEquipUniqueItem check
// should ignore the item we are trying to swap, and not the
@@ -11601,8 +11512,8 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
if (ItemTemplate const* pBagProto = pBag->GetTemplate())
if (pBagProto->Class == pProto->Class && (!swap || pBag->GetSlot() != eslot))
return (pBagProto->SubClass == ITEM_SUBCLASS_AMMO_POUCH)
- ? EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH
- : EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER;
+ ? EQUIP_ERR_ONLY_ONE_AMMO
+ : EQUIP_ERR_ONLY_ONE_QUIVER;
uint32 type = pProto->InventoryType;
@@ -11610,21 +11521,20 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
{
// Do not allow polearm to be equipped in the offhand (rare case for the only 1h polearm 41750)
if (type == INVTYPE_WEAPON && pProto->SubClass == ITEM_SUBCLASS_WEAPON_POLEARM)
- return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
-
+ return EQUIP_ERR_2HSKILLNOTFOUND;
else if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND)
{
if (!CanDualWield())
- return EQUIP_ERR_CANT_DUAL_WIELD;
+ return EQUIP_ERR_2HSKILLNOTFOUND;
}
else if (type == INVTYPE_2HWEAPON)
{
if (!CanDualWield() || !CanTitanGrip())
- return EQUIP_ERR_CANT_DUAL_WIELD;
+ return EQUIP_ERR_2HSKILLNOTFOUND;
}
if (IsTwoHandUsed())
- return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;
+ return EQUIP_ERR_2HANDED_EQUIPPED;
}
// equip two-hand weapon case (with possible unequip 2 items)
@@ -11633,10 +11543,10 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
if (eslot == EQUIPMENT_SLOT_OFFHAND)
{
if (!CanTitanGrip())
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
}
else if (eslot != EQUIPMENT_SLOT_MAINHAND)
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
if (!CanTitanGrip())
{
@@ -11646,7 +11556,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
if (offItem && (!not_loading ||
CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND, false) != EQUIP_ERR_OK ||
CanStoreItem(NULL_BAG, NULL_SLOT, off_dest, offItem, false) != EQUIP_ERR_OK))
- return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL;
+ return swap ? EQUIP_ERR_CANT_SWAP : EQUIP_ERR_INV_FULL;
}
}
dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);
@@ -11654,7 +11564,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
}
}
- return !swap ? EQUIP_ERR_ITEM_NOT_FOUND : EQUIP_ERR_ITEMS_CANT_BE_SWAPPED;
+ return !swap ? EQUIP_ERR_ITEM_NOT_FOUND : EQUIP_ERR_CANT_SWAP;
}
InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
@@ -11677,7 +11587,7 @@ InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
// item used
if (pItem->m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
// do not allow unequipping gear except weapons, offhands, projectiles, relics in
// - combat
@@ -11693,7 +11603,7 @@ InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
}
if (!swap && pItem->IsNotEmptyBag())
- return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
+ return EQUIP_ERR_DESTROY_NONEMPTY_BAG;
return EQUIP_ERR_OK;
}
@@ -11701,29 +11611,28 @@ InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item* pItem, bool swap, bool not_loading) const
{
if (!pItem)
- return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
+ return swap ? EQUIP_ERR_CANT_SWAP : EQUIP_ERR_ITEM_NOT_FOUND;
uint32 count = pItem->GetCount();
TC_LOG_DEBUG("entities.player.items", "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
ItemTemplate const* pProto = pItem->GetTemplate();
if (!pProto)
- return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;
+ return swap ? EQUIP_ERR_CANT_SWAP : EQUIP_ERR_ITEM_NOT_FOUND;
// item used
if (pItem->m_lootGenerated)
- return EQUIP_ERR_ALREADY_LOOTED;
+ return EQUIP_ERR_LOOT_GONE;
if (pItem->IsBindedNotWith(this))
- return EQUIP_ERR_DONT_OWN_THAT_ITEM;
+ return EQUIP_ERR_NOT_OWNER;
- // Currency tokens are not supposed to be swapped out of their hidden bag
- uint8 pItemslot = pItem->GetSlot();
- if (pItemslot >= CURRENCYTOKEN_SLOT_START && pItemslot < CURRENCYTOKEN_SLOT_END)
+ // Currency Tokenizer are not supposed to be swapped out of their hidden bag
+ if (pItem->IsCurrencyToken())
{
TC_LOG_ERROR("entities.player", "Possible hacking attempt: Player %s [guid: %u] tried to move token [guid: %u, entry: %u] out of the currency bag!",
GetName().c_str(), GetGUIDLow(), pItem->GetGUIDLow(), pProto->ItemId);
- return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED;
+ return EQUIP_ERR_CANT_SWAP;
}
// check count of items (skip for auto move for same player from bank)
@@ -11737,10 +11646,10 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
if (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END)
{
if (!pItem->IsBag())
- return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
+ return EQUIP_ERR_WRONG_SLOT;
if (slot - BANK_SLOT_BAG_START >= GetBankBagSlotCount())
- return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
+ return EQUIP_ERR_NO_BANK_SLOT;
res = CanUseItem(pItem, not_loading);
if (res != EQUIP_ERR_OK)
@@ -11761,7 +11670,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
if (bag != NULL_BAG)
{
if (pItem->IsNotEmptyBag())
- return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG;
+ return EQUIP_ERR_BAG_IN_BAG;
// search stack in bag for merge to
if (pProto->Stackable != 1)
@@ -11892,16 +11801,16 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
TC_LOG_DEBUG("entities.player.items", "STORAGE: CanUseItem item = %u", pItem->GetEntry());
if (!IsAlive() && not_loading)
- return EQUIP_ERR_YOU_ARE_DEAD;
+ return EQUIP_ERR_PLAYER_DEAD;
//if (isStunned())
- // return EQUIP_ERR_YOU_ARE_STUNNED;
+ // return EQUIP_ERR_GENERIC_STUNNED;
ItemTemplate const* pProto = pItem->GetTemplate();
if (pProto)
{
if (pItem->IsBindedNotWith(this))
- return EQUIP_ERR_DONT_OWN_THAT_ITEM;
+ return EQUIP_ERR_NOT_OWNER;
InventoryResult res = CanUseItem(pProto);
if (res != EQUIP_ERR_OK)
@@ -11914,8 +11823,7 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
// Armor that is binded to account can "morph" from plate to mail, etc. if skill is not learned yet.
if (pProto->Quality == ITEM_QUALITY_HEIRLOOM && pProto->Class == ITEM_CLASS_ARMOR && !HasSkill(itemSkill))
{
- /// @todo when you right-click already equipped item it throws EQUIP_ERR_NO_REQUIRED_PROFICIENCY.
-
+ /// @todo when you right-click already equipped item it throws EQUIP_ERR_PROFICIENCY_NEEDED.
// In fact it's a visual bug, everything works properly... I need sniffs of operations with
// binded to account items from off server.
@@ -11932,7 +11840,7 @@ InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
}
}
if (!allowEquip && GetSkillValue(itemSkill) == 0)
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
}
if (pProto->RequiredReputationFaction && uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank)
@@ -11951,31 +11859,31 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
if (proto)
{
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY) && GetTeam() != HORDE)
- return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+ return EQUIP_ERR_CANT_EQUIP_EVER;
if ((proto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && GetTeam() != ALLIANCE)
- return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+ return EQUIP_ERR_CANT_EQUIP_EVER;
if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
- return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+ return EQUIP_ERR_CANT_EQUIP_EVER;
if (proto->RequiredSkill != 0)
{
if (GetSkillValue(proto->RequiredSkill) == 0)
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank)
return EQUIP_ERR_CANT_EQUIP_SKILL;
}
if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
if (getLevel() < proto->RequiredLevel)
return EQUIP_ERR_CANT_EQUIP_LEVEL_I;
// If World Event is not active, prevent using event dependant items
if (proto->HolidayId && !IsHolidayActive((HolidayIds)proto->HolidayId))
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
return EQUIP_ERR_OK;
}
@@ -12007,15 +11915,15 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
}; //Copy from function Item::GetSkill()
if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
- return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+ return EQUIP_ERR_CANT_EQUIP_EVER;
if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
if (proto->RequiredSkill != 0)
{
if (!GetSkillValue(proto->RequiredSkill))
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank)
return EQUIP_ERR_CANT_EQUIP_SKILL;
}
@@ -12023,108 +11931,43 @@ InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObje
uint8 _class = getClass();
if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0)
- return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ return EQUIP_ERR_PROFICIENCY_NEEDED;
- if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISC && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK)
+ if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISCELLANEOUS && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK)
{
if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT)
{
if (getLevel() < 40)
{
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_PLATE)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
else if (_class == CLASS_HUNTER || _class == CLASS_SHAMAN)
{
if (getLevel() < 40)
{
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
if (_class == CLASS_ROGUE || _class == CLASS_DRUID)
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
if (_class == CLASS_MAGE || _class == CLASS_PRIEST || _class == CLASS_WARLOCK)
if (proto->SubClass != ITEM_SUBCLASS_ARMOR_CLOTH)
- return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
return EQUIP_ERR_OK;
}
-InventoryResult Player::CanUseAmmo(uint32 item) const
-{
- TC_LOG_DEBUG("entities.player.items", "STORAGE: CanUseAmmo item = %u", item);
- if (!IsAlive())
- return EQUIP_ERR_YOU_ARE_DEAD;
- //if (isStunned())
- // return EQUIP_ERR_YOU_ARE_STUNNED;
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
- if (pProto)
- {
- if (pProto->InventoryType!= INVTYPE_AMMO)
- return EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE;
-
- InventoryResult res = CanUseItem(pProto);
- if (res != EQUIP_ERR_OK)
- return res;
-
- /*if (GetReputationMgr().GetReputation() < pProto->RequiredReputation)
- return EQUIP_ERR_CANT_EQUIP_REPUTATION;
- */
-
- // Requires No Ammo
- if (HasAura(46699))
- return EQUIP_ERR_BAG_FULL6;
-
- return EQUIP_ERR_OK;
- }
- return EQUIP_ERR_ITEM_NOT_FOUND;
-}
-
-void Player::SetAmmo(uint32 item)
-{
- if (!item)
- return;
-
- // already set
- if (GetUInt32Value(PLAYER_AMMO_ID) == item)
- return;
-
- // check ammo
- if (item)
- {
- InventoryResult msg = CanUseAmmo(item);
- if (msg != EQUIP_ERR_OK)
- {
- SendEquipError(msg, NULL, NULL, item);
- return;
- }
- }
-
- SetUInt32Value(PLAYER_AMMO_ID, item);
-
- _ApplyAmmoBonuses();
-}
-
-void Player::RemoveAmmo()
-{
- SetUInt32Value(PLAYER_AMMO_ID, 0);
-
- m_ammoDPS = 0.0f;
-
- if (CanModifyStats())
- UpdateDamagePhysical(RANGED_ATTACK);
-}
-
// Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case.
Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update, int32 randomPropertyId, AllowedLooterSet const& allowedLooters)
{
@@ -12226,10 +12069,6 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool
pItem->SetSlot(slot);
pItem->SetContainer(NULL);
-
- // need update known currency
- if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END)
- AddKnownCurrency(pItem->GetEntry());
}
else
pBag->StoreItem(slot, pItem, update);
@@ -12447,7 +12286,7 @@ void Player::SetVisibleItemSlot(uint8 slot, Item* pItem)
{
if (pItem)
{
- SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetEntry());
+ SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), pItem->GetVisibleEntry());
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 0, pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
SetUInt16Value(PLAYER_VISIBLE_ITEM_1_ENCHANTMENT + (slot * 2), 1, pItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
}
@@ -12745,34 +12584,6 @@ void Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, bool
}
}
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- {
- if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- {
- if (item->GetEntry() == itemEntry && !item->IsInTrade())
- {
- if (item->GetCount() + remcount <= count)
- {
- // all keys can be unequipped
- remcount += item->GetCount();
- DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
-
- if (remcount >= count)
- return;
- }
- else
- {
- ItemRemovedQuestCheck(item->GetEntry(), count - remcount);
- item->SetCount(item->GetCount() - count + remcount);
- if (IsInWorld() && update)
- item->SendUpdateToPlayer(this);
- item->SetState(ITEM_CHANGED, this);
- return;
- }
- }
- }
- }
-
// in inventory bags
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
{
@@ -12912,11 +12723,6 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone)
if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone))
DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone))
- DestroyItem(INVENTORY_SLOT_BAG_0, i, update);
-
// in inventory bags
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
if (Bag* pBag = GetBagByPos(i))
@@ -12967,11 +12773,6 @@ Item* Player::GetItemByEntry(uint32 entry) const
if (pItem->GetEntry() == entry)
return pItem;
- for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
- if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
- if (pItem->GetEntry() == entry)
- return pItem;
-
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
@@ -13029,21 +12830,21 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
if (pSrcItem->m_lootGenerated) // prevent split looting item (item
{
//best error message found for attempting to split while looting
- SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_SPLIT_FAILED, pSrcItem, NULL);
return;
}
// not let split all items (can be only at cheating)
if (pSrcItem->GetCount() == count)
{
- SendEquipError(EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_SPLIT_FAILED, pSrcItem, NULL);
return;
}
// not let split more existed items (can be only at cheating)
if (pSrcItem->GetCount() < count)
{
- SendEquipError(EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_TOO_FEW_TO_SPLIT, pSrcItem, NULL);
return;
}
@@ -13144,7 +12945,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (!IsAlive())
{
- SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, pSrcItem, pDstItem);
+ SendEquipError(EQUIP_ERR_PLAYER_DEAD, pSrcItem, pDstItem);
return;
}
@@ -13153,7 +12954,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (pSrcItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
- SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pSrcItem, NULL);
+ SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, pSrcItem, NULL);
return;
}
@@ -13172,14 +12973,14 @@ void Player::SwapItem(uint16 src, uint16 dst)
// prevent put equipped/bank bag in self
if (IsBagPos(src) && srcslot == dstbag)
{
- SendEquipError(EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem);
+ SendEquipError(EQUIP_ERR_BAG_IN_BAG, pSrcItem, pDstItem);
return;
}
// prevent equipping bag in the same slot from its inside
if (IsBagPos(dst) && srcbag == dstslot)
{
- SendEquipError(EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pSrcItem, pDstItem);
+ SendEquipError(EQUIP_ERR_CANT_SWAP, pSrcItem, pDstItem);
return;
}
@@ -13190,7 +12991,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (pDstItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
- SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, pDstItem, NULL);
+ SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, pDstItem, NULL);
return;
}
@@ -13387,7 +13188,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emptyProto))
{
// one from items not go to empty target bag
- SendEquipError(EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem);
+ SendEquipError(EQUIP_ERR_BAG_IN_BAG, pSrcItem, pDstItem);
return;
}
@@ -13397,7 +13198,7 @@ void Player::SwapItem(uint16 src, uint16 dst)
if (count > emptyBag->GetBagSize())
{
// too small targeted bag
- SendEquipError(EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pSrcItem, pDstItem);
+ SendEquipError(EQUIP_ERR_CANT_SWAP, pSrcItem, pDstItem);
return;
}
@@ -13591,16 +13392,16 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
data << uint32(proto ? proto->RequiredLevel : 0);
break;
}
- case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one...
+ case EQUIP_ERR_NO_OUTPUT: // no idea about this one...
{
data << uint64(0); // item guid
data << uint32(0); // slot
data << uint64(0); // container
break;
}
- case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED:
- case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED:
- case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED:
+ case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED_IS:
+ case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED_IS:
+ case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS:
{
ItemTemplate const* proto = pItem ? pItem->GetTemplate() : sObjectMgr->GetItemTemplate(itemid);
data << uint32(proto ? proto->ItemLimitCategory : 0);
@@ -13613,26 +13414,22 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
GetSession()->SendPacket(&data);
}
-void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param)
+void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 /*param*/)
{
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_BUY_FAILED");
WorldPacket data(SMSG_BUY_FAILED, (8+4+4+1));
data << uint64(creature ? creature->GetGUID() : 0);
data << uint32(item);
- if (param > 0)
- data << uint32(param);
data << uint8(msg);
GetSession()->SendPacket(&data);
}
-void Player::SendSellError(SellResult msg, Creature* creature, uint64 guid, uint32 param)
+void Player::SendSellError(SellResult msg, Creature* creature, uint64 guid)
{
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_SELL_ITEM");
- WorldPacket data(SMSG_SELL_ITEM, (8+8+(param?4:0)+1)); // last check 2.0.10
+ WorldPacket data(SMSG_SELL_ITEM, (8+8+1)); // last check 4.3.4
data << uint64(creature ? creature->GetGUID() : 0);
data << uint64(guid);
- if (param > 0)
- data << uint32(param);
data << uint8(msg);
GetSession()->SendPacket(&data);
}
@@ -13748,6 +13545,9 @@ void Player::AddEnchantmentDurations(Item* item)
{
for (int x = 0; x < MAX_ENCHANTMENT_SLOT; ++x)
{
+ if (x > PRISMATIC_ENCHANTMENT_SLOT && x < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
if (!item->GetEnchantmentId(EnchantmentSlot(x)))
continue;
@@ -13842,10 +13642,257 @@ void Player::AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 dur
}
}
+void Player::ApplyReforgeEnchantment(Item* item, bool apply)
+{
+ if (!item)
+ return;
+
+ ItemReforgeEntry const* reforge = sItemReforgeStore.LookupEntry(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));
+ if (!reforge)
+ return;
+
+ float removeValue = item->GetReforgableStat(ItemModType(reforge->SourceStat)) * reforge->SourceMultiplier;
+ float addValue = removeValue * reforge->FinalMultiplier;
+
+ switch (reforge->SourceStat)
+ {
+ case ITEM_MOD_MANA:
+ HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, -removeValue, apply);
+ break;
+ case ITEM_MOD_HEALTH:
+ HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, -removeValue, apply);
+ break;
+ case ITEM_MOD_AGILITY:
+ HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, -removeValue, apply);
+ ApplyStatBuffMod(STAT_AGILITY, -removeValue, apply);
+ break;
+ case ITEM_MOD_STRENGTH:
+ HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, -removeValue, apply);
+ ApplyStatBuffMod(STAT_STRENGTH, -removeValue, apply);
+ break;
+ case ITEM_MOD_INTELLECT:
+ HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, -removeValue, apply);
+ ApplyStatBuffMod(STAT_INTELLECT, -removeValue, apply);
+ break;
+ case ITEM_MOD_SPIRIT:
+ HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, -removeValue, apply);
+ ApplyStatBuffMod(STAT_SPIRIT, -removeValue, apply);
+ break;
+ case ITEM_MOD_STAMINA:
+ HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, -removeValue, apply);
+ ApplyStatBuffMod(STAT_STAMINA, -removeValue, apply);
+ break;
+ case ITEM_MOD_DEFENSE_SKILL_RATING:
+ ApplyRatingMod(CR_DEFENSE_SKILL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_DODGE_RATING:
+ ApplyRatingMod(CR_DODGE, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_PARRY_RATING:
+ ApplyRatingMod(CR_PARRY, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_BLOCK_RATING:
+ ApplyRatingMod(CR_BLOCK, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HIT_MELEE_RATING:
+ ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HIT_RANGED_RATING:
+ ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HIT_SPELL_RATING:
+ ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_CRIT_MELEE_RATING:
+ ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_CRIT_RANGED_RATING:
+ ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_CRIT_SPELL_RATING:
+ ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HASTE_SPELL_RATING:
+ ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HIT_RATING:
+ ApplyRatingMod(CR_HIT_MELEE, -int32(removeValue), apply);
+ ApplyRatingMod(CR_HIT_RANGED, -int32(removeValue), apply);
+ ApplyRatingMod(CR_HIT_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_CRIT_RATING:
+ ApplyRatingMod(CR_CRIT_MELEE, -int32(removeValue), apply);
+ ApplyRatingMod(CR_CRIT_RANGED, -int32(removeValue), apply);
+ ApplyRatingMod(CR_CRIT_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_RESILIENCE_RATING:
+ ApplyRatingMod(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HASTE_RATING:
+ ApplyRatingMod(CR_HASTE_MELEE, -int32(removeValue), apply);
+ ApplyRatingMod(CR_HASTE_RANGED, -int32(removeValue), apply);
+ ApplyRatingMod(CR_HASTE_SPELL, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_EXPERTISE_RATING:
+ ApplyRatingMod(CR_EXPERTISE, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, -removeValue, apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, -removeValue, apply);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ApplyManaRegenBonus(-int32(removeValue), apply);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ApplyRatingMod(CR_ARMOR_PENETRATION, -int32(removeValue), apply);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ApplySpellPowerBonus(-int32(removeValue), apply);
+ break;
+ case ITEM_MOD_HEALTH_REGEN:
+ ApplyHealthRegenBonus(-int32(removeValue), apply);
+ break;
+ case ITEM_MOD_SPELL_PENETRATION:
+ ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, -int32(removeValue), apply);
+ m_spellPenetrationItemMod += apply ? -int32(removeValue) : int32(removeValue);
+ break;
+ case ITEM_MOD_BLOCK_VALUE:
+ HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, -removeValue, apply);
+ break;
+ case ITEM_MOD_MASTERY_RATING:
+ ApplyRatingMod(CR_MASTERY, -int32(removeValue), apply);
+ break;
+ }
+
+ switch (reforge->FinalStat)
+ {
+ case ITEM_MOD_MANA:
+ HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, addValue, apply);
+ break;
+ case ITEM_MOD_HEALTH:
+ HandleStatModifier(UNIT_MOD_HEALTH, BASE_VALUE, addValue, apply);
+ break;
+ case ITEM_MOD_AGILITY:
+ HandleStatModifier(UNIT_MOD_STAT_AGILITY, TOTAL_VALUE, addValue, apply);
+ ApplyStatBuffMod(STAT_AGILITY, addValue, apply);
+ break;
+ case ITEM_MOD_STRENGTH:
+ HandleStatModifier(UNIT_MOD_STAT_STRENGTH, TOTAL_VALUE, addValue, apply);
+ ApplyStatBuffMod(STAT_STRENGTH, addValue, apply);
+ break;
+ case ITEM_MOD_INTELLECT:
+ HandleStatModifier(UNIT_MOD_STAT_INTELLECT, TOTAL_VALUE, addValue, apply);
+ ApplyStatBuffMod(STAT_INTELLECT, addValue, apply);
+ break;
+ case ITEM_MOD_SPIRIT:
+ HandleStatModifier(UNIT_MOD_STAT_SPIRIT, TOTAL_VALUE, addValue, apply);
+ ApplyStatBuffMod(STAT_SPIRIT, addValue, apply);
+ break;
+ case ITEM_MOD_STAMINA:
+ HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_VALUE, addValue, apply);
+ ApplyStatBuffMod(STAT_STAMINA, addValue, apply);
+ break;
+ case ITEM_MOD_DEFENSE_SKILL_RATING:
+ ApplyRatingMod(CR_DEFENSE_SKILL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_DODGE_RATING:
+ ApplyRatingMod(CR_DODGE, int32(addValue), apply);
+ break;
+ case ITEM_MOD_PARRY_RATING:
+ ApplyRatingMod(CR_PARRY, int32(addValue), apply);
+ break;
+ case ITEM_MOD_BLOCK_RATING:
+ ApplyRatingMod(CR_BLOCK, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HIT_MELEE_RATING:
+ ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HIT_RANGED_RATING:
+ ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HIT_SPELL_RATING:
+ ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_CRIT_MELEE_RATING:
+ ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply);
+ break;
+ case ITEM_MOD_CRIT_RANGED_RATING:
+ ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply);
+ break;
+ case ITEM_MOD_CRIT_SPELL_RATING:
+ ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HASTE_SPELL_RATING:
+ ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HIT_RATING:
+ ApplyRatingMod(CR_HIT_MELEE, int32(addValue), apply);
+ ApplyRatingMod(CR_HIT_RANGED, int32(addValue), apply);
+ ApplyRatingMod(CR_HIT_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_CRIT_RATING:
+ ApplyRatingMod(CR_CRIT_MELEE, int32(addValue), apply);
+ ApplyRatingMod(CR_CRIT_RANGED, int32(addValue), apply);
+ ApplyRatingMod(CR_CRIT_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_RESILIENCE_RATING:
+ ApplyRatingMod(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, int32(addValue), apply);
+ break;
+ case ITEM_MOD_HASTE_RATING:
+ ApplyRatingMod(CR_HASTE_MELEE, int32(addValue), apply);
+ ApplyRatingMod(CR_HASTE_RANGED, int32(addValue), apply);
+ ApplyRatingMod(CR_HASTE_SPELL, int32(addValue), apply);
+ break;
+ case ITEM_MOD_EXPERTISE_RATING:
+ ApplyRatingMod(CR_EXPERTISE, int32(addValue), apply);
+ break;
+ case ITEM_MOD_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, addValue, apply);
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply);
+ break;
+ case ITEM_MOD_RANGED_ATTACK_POWER:
+ HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, addValue, apply);
+ break;
+ case ITEM_MOD_MANA_REGENERATION:
+ ApplyManaRegenBonus(int32(addValue), apply);
+ break;
+ case ITEM_MOD_ARMOR_PENETRATION_RATING:
+ ApplyRatingMod(CR_ARMOR_PENETRATION, int32(addValue), apply);
+ break;
+ case ITEM_MOD_SPELL_POWER:
+ ApplySpellPowerBonus(int32(addValue), apply);
+ break;
+ case ITEM_MOD_HEALTH_REGEN:
+ ApplyHealthRegenBonus(int32(addValue), apply);
+ break;
+ case ITEM_MOD_SPELL_PENETRATION:
+ ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE, int32(addValue), apply);
+ m_spellPenetrationItemMod += apply ? int32(addValue) : -int32(addValue);
+ break;
+ case ITEM_MOD_BLOCK_VALUE:
+ HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, addValue, apply);
+ break;
+ case ITEM_MOD_MASTERY_RATING:
+ ApplyRatingMod(CR_MASTERY, int32(addValue), apply);
+ break;
+ }
+}
+
void Player::ApplyEnchantment(Item* item, bool apply)
{
for (uint32 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
+ {
+ // Apply reforge as last enchant
+ if (slot == REFORGE_ENCHANTMENT_SLOT)
+ continue;
+
ApplyEnchantment(item, EnchantmentSlot(slot), apply);
+ }
+
+ ApplyEnchantment(item, REFORGE_ENCHANTMENT_SLOT, apply);
}
void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur, bool ignore_condition)
@@ -13856,6 +13903,15 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (slot >= MAX_ENCHANTMENT_SLOT)
return;
+ if (slot == TRANSMOGRIFY_ENCHANTMENT_SLOT)
+ return;
+
+ if (slot == REFORGE_ENCHANTMENT_SLOT)
+ {
+ ApplyReforgeEnchantment(item, apply);
+ return;
+ }
+
uint32 enchant_id = item->GetEnchantmentId(slot);
if (!enchant_id)
return;
@@ -13873,6 +13929,11 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
if (pEnchant->requiredSkill > 0 && pEnchant->requiredSkillValue > GetSkillValue(pEnchant->requiredSkill))
return;
+ // Cogwheel gems dont have requirement data set in SpellItemEnchantment.dbc, but they do have it in Item-sparse.db2
+ if (ItemTemplate const* gem = sObjectMgr->GetItemTemplate(pEnchant->GemID))
+ if (gem->RequiredSkill && GetSkillValue(gem->RequiredSkill) < gem->RequiredSkillRank)
+ return;
+
// If we're dealing with a gem inside a prismatic socket we need to check the prismatic socket requirements
// rather than the gem requirements itself. If the socket has no color it is a prismatic socket.
if ((slot == SOCK_ENCHANTMENT_SLOT || slot == SOCK_ENCHANTMENT_SLOT_2 || slot == SOCK_ENCHANTMENT_SLOT_3)
@@ -13914,13 +13975,13 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
{
int32 basepoints = 0;
// Random Property Exist - try found basepoints for spell (basepoints depends from item suffix factor)
- if (item->GetItemRandomPropertyId())
+ if (item->GetItemRandomPropertyId() < 0)
{
ItemRandomSuffixEntry const* item_rand = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
if (item_rand)
{
// Search enchant_amount
- for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ for (int k = 0; k < 5; ++k)
{
if (item_rand->enchant_id[k] == enchant_id)
{
@@ -13966,7 +14027,7 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
ItemRandomSuffixEntry const* item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(item->GetItemRandomPropertyId()));
if (item_rand_suffix)
{
- for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
+ for (int k = 0; k < 5; ++k)
{
if (item_rand_suffix->enchant_id[k] == enchant_id)
{
@@ -14053,32 +14114,32 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
TC_LOG_DEBUG("entities.player.items", "+ %u SPELL_CRIT", enchant_amount);
break;
-// Values from ITEM_STAT_MELEE_HA_RATING to ITEM_MOD_HASTE_RANGED_RATING are never used
-// in Enchantments
-// case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
-// ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
-// ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
-// ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
-// ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:
-// ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
-// ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HASTE_MELEE_RATING:
-// ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
-// break;
-// case ITEM_MOD_HASTE_RANGED_RATING:
-// ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
-// break;
+ // Values from ITEM_STAT_MELEE_HA_RATING to ITEM_MOD_HASTE_RANGED_RATING are never used
+ // in Enchantments
+ // case ITEM_MOD_HIT_TAKEN_MELEE_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_HIT_TAKEN_RANGED_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_HIT_TAKEN_SPELL_RATING:
+ // ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_MELEE_RATING:
+ // ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_RANGED_RATING:
+ // ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_SPELL_RATING:
+ // ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_HASTE_MELEE_RATING:
+ // ApplyRatingMod(CR_HASTE_MELEE, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_HASTE_RANGED_RATING:
+ // ApplyRatingMod(CR_HASTE_RANGED, enchant_amount, apply);
+ // break;
case ITEM_MOD_HASTE_SPELL_RATING:
ApplyRatingMod(CR_HASTE_SPELL, enchant_amount, apply);
break;
@@ -14094,21 +14155,18 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
ApplyRatingMod(CR_CRIT_SPELL, enchant_amount, apply);
TC_LOG_DEBUG("entities.player.items", "+ %u CRITICAL", enchant_amount);
break;
-// Values ITEM_MOD_HIT_TAKEN_RATING and ITEM_MOD_CRIT_TAKEN_RATING are never used in Enchantment
-// case ITEM_MOD_HIT_TAKEN_RATING:
-// ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
-// ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
-// ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
-// case ITEM_MOD_CRIT_TAKEN_RATING:
-// ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
-// ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
-// ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
-// break;
+ // case ITEM_MOD_HIT_TAKEN_RATING: // Unused since 3.3.5
+ // ApplyRatingMod(CR_HIT_TAKEN_MELEE, enchant_amount, apply);
+ // ApplyRatingMod(CR_HIT_TAKEN_RANGED, enchant_amount, apply);
+ // ApplyRatingMod(CR_HIT_TAKEN_SPELL, enchant_amount, apply);
+ // break;
+ // case ITEM_MOD_CRIT_TAKEN_RATING: // Unused since 3.3.5
+ // ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
+ // ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
+ // ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+ // break;
case ITEM_MOD_RESILIENCE_RATING:
- ApplyRatingMod(CR_CRIT_TAKEN_MELEE, enchant_amount, apply);
- ApplyRatingMod(CR_CRIT_TAKEN_RANGED, enchant_amount, apply);
- ApplyRatingMod(CR_CRIT_TAKEN_SPELL, enchant_amount, apply);
+ ApplyRatingMod(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, enchant_amount, apply);
TC_LOG_DEBUG("entities.player.items", "+ %u RESILIENCE", enchant_amount);
break;
case ITEM_MOD_HASTE_RATING:
@@ -14130,10 +14188,6 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(enchant_amount), apply);
TC_LOG_DEBUG("entities.player.items", "+ %u RANGED_ATTACK_POWER", enchant_amount);
break;
-// case ITEM_MOD_FERAL_ATTACK_POWER:
-// ApplyFeralAPBonus(enchant_amount, apply);
-// TC_LOG_DEBUG("entities.player.items", "+ %u FERAL_ATTACK_POWER", enchant_amount);
-// break;
case ITEM_MOD_MANA_REGENERATION:
ApplyManaRegenBonus(enchant_amount, apply);
TC_LOG_DEBUG("entities.player.items", "+ %u MANA_REGENERATION", enchant_amount);
@@ -14158,8 +14212,10 @@ void Player::ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool
HandleBaseModValue(SHIELD_BLOCK_VALUE, FLAT_MOD, float(enchant_amount), apply);
TC_LOG_DEBUG("entities.player.items", "+ %u BLOCK_VALUE", enchant_amount);
break;
- case ITEM_MOD_SPELL_HEALING_DONE: // deprecated
- case ITEM_MOD_SPELL_DAMAGE_DONE: // deprecated
+ case ITEM_MOD_MASTERY_RATING:
+ ApplyRatingMod(CR_MASTERY, enchant_amount, apply);
+ TC_LOG_DEBUG("entities.player.items", "+ %u MASTERY", enchant_amount);
+ break;
default:
break;
}
@@ -14228,6 +14284,9 @@ void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16
{
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
{
+ if (slot > PRISMATIC_ENCHANTMENT_SLOT && slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
uint32 ench_id = m_items[i]->GetEnchantmentId(EnchantmentSlot(slot));
if (!ench_id)
continue;
@@ -14268,17 +14327,13 @@ void Player::UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16
void Player::SendEnchantmentDurations()
{
for (EnchantDurationList::const_iterator itr = m_enchantDuration.begin(); itr != m_enchantDuration.end(); ++itr)
- {
GetSession()->SendItemEnchantTimeUpdate(GetGUID(), itr->item->GetGUID(), itr->slot, uint32(itr->leftduration) / 1000);
- }
}
void Player::SendItemDurations()
{
for (ItemDurationList::const_iterator itr = m_itemDuration.begin(); itr != m_itemDuration.end(); ++itr)
- {
(*itr)->SendTimeUpdate(this);
- }
}
void Player::SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast)
@@ -14516,7 +14571,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men
return;
int32 cost = int32(item->BoxMoney);
- if (!HasEnoughMoney(cost))
+ if (!HasEnoughMoney(int64(cost)))
{
SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
PlayerTalkClass->SendCloseGossip();
@@ -14685,11 +14740,11 @@ void Player::PrepareQuestMenu(uint64 guid)
//only for quests which cast teleport spells on player
Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId());
ASSERT(_map);
- GameObject* pGameObject = _map->GetGameObject(guid);
- if (pGameObject)
+ GameObject* gameObject = _map->GetGameObject(guid);
+ if (gameObject)
{
- objectQR = sObjectMgr->GetGOQuestRelationBounds(pGameObject->GetEntry());
- objectQIR = sObjectMgr->GetGOQuestInvolvedRelationBounds(pGameObject->GetEntry());
+ objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry());
+ objectQIR = sObjectMgr->GetGOQuestInvolvedRelationBounds(gameObject->GetEntry());
}
else
return;
@@ -14821,24 +14876,40 @@ bool Player::IsActiveQuest(uint32 quest_id) const
Quest const* Player::GetNextQuest(uint64 guid, Quest const* quest)
{
QuestRelationBounds objectQR;
+ uint32 nextQuestID = quest->GetNextQuestInChain();
- Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid);
- if (creature)
- objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
- else
+ switch (GUID_HIPART(guid))
{
- //we should obtain map pointer from GetMap() in 99% of cases. Special case
- //only for quests which cast teleport spells on player
- Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId());
- ASSERT(_map);
- GameObject* pGameObject = _map->GetGameObject(guid);
- if (pGameObject)
- objectQR = sObjectMgr->GetGOQuestRelationBounds(pGameObject->GetEntry());
- else
+ case HIGHGUID_PLAYER:
+ ASSERT(quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT));
+ return sObjectMgr->GetQuestTemplate(nextQuestID);
+ case HIGHGUID_UNIT:
+ case HIGHGUID_PET:
+ case HIGHGUID_VEHICLE:
+ {
+ if (Creature* creature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this, guid))
+ objectQR = sObjectMgr->GetCreatureQuestRelationBounds(creature->GetEntry());
+ else
+ return NULL;
+ break;
+ }
+ case HIGHGUID_GAMEOBJECT:
+ {
+ //we should obtain map pointer from GetMap() in 99% of cases. Special case
+ //only for quests which cast teleport spells on player
+ Map* _map = IsInWorld() ? GetMap() : sMapMgr->FindMap(GetMapId(), GetInstanceId());
+ ASSERT(_map);
+ if (GameObject* gameObject = _map->GetGameObject(guid))
+ objectQR = sObjectMgr->GetGOQuestRelationBounds(gameObject->GetEntry());
+ else
+ return NULL;
+ break;
+ }
+ default:
return NULL;
}
- uint32 nextQuestID = quest->GetNextQuestInChain();
+ // for unit and go state
for (QuestRelations::const_iterator itr = objectQR.first; itr != objectQR.second; ++itr)
{
if (itr->second == nextQuestID)
@@ -14888,7 +14959,7 @@ bool Player::CanAddQuest(Quest const* quest, bool msg)
InventoryResult msg2 = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, srcitem, count);
// player already have max number (in most case 1) source item, no additional item needed and quest can be added.
- if (msg2 == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
+ if (msg2 == EQUIP_ERR_ITEM_MAX_COUNT)
return true;
else if (msg2 != EQUIP_ERR_OK)
{
@@ -14955,7 +15026,7 @@ bool Player::CanCompleteQuest(uint32 quest_id)
if (qInfo->GetRewOrReqMoney() < 0)
{
- if (!HasEnoughMoney(-qInfo->GetRewOrReqMoney()))
+ if (!HasEnoughMoney(-int64(qInfo->GetRewOrReqMoney())))
return false;
}
@@ -15017,8 +15088,12 @@ bool Player::CanRewardQuest(Quest const* quest, bool msg)
}
}
+ for (uint8 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; i++)
+ if (quest->RequiredCurrencyId[i] && !HasCurrency(quest->RequiredCurrencyId[i], quest->RequiredCurrencyCount[i]))
+ return false;
+
// prevent receive reward with low money and GetRewOrReqMoney() < 0
- if (quest->GetRewOrReqMoney() < 0 && !HasEnoughMoney(-quest->GetRewOrReqMoney()))
+ if (quest->GetRewOrReqMoney() < 0 && !HasEnoughMoney(-int64(quest->GetRewOrReqMoney())))
return false;
return true;
@@ -15198,7 +15273,7 @@ void Player::CompleteQuest(uint32 quest_id)
if (qInfo->HasFlag(QUEST_FLAGS_TRACKING))
RewardQuest(qInfo, 0, this, false);
else
- SendQuestComplete(quest_id);
+ SendQuestComplete(qInfo);
}
}
}
@@ -15227,6 +15302,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
if (quest->RequiredItemId[i])
DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true);
+ for (uint8 i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ if (quest->RequiredCurrencyId[i])
+ ModifyCurrency(quest->RequiredCurrencyId[i], -int32(quest->RequiredCurrencyCount[i]));
+
for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
{
if (quest->RequiredSourceItemId[i])
@@ -15267,6 +15346,13 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
}
}
+ for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ if (quest->RewardCurrencyId[i])
+ ModifyCurrency(quest->RewardCurrencyId[i], quest->RewardCurrencyCount[i]);
+
+ if (uint32 skill = quest->GetRewardSkillId())
+ UpdateSkillPro(skill, 1000, quest->GetRewardSkillPoints());
+
RewardReputation(quest);
uint16 log_slot = FindQuestSlot(quest_id);
@@ -15276,7 +15362,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
bool rewarded = (m_RewardedQuests.find(quest_id) != m_RewardedQuests.end());
// Not give XP in case already completed once repeatable quest
- uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this)*sWorld->getRate(RATE_XP_QUEST));
+ uint32 XP = rewarded ? 0 : uint32(quest->XPValue(this) * sWorld->getRate(RATE_XP_QUEST));
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
@@ -15289,6 +15375,9 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
else
moneyRew = int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY));
+ if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
+ guild->GiveXP(uint32(quest->XPValue(this) * sWorld->getRate(RATE_XP_QUEST) * sWorld->getRate(RATE_XP_GUILD_MODIFIER)), this);
+
// Give player extra money if GetRewOrReqMoney > 0 and get ReqMoney if negative
if (quest->GetRewOrReqMoney())
moneyRew += quest->GetRewOrReqMoney();
@@ -15312,15 +15401,12 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
SetTitle(titleEntry);
}
- if (quest->GetBonusTalents())
+ if (uint32 talents = quest->GetBonusTalents())
{
- m_questRewardTalentCount+=quest->GetBonusTalents();
+ AddQuestRewardedTalentCount(talents);
InitTalentForLevel();
}
- if (quest->GetRewArenaPoints())
- ModifyArenaPoints(quest->GetRewArenaPoints());
-
// Send reward mail
if (uint32 mail_template_id = quest->GetRewMailTemplateId())
{
@@ -15350,6 +15436,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
m_RewardedQuests.insert(quest_id);
m_RewardedQuestsSave[quest_id] = true;
+ PhaseUpdateData phaseUpdateData;
+ phaseUpdateData.AddQuestUpdate(quest_id);
+ phaseMgr.NotifyConditionChanged(phaseUpdateData);
+
// StoreNewItem, mail reward, etc. save data directly to the database
// to prevent exploitable data desynchronisation we save the quest status to the database too
// (to prevent rewarding this quest another time while rewards were already given out)
@@ -15897,7 +15987,7 @@ bool Player::GiveQuestSourceItem(Quest const* quest)
return true;
}
// player already have max amount required item, just report success
- else if (msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
+ else if (msg == EQUIP_ERR_ITEM_MAX_COUNT)
return true;
else
SendEquipError(msg, NULL, NULL, srcitem);
@@ -15995,6 +16085,11 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
m_QuestStatusSave[quest_id] = true;
}
+ PhaseUpdateData phaseUpdateData;
+ phaseUpdateData.AddQuestUpdate(quest_id);
+
+ phaseMgr.NotifyConditionChanged(phaseUpdateData);
+
uint32 zone = 0, area = 0;
SpellAreaForQuestMapBounds saBounds = sSpellMgr->GetSpellAreaForQuestMapBounds(quest_id);
@@ -16029,6 +16124,11 @@ void Player::RemoveActiveQuest(uint32 quest_id)
{
m_QuestStatus.erase(itr);
m_QuestStatusSave[quest_id] = false;
+
+ PhaseUpdateData phaseUpdateData;
+ phaseUpdateData.AddQuestUpdate(quest_id);
+
+ phaseMgr.NotifyConditionChanged(phaseUpdateData);
return;
}
}
@@ -16040,6 +16140,11 @@ void Player::RemoveRewardedQuest(uint32 quest_id)
{
m_RewardedQuests.erase(rewItr);
m_RewardedQuestsSave[quest_id] = false;
+
+ PhaseUpdateData phaseUpdateData;
+ phaseUpdateData.AddQuestUpdate(quest_id);
+
+ phaseMgr.NotifyConditionChanged(phaseUpdateData);
}
}
@@ -16217,7 +16322,8 @@ void Player::ItemAddedQuestCheck(uint32 entry, uint32 count)
m_QuestStatusSave[questid] = true;
- SendQuestUpdateAddItem(qInfo, j, additemcount);
+ //SendQuestUpdateAddItem(qInfo, j, additemcount);
+ // FIXME: verify if there's any packet sent updating item
}
if (CanCompleteQuest(questid))
CompleteQuest(questid);
@@ -16295,7 +16401,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid /*= 0*/)
}
StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_CREATURE, real_entry); // MUST BE CALLED FIRST
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, killed);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, real_entry, addkillcount, 0, killed);
for (uint8 i = 0; i < MAX_QUEST_LOG_SIZE; ++i)
{
@@ -16639,39 +16745,50 @@ bool Player::HasQuestForItem(uint32 itemid) const
return false;
}
-void Player::SendQuestComplete(uint32 quest_id)
+void Player::SendQuestComplete(Quest const* quest)
{
- if (quest_id)
+ if (quest)
{
WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4);
- data << uint32(quest_id);
+ data << uint32(quest->GetQuestId());
GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest_id);
+ TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_COMPLETE quest = %u", quest->GetQuestId());
}
}
void Player::SendQuestReward(Quest const* quest, uint32 XP)
{
- uint32 questid = quest->GetQuestId();
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid);
- sGameEventMgr->HandleQuestComplete(questid);
- WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4));
- data << uint32(questid);
+ uint32 questId = quest->GetQuestId();
+ TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questId);
+ sGameEventMgr->HandleQuestComplete(questId);
+
+ uint32 xp;
+ uint32 moneyReward;
if (getLevel() < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
{
- data << uint32(XP);
- data << uint32(quest->GetRewOrReqMoney());
+ xp = XP;
+ moneyReward = quest->GetRewOrReqMoney();
}
- else
+ else // At max level, increase gold reward
{
- data << uint32(0);
- data << uint32(quest->GetRewOrReqMoney() + int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY)));
+ xp = 0;
+ moneyReward = uint32(quest->GetRewOrReqMoney() + int32(quest->GetRewMoneyMaxLevel() * sWorld->getRate(RATE_DROP_MONEY)));
}
- data << uint32(10 * quest->CalculateHonorGain(GetQuestLevel(quest)));
- data << uint32(quest->GetBonusTalents()); // bonus talents
- data << uint32(quest->GetRewArenaPoints());
+ WorldPacket data(SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4));
+
+ data << uint32(quest->GetBonusTalents()); // bonus talents (not verified for 4.x)
+ data << uint32(quest->GetRewardSkillPoints()); // 4.x bonus skill points
+ data << uint32(moneyReward);
+ data << uint32(xp);
+ data << uint32(questId);
+ data << uint32(quest->GetRewardSkillId()); // 4.x bonus skill id
+
+ data.WriteBit(0); // FIXME: unknown bits, common values sent
+ data.WriteBit(1);
+ data.FlushBits();
+
GetSession()->SendPacket(&data);
}
@@ -16739,15 +16856,6 @@ void Player::SendPushToPartyResponse(Player* player, uint8 msg)
}
}
-void Player::SendQuestUpdateAddItem(Quest const* /*quest*/, uint32 /*item_idx*/, uint16 /*count*/)
-{
- WorldPacket data(SMSG_QUESTUPDATE_ADD_ITEM, 0);
- TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM");
- //data << quest->RequiredItemId[item_idx];
- //data << count;
- GetSession()->SendPacket(&data);
-}
-
void Player::SendQuestUpdateAddCreatureOrGo(Quest const* quest, uint64 guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count)
{
ASSERT(old_count + add_count < 65536 && "mob/GO count store in 16 bits 2^16 = 65536 (0..65536)");
@@ -16988,12 +17096,14 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
//QueryResult* result = CharacterDatabase.PQuery("SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
// 12 13 14 15 16 17 18 19 20 21 22 23 24
//"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
- // 25 26 27 28 29 30 31 32 33 34 35 36 37 38
- //"resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
- // 39 40 41 42 43 44 45 46 47 48 49
- //"arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
- // 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
- //"health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
+ // 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
+ //"resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
+ // 40 41 42 43 44 45
+ //"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
+ // 46 47 48 49 50 51 52 53 54 55 56
+ //"health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, "
+ // 57 58 59
+ //"knownTitles, actionBars, grantableLevels FROM characters WHERE guid = '%u'", guid);
PreparedQueryResult result = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_FROM);
if (!result)
{
@@ -17057,8 +17167,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
SetUInt32Value(PLAYER_XP, fields[7].GetUInt32());
- _LoadIntoDataField(fields[61].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
- _LoadIntoDataField(fields[64].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2);
+ _LoadIntoDataField(fields[55].GetCString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE);
+ _LoadIntoDataField(fields[57].GetCString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE*2);
SetObjectScale(1.0f);
SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);
@@ -17066,7 +17176,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// load achievements before anything else to prevent multiple gains for the same achievement/criteria on every loading (as loading does call UpdateAchievementCriteria)
m_achievementMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACHIEVEMENTS), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CRITERIA_PROGRESS));
- uint32 money = fields[8].GetUInt32();
+ uint64 money = fields[8].GetUInt64();
if (money > MAX_MONEY_AMOUNT)
money = MAX_MONEY_AMOUNT;
SetMoney(money);
@@ -17074,16 +17184,12 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32());
SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32());
SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8());
- SetByteValue(PLAYER_BYTES_3, 1, fields[49].GetUInt8());
+ SetByteValue(PLAYER_BYTES_3, 1, fields[45].GetUInt8());
SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32());
- SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetUInt32());
-
- SetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES, fields[47].GetUInt64());
-
- SetUInt32Value(PLAYER_AMMO_ID, fields[63].GetUInt32());
+ SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[44].GetUInt32());
// set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise)
- SetByteValue(PLAYER_FIELD_BYTES, 2, fields[65].GetUInt8());
+ SetByteValue(PLAYER_FIELD_BYTES, 2, fields[58].GetUInt8());
InitDisplayIds();
@@ -17111,21 +17217,23 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
InitPrimaryProfessions(); // to max set before any spell loaded
// init saved position, and fix it later if problematic
- uint32 transLowGUID = fields[30].GetUInt32();
+ uint32 transLowGUID = uint32(fields[31].GetUInt32());
+
Relocate(fields[12].GetFloat(), fields[13].GetFloat(), fields[14].GetFloat(), fields[16].GetFloat());
+
uint32 mapId = fields[15].GetUInt16();
- uint32 instanceId = fields[58].GetUInt32();
+ uint32 instanceId = fields[52].GetUInt32();
- uint32 dungeonDiff = fields[38].GetUInt8() & 0x0F;
+ uint32 dungeonDiff = fields[39].GetUInt8() & 0x0F;
if (dungeonDiff >= MAX_DUNGEON_DIFFICULTY)
dungeonDiff = DUNGEON_DIFFICULTY_NORMAL;
- uint32 raidDiff = (fields[38].GetUInt8() >> 4) & 0x0F;
+ uint32 raidDiff = (fields[39].GetUInt8() >> 4) & 0x0F;
if (raidDiff >= MAX_RAID_DIFFICULTY)
raidDiff = RAID_DIFFICULTY_10MAN_NORMAL;
SetDungeonDifficulty(Difficulty(dungeonDiff)); // may be changed in _LoadGroup
SetRaidDifficulty(Difficulty(raidDiff)); // may be changed in _LoadGroup
- std::string taxi_nodes = fields[37].GetString();
+ std::string taxi_nodes = fields[38].GetString();
#define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); }
@@ -17133,8 +17241,6 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
_LoadArenaTeamInfo(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ARENA_INFO));
- SetArenaPoints(fields[39].GetUInt32());
-
// check arena teams integrity
for (uint32 arena_slot = 0; arena_slot < MAX_ARENA_SLOT; ++arena_slot)
{
@@ -17151,12 +17257,10 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
SetArenaTeamInfoField(arena_slot, ArenaTeamInfoType(j), 0);
}
- SetHonorPoints(fields[40].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, fields[41].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, fields[42].GetUInt32());
- SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[43].GetUInt32());
- SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[44].GetUInt16());
- SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[45].GetUInt16());
+ _LoadCurrency(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CURRENCY));
+ SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[40].GetUInt32());
+ SetUInt16Value(PLAYER_FIELD_KILLS, 0, fields[41].GetUInt16());
+ SetUInt16Value(PLAYER_FIELD_KILLS, 1, fields[42].GetUInt16());
_LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES));
_LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES));
@@ -17227,7 +17331,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
if (m_transport)
{
m_movementInfo.transport.guid = transGUID;
- float x = fields[26].GetFloat(), y = fields[27].GetFloat(), z = fields[28].GetFloat(), o = fields[29].GetFloat();
+ float x = fields[27].GetFloat(), y = fields[28].GetFloat(), z = fields[29].GetFloat(), o = fields[30].GetFloat();
m_movementInfo.transport.pos.Relocate(x, y, z, o);
m_transport->CalculatePassengerPosition(x, y, z, &o);
@@ -17251,12 +17355,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
mapId = m_transport->GetMapId();
m_transport->AddPassenger(this);
- AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
}
}
else
{
- TC_LOG_ERROR("entities.player", "Player (guidlow %u) have problems with transport guid (%u). Teleport to bind location.",
+ TC_LOG_ERROR("entities.player", "Player (guidlow %d) have problems with transport guid (%u). Teleport to bind location.",
guid, transLowGUID);
RelocateToHomebind();
@@ -17330,7 +17433,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// NOW player must have valid map
// load the player's map here if it's not already loaded
Map* map = sMapMgr->CreateMap(mapId, this);
- AreaTrigger const* areaTrigger = NULL;
+ AreaTriggerStruct const* areaTrigger = NULL;
bool check = false;
if (!map)
@@ -17410,21 +17513,21 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32();
m_Played_time[PLAYED_TIME_LEVEL]= fields[20].GetUInt32();
- m_resetTalentsCost = fields[24].GetUInt32();
- m_resetTalentsTime = time_t(fields[25].GetUInt32());
+ SetTalentResetCost(fields[24].GetUInt32());
+ SetTalentResetTime(time_t(fields[25].GetUInt32()));
m_taxi.LoadTaxiMask(fields[17].GetString()); // must be before InitTaxiNodesForLevel
- uint32 extraflags = fields[31].GetUInt16();
+ uint32 extraflags = fields[32].GetUInt16();
- m_stableSlots = fields[32].GetUInt8();
+ m_stableSlots = fields[33].GetUInt8();
if (m_stableSlots > MAX_PET_STABLES)
{
TC_LOG_ERROR("entities.player", "Player can have not more %u stable slots, but have in DB %u", MAX_PET_STABLES, uint32(m_stableSlots));
m_stableSlots = MAX_PET_STABLES;
}
- m_atLoginFlags = fields[33].GetUInt16();
+ m_atLoginFlags = fields[34].GetUInt16();
if (HasAtLoginFlag(AT_LOGIN_RENAME))
{
@@ -17437,7 +17540,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
m_lastHonorUpdateTime = logoutTime;
UpdateHonorFields();
- m_deathExpireTime = time_t(fields[36].GetUInt32());
+ m_deathExpireTime = time_t(fields[37].GetUInt32());
if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP)
m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1;
@@ -17498,14 +17601,26 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
//mails are loaded only when needed ;-) - when player in game click on mailbox.
//_LoadMail();
- m_specsCount = fields[59].GetUInt8();
- m_activeSpec = fields[60].GetUInt8();
+ SetSpecsCount(fields[53].GetUInt8());
+ SetActiveSpec(fields[54].GetUInt8());
// sanity check
- if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || m_specsCount < MIN_TALENT_SPECS)
+ if (GetSpecsCount() > MAX_TALENT_SPECS || GetActiveSpec() > MAX_TALENT_SPEC || GetSpecsCount() < MIN_TALENT_SPECS)
+ {
+ SetActiveSpec(0);
+ TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName().c_str(), GetGUIDLow(), GetSpecsCount(), GetActiveSpec());
+ }
+
+ // Only load selected specializations, learning mastery spells requires this
+ Tokenizer talentTrees(fields[26].GetString(), ' ', MAX_TALENT_SPECS);
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
- m_activeSpec = 0;
- TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName().c_str(), GetGUIDLow(), m_specsCount, m_activeSpec);
+ if (i >= talentTrees.size())
+ break;
+
+ uint32 talentTree = atol(talentTrees[i]);
+ if (sTalentTabStore.LookupEntry(talentTree))
+ SetPrimaryTalentTree(i, talentTree);
}
_LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
@@ -17536,6 +17651,9 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
_LoadInventory(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INVENTORY), time_diff);
+ if (IsVoidStorageUnlocked())
+ _LoadVoidStorage(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE));
+
// update items with duration and realtime
UpdateItemDuration(time_diff, true);
@@ -17548,7 +17666,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES
// note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded
- uint32 curTitle = fields[46].GetUInt32();
+ uint32 curTitle = fields[43].GetUInt32();
if (curTitle && !HasTitle(curTitle))
curTitle = 0;
@@ -17571,12 +17689,35 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
UpdateAllStats();
// restore remembered power/health values (but not more max values)
- uint32 savedHealth = fields[50].GetUInt32();
+ uint32 savedHealth = fields[46].GetUInt32();
SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth);
- for (uint8 i = 0; i < MAX_POWERS; ++i)
+ uint32 loadedPowers = 0;
+ for (uint32 i = 0; i < MAX_POWERS; ++i)
{
- uint32 savedPower = fields[51+i].GetUInt32();
- SetPower(Powers(i), savedPower > GetMaxPower(Powers(i)) ? GetMaxPower(Powers(i)) : savedPower);
+ if (GetPowerIndex(i) != MAX_POWERS)
+ {
+ uint32 savedPower = fields[47+loadedPowers].GetUInt32();
+ uint32 maxPower = GetUInt32Value(UNIT_FIELD_MAXPOWER1 + loadedPowers);
+ SetPower(Powers(i), (savedPower > maxPower) ? maxPower : savedPower);
+ if (++loadedPowers >= MAX_POWERS_PER_CLASS)
+ break;
+ }
+ }
+
+ for (; loadedPowers < MAX_POWERS_PER_CLASS; ++loadedPowers)
+ SetUInt32Value(UNIT_FIELD_POWER1 + loadedPowers, 0);
+
+ SetPower(POWER_ECLIPSE, 0);
+
+ // Verify loaded talent specializations
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ {
+ if (i >= talentTrees.size())
+ break;
+
+ uint32 talentTree = atol(talentTrees[i]);
+ if (talentTree != 0 && !sTalentTabStore.LookupEntry(talentTree) && i == GetActiveSpec())
+ SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents
}
TC_LOG_DEBUG("entities.player.loading", "The value of player %s after load item and aura is: ", m_name.c_str());
@@ -17631,7 +17772,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
}
// RaF stuff.
- m_grantableLevels = fields[66].GetUInt8();
+ m_grantableLevels = fields[59].GetUInt8();
if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0))
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND);
@@ -17640,13 +17781,50 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
_LoadDeclinedNames(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_DECLINED_NAMES));
- m_achievementMgr->CheckAllAchievementCriteria();
+ m_achievementMgr->CheckAllAchievementCriteria(this);
_LoadEquipmentSets(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS));
+ _LoadCUFProfiles(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES));
+
return true;
}
+void Player::_LoadCUFProfiles(PreparedQueryResult result)
+{
+ if (!result)
+ return;
+
+ do
+ {
+ // SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ?
+ Field* fields = result->Fetch();
+
+ uint8 id = fields[0].GetUInt8();
+ std::string name = fields[1].GetString();
+ uint16 frameHeight = fields[2].GetUInt16();
+ uint16 frameWidth = fields[3].GetUInt16();
+ uint8 sortBy = fields[4].GetUInt8();
+ uint8 healthText = fields[5].GetUInt8();
+ uint32 boolOptions = fields[6].GetUInt32();
+ uint8 unk146 = fields[7].GetUInt8();
+ uint8 unk147 = fields[8].GetUInt8();
+ uint8 unk148 = fields[9].GetUInt8();
+ uint16 unk150 = fields[10].GetUInt16();
+ uint16 unk152 = fields[11].GetUInt16();
+ uint16 unk154 = fields[12].GetUInt16();
+
+ if (id > MAX_CUF_PROFILES)
+ {
+ TC_LOG_ERROR("entities.player", "Player::_LoadCUFProfiles - Player (GUID: %u, name: %s) has an CUF profile with invalid id (id: %u), max is %i.", GetGUIDLow(), GetName().c_str(), id, MAX_CUF_PROFILES);
+ continue;
+ }
+
+ _CUFProfiles[id] = new CUFProfile(name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154);
+ }
+ while (result->NextRow());
+}
+
bool Player::isAllowedToLoot(const Creature* creature)
{
if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward())
@@ -17800,7 +17978,7 @@ void Player::_LoadGlyphAuras()
{
for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
{
- if (uint32 glyph = GetGlyph(i))
+ if (uint32 glyph = GetGlyph(GetActiveSpec(), i))
{
if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph))
{
@@ -17924,7 +18102,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
{
std::map<uint32, Item*>::iterator itr = invalidBagMap.find(bagGuid);
if (std::find(problematicItems.begin(), problematicItems.end(), itr->second) != problematicItems.end())
- err = EQUIP_ERR_INT_BAG_ERROR;
+ err = EQUIP_ERR_INTERNAL_BAG_ERROR;
}
else
{
@@ -17971,6 +18149,53 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff)
_ApplyAllItemMods();
}
+void Player::_LoadVoidStorage(PreparedQueryResult result)
+{
+ if (!result)
+ return;
+
+ do
+ {
+ // SELECT itemid, itemEntry, slot, creatorGuid FROM character_void_storage WHERE playerGuid = ?
+ Field* fields = result->Fetch();
+
+ uint64 itemId = fields[0].GetUInt64();
+ uint32 itemEntry = fields[1].GetUInt32();
+ uint8 slot = fields[2].GetUInt8();
+ uint32 creatorGuid = fields[3].GetUInt32();
+ uint32 randomProperty = fields[4].GetUInt32();
+ uint32 suffixFactor = fields[5].GetUInt32();
+
+ if (!itemId)
+ {
+ TC_LOG_ERROR("entities.player", "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid id (item id: " UI64FMTD ", entry: %u).", GetGUIDLow(), GetName().c_str(), itemId, itemEntry);
+ continue;
+ }
+
+ if (!sObjectMgr->GetItemTemplate(itemEntry))
+ {
+ TC_LOG_ERROR("entities.player", "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid entry (item id: " UI64FMTD ", entry: %u).", GetGUIDLow(), GetName().c_str(), itemId, itemEntry);
+ continue;
+ }
+
+ if (slot >= VOID_STORAGE_MAX_SLOT)
+ {
+ TC_LOG_ERROR("entities.player", "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid slot (item id: " UI64FMTD ", entry: %u, slot: %u).", GetGUIDLow(), GetName().c_str(), itemId, itemEntry, slot);
+ continue;
+ }
+
+ std::string name;
+ if (creatorGuid && !sObjectMgr->GetPlayerNameByGUID(creatorGuid, name))
+ {
+ TC_LOG_ERROR("entities.player", "Player::_LoadVoidStorage - Player (GUID: %u, name: %s) has an item with an invalid creator guid, set to 0 (item id: " UI64FMTD ", entry: %u, creatorGuid: %u).", GetGUIDLow(), GetName().c_str(), itemId, itemEntry, creatorGuid);
+ creatorGuid = 0;
+ }
+
+ _voidStorageItems[slot] = new VoidStorageItem(itemId, itemEntry, creatorGuid, randomProperty, suffixFactor);
+ }
+ while (result->NextRow());
+}
+
Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, Field* fields)
{
Item* item = NULL;
@@ -18192,8 +18417,8 @@ void Player::_LoadMail()
bool has_items = fields[6].GetBool();
m->expire_time = time_t(fields[7].GetUInt32());
m->deliver_time = time_t(fields[8].GetUInt32());
- m->money = fields[9].GetUInt32();
- m->COD = fields[10].GetUInt32();
+ m->money = fields[9].GetUInt64();
+ m->COD = fields[10].GetUInt64();
m->checked = fields[11].GetUInt8();
m->stationery = fields[12].GetUInt8();
m->mailTemplateId = fields[13].GetInt16();
@@ -18343,8 +18568,8 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result)
SetTitle(titleEntry);
}
- if (quest->GetBonusTalents())
- m_questRewardTalentCount += quest->GetBonusTalents();
+ if (uint32 talents = quest->GetBonusTalents())
+ AddQuestRewardedTalentCount(talents);
}
m_RewardedQuests.insert(quest_id);
@@ -18533,7 +18758,7 @@ void Player::_LoadBoundInstances(PreparedQueryResult result)
bool deleteInstance = false;
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
- std::string mapname = mapEntry ? mapEntry->name[sWorld->GetDefaultDbcLocale()] : "Unknown";
+ std::string mapname = mapEntry ? mapEntry->name : "Unknown";
if (!mapEntry || !mapEntry->IsDungeon())
{
@@ -18727,16 +18952,25 @@ 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;
+ uint32 completedEncounters = 0;
+ if (Map* map = sMapMgr->FindMap(save->GetMapId(), save->GetInstanceId()))
+ if (InstanceScript* instanceScript = ((InstanceMap*)map)->GetInstanceScript())
+ completedEncounters = instanceScript->GetCompletedEncounterMask();
+
data << uint32(save->GetMapId()); // map id
data << uint32(save->GetDifficulty()); // difficulty
+ data << uint32(isHeroic); // heroic
data << uint64(save->GetInstanceId()); // instance id
data << uint8(1); // expired = 0
data << uint8(0); // extended = 1
data << uint32(save->GetResetTime() - now); // reset time
+ data << uint32(completedEncounters); // completed encounters mask
++counter;
}
}
}
+
data.put<uint32>(p_counter, counter);
GetSession()->SendPacket(&data);
}
@@ -18761,8 +18995,8 @@ void Player::SendSavedInstances()
}
}
- //Send opcode 811. true or false means, whether you have current raid/heroic instances
- data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP);
+ //Send opcode SMSG_UPDATE_INSTANCE_OWNERSHIP. true or false means, whether you have current raid/heroic instances
+ data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP, 4);
data << uint32(hasBeenSaved);
GetSession()->SendPacket(&data);
@@ -18775,7 +19009,7 @@ void Player::SendSavedInstances()
{
if (itr->second.perm)
{
- data.Initialize(SMSG_UPDATE_LAST_INSTANCE);
+ data.Initialize(SMSG_UPDATE_LAST_INSTANCE, 4);
data << uint32(itr->second.save->GetMapId());
GetSession()->SendPacket(&data);
}
@@ -18923,7 +19157,8 @@ bool Player::_LoadHomeBind(PreparedQueryResult result)
PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass());
if (!info)
{
- TC_LOG_ERROR("entities.player", "Player (Name %s) has incorrect race/class pair. Can't be loaded.", GetName().c_str());
+ TC_LOG_ERROR("entities.player", "Player (Name %s) has incorrect race/class (%u/%u) pair. Can't be loaded.",
+ GetName().c_str(), uint32(getRace()), uint32(getClass()));
return false;
}
@@ -19015,7 +19250,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, getGender());
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
- stmt->setUInt32(index++, GetMoney());
+ stmt->setUInt64(index++, GetMoney());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
@@ -19046,8 +19281,13 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0));
//save, far from tavern/city
//save, but in tavern/city
- stmt->setUInt32(index++, m_resetTalentsCost);
- stmt->setUInt32(index++, uint32(m_resetTalentsTime));
+ stmt->setUInt32(index++, GetTalentResetCost());
+ stmt->setUInt32(index++, GetTalentResetTime());
+
+ ss.str("");
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ ss << GetPrimaryTalentTree(i) << " ";
+ stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
stmt->setUInt16(index++, (uint16)m_atLoginFlags);
@@ -19058,26 +19298,32 @@ void Player::SaveToDB(bool create /*=false*/)
ss << m_taxi.SaveTaxiDestinationsToString();
stmt->setString(index++, ss.str());
- stmt->setUInt32(index++, GetArenaPoints());
- stmt->setUInt32(index++, GetHonorPoints());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION));
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 0));
stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 1));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE));
- stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX));
stmt->setUInt8(index++, GetDrunkValue());
stmt->setUInt32(index++, GetHealth());
+ uint32 storedPowers = 0;
for (uint32 i = 0; i < MAX_POWERS; ++i)
- stmt->setUInt32(index++, GetPower(Powers(i)));
+ {
+ if (GetPowerIndex(i) != MAX_POWERS)
+ {
+ stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers));
+ if (++storedPowers >= MAX_POWERS_PER_CLASS)
+ break;
+ }
+ }
+
+ for (; storedPowers < MAX_POWERS_PER_CLASS; ++storedPowers)
+ stmt->setUInt32(index++, 0);
stmt->setUInt32(index++, GetSession()->GetLatency());
- stmt->setUInt8(index++, m_specsCount);
- stmt->setUInt8(index++, m_activeSpec);
+ stmt->setUInt8(index++, GetSpecsCount());
+ stmt->setUInt8(index++, GetActiveSpec());
ss.str("");
for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i)
@@ -19098,15 +19344,13 @@ void Player::SaveToDB(bool create /*=false*/)
ss << '0';
ss << " 0 ";
}
-
stmt->setString(index++, ss.str());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_AMMO_ID));
ss.str("");
for (uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i)
ss << GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES + i) << ' ';
-
stmt->setString(index++, ss.str());
+
stmt->setUInt8(index++, GetByteValue(PLAYER_FIELD_BYTES, 2));
stmt->setUInt32(index++, m_grantableLevels);
}
@@ -19120,7 +19364,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, getGender());
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
- stmt->setUInt32(index++, GetMoney());
+ stmt->setUInt64(index++, GetMoney());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_BYTES_2));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS));
@@ -19166,8 +19410,13 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt8(index++, (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) ? 1 : 0));
//save, far from tavern/city
//save, but in tavern/city
- stmt->setUInt32(index++, m_resetTalentsCost);
- stmt->setUInt32(index++, uint32(m_resetTalentsTime));
+ stmt->setUInt32(index++, GetTalentResetCost());
+ stmt->setUInt32(index++, GetTalentResetTime());
+
+ ss.str("");
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ ss << GetPrimaryTalentTree(i) << " ";
+ stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
stmt->setUInt16(index++, (uint16)m_atLoginFlags);
@@ -19178,26 +19427,32 @@ void Player::SaveToDB(bool create /*=false*/)
ss << m_taxi.SaveTaxiDestinationsToString();
stmt->setString(index++, ss.str());
- stmt->setUInt32(index++, GetArenaPoints());
- stmt->setUInt32(index++, GetHonorPoints());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION));
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 0));
stmt->setUInt16(index++, GetUInt16Value(PLAYER_FIELD_KILLS, 1));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE));
- stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX));
stmt->setUInt8(index++, GetDrunkValue());
stmt->setUInt32(index++, GetHealth());
+ uint32 storedPowers = 0;
for (uint32 i = 0; i < MAX_POWERS; ++i)
- stmt->setUInt32(index++, GetPower(Powers(i)));
+ {
+ if (GetPowerIndex(i) != MAX_POWERS)
+ {
+ stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_POWER1 + storedPowers));
+ if (++storedPowers >= MAX_POWERS_PER_CLASS)
+ break;
+ }
+ }
+
+ for (; storedPowers < MAX_POWERS_PER_CLASS; ++storedPowers)
+ stmt->setUInt32(index++, 0);
stmt->setUInt32(index++, GetSession()->GetLatency());
- stmt->setUInt8(index++, m_specsCount);
- stmt->setUInt8(index++, m_activeSpec);
+ stmt->setUInt8(index++, GetSpecsCount());
+ stmt->setUInt8(index++, GetActiveSpec());
ss.str("");
for (uint32 i = 0; i < PLAYER_EXPLORED_ZONES_SIZE; ++i)
@@ -19220,7 +19475,6 @@ void Player::SaveToDB(bool create /*=false*/)
}
stmt->setString(index++, ss.str());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_AMMO_ID));
ss.str("");
for (uint32 i = 0; i < KNOWN_TITLES_SIZE*2; ++i)
@@ -19244,6 +19498,7 @@ void Player::SaveToDB(bool create /*=false*/)
_SaveBGData(trans);
_SaveInventory(trans);
+ _SaveVoidStorage(trans);
_SaveQuestStatus(trans);
_SaveDailyQuestStatus(trans);
_SaveWeeklyQuestStatus(trans);
@@ -19261,6 +19516,8 @@ void Player::SaveToDB(bool create /*=false*/)
GetSession()->SaveTutorialsData(trans); // changed only while character in game
_SaveGlyphs(trans);
_SaveInstanceTimeRestrictions(trans);
+ _SaveCurrency(trans);
+ _SaveCUFProfiles(trans);
// check if stats should only be saved on logout
// save stats can be out of transaction
@@ -19278,13 +19535,14 @@ void Player::SaveToDB(bool create /*=false*/)
void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans)
{
_SaveInventory(trans);
+ _SaveCurrency(trans);
SaveGoldToDB(trans);
}
void Player::SaveGoldToDB(SQLTransaction& trans)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_MONEY);
- stmt->setUInt32(0, GetMoney());
+ stmt->setUInt64(0, GetMoney());
stmt->setUInt32(1, GetGUIDLow());
trans->Append(stmt);
}
@@ -19300,7 +19558,7 @@ void Player::_SaveActions(SQLTransaction& trans)
case ACTIONBUTTON_NEW:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION);
stmt->setUInt32(0, GetGUIDLow());
- stmt->setUInt8(1, m_activeSpec);
+ stmt->setUInt8(1, GetActiveSpec());
stmt->setUInt8(2, itr->first);
stmt->setUInt32(3, itr->second.GetAction());
stmt->setUInt8(4, uint8(itr->second.GetType()));
@@ -19315,7 +19573,7 @@ void Player::_SaveActions(SQLTransaction& trans)
stmt->setUInt8(1, uint8(itr->second.GetType()));
stmt->setUInt32(2, GetGUIDLow());
stmt->setUInt8(3, itr->first);
- stmt->setUInt8(4, m_activeSpec);
+ stmt->setUInt8(4, GetActiveSpec());
trans->Append(stmt);
itr->second.uState = ACTIONBUTTON_UNCHANGED;
@@ -19325,7 +19583,7 @@ void Player::_SaveActions(SQLTransaction& trans)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC);
stmt->setUInt32(0, GetGUIDLow());
stmt->setUInt8(1, itr->first);
- stmt->setUInt8(2, m_activeSpec);
+ stmt->setUInt8(2, GetActiveSpec());
trans->Append(stmt);
m_actionButtons.erase(itr++);
@@ -19484,7 +19742,7 @@ void Player::_SaveInventory(SQLTransaction& trans)
// save all changes to the item...
if (item->GetState() != ITEM_NEW) // only for existing items, no dupes
item->SaveToDB(trans);
- // ...but do not save position in invntory
+ // ...but do not save position in inventory
continue;
}
}
@@ -19513,6 +19771,76 @@ void Player::_SaveInventory(SQLTransaction& trans)
m_itemUpdateQueue.clear();
}
+void Player::_SaveVoidStorage(SQLTransaction& trans)
+{
+ PreparedStatement* stmt = NULL;
+ uint32 lowGuid = GetGUIDLow();
+
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ {
+ if (!_voidStorageItems[i]) // unused item
+ {
+ // DELETE FROM void_storage WHERE slot = ? AND playerGuid = ?
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT);
+ stmt->setUInt8(0, i);
+ stmt->setUInt32(1, lowGuid);
+ }
+ else
+ {
+ // REPLACE INTO character_inventory (itemId, playerGuid, itemEntry, slot, creatorGuid) VALUES (?, ?, ?, ?, ?)
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM);
+ stmt->setUInt64(0, _voidStorageItems[i]->ItemId);
+ stmt->setUInt32(1, lowGuid);
+ stmt->setUInt32(2, _voidStorageItems[i]->ItemEntry);
+ stmt->setUInt8(3, i);
+ stmt->setUInt32(4, _voidStorageItems[i]->CreatorGuid);
+ stmt->setUInt32(5, _voidStorageItems[i]->ItemRandomPropertyId);
+ stmt->setUInt32(6, _voidStorageItems[i]->ItemSuffixFactor);
+ }
+
+ trans->Append(stmt);
+ }
+}
+
+
+void Player::_SaveCUFProfiles(SQLTransaction& trans)
+{
+ PreparedStatement* stmt = NULL;
+ uint32 lowGuid = GetGUIDLow();
+
+ for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
+ {
+ if (!_CUFProfiles[i]) // unused profile
+ {
+ // DELETE FROM character_cuf_profiles WHERE guid = ? and id = ?
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_CUF_PROFILES);
+ stmt->setUInt32(0, lowGuid);
+ stmt->setUInt8(1, i);
+ }
+ else
+ {
+ // REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_CUF_PROFILES);
+ stmt->setUInt32(0, lowGuid);
+ stmt->setUInt8(1, i);
+ stmt->setString(2, _CUFProfiles[i]->ProfileName);
+ stmt->setUInt16(3, _CUFProfiles[i]->FrameHeight);
+ stmt->setUInt16(4, _CUFProfiles[i]->FrameWidth);
+ stmt->setUInt8(5, _CUFProfiles[i]->SortBy);
+ stmt->setUInt8(6, _CUFProfiles[i]->HealthText);
+ stmt->setUInt32(7, _CUFProfiles[i]->BoolOptions.to_ulong()); // 27 of 32 fields used, fits in an int
+ stmt->setUInt8(8, _CUFProfiles[i]->Unk146);
+ stmt->setUInt8(9, _CUFProfiles[i]->Unk147);
+ stmt->setUInt8(10, _CUFProfiles[i]->Unk148);
+ stmt->setUInt16(11, _CUFProfiles[i]->Unk150);
+ stmt->setUInt16(12, _CUFProfiles[i]->Unk152);
+ stmt->setUInt16(13, _CUFProfiles[i]->Unk154);
+ }
+
+ trans->Append(stmt);
+ }
+}
+
void Player::_SaveMail(SQLTransaction& trans)
{
if (!m_mailsLoaded)
@@ -19794,9 +20122,11 @@ void Player::_SaveSkills(SQLTransaction& trans)
continue;
}
- uint32 valueData = GetUInt32Value(PLAYER_SKILL_VALUE_INDEX(itr->second.pos));
- uint16 value = SKILL_VALUE(valueData);
- uint16 max = SKILL_MAX(valueData);
+ uint16 field = itr->second.pos / 2;
+ uint8 offset = itr->second.pos & 1;
+
+ uint16 value = GetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset);
+ uint16 max = GetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset);
switch (itr->second.uState)
{
@@ -19807,7 +20137,6 @@ void Player::_SaveSkills(SQLTransaction& trans)
stmt->setUInt16(2, value);
stmt->setUInt16(3, max);
trans->Append(stmt);
-
break;
case SKILL_CHANGED:
stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_CHAR_SKILLS);
@@ -19816,13 +20145,12 @@ void Player::_SaveSkills(SQLTransaction& trans)
stmt->setUInt32(2, GetGUIDLow());
stmt->setUInt16(3, uint16(itr->first));
trans->Append(stmt);
-
break;
default:
break;
}
- itr->second.uState = SKILL_UNCHANGED;
+ itr->second.uState = SKILL_UNCHANGED;
++itr;
}
}
@@ -19885,7 +20213,7 @@ void Player::_SaveStats(SQLTransaction& trans)
stmt->setUInt32(index++, GetGUIDLow());
stmt->setUInt32(index++, GetMaxHealth());
- for (uint8 i = 0; i < MAX_POWERS; ++i)
+ for (uint8 i = 0; i < MAX_POWERS_PER_CLASS; ++i)
stmt->setUInt32(index++, GetMaxPower(Powers(i)));
for (uint8 i = 0; i < MAX_STATS; ++i)
@@ -19903,7 +20231,7 @@ void Player::_SaveStats(SQLTransaction& trans)
stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_ATTACK_POWER));
stmt->setUInt32(index++, GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER));
stmt->setUInt32(index++, GetBaseSpellPowerBonus());
- stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_CRIT_TAKEN_SPELL));
+ stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + CR_RESILIENCE_PLAYER_DAMAGE_TAKEN));
trans->Append(stmt);
}
@@ -19991,15 +20319,15 @@ void Player::SavePositionInDB(uint32 mapid, float x, float y, float z, float o,
CharacterDatabase.Execute(stmt);
}
-void Player::SetUInt32ValueInArray(Tokenizer& tokens, uint16 index, uint32 value)
+void Player::SetUInt32ValueInArray(Tokenizer& Tokenizer, uint16 index, uint32 value)
{
char buf[11];
snprintf(buf, 11, "%u", value);
- if (index >= tokens.size())
+ if (index >= Tokenizer.size())
return;
- tokens[index] = buf;
+ Tokenizer[index] = buf;
}
void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair)
@@ -20086,10 +20414,9 @@ void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty)
GetSession()->SendPacket(&data);
}
-void Player::SendResetFailedNotify(uint32 mapid)
+void Player::SendResetFailedNotify(uint32 /*mapid*/)
{
WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4);
- data << uint32(mapid);
GetSession()->SendPacket(&data);
}
@@ -20156,7 +20483,7 @@ void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId)
// 1: There are players offline in your party.
// 2>: There are players in your party attempting to zone into an instance.
*/
- WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4);
+ WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 8);
data << uint32(reason);
data << uint32(MapId);
GetSession()->SendPacket(&data);
@@ -20381,12 +20708,25 @@ void Player::TextEmote(const std::string& text)
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !GetSession()->HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT));
}
+void Player::WhisperAddon(const std::string& text, const std::string& prefix, Player* receiver)
+{
+ std::string _text(text);
+ sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, LANG_ADDON, _text, receiver);
+
+ 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);
+}
+
void Player::Whisper(const std::string& text, uint32 language, uint64 receiver)
{
bool isAddonMessage = language == LANG_ADDON;
- if (!isAddonMessage) // if not addon data
- language = LANG_UNIVERSAL; // whispers should always be readable
+ if (!isAddonMessage) // if not addon data
+ language = LANG_UNIVERSAL; // whispers should always be readable
Player* rPlayer = ObjectAccessor::FindPlayer(receiver);
@@ -20716,33 +21056,37 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod
void Player::AddSpellMod(SpellModifier* mod, bool apply)
{
TC_LOG_DEBUG("spells", "Player::AddSpellMod %d", mod->spellId);
- uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
+ Opcodes opcode = Opcodes((mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER);
int i = 0;
flag96 _mask = 0;
+ 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)
{
- if (eff != 0 && eff%32 == 0)
+ if (eff != 0 && (eff % 32) == 0)
_mask[i++] = 0;
- _mask[i] = uint32(1) << (eff-(32*i));
+ _mask[i] = uint32(1) << (eff - (32 * i));
if (mod->mask & _mask)
{
int32 val = 0;
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);
- WorldPacket data(Opcode, (1+1+4));
+
data << uint8(eff);
- data << uint8(mod->op);
- data << int32(val);
- SendDirectMessage(&data);
+ data << float(val);
+ ++modTypeCount;
}
}
-
+ data.put<uint32>(writePos, modTypeCount);
+ SendDirectMessage(&data);
if (apply)
m_spellMods[mod->op].push_back(mod);
else
@@ -21169,7 +21513,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
return false;
}
- uint32 money = GetMoney();
+ uint64 money = GetMoney();
if (npc)
totalcost = (uint32)ceil(totalcost*GetReputationPriceDiscount(npc));
@@ -21182,7 +21526,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc
}
//Checks and preparations done, DO FLIGHT
- ModifyMoney(-(int32)totalcost);
+ ModifyMoney(-int64(totalcost));
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1);
@@ -21323,7 +21667,7 @@ void Player::InitDataForForm(bool reapplyMods)
{
ShapeshiftForm form = GetShapeshiftForm();
- SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (ssEntry && ssEntry->attackSpeed)
{
SetAttackTime(BASE_ATTACK, ssEntry->attackSpeed);
@@ -21343,7 +21687,6 @@ void Player::InitDataForForm(bool reapplyMods)
break;
}
case FORM_BEAR:
- case FORM_DIREBEAR:
{
if (getPowerType() != POWER_RAGE)
setPowerType(POWER_RAGE);
@@ -21394,10 +21737,11 @@ void Player::InitDisplayIds()
inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore)
{
+ uint32 stacks = count / pProto->BuyCount;
ItemPosCountVec vDest;
uint16 uiDest = 0;
InventoryResult msg = bStore ?
- CanStoreNewItem(bag, slot, vDest, item, pProto->BuyCount * count) :
+ CanStoreNewItem(bag, slot, vDest, item, count) :
CanEquipNewItem(slot, uiDest, item, false);
if (msg != EQUIP_ERR_OK)
{
@@ -21407,19 +21751,22 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
ModifyMoney(-price);
- if (crItem->ExtendedCost) // case for new honor system
+ if (crItem->ExtendedCost) // case for new honor system
{
ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
- if (iece->reqhonorpoints)
- ModifyHonorPoints(- int32(iece->reqhonorpoints * count));
-
- if (iece->reqarenapoints)
- ModifyArenaPoints(- int32(iece->reqarenapoints * count));
+ for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (iece->RequiredItem[i])
+ DestroyItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks, true);
+ }
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i)
+ for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
{
- if (iece->reqitem[i])
- DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true);
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ continue;
+
+ if (iece->RequiredCurrency[i])
+ ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i] * stacks), true, true);
}
}
@@ -21428,7 +21775,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
EquipNewItem(uiDest, item, true);
if (it)
{
- uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, pProto->BuyCount * count);
+ uint32 new_count = pVendor->UpdateVendorItemCurrentCount(crItem, count);
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << uint64(pVendor->GetGUID());
@@ -21436,7 +21783,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
data << int32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << uint32(count);
GetSession()->SendPacket(&data);
- SendNewItem(it, pProto->BuyCount * count, true, false, false);
+ SendNewItem(it, count, true, false, false);
if (!bStore)
AutoUnequipOffhandIfNeed();
@@ -21454,6 +21801,165 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
return true;
}
+bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count)
+{
+ // cheating attempt
+ if (count < 1) count = 1;
+
+ if (!IsAlive())
+ return false;
+
+ CurrencyTypesEntry const* proto = sCurrencyTypesStore.LookupEntry(currency);
+ if (!proto)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, currency, 0);
+ return false;
+ }
+
+ Creature* creature = GetNPCIfCanInteractWith(vendorGuid, UNIT_NPC_FLAG_VENDOR);
+ if (!creature)
+ {
+ TC_LOG_DEBUG("network", "WORLD: BuyCurrencyFromVendorSlot - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(vendorGuid));
+ SendBuyError(BUY_ERR_DISTANCE_TOO_FAR, NULL, currency, 0);
+ return false;
+ }
+
+ VendorItemData const* vItems = creature->GetVendorItems();
+ if (!vItems || vItems->Empty())
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ if (vendorSlot >= vItems->GetItemCount())
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ VendorItem const* crItem = vItems->GetItem(vendorSlot);
+ // store diff item (cheating)
+ if (!crItem || crItem->item != currency || crItem->Type != ITEM_VENDOR_TYPE_CURRENCY)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0);
+ return false;
+ }
+
+ if (count % crItem->maxcount)
+ {
+ SendEquipError(EQUIP_ERR_CANT_BUY_QUANTITY, NULL, NULL);
+ return false;
+ }
+
+ uint32 stacks = count / crItem->maxcount;
+ ItemExtendedCostEntry const* iece = NULL;
+ if (crItem->ExtendedCost)
+ {
+ iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
+ if (!iece)
+ {
+ TC_LOG_ERROR("entities.player", "Currency %u have wrong ExtendedCost field value %u", currency, crItem->ExtendedCost);
+ return false;
+ }
+
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i)
+ {
+ if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], (iece->RequiredItemCount[i] * stacks)))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
+ return false;
+ }
+ }
+
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (!iece->RequiredCurrency[i])
+ continue;
+
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
+ if (!entry)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, currency, 0); // Find correct error
+ return false;
+ }
+
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ {
+ // Not implemented
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+ else if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * stacks)))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+ }
+
+ // check for personal arena rating requirement
+ if (GetMaxPersonalArenaRatingRequirement(iece->RequiredArenaSlot) < iece->RequiredPersonalArenaRating)
+ {
+ // probably not the proper equip err
+ SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
+ return false;
+ }
+
+ if (iece->RequiredFactionId && uint32(GetReputationRank(iece->RequiredFactionId)) < iece->RequiredFactionStanding)
+ {
+ SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, currency, 0);
+ return false;
+ }
+
+ if (iece->RequirementFlags & ITEM_EXT_COST_FLAG_REQUIRE_GUILD && !GetGuildId())
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+
+ if (iece->RequiredGuildLevel && iece->RequiredGuildLevel < GetGuildLevel())
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+
+ if (iece->RequiredAchievement && !HasAchieved(iece->RequiredAchievement))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+ }
+ else // currencies have no price defined, can only be bought with ExtendedCost
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, currency, 0);
+ return false;
+ }
+
+ ModifyCurrency(currency, count, true, true);
+ if (iece)
+ {
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i)
+ {
+ if (!iece->RequiredItem[i])
+ continue;
+
+ DestroyItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks, true);
+ }
+
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (!iece->RequiredCurrency[i])
+ continue;
+
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ continue;
+
+ ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i]) * stacks, false, true);
+ }
+ }
+
+ return true;
+}
+
// Return true is the bought item has a max count to force refresh of window by caller
bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
{
@@ -21521,31 +22027,48 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
if (crItem->ExtendedCost)
{
- ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
- if (!iece)
+ // Can only buy full stacks for extended cost
+ if (count % pProto->BuyCount)
{
- TC_LOG_ERROR("entities.player", "Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
+ SendEquipError(EQUIP_ERR_CANT_BUY_QUANTITY, NULL, NULL);
return false;
}
- // honor points price
- if (GetHonorPoints() < (iece->reqhonorpoints * count))
+ uint32 stacks = count / pProto->BuyCount;
+ ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(crItem->ExtendedCost);
+ if (!iece)
{
- SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL);
+ TC_LOG_ERROR("entities.player", "Item %u have wrong ExtendedCost field value %u", pProto->ItemId, crItem->ExtendedCost);
return false;
}
- // arena points price
- if (GetArenaPoints() < (iece->reqarenapoints * count))
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i)
{
- SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL);
- return false;
+ if (iece->RequiredItem[i] && !HasItemCount(iece->RequiredItem[i], iece->RequiredItemCount[i] * stacks))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
+ return false;
+ }
}
- // item base price
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i)
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
{
- if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count)))
+ if (!iece->RequiredCurrency[i])
+ continue;
+
+ CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
+ if (!entry)
+ {
+ SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
+ return false;
+ }
+
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+ else if (!HasCurrency(iece->RequiredCurrency[i], iece->RequiredCurrencyCount[i] * stacks))
{
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
return false;
@@ -21553,12 +22076,36 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
}
// check for personal arena rating requirement
- if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating)
+ if (GetMaxPersonalArenaRatingRequirement(iece->RequiredArenaSlot) < iece->RequiredPersonalArenaRating)
{
// probably not the proper equip err
SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
return false;
}
+
+ if (iece->RequiredFactionId && uint32(GetReputationRank(iece->RequiredFactionId)) < iece->RequiredFactionStanding)
+ {
+ SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, item, 0);
+ return false;
+ }
+
+ if (iece->RequirementFlags & ITEM_EXT_COST_FLAG_REQUIRE_GUILD && !GetGuildId())
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+
+ if (iece->RequiredGuildLevel && iece->RequiredGuildLevel < GetGuildLevel())
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
+
+ if (iece->RequiredAchievement && !HasAchieved(iece->RequiredAchievement))
+ {
+ SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
+ return false;
+ }
}
uint32 price = 0;
@@ -21575,7 +22122,10 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
// reputation discount
price = uint32(floor(price * GetReputationPriceDiscount(creature)));
- if (!HasEnoughMoney(price))
+ if (int32 priceMod = GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES))
+ price -= CalculatePct(price, priceMod);
+
+ if (!HasEnoughMoney(uint64(price)))
{
SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, item, 0);
return false;
@@ -21589,9 +22139,9 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
}
else if (IsEquipmentPos(bag, slot))
{
- if (pProto->BuyCount * count != 1)
+ if (count != 1)
{
- SendEquipError(EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL);
+ SendEquipError(EQUIP_ERR_NOT_EQUIPPABLE, NULL, NULL);
return false;
}
if (!_StoreOrEquipNewItem(vendorslot, item, count, bag, slot, price, pProto, creature, crItem, false))
@@ -21599,11 +22149,19 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
}
else
{
- SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ SendEquipError(EQUIP_ERR_WRONG_SLOT, NULL, NULL);
return false;
}
- return crItem->maxcount != 0;
+ if (crItem->maxcount != 0) // bought
+ {
+ if (pProto->Quality > ITEM_QUALITY_EPIC || (pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]))
+ if (Guild* guild = GetGuild())
+ guild->AddGuildNews(GUILD_NEWS_ITEM_PURCHASED, GetGUID(), 0, item);
+ return true;
+ }
+
+ return false;
}
uint32 Player::GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const
@@ -21798,9 +22356,35 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite
if (catrec > 0 && !(spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS))
ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell);
+ // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
+ // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
+ if (cat)
+ {
+ if (int32 categoryModifier = GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN, cat))
+ {
+ if (rec > 0)
+ rec += categoryModifier;
+
+ if (catrec > 0)
+ catrec += categoryModifier;
+ }
+
+ SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.LookupEntry(cat);
+ ASSERT(categoryEntry);
+ if (categoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_MIDNIGHT)
+ {
+ tm date;
+ ACE_OS::localtime_r(&curTime, &date);
+ catrec = catrec * DAY - (date.tm_hour * HOUR + date.tm_min * MINUTE + date.tm_sec) * IN_MILLISECONDS;
+ }
+ }
+
// replace negative cooldowns by 0
- if (rec < 0) rec = 0;
- if (catrec < 0) catrec = 0;
+ if (rec < 0)
+ rec = 0;
+
+ if (catrec < 0)
+ catrec = 0;
// no cooldown after applying spell mods
if (rec == 0 && catrec == 0)
@@ -21839,6 +22423,27 @@ void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time)
m_spellCooldowns[spellid] = sc;
}
+void Player::ModifySpellCooldown(uint32 spellId, int32 cooldown)
+{
+ SpellCooldowns::iterator itr = m_spellCooldowns.find(spellId);
+ if (itr == m_spellCooldowns.end())
+ return;
+
+ time_t now = time(NULL);
+ if (itr->second.end + (cooldown / IN_MILLISECONDS) > now)
+ itr->second.end += (cooldown / IN_MILLISECONDS);
+ else
+ m_spellCooldowns.erase(itr);
+
+ WorldPacket data(SMSG_MODIFY_COOLDOWN, 4 + 8 + 4);
+ data << uint32(spellId); // Spell ID
+ data << uint64(GetGUID()); // Player GUID
+ data << int32(cooldown); // Cooldown mod in milliseconds
+ GetSession()->SendPacket(&data);
+
+ TC_LOG_DEBUG("misc", "ModifySpellCooldown:: Player: %s (GUID: %u) Spell: %u cooldown: %u", GetName().c_str(), GetGUIDLow(), spellId, GetSpellCooldownDelay(spellId));
+}
+
void Player::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId /*= 0*/, Spell* spell /*= NULL*/, bool setCooldown /*= true*/)
{
// start cooldowns at server side, if any
@@ -21875,15 +22480,15 @@ void Player::UpdatePotionCooldown(Spell* spell)
m_lastPotionId = 0;
}
-void Player::setResurrectRequestData(uint64 guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
+void Player::SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura)
{
- m_resurrectGUID = guid;
- m_resurrectMap = mapId;
- m_resurrectX = X;
- m_resurrectY = Y;
- m_resurrectZ = Z;
- m_resurrectHealth = health;
- m_resurrectMana = mana;
+ ASSERT(!IsRessurectRequested());
+ _resurrectionData = new ResurrectionData();
+ _resurrectionData->GUID = caster->GetGUID();
+ _resurrectionData->Location.WorldRelocate(*caster);
+ _resurrectionData->Health = health;
+ _resurrectionData->Mana = mana;
+ _resurrectionData->Aura = appliedAura;
}
//slot to be excluded while counting
bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)
@@ -22329,7 +22934,7 @@ void Player::UpdateTriggerVisibility()
if (!IsInWorld())
return;
- UpdateData udata;
+ UpdateData udata(GetMapId());
WorldPacket packet;
for (ClientGUIDs::iterator itr = m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
{
@@ -22434,7 +23039,7 @@ void Player::InitPrimaryProfessions()
SetFreePrimaryProfessions(sWorld->getIntConfig(CONFIG_MAX_PRIMARY_TRADE_SKILL));
}
-bool Player::ModifyMoney(int32 amount, bool sendError /*= true*/)
+bool Player::ModifyMoney(int64 amount, bool sendError /*= true*/)
{
if (!amount)
return true;
@@ -22442,10 +23047,10 @@ bool Player::ModifyMoney(int32 amount, bool sendError /*= true*/)
sScriptMgr->OnPlayerMoneyChanged(this, amount);
if (amount < 0)
- SetMoney (GetMoney() > uint32(-amount) ? GetMoney() + amount : 0);
+ SetMoney(GetMoney() > uint64(-amount) ? GetMoney() + amount : 0);
else
{
- if (GetMoney() < uint32(MAX_MONEY_AMOUNT - amount))
+ if (GetMoney() < uint64(MAX_MONEY_AMOUNT - amount))
SetMoney(GetMoney() + amount);
else
{
@@ -22458,16 +23063,16 @@ bool Player::ModifyMoney(int32 amount, bool sendError /*= true*/)
return true;
}
-bool Player::HasEnoughMoney(int32 amount) const
+bool Player::HasEnoughMoney(int64 amount) const
{
if (amount > 0)
- return (GetMoney() >= (uint32) amount);
+ return (GetMoney() >= (uint64) amount);
return true;
}
-void Player::SetMoney(uint32 value)
+void Player::SetMoney(uint64 value)
{
- SetUInt32Value(PLAYER_FIELD_COINAGE, value);
+ SetUInt64Value(PLAYER_FIELD_COINAGE, value);
MoneyChanged(value);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED);
}
@@ -22613,10 +23218,22 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendTalentsInfoData(false);
- // SMSG_INSTANCE_DIFFICULTY
- data.Initialize(SMSG_INSTANCE_DIFFICULTY, 4+4);
+ 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());
- data << uint32(0);
GetSession()->SendPacket(&data);
SendInitialSpells();
@@ -22627,7 +23244,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
SendInitialActionButtons();
m_reputationMgr->SendInitialReputations();
- m_achievementMgr->SendAllAchievementData();
+ m_achievementMgr->SendAllAchievementData(this);
SendEquipmentSetList();
@@ -22644,6 +23261,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
// SMSG_UPDATE_WORLD_STATE
// SMSG_POWER_UPDATE
+ SendCurrencies();
SetMover(this);
}
@@ -22659,6 +23277,8 @@ void Player::SendInitialPacketsAfterAddToMap()
ResetTimeSync();
SendTimeSync();
+ GetSession()->SendLoadCUFProfiles();
+
CastSpell(this, 836, true); // LOGINEFFECT
// set some aura effects that send packet to player client after add player to map
@@ -22678,16 +23298,11 @@ void Player::SendInitialPacketsAfterAddToMap()
}
if (HasAuraType(SPELL_AURA_MOD_STUN))
- SetMovement(MOVE_ROOT);
+ SetRooted(true);
// manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that must not be re-applied.
if (HasAuraType(SPELL_AURA_MOD_ROOT))
- {
- WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
- data2.append(GetPackGUID());
- data2 << (uint32)2;
- SendMessageToSet(&data2, true);
- }
+ SetRooted(true, true);
SendAurasForTarget(this);
SendEnchantmentDurations(); // must be after add to map
@@ -22723,18 +23338,8 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8
{
WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);
data << uint32(mapid);
- data << uint8(reason); // transfer abort reason
- switch (reason)
- {
- case TRANSFER_ABORT_INSUF_EXPAN_LVL:
- case TRANSFER_ABORT_DIFFICULTY:
- case TRANSFER_ABORT_UNIQUE_MESSAGE:
- // these are the ONLY cases that have an extra argument in the packet!!!
- data << uint8(arg);
- break;
- default:
- break;
- }
+ data << uint8(reason); // transfer abort reason
+ data << uint8(arg);
GetSession()->SendPacket(&data);
}
@@ -23085,6 +23690,7 @@ void Player::ResetWeeklyQuestStatus()
m_weeklyquests.clear();
// DB data deleted in caller
m_WeeklyQuestChanged = false;
+
}
void Player::ResetSeasonalQuestStatus(uint16 event_id)
@@ -23311,7 +23917,7 @@ void Player::UpdateForQuestWorldObjects()
if (m_clientGUIDs.empty())
return;
- UpdateData udata;
+ UpdateData udata(GetMapId());
WorldPacket packet;
for (ClientGUIDs::iterator itr=m_clientGUIDs.begin(); itr != m_clientGUIDs.end(); ++itr)
{
@@ -23592,7 +24198,7 @@ uint32 Player::GetResurrectionSpellId()
}
// Used in triggers for check "Only to targets that grant experience or honor" req
-bool Player::isHonorOrXPTarget(Unit* victim)
+bool Player::isHonorOrXPTarget(Unit const* victim)
{
uint8 v_level = victim->getLevel();
uint8 k_grey = Trinity::XP::GetGrayLevel(getLevel());
@@ -23601,11 +24207,11 @@ bool Player::isHonorOrXPTarget(Unit* victim)
if (v_level <= k_grey)
return false;
- if (victim->GetTypeId() == TYPEID_UNIT)
+ if (Creature const* const creature = victim->ToCreature())
{
- if (victim->ToCreature()->IsTotem() ||
- victim->ToCreature()->IsPet() ||
- victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)
+ if (creature->IsTotem() ||
+ creature->IsPet() ||
+ creature->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_XP_AT_KILL)
return false;
}
return true;
@@ -23712,23 +24318,12 @@ bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const
return pOther->GetDistance(player) <= sWorld->getFloatConfig(CONFIG_MAX_RECRUIT_A_FRIEND_DISTANCE);
}
-uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const
-{
- Item* item = GetWeaponForAttack(attType, true);
-
- // unarmed only with base attack
- if (attType != BASE_ATTACK && !item)
- return 0;
-
- // weapon skill or (unarmed for base attack and for fist weapons)
- uint32 skill = (item && item->GetSkill() != SKILL_FIST_WEAPONS) ? item->GetSkill() : uint32(SKILL_UNARMED);
- return GetBaseSkillValue(skill);
-}
-
void Player::ResurectUsingRequestData()
{
/// Teleport before resurrecting by player, otherwise the player might get attacked from creatures near his corpse
- TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());
+ float x, y, z, o;
+ _resurrectionData->Location.GetPosition(x, y, z, o);
+ TeleportTo(_resurrectionData->Location.GetMapId(), x, y, z, o);
if (IsBeingTeleported())
{
@@ -23738,19 +24333,23 @@ void Player::ResurectUsingRequestData()
ResurrectPlayer(0.0f, false);
- if (GetMaxHealth() > m_resurrectHealth)
- SetHealth(m_resurrectHealth);
+ if (GetMaxHealth() > _resurrectionData->Health)
+ SetHealth(_resurrectionData->Health);
else
SetFullHealth();
- if (GetMaxPower(POWER_MANA) > m_resurrectMana)
- SetPower(POWER_MANA, m_resurrectMana);
+ if (uint32(GetMaxPower(POWER_MANA)) > _resurrectionData->Mana)
+ SetPower(POWER_MANA, _resurrectionData->Mana);
else
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
SetPower(POWER_RAGE, 0);
-
SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY));
+ SetPower(POWER_FOCUS, GetMaxPower(POWER_FOCUS));
+ SetPower(POWER_ECLIPSE, 0);
+
+ if (uint32 aura = _resurrectionData->Aura)
+ CastSpell(this, aura, true, NULL, NULL, _resurrectionData->GUID);
SpawnCorpseBones();
}
@@ -23774,6 +24373,29 @@ void Player::SetMover(Unit* target)
m_mover->m_movedPlayer = NULL;
m_mover = target;
m_mover->m_movedPlayer = this;
+
+ ObjectGuid guid = target->GetGUID();
+
+ WorldPacket data(SMSG_MOVE_SET_ACTIVE_MOVER, 9);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[4]);
+
+ SendDirectMessage(&data);
}
void Player::UpdateZoneDependentAuras(uint32 newZone)
@@ -24254,32 +24876,27 @@ uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 n
void Player::InitGlyphsForLevel()
{
- for (uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i)
+ uint32 slot = 0;
+ for (uint32 i = 0; i < sGlyphSlotStore.GetNumRows() && slot < MAX_GLYPH_SLOT_INDEX; ++i)
if (GlyphSlotEntry const* gs = sGlyphSlotStore.LookupEntry(i))
- if (gs->Order)
- SetGlyphSlot(gs->Order - 1, gs->Id);
+ SetGlyphSlot(slot++, gs->Id);
uint8 level = getLevel();
- uint32 value = 0;
+ uint32 slotMask = 0;
- // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level
- if (level >= 15)
- value |= (0x01 | 0x02);
- if (level >= 30)
- value |= 0x08;
+ if (level >= 25)
+ slotMask |= 0x01 | 0x02 | 0x40;
if (level >= 50)
- value |= 0x04;
- if (level >= 70)
- value |= 0x10;
- if (level >= 80)
- value |= 0x20;
+ slotMask |= 0x04 | 0x08 | 0x80;
+ if (level >= 75)
+ slotMask |= 0x10 | 0x20 | 0x100;
- SetUInt32Value(PLAYER_GLYPHS_ENABLED, value);
+ SetUInt32Value(PLAYER_GLYPHS_ENABLED, slotMask);
}
void Player::SetGlyph(uint8 slot, uint32 glyph)
{
- m_Glyphs[m_activeSpec][slot] = glyph;
+ _talentMgr->SpecInfo[GetActiveSpec()].Glyphs[slot] = glyph;
SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph);
}
@@ -24389,17 +25006,25 @@ void Player::UpdateCharmedAI()
}
}
-uint32 Player::GetRuneBaseCooldown(uint8 index)
+uint32 Player::GetRuneTypeBaseCooldown(RuneType runeType) const
{
- uint8 rune = GetBaseRune(index);
- uint32 cooldown = RUNE_BASE_COOLDOWN;
+ float cooldown = RUNE_BASE_COOLDOWN;
+ float hastePct = 0.0f;
AuraEffectList const& regenAura = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = regenAura.begin();i != regenAura.end(); ++i)
- {
- if ((*i)->GetMiscValue() == POWER_RUNE && (*i)->GetMiscValueB() == rune)
- cooldown = cooldown*(100-(*i)->GetAmount())/100;
- }
+ if ((*i)->GetMiscValue() == POWER_RUNES && (*i)->GetMiscValueB() == runeType)
+ cooldown *= 1.0f - (*i)->GetAmount() / 100.0f;
+
+ // Runes cooldown are now affected by player's haste from equipment ...
+ hastePct = GetRatingBonusValue(CR_HASTE_MELEE);
+
+ // ... and some auras.
+ hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE);
+ hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE_2);
+ hastePct += GetTotalAuraModifier(SPELL_AURA_MOD_MELEE_HASTE_3);
+
+ cooldown *= 1.0f - (hastePct / 100.0f);
return cooldown;
}
@@ -24510,7 +25135,7 @@ void Player::InitRunes()
}
for (uint8 i = 0; i < NUM_RUNE_TYPES; ++i)
- SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f);
+ SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); // set a base regen timer equal to 10 sec
}
bool Player::IsBaseRuneSlotsOnCooldown(RuneType runeType) const
@@ -24559,7 +25184,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
if (!item)
{
- SendEquipError(EQUIP_ERR_ALREADY_LOOTED, NULL, NULL);
+ SendEquipError(EQUIP_ERR_LOOT_GONE, NULL, NULL);
return;
}
@@ -24609,9 +25234,14 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
--loot->unlootedCount;
+ if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
+ if (proto->Quality > ITEM_QUALITY_EPIC || (proto->Quality == ITEM_QUALITY_EPIC && proto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]))
+ if (Guild* guild = GetGuild())
+ guild->AddGuildNews(GUILD_NEWS_ITEM_LOOTED, GetGUID(), 0, item->itemid);
+
SendNewItem(newitem, uint32(item->count), false, false, true);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item->count);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, item->itemid, item->count, loot->loot_type);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item->itemid, item->count);
// LootItem is being removed (looted) from the container, delete it from the DB.
@@ -24625,16 +25255,30 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
uint32 Player::CalculateTalentsPoints() const
{
- uint32 base_talent = getLevel() < 10 ? 0 : getLevel()-9;
+ // this dbc file has entries only up to level 100
+ NumTalentsAtLevelEntry const* count = sNumTalentsAtLevelStore.LookupEntry(std::min<uint32>(getLevel(), 100));
+ if (!count)
+ return 0;
+
+ float baseForLevel = count->Talents;
if (getClass() != CLASS_DEATH_KNIGHT || GetMapId() != 609)
- return uint32(base_talent * sWorld->getRate(RATE_TALENT));
+ return uint32(baseForLevel * sWorld->getRate(RATE_TALENT));
- uint32 talentPointsForLevel = getLevel() < 56 ? 0 : getLevel() - 55;
- talentPointsForLevel += m_questRewardTalentCount;
+ // Death Knight starting level
+ // hardcoded here - number of quest awarded talents is equal to number of talents any other class would have at level 55
+ if (getLevel() < 55)
+ return 0;
+
+ NumTalentsAtLevelEntry const* dkBase = sNumTalentsAtLevelStore.LookupEntry(55);
+ if (!dkBase)
+ return 0;
- if (talentPointsForLevel > base_talent)
- talentPointsForLevel = base_talent;
+ float talentPointsForLevel = count->Talents - dkBase->Talents;
+ talentPointsForLevel += float(GetQuestRewardedTalentCount());
+
+ if (talentPointsForLevel > baseForLevel)
+ talentPointsForLevel = baseForLevel;
return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT));
}
@@ -24660,6 +25304,7 @@ void Player::_LoadSkills(PreparedQueryResult result)
// SetPQuery(PLAYER_LOGIN_QUERY_LOADSKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = '%u'", GUID_LOPART(m_guid));
uint32 count = 0;
+ uint8 professionCount = 0;
if (result)
{
do
@@ -24702,14 +25347,28 @@ void Player::_LoadSkills(PreparedQueryResult result)
continue;
}
- // enable unlearn button for primary professions only
+ uint16 field = count / 2;
+ uint8 offset = count & 1;
+
+ SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, skill);
+ uint16 step = 0;
+
+ if (pSkill->categoryId == SKILL_CATEGORY_SECONDARY)
+ step = max / 75;
+
if (pSkill->categoryId == SKILL_CATEGORY_PROFESSION)
- SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill, 1));
- else
- SetUInt32Value(PLAYER_SKILL_INDEX(count), MAKE_PAIR32(skill, 0));
+ {
+ step = max / 75;
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count), MAKE_SKILL_VALUE(value, max));
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count), 0);
+ if (professionCount < 2)
+ SetUInt32Value(PLAYER_PROFESSION_SKILL_LINE_1 + professionCount++, skill);
+ }
+
+ SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, step);
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, value);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, max);
+ SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0);
mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(count, SKILL_UNCHANGED)));
@@ -24728,9 +25387,15 @@ void Player::_LoadSkills(PreparedQueryResult result)
for (; count < PLAYER_MAX_SKILLS; ++count)
{
- SetUInt32Value(PLAYER_SKILL_INDEX(count), 0);
- SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(count), 0);
- SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(count), 0);
+ uint16 field = count / 2;
+ uint8 offset = count & 1;
+
+ SetUInt16Value(PLAYER_SKILL_LINEID_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_STEP_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_RANK_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_MAX_RANK_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_MODIFIER_0 + field, offset, 0);
+ SetUInt16Value(PLAYER_SKILL_TALENT_0 + field, offset, 0);
}
// special settings
@@ -24762,25 +25427,6 @@ void Player::_LoadSkills(PreparedQueryResult result)
}
}
-uint32 Player::GetPhaseMaskForSpawn() const
-{
- uint32 phase = PHASEMASK_NORMAL;
- if (!IsGameMaster())
- phase = GetPhaseMask();
- else
- {
- AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
- if (!phases.empty())
- phase = phases.front()->GetMiscValue();
- }
-
- // some aura phases include 1 normal map in addition to phase itself
- if (uint32 n_phase = phase & ~PHASEMASK_NORMAL)
- return n_phase;
-
- return PHASEMASK_NORMAL;
-}
-
InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
{
ItemTemplate const* pProto = pItem->GetTemplate();
@@ -24821,7 +25467,7 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8
{
// there is an equip limit on this item
if (HasItemOrGemWithIdEquipped(itemProto->ItemId, 1, except_slot))
- return EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE;
+ return EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE;
}
// check unique-equipped limit
@@ -24829,12 +25475,12 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8
{
ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(itemProto->ItemLimitCategory);
if (!limitEntry)
- return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED;
+ return EQUIP_ERR_NOT_EQUIPPABLE;
// NOTE: limitEntry->mode not checked because if item have have-limit then it applied and to equip case
if (limit_count > limitEntry->maxCount)
- return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED;
+ return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED_IS;
// there is an equip limit on this item
if (HasItemOrGemWithLimitCategoryEquipped(itemProto->ItemLimitCategory, limitEntry->maxCount - limit_count + 1, except_slot))
@@ -24854,7 +25500,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
{
// calculate total z distance of the fall
float z_diff = m_lastFallZ - movementInfo.pos.GetPositionZ();
- //TC_LOG_DEBUG("zDiff = %f", z_diff);
+ //TC_LOG_DEBUG("misc", "zDiff = %f", z_diff);
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
// 14.57 can be calculated by resolving damageperc formula below to 0
@@ -24893,7 +25539,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
}
//Z given by moveinfo, LastZ, FallTime, WaterZ, MapZ, Damage, Safefall reduction
- TC_LOG_DEBUG("entities.player", "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
+ TC_LOG_DEBUG("entities.player", "FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d", movementInfo.pos.GetPositionZ(), height, GetPositionZ(), movementInfo.jump.fallTime, height, damage, safe_fall);
}
}
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute
@@ -24906,7 +25552,12 @@ void Player::ResetAchievements()
void Player::SendRespondInspectAchievements(Player* player) const
{
- m_achievementMgr->SendRespondInspectAchievements(player);
+ m_achievementMgr->SendAchievementInfo(player);
+}
+
+uint32 Player::GetAchievementPoints() const
+{
+ return m_achievementMgr->GetAchievementPoints();
}
bool Player::HasAchieved(uint32 achievementId) const
@@ -24924,44 +25575,54 @@ void Player::RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 e
m_achievementMgr->RemoveTimedAchievement(type, entry);
}
-void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/)
+void Player::ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, bool evenIfCriteriaComplete /* = false*/)
{
m_achievementMgr->ResetAchievementCriteria(type, miscValue1, miscValue2, evenIfCriteriaComplete);
}
-void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/)
+void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit* unit /*= NULL*/)
{
- m_achievementMgr->UpdateAchievementCriteria(type, miscValue1, miscValue2, unit);
+ m_achievementMgr->UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
+ Guild* guild = sGuildMgr->GetGuildById(GetGuildId());
+ if (!guild)
+ return;
+
+ // Update only individual achievement criteria here, otherwise we may get multiple updates
+ // from a single boss kill
+ if (sAchievementMgr->IsGroupCriteriaType(type))
+ return;
+
+ guild->UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
}
void Player::CompletedAchievement(AchievementEntry const* entry)
{
- m_achievementMgr->CompletedAchievement(entry);
+ m_achievementMgr->CompletedAchievement(entry, this);
}
-void Player::LearnTalent(uint32 talentId, uint32 talentRank)
+bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
{
uint32 CurTalentPoints = GetFreeTalentPoints();
if (CurTalentPoints == 0)
- return;
+ return false;
if (talentRank >= MAX_TALENT_RANK)
- return;
+ return false;
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
if (!talentInfo)
- return;
+ return false;
TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
if (!talentTabInfo)
- return;
+ return false;
// prevent learn talent for different class (cheating)
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
- return;
+ return false;
// find current max talent rank (0~5)
uint8 curtalent_maxrank = 0; // 0 = not learned any rank
@@ -24976,11 +25637,11 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
// we already have same or higher talent rank learned
if (curtalent_maxrank >= (talentRank + 1))
- return;
+ return false;
// check if we have enough talent points
if (CurTalentPoints < (talentRank - curtalent_maxrank + 1))
- return;
+ return false;
// Check if it requires another talent
if (talentInfo->DependsOn > 0)
@@ -24995,33 +25656,32 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
hasEnoughRank = true;
}
if (!hasEnoughRank)
- return;
+ return false;
}
}
// Find out how many points we have in this field
uint32 spentPoints = 0;
-
+ uint32 primaryTreeTalents = 0;
uint32 tTab = talentInfo->TalentTab;
- if (talentInfo->Row > 0)
+ bool isMainTree = GetPrimaryTalentTree(GetActiveSpec()) == tTab || !GetPrimaryTalentTree(GetActiveSpec());
+
+ if (talentInfo->Row > 0 || !isMainTree)
{
- uint32 numRows = sTalentStore.GetNumRows();
- for (uint32 i = 0; i < numRows; i++) // Loop through all talents.
+ for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents.
{
- // Someday, someone needs to revamp
- const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i);
- if (tmpTalent) // the way talents are tracked
+ if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // Someday, someone needs to revamp the way talents are tracked
{
- if (tmpTalent->TalentTab == tTab)
+ for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++)
{
- for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++)
+ if (tmpTalent->RankID[rank] != 0)
{
- if (tmpTalent->RankID[rank] != 0)
+ if (HasSpell(tmpTalent->RankID[rank]))
{
- if (HasSpell(tmpTalent->RankID[rank]))
- {
+ if (tmpTalent->TalentTab == tTab)
spentPoints += (rank + 1);
- }
+ if (tmpTalent->TalentTab == GetPrimaryTalentTree(GetActiveSpec()))
+ primaryTreeTalents += (rank + 1);
}
}
}
@@ -25031,28 +25691,49 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank)
// not have required min points spent in talent tree
if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK))
- return;
+ return false;
+
+ // player has not spent 31 talents in main tree before attempting to learn other tree's talents
+ if (!isMainTree && primaryTreeTalents < REQ_PRIMARY_TREE_TALENTS)
+ return false;
// spell not set in talent.dbc
uint32 spellid = talentInfo->RankID[talentRank];
if (spellid == 0)
{
TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
- return;
+ return false;
}
// already known
if (HasSpell(spellid))
- return;
+ return false;
// learn! (other talent ranks will unlearned at learning)
learnSpell(spellid, false);
- AddTalent(spellid, m_activeSpec, true);
+ AddTalent(spellid, GetActiveSpec(), true);
+
+ TC_LOG_INFO("misc", "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, GetActiveSpec());
+
+ // set talent tree for player
+ if (!GetPrimaryTalentTree(GetActiveSpec()))
+ {
+ SetPrimaryTalentTree(GetActiveSpec(), talentInfo->TalentTab);
+ std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab);
+ if (specSpells)
+ for (size_t i = 0; i < specSpells->size(); ++i)
+ learnSpell(specSpells->at(i), false);
- TC_LOG_INFO("entities.player", "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, m_activeSpec);
+ if (CanUseMastery())
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(talentTabInfo->MasterySpellId[i]))
+ if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell))
+ CastSpell(this, masterySpell->Id, true);
+ }
// update free talent points
SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+ return true;
}
void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
@@ -25193,13 +25874,13 @@ void Player::LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank)
void Player::AddKnownCurrency(uint32 itemId)
{
if (CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemId))
- SetFlag64(PLAYER_FIELD_KNOWN_CURRENCIES, (1LL << (ctEntry->BitIndex-1)));
+ SetFlag64(0, (1LL << (ctEntry->ID-1)));
}
void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode)
{
- if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
- SetFallInformation(minfo.fallTime, minfo.pos.GetPositionZ());
+ if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
+ SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ());
}
void Player::UnsummonPetTemporaryIfAny()
@@ -25267,17 +25948,18 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const
void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
{
*data << uint32(GetFreeTalentPoints()); // unspentTalentPoints
- *data << uint8(m_specsCount); // talent group count (0, 1 or 2)
- *data << uint8(m_activeSpec); // talent group index (0 or 1)
+ *data << uint8(GetSpecsCount()); // talent group count (0, 1 or 2)
+ *data << uint8(GetActiveSpec()); // talent group index (0 or 1)
- if (m_specsCount)
+ if (GetSpecsCount())
{
- if (m_specsCount > MAX_TALENT_SPECS)
- m_specsCount = MAX_TALENT_SPECS;
+ if (GetSpecsCount() > MAX_TALENT_SPECS)
+ SetSpecsCount(MAX_TALENT_SPECS);
// loop through all specs (only 1 for now)
- for (uint32 specIdx = 0; specIdx < m_specsCount; ++specIdx)
+ for (uint8 specIdx = 0; specIdx < GetSpecsCount(); ++specIdx)
{
+ *data << uint32(GetPrimaryTalentTree(specIdx));
uint8 talentIdCount = 0;
size_t pos = data->wpos();
*data << uint8(talentIdCount); // [PH], talentIdCount
@@ -25326,7 +26008,7 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
*data << uint8(MAX_GLYPH_SLOT_INDEX); // glyphs count
for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
- *data << uint16(m_Glyphs[specIdx][i]); // GlyphProperties.dbc
+ *data << uint16(GetGlyph(specIdx, i)); // GlyphProperties.dbc
}
}
}
@@ -25637,6 +26319,39 @@ void Player::SendClearCooldown(uint32 spell_id, Unit* target)
SendDirectMessage(&data);
}
+void Player::SendClearAllCooldowns(Unit* target)
+{
+ uint32 spellCount = m_spellCooldowns.size();
+ ObjectGuid guid = target ? target->GetGUID() : 0;
+
+ WorldPacket data(SMSG_CLEAR_COOLDOWNS, 4+8);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[6]);
+ data.WriteBits(spellCount, 24); // Spell Count
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[0]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[3]);
+ for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
+ data << uint32(itr->first); // Spell ID
+
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[6]);
+
+ SendDirectMessage(&data);
+}
+
void Player::ResetMap()
{
// this may be called during Map::Update
@@ -25657,7 +26372,7 @@ void Player::SetMap(Map* map)
void Player::_LoadGlyphs(PreparedQueryResult result)
{
- // SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 from character_glyphs WHERE guid = '%u'
+ // SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = '%u'
if (!result)
return;
@@ -25666,15 +26381,11 @@ void Player::_LoadGlyphs(PreparedQueryResult result)
Field* fields = result->Fetch();
uint8 spec = fields[0].GetUInt8();
- if (spec >= m_specsCount)
+ if (spec >= GetSpecsCount())
continue;
- m_Glyphs[spec][0] = fields[1].GetUInt16();
- m_Glyphs[spec][1] = fields[2].GetUInt16();
- m_Glyphs[spec][2] = fields[3].GetUInt16();
- m_Glyphs[spec][3] = fields[4].GetUInt16();
- m_Glyphs[spec][4] = fields[5].GetUInt16();
- m_Glyphs[spec][5] = fields[6].GetUInt16();
+ for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
+ _talentMgr->SpecInfo[spec].Glyphs[i] = fields[i + 1].GetUInt16();
}
while (result->NextRow());
}
@@ -25686,7 +26397,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans)
trans->Append(stmt);
- for (uint8 spec = 0; spec < m_specsCount; ++spec)
+ for (uint8 spec = 0; spec < GetSpecsCount(); ++spec)
{
uint8 index = 0;
@@ -25696,7 +26407,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans)
stmt->setUInt8(index++, spec);
for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
- stmt->setUInt16(index++, uint16(m_Glyphs[spec][i]));
+ stmt->setUInt16(index++, uint16(GetGlyph(spec, i)));
trans->Append(stmt);
}
@@ -25719,7 +26430,7 @@ void Player::_SaveTalents(SQLTransaction& trans)
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
- for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();)
+ for (PlayerTalentMap::iterator itr = GetTalentMap(i)->begin(); itr != GetTalentMap(i)->end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
{
@@ -25742,7 +26453,7 @@ void Player::_SaveTalents(SQLTransaction& trans)
if (itr->second->state == PLAYERSPELL_REMOVED)
{
delete itr->second;
- m_talents[i]->erase(itr++);
+ GetTalentMap(i)->erase(itr++);
}
else
{
@@ -25759,7 +26470,7 @@ void Player::UpdateSpecCount(uint8 count)
if (curCount == count)
return;
- if (m_activeSpec >= count)
+ if (GetActiveSpec() >= count)
ActivateSpec(0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -25786,11 +26497,10 @@ void Player::UpdateSpecCount(uint8 count)
_SaveActions(trans);
stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC);
- stmt->setUInt8(0, m_activeSpec);
+ stmt->setUInt8(0, GetActiveSpec());
stmt->setUInt32(1, GetGUIDLow());
trans->Append(stmt);
- m_activeSpec = 0;
}
CharacterDatabase.CommitTransaction(trans);
@@ -25869,10 +26579,25 @@ void Player::ActivateSpec(uint8 spec)
}
}
+ // Remove spec specific spells
+ for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
+ {
+ uint32 const* talentTabs = GetTalentTabPages(getClass());
+ std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentTabs[i]);
+ if (specSpells)
+ for (size_t i = 0; i < specSpells->size(); ++i)
+ removeSpell(specSpells->at(i), true);
+
+ TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabs[i]);
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (uint32 mastery = talentTabInfo->MasterySpellId[i])
+ removeSpell(mastery, true);
+ }
+
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
// remove secondary glyph
- if (uint32 oldglyph = m_Glyphs[m_activeSpec][slot])
+ if (uint32 oldglyph = GetGlyph(GetActiveSpec(), slot))
if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
RemoveAurasDueToSpell(old_gp->SpellId);
@@ -25902,7 +26627,7 @@ void Player::ActivateSpec(uint8 spec)
if (talentInfo->RankID[rank] == 0)
continue;
// if the talent can be found in the newly activated PlayerTalentMap
- if (HasTalent(talentInfo->RankID[rank], m_activeSpec))
+ if (HasTalent(talentInfo->RankID[rank], GetActiveSpec()))
{
learnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap
spentTalents += (rank + 1); // increment the spentTalents count
@@ -25910,10 +26635,21 @@ void Player::ActivateSpec(uint8 spec)
}
}
+ std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetPrimaryTalentTree(GetActiveSpec()));
+ if (specSpells)
+ for (size_t i = 0; i < specSpells->size(); ++i)
+ learnSpell(specSpells->at(i), false);
+
+ if (CanUseMastery())
+ if (TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (uint32 mastery = talentTabInfo->MasterySpellId[i])
+ learnSpell(mastery, false);
+
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
{
- uint32 glyph = m_Glyphs[m_activeSpec][slot];
+ uint32 glyph = GetGlyph(GetActiveSpec(), slot);
// apply primary glyph
if (glyph)
@@ -25923,13 +26659,13 @@ void Player::ActivateSpec(uint8 spec)
SetGlyph(slot, glyph);
}
- m_usedTalentCount = spentTalents;
+ SetUsedTalentCount(spentTalents);
InitTalentForLevel();
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC);
stmt->setUInt32(0, GetGUIDLow());
- stmt->setUInt8(1, m_activeSpec);
+ stmt->setUInt8(1, GetActiveSpec());
if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
_LoadActions(result);
}
@@ -25941,11 +26677,13 @@ void Player::ActivateSpec(uint8 spec)
SetPower(POWER_MANA, 0); // Mana must be 0 even if it isn't the active power type.
SetPower(pw, 0);
+
+ if (!sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ ResetTalents(true);
}
void Player::ResetTimeSync()
{
- m_timeSyncCounter = 0;
m_timeSyncTimer = 0;
m_timeSyncClient = 0;
m_timeSyncServer = getMSTime();
@@ -25953,13 +26691,18 @@ void Player::ResetTimeSync()
void Player::SendTimeSync()
{
+ m_timeSyncQueue.push(m_movementCounter++);
+
WorldPacket data(SMSG_TIME_SYNC_REQ, 4);
- data << uint32(m_timeSyncCounter++);
+ data << uint32(m_timeSyncQueue.back());
GetSession()->SendPacket(&data);
// Schedule next sync in 10 sec
m_timeSyncTimer = 10000;
m_timeSyncServer = getMSTime();
+
+ if (m_timeSyncQueue.size() > 3)
+ TC_LOG_ERROR("network", "Not received CMSG_TIME_SYNC_RESP for over 30 seconds from player %u (%s), possible cheater", GetGUIDLow(), GetName().c_str());
}
void Player::SetReputation(uint32 factionentry, uint32 value)
@@ -25971,9 +26714,9 @@ uint32 Player::GetReputation(uint32 factionentry) const
return GetReputationMgr().GetReputation(sFactionStore.LookupEntry(factionentry));
}
-std::string const& Player::GetGuildName()
+std::string Player::GetGuildName()
{
- return sGuildMgr->GetGuildById(GetGuildId())->GetName();
+ return GetGuildId() ? sGuildMgr->GetGuildById(GetGuildId())->GetName() : "";
}
void Player::SendDuelCountdown(uint32 counter)
@@ -26022,18 +26765,51 @@ void Player::SendRefundInfo(Item* item)
return;
}
+ ObjectGuid guid = item->GetGUID();
WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4);
- data << uint64(item->GetGUID()); // item guid
- data << uint32(item->GetPaidMoney()); // money cost
- data << uint32(iece->reqhonorpoints); // honor point cost
- data << uint32(iece->reqarenapoints); // arena point cost
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) // item cost data
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[1]);
+ data.FlushBits();
+
+ data.WriteByteSeq(guid[7]);
+ data << uint32(GetTotalPlayedTime() - item->GetPlayedTime());
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
+ {
+ data << uint32(iece->RequiredItemCount[i]);
+ data << uint32(iece->RequiredItem[i]);
+ }
+
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[2]);
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data
{
- data << uint32(iece->reqitem[i]);
- data << uint32(iece->reqitemcount[i]);
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ {
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
+
+ CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
+ uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+
+ data << uint32(iece->RequiredCurrencyCount[i] / precision);
+ data << uint32(iece->RequiredCurrency[i]);
}
+
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[5]);
data << uint32(0);
- data << uint32(GetTotalPlayedTime() - item->GetPlayedTime());
+ data.WriteByteSeq(guid[0]);
+ data << uint32(item->GetPaidMoney()); // money cost
GetSession()->SendPacket(&data);
}
@@ -26060,6 +26836,61 @@ bool Player::AddItem(uint32 itemId, uint32 count)
return true;
}
+void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, uint8 error)
+{
+ ObjectGuid guid = item->GetGUID();
+ WorldPacket data(SMSG_ITEM_REFUND_RESULT, 1 + 1 + 8 + 4*8 + 4 + 4*8 + 1);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(!error);
+ data.WriteBit(item->GetPaidMoney() > 0);
+ data.FlushBits();
+ if (!error)
+ {
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ {
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
+
+ CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
+ uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
+
+ data << uint32(iece->RequiredCurrencyCount[i] / precision);
+ data << uint32(iece->RequiredCurrency[i]);
+ }
+
+ data << uint32(item->GetPaidMoney()); // money cost
+
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
+ {
+ data << uint32(iece->RequiredItemCount[i]);
+ data << uint32(iece->RequiredItem[i]);
+ }
+ }
+
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[5]);
+
+ data << uint8(error); // error code
+ GetSession()->SendPacket(&data);
+}
+
void Player::RefundItem(Item* item)
{
if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE))
@@ -26071,10 +26902,7 @@ void Player::RefundItem(Item* item)
if (item->IsRefundExpired()) // item refund has expired
{
item->SetNotRefundable(this);
- WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4);
- data << uint64(item->GetGUID()); // Guid
- data << uint32(10); // Error!
- GetSession()->SendPacket(&data);
+ SendItemRefundResult(item, NULL, 10);
return;
}
@@ -26093,10 +26921,10 @@ void Player::RefundItem(Item* item)
}
bool store_error = false;
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i)
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i)
{
- uint32 count = iece->reqitemcount[i];
- uint32 itemid = iece->reqitem[i];
+ uint32 count = iece->RequiredItemCount[i];
+ uint32 itemid = iece->RequiredItem[i];
if (count && itemid)
{
@@ -26112,25 +26940,11 @@ void Player::RefundItem(Item* item)
if (store_error)
{
- WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4);
- data << uint64(item->GetGUID()); // Guid
- data << uint32(10); // Error!
- GetSession()->SendPacket(&data);
+ SendItemRefundResult(item, iece, 10);
return;
}
- WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4+4+4+4+4*4+4*4);
- data << uint64(item->GetGUID()); // item guid
- data << uint32(0); // 0, or error code
- data << uint32(item->GetPaidMoney()); // money cost
- data << uint32(iece->reqhonorpoints); // honor point cost
- data << uint32(iece->reqarenapoints); // arena point cost
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i) // item cost data
- {
- data << uint32(iece->reqitem[i]);
- data << uint32(iece->reqitemcount[i]);
- }
- GetSession()->SendPacket(&data);
+ SendItemRefundResult(item, iece, 0);
uint32 moneyRefund = item->GetPaidMoney(); // item-> will be invalidated in DestroyItem
@@ -26144,10 +26958,10 @@ void Player::RefundItem(Item* item)
DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
// Grant back extendedcost items
- for (uint8 i = 0; i < MAX_ITEM_EXTENDED_COST_REQUIREMENTS; ++i)
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i)
{
- uint32 count = iece->reqitemcount[i];
- uint32 itemid = iece->reqitem[i];
+ uint32 count = iece->RequiredItemCount[i];
+ uint32 itemid = iece->RequiredItem[i];
if (count && itemid)
{
ItemPosCountVec dest;
@@ -26158,18 +26972,22 @@ void Player::RefundItem(Item* item)
}
}
+ // Grant back currencies
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ {
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ continue;
+
+ uint32 count = iece->RequiredCurrencyCount[i];
+ uint32 currencyid = iece->RequiredCurrency[i];
+ if (count && currencyid)
+ ModifyCurrency(currencyid, count);
+ }
+
// Grant back money
if (moneyRefund)
ModifyMoney(moneyRefund); // Saved in SaveInventoryAndGoldToDB
- // Grant back Honor points
- if (uint32 honorRefund = iece->reqhonorpoints)
- ModifyHonorPoints(honorRefund, &trans);
-
- // Grant back Arena points
- if (uint32 arenaRefund = iece->reqarenapoints)
- ModifyArenaPoints(arenaRefund, &trans);
-
SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
@@ -26256,89 +27074,119 @@ bool Player::IsInWhisperWhiteList(uint64 guid)
return false;
}
-bool Player::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
+uint8 Player::GetNextVoidStorageFreeSlot() const
{
- if (!packetOnly && !Unit::SetDisableGravity(disable))
- return false;
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ if (!_voidStorageItems[i]) // unused item
+ return i;
- WorldPacket data(disable ? SMSG_MOVE_GRAVITY_DISABLE : SMSG_MOVE_GRAVITY_ENABLE, 12);
- data.append(GetPackGUID());
- data << uint32(0); //! movement counter
- SendDirectMessage(&data);
+ return VOID_STORAGE_MAX_SLOT;
+}
- data.Initialize(MSG_MOVE_GRAVITY_CHNG, 64);
- data.append(GetPackGUID());
- BuildMovementPacket(&data);
- SendMessageToSet(&data, false);
- return true;
+uint8 Player::GetNumOfVoidStorageFreeSlots() const
+{
+ uint8 count = 0;
+
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ if (!_voidStorageItems[i])
+ count++;
+
+ return count;
}
-bool Player::SetCanFly(bool apply)
+uint8 Player::AddVoidStorageItem(const VoidStorageItem& item)
{
- if (!Unit::SetCanFly(apply))
- return false;
+ int8 slot = GetNextVoidStorageFreeSlot();
- WorldPacket data(apply ? SMSG_MOVE_SET_CAN_FLY : SMSG_MOVE_UNSET_CAN_FLY, 12);
- data.append(GetPackGUID());
- data << uint32(0); //! movement counter
- SendDirectMessage(&data);
+ if (slot >= VOID_STORAGE_MAX_SLOT)
+ {
+ GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL);
+ return 255;
+ }
- data.Initialize(MSG_MOVE_UPDATE_CAN_FLY, 64);
- data.append(GetPackGUID());
- BuildMovementPacket(&data);
- SendMessageToSet(&data, false);
- return true;
+ _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemEntry,
+ item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor);
+ return slot;
}
-bool Player::SetHover(bool apply, bool packetOnly /*= false*/)
+void Player::AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item)
{
- if (!packetOnly && !Unit::SetHover(apply))
- return false;
+ if (slot >= VOID_STORAGE_MAX_SLOT)
+ {
+ GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL);
+ return;
+ }
- WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);
- data.append(GetPackGUID());
- data << uint32(0); //! movement counter
- SendDirectMessage(&data);
+ if (_voidStorageItems[slot])
+ {
+ TC_LOG_ERROR("misc", "Player::AddVoidStorageItemAtSlot - Player (GUID: %u, name: %s) tried to add an item to an used slot (item id: " UI64FMTD ", entry: %u, slot: %u).", GetGUIDLow(), GetName().c_str(), _voidStorageItems[slot]->ItemId, _voidStorageItems[slot]->ItemEntry, slot);
+ GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1);
+ return;
+ }
- data.Initialize(MSG_MOVE_HOVER, 64);
- data.append(GetPackGUID());
- BuildMovementPacket(&data);
- SendMessageToSet(&data, false);
- return true;
+ _voidStorageItems[slot] = new VoidStorageItem(item.ItemId, item.ItemId,
+ item.CreatorGuid, item.ItemRandomPropertyId, item.ItemSuffixFactor);
}
-bool Player::SetWaterWalking(bool apply, bool packetOnly /*= false*/)
+void Player::DeleteVoidStorageItem(uint8 slot)
{
- if (!packetOnly && !Unit::SetWaterWalking(apply))
- return false;
+ if (slot >= VOID_STORAGE_MAX_SLOT)
+ {
+ GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1);
+ return;
+ }
- WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);
- data.append(GetPackGUID());
- data << uint32(0); //! movement counter
- SendDirectMessage(&data);
+ delete _voidStorageItems[slot];
+ _voidStorageItems[slot] = NULL;
+}
- data.Initialize(MSG_MOVE_WATER_WALK, 64);
- data.append(GetPackGUID());
- BuildMovementPacket(&data);
- SendMessageToSet(&data, false);
+bool Player::SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot)
+{
+ if (oldSlot >= VOID_STORAGE_MAX_SLOT || newSlot >= VOID_STORAGE_MAX_SLOT || oldSlot == newSlot)
+ return false;
+
+ std::swap(_voidStorageItems[newSlot], _voidStorageItems[oldSlot]);
return true;
}
-bool Player::SetFeatherFall(bool apply, bool packetOnly /*= false*/)
+VoidStorageItem* Player::GetVoidStorageItem(uint8 slot) const
{
- if (!packetOnly && !Unit::SetFeatherFall(apply))
- return false;
+ if (slot >= VOID_STORAGE_MAX_SLOT)
+ {
+ GetSession()->SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1);
+ return NULL;
+ }
- WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);
- data.append(GetPackGUID());
- data << uint32(0); //! movement counter
- SendDirectMessage(&data);
+ return _voidStorageItems[slot];
+}
- data.Initialize(MSG_MOVE_FEATHER_FALL, 64);
- data.append(GetPackGUID());
- BuildMovementPacket(&data);
- SendMessageToSet(&data, false);
- return true;
+VoidStorageItem* Player::GetVoidStorageItem(uint64 id, uint8& slot) const
+{
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ {
+ if (_voidStorageItems[i] && _voidStorageItems[i]->ItemId == id)
+ {
+ slot = i;
+ return _voidStorageItems[i];
+ }
+ }
+
+ return NULL;
+}
+
+void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)
+{
+ Movement::PacketSender(this, NULL_OPCODE, apply ?
+ SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY :
+ SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY).Send();
+}
+
+void Player::SendMovementSetCollisionHeight(float height)
+{
+ static MovementStatusElements const heightElement = MSEExtraFloat;
+ Movement::ExtraMovementStatusElement extra(&heightElement);
+ extra.Data.floatData = height;
+ Movement::PacketSender(this, NULL_OPCODE, SMSG_MOVE_SET_COLLISION_HEIGHT, SMSG_MOVE_UPDATE_COLLISION_HEIGHT, &extra).Send();
}
float Player::GetCollisionHeight(bool mounted) const
@@ -26517,3 +27365,307 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
return pet;
}
+
+bool Player::CanUseMastery() const
+{
+ return HasSpell(MasterySpells[getClass()]);
+}
+
+void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::ExtraMovementStatusElement* extras /*= NULL*/)
+{
+ MovementStatusElements const* sequence = GetMovementStatusElementsSequence(data.GetOpcode());
+ if (!sequence)
+ {
+ TC_LOG_ERROR("network", "Player::ReadMovementInfo: No movement sequence found for opcode %s", GetOpcodeNameForLogging(data.GetOpcode()).c_str());
+ return;
+ }
+
+ bool hasMovementFlags = false;
+ bool hasMovementFlags2 = false;
+ bool hasTimestamp = false;
+ bool hasOrientation = false;
+ bool hasTransportData = false;
+ bool hasTransportTime2 = false;
+ bool hasTransportTime3 = false;
+ bool hasPitch = false;
+ bool hasFallData = false;
+ bool hasFallDirection = false;
+ bool hasSplineElevation = false;
+
+ ObjectGuid guid;
+ ObjectGuid tguid;
+
+ for (; *sequence != MSEEnd; ++sequence)
+ {
+ MovementStatusElements const& element = *sequence;
+
+ switch (element)
+ {
+ case MSEHasGuidByte0:
+ case MSEHasGuidByte1:
+ case MSEHasGuidByte2:
+ case MSEHasGuidByte3:
+ case MSEHasGuidByte4:
+ case MSEHasGuidByte5:
+ case MSEHasGuidByte6:
+ case MSEHasGuidByte7:
+ guid[element - MSEHasGuidByte0] = data.ReadBit();
+ break;
+ case MSEHasTransportGuidByte0:
+ case MSEHasTransportGuidByte1:
+ case MSEHasTransportGuidByte2:
+ case MSEHasTransportGuidByte3:
+ case MSEHasTransportGuidByte4:
+ case MSEHasTransportGuidByte5:
+ case MSEHasTransportGuidByte6:
+ case MSEHasTransportGuidByte7:
+ if (hasTransportData)
+ tguid[element - MSEHasTransportGuidByte0] = data.ReadBit();
+ break;
+ case MSEGuidByte0:
+ case MSEGuidByte1:
+ case MSEGuidByte2:
+ case MSEGuidByte3:
+ case MSEGuidByte4:
+ case MSEGuidByte5:
+ case MSEGuidByte6:
+ case MSEGuidByte7:
+ data.ReadByteSeq(guid[element - MSEGuidByte0]);
+ break;
+ case MSETransportGuidByte0:
+ case MSETransportGuidByte1:
+ case MSETransportGuidByte2:
+ case MSETransportGuidByte3:
+ case MSETransportGuidByte4:
+ case MSETransportGuidByte5:
+ case MSETransportGuidByte6:
+ case MSETransportGuidByte7:
+ if (hasTransportData)
+ data.ReadByteSeq(tguid[element - MSETransportGuidByte0]);
+ break;
+ case MSEHasMovementFlags:
+ hasMovementFlags = !data.ReadBit();
+ break;
+ case MSEHasMovementFlags2:
+ hasMovementFlags2 = !data.ReadBit();
+ break;
+ case MSEHasTimestamp:
+ hasTimestamp = !data.ReadBit();
+ break;
+ case MSEHasOrientation:
+ hasOrientation = !data.ReadBit();
+ break;
+ case MSEHasTransportData:
+ hasTransportData = data.ReadBit();
+ break;
+ case MSEHasTransportTime2:
+ if (hasTransportData)
+ hasTransportTime2 = data.ReadBit();
+ break;
+ case MSEHasTransportTime3:
+ if (hasTransportData)
+ hasTransportTime3 = data.ReadBit();
+ break;
+ case MSEHasPitch:
+ hasPitch = !data.ReadBit();
+ break;
+ case MSEHasFallData:
+ hasFallData = data.ReadBit();
+ break;
+ case MSEHasFallDirection:
+ if (hasFallData)
+ hasFallDirection = data.ReadBit();
+ break;
+ case MSEHasSplineElevation:
+ hasSplineElevation = !data.ReadBit();
+ break;
+ case MSEHasSpline:
+ data.ReadBit();
+ break;
+ case MSEMovementFlags:
+ if (hasMovementFlags)
+ mi->flags = data.ReadBits(30);
+ break;
+ case MSEMovementFlags2:
+ if (hasMovementFlags2)
+ mi->flags2 = data.ReadBits(12);
+ break;
+ case MSETimestamp:
+ if (hasTimestamp)
+ data >> mi->time;
+ break;
+ case MSEPositionX:
+ data >> mi->pos.m_positionX;
+ break;
+ case MSEPositionY:
+ data >> mi->pos.m_positionY;
+ break;
+ case MSEPositionZ:
+ data >> mi->pos.m_positionZ;
+ break;
+ case MSEOrientation:
+ if (hasOrientation)
+ mi->pos.SetOrientation(data.read<float>());
+ break;
+ case MSETransportPositionX:
+ if (hasTransportData)
+ data >> mi->transport.pos.m_positionX;
+ break;
+ case MSETransportPositionY:
+ if (hasTransportData)
+ data >> mi->transport.pos.m_positionY;
+ break;
+ case MSETransportPositionZ:
+ if (hasTransportData)
+ data >> mi->transport.pos.m_positionZ;
+ break;
+ case MSETransportOrientation:
+ if (hasTransportData)
+ mi->transport.pos.SetOrientation(data.read<float>());
+ break;
+ case MSETransportSeat:
+ if (hasTransportData)
+ data >> mi->transport.seat;
+ break;
+ case MSETransportTime:
+ if (hasTransportData)
+ data >> mi->transport.time;
+ break;
+ case MSETransportTime2:
+ if (hasTransportData && hasTransportTime2)
+ data >> mi->transport.time2;
+ break;
+ case MSETransportTime3:
+ if (hasTransportData && hasTransportTime3)
+ data >> mi->transport.time3;
+ break;
+ case MSEPitch:
+ if (hasPitch)
+ mi->pitch = G3D::wrap(data.read<float>(), float(-M_PI), float(M_PI));
+ break;
+ case MSEFallTime:
+ if (hasFallData)
+ data >> mi->jump.fallTime;
+ break;
+ case MSEFallVerticalSpeed:
+ if (hasFallData)
+ data >> mi->jump.zspeed;
+ break;
+ case MSEFallCosAngle:
+ if (hasFallData && hasFallDirection)
+ data >> mi->jump.cosAngle;
+ break;
+ case MSEFallSinAngle:
+ if (hasFallData && hasFallDirection)
+ data >> mi->jump.sinAngle;
+ break;
+ case MSEFallHorizontalSpeed:
+ if (hasFallData && hasFallDirection)
+ data >> mi->jump.xyspeed;
+ break;
+ case MSESplineElevation:
+ if (hasSplineElevation)
+ data >> mi->splineElevation;
+ break;
+ case MSECounter:
+ data.read_skip<uint32>(); /// @TODO: Maybe compare it with m_movementCounter to verify that packets are sent & received in order?
+ break;
+ case MSEZeroBit:
+ case MSEOneBit:
+ data.ReadBit();
+ break;
+ case MSEExtraElement:
+ extras->ReadNextElement(data);
+ break;
+ default:
+ ASSERT(Movement::PrintInvalidSequenceElement(element, __FUNCTION__));
+ break;
+ }
+ }
+
+ mi->guid = guid;
+ mi->transport.guid = tguid;
+
+ //! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
+ //! Might be subject to latency, so just remove improper flags.
+ #ifdef TRINITY_DEBUG
+ #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
+ { \
+ if (check) \
+ { \
+ TC_LOG_DEBUG("entities.unit", "Player::ReadMovementInfo: Violation of MovementFlags found (%s). " \
+ "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \
+ STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetGUIDLow(), maskToRemove); \
+ mi->RemoveMovementFlag((maskToRemove)); \
+ } \
+ }
+ #else
+ #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
+ if (check) \
+ mi->RemoveMovementFlag((maskToRemove));
+ #endif
+
+ /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
+ in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
+ It will freeze clients that receive this player's movement info.
+ */
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT),
+ MOVEMENTFLAG_ROOT);
+
+ //! Cannot hover without SPELL_AURA_HOVER
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !HasAuraType(SPELL_AURA_HOVER),
+ MOVEMENTFLAG_HOVER);
+
+ //! Cannot ascend and descend at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
+ MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
+
+ //! Cannot move left and right at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
+ MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
+
+ //! Cannot strafe left and right at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
+ MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
+
+ //! Cannot pitch up and down at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
+ MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
+
+ //! Cannot move forwards and backwards at the same time
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
+ MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
+
+ //! Cannot walk on water without SPELL_AURA_WATER_WALK
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !HasAuraType(SPELL_AURA_WATER_WALK),
+ MOVEMENTFLAG_WATERWALKING);
+
+ //! Cannot feather fall without SPELL_AURA_FEATHER_FALL
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !HasAuraType(SPELL_AURA_FEATHER_FALL),
+ MOVEMENTFLAG_FALLING_SLOW);
+
+ /*! Cannot fly if no fly auras present. Exception is being a GM.
+ Note that we check for account level instead of Player::IsGameMaster() because in some
+ situations it may be feasable to use .gm fly on as a GM without having .gm on,
+ e.g. aerial combat.
+ */
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && ToPlayer()->GetSession()->GetSecurity() == SEC_PLAYER &&
+ !ToPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
+ !ToPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
+ MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
+ MOVEMENTFLAG_FALLING);
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING) && (!hasFallData || !hasFallDirection), MOVEMENTFLAG_FALLING);
+
+ REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION) &&
+ (!hasSplineElevation || G3D::fuzzyEq(mi->splineElevation, 0.0f)), MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ // Client first checks if spline elevation != 0, then verifies flag presence
+ if (hasSplineElevation)
+ mi->AddMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ #undef REMOVE_VIOLATING_FLAGS
+}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1f5f9fee7d4..0c4ce8b2c6e 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -25,19 +25,23 @@
#include "Item.h"
#include "PetDefines.h"
+#include "PhaseMgr.h"
#include "QuestDef.h"
#include "SpellMgr.h"
#include "Unit.h"
+#include "Opcodes.h"
+#include "WorldSession.h"
#include <string>
#include <vector>
struct CreatureTemplate;
struct Mail;
+struct ItemExtendedCostEntry;
struct TrainerSpell;
struct VendorItem;
-class AchievementMgr;
+template<class T> class AchievementMgr;
class ReputationMgr;
class Channel;
class CharacterCreateInfo;
@@ -51,12 +55,13 @@ class PlayerMenu;
class PlayerSocial;
class SpellCastTargets;
class UpdateMask;
+class PhaseMgr;
typedef std::deque<Mail*> PlayerMails;
-#define PLAYER_MAX_SKILLS 127
+#define PLAYER_MAX_SKILLS 128
#define PLAYER_MAX_DAILY_QUESTS 25
-#define PLAYER_EXPLORED_ZONES_SIZE 128
+#define PLAYER_EXPLORED_ZONES_SIZE 156
// Note: SPELLMOD_* values is aura types in fact
enum SpellModType
@@ -108,6 +113,42 @@ struct PlayerTalent
uint8 spec : 8;
};
+extern uint32 const MasterySpells[MAX_CLASSES];
+
+enum TalentTree // talent tabs
+{
+ TALENT_TREE_WARRIOR_ARMS = 746,
+ TALENT_TREE_WARRIOR_FURY = 815,
+ TALENT_TREE_WARRIOR_PROTECTION = 845,
+ TALENT_TREE_PALADIN_HOLY = 831,
+ TALENT_TREE_PALADIN_PROTECTION = 839,
+ TALENT_TREE_PALADIN_RETRIBUTION = 855,
+ TALENT_TREE_HUNTER_BEAST_MASTERY = 811,
+ TALENT_TREE_HUNTER_MARKSMANSHIP = 807,
+ TALENT_TREE_HUNTER_SURVIVAL = 809,
+ TALENT_TREE_ROGUE_ASSASSINATION = 182,
+ TALENT_TREE_ROGUE_COMBAT = 181,
+ TALENT_TREE_ROGUE_SUBTLETY = 183,
+ TALENT_TREE_PRIEST_DISCIPLINE = 760,
+ TALENT_TREE_PRIEST_HOLY = 813,
+ TALENT_TREE_PRIEST_SHADOW = 795,
+ TALENT_TREE_DEATH_KNIGHT_BLOOD = 398,
+ TALENT_TREE_DEATH_KNIGHT_FROST = 399,
+ TALENT_TREE_DEATH_KNIGHT_UNHOLY = 400,
+ TALENT_TREE_SHAMAN_ELEMENTAL = 261,
+ TALENT_TREE_SHAMAN_ENHANCEMENT = 263,
+ TALENT_TREE_SHAMAN_RESTORATION = 262,
+ TALENT_TREE_MAGE_ARCANE = 799,
+ TALENT_TREE_MAGE_FIRE = 851,
+ TALENT_TREE_MAGE_FROST = 823,
+ TALENT_TREE_WARLOCK_AFFLICTION = 871,
+ TALENT_TREE_WARLOCK_DEMONOLOGY = 867,
+ TALENT_TREE_WARLOCK_DESTRUCTION = 865,
+ TALENT_TREE_DRUID_BALANCE = 752,
+ TALENT_TREE_DRUID_FERAL_COMBAT = 750,
+ TALENT_TREE_DRUID_RESTORATION = 748
+};
+
// Spell modifier (used for modify other spells)
struct SpellModifier
{
@@ -121,12 +162,121 @@ struct SpellModifier
Aura* const ownerAura;
};
+enum PlayerCurrencyState
+{
+ PLAYERCURRENCY_UNCHANGED = 0,
+ PLAYERCURRENCY_CHANGED = 1,
+ PLAYERCURRENCY_NEW = 2,
+ PLAYERCURRENCY_REMOVED = 3 //not removed just set count == 0
+};
+
+struct PlayerCurrency
+{
+ PlayerCurrencyState state;
+ uint32 totalCount;
+ uint32 weekCount;
+};
+
typedef UNORDERED_MAP<uint32, PlayerTalent*> PlayerTalentMap;
typedef UNORDERED_MAP<uint32, PlayerSpell*> PlayerSpellMap;
typedef std::list<SpellModifier*> SpellModList;
+typedef UNORDERED_MAP<uint32, PlayerCurrency> PlayerCurrenciesMap;
typedef std::list<uint64> WhisperListContainer;
+/// Maximum number of CompactUnitFrames profiles
+#define MAX_CUF_PROFILES 5
+
+/// Bit index used in the many bool options of CompactUnitFrames
+enum CUFBoolOptions
+{
+ CUF_KEEP_GROUPS_TOGETHER,
+ CUF_DISPLAY_PETS,
+ CUF_DISPLAY_MAIN_TANK_AND_ASSIST,
+ CUF_DISPLAY_HEAL_PREDICTION,
+ CUF_DISPLAY_AGGRO_HIGHLIGHT,
+ CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS,
+ CUF_DISPLAY_POWER_BAR,
+ CUF_DISPLAY_BORDER,
+ CUF_USE_CLASS_COLORS,
+ CUF_DISPLAY_NON_BOSS_DEBUFFS,
+ CUF_DISPLAY_HORIZONTAL_GROUPS,
+ CUF_LOCKED,
+ CUF_SHOWN,
+ CUF_AUTO_ACTIVATE_2_PLAYERS,
+ CUF_AUTO_ACTIVATE_3_PLAYERS,
+ CUF_AUTO_ACTIVATE_5_PLAYERS,
+ CUF_AUTO_ACTIVATE_10_PLAYERS,
+ CUF_AUTO_ACTIVATE_15_PLAYERS,
+ CUF_AUTO_ACTIVATE_25_PLAYERS,
+ CUF_AUTO_ACTIVATE_40_PLAYERS,
+ CUF_AUTO_ACTIVATE_SPEC_1,
+ CUF_AUTO_ACTIVATE_SPEC_2,
+ CUF_AUTO_ACTIVATE_PVP,
+ CUF_AUTO_ACTIVATE_PVE,
+ CUF_UNK_145,
+ CUF_UNK_156,
+ CUF_UNK_157,
+
+ // The unks is _LOCKED and _SHOWN and _DYNAMIC, unknown order
+
+ CUF_BOOL_OPTIONS_COUNT,
+};
+
+/// Represents a CompactUnitFrame profile
+struct CUFProfile
+{
+ CUFProfile() : ProfileName(), BoolOptions() // might want to change default value for options
+ {
+ FrameHeight = 0;
+ FrameWidth = 0;
+ SortBy = 0;
+ HealthText = 0;
+ Unk146 = 0;
+ Unk147 = 0;
+ Unk148 = 0;
+ Unk150 = 0;
+ Unk152 = 0;
+ Unk154 = 0;
+ }
+
+ CUFProfile(const std::string& name, uint16 frameHeight, uint16 frameWidth, uint8 sortBy, uint8 healthText, uint32 boolOptions,
+ uint8 unk146, uint8 unk147, uint8 unk148, uint16 unk150, uint16 unk152, uint16 unk154)
+ : ProfileName(name), BoolOptions((int)boolOptions)
+ {
+ FrameHeight = frameHeight;
+ FrameWidth = frameWidth;
+ SortBy = sortBy;
+ HealthText = healthText;
+ Unk146 = unk146;
+ Unk147 = unk147;
+ Unk148 = unk148;
+ Unk150 = unk150;
+ Unk152 = unk152;
+ Unk154 = unk154;
+ }
+
+ std::string ProfileName;
+ uint16 FrameHeight;
+ uint16 FrameWidth;
+ uint8 SortBy;
+ uint8 HealthText;
+
+ // LeftAlign, TopAlight, BottomAllign (unk order)
+ uint8 Unk146;
+ uint8 Unk147;
+ uint8 Unk148;
+
+ // LeftOffset, TopOffset and BottomOffset (unk order)
+ uint16 Unk150;
+ uint16 Unk152;
+ uint16 Unk154;
+
+ std::bitset<CUF_BOOL_OPTIONS_COUNT> BoolOptions;
+
+ // More fields can be added to BoolOptions without changing DB schema (up to 32, currently 27)
+};
+
struct SpellCooldown
{
time_t end;
@@ -138,9 +288,9 @@ typedef UNORDERED_MAP<uint32 /*instanceId*/, time_t/*releaseTime*/> InstanceTime
enum TrainerSpellState
{
- TRAINER_SPELL_GREEN = 0,
- TRAINER_SPELL_RED = 1,
- TRAINER_SPELL_GRAY = 2,
+ TRAINER_SPELL_GRAY = 0,
+ TRAINER_SPELL_GREEN = 1,
+ TRAINER_SPELL_RED = 2,
TRAINER_SPELL_GREEN_DISABLED = 10 // custom value, not send to client: formally green but learn not allowed
};
@@ -157,6 +307,7 @@ enum ActionButtonType
ACTION_BUTTON_SPELL = 0x00,
ACTION_BUTTON_C = 0x01, // click?
ACTION_BUTTON_EQSET = 0x20,
+ ACTION_BUTTON_DROPDOWN = 0x30,
ACTION_BUTTON_MACRO = 0x40,
ACTION_BUTTON_CMACRO = ACTION_BUTTON_C | ACTION_BUTTON_MACRO,
ACTION_BUTTON_ITEM = 0x80
@@ -213,20 +364,6 @@ struct PlayerCreateInfoItem
typedef std::list<PlayerCreateInfoItem> PlayerCreateInfoItems;
-struct PlayerClassLevelInfo
-{
- PlayerClassLevelInfo() : basehealth(0), basemana(0) { }
- uint16 basehealth;
- uint16 basemana;
-};
-
-struct PlayerClassInfo
-{
- PlayerClassInfo() : levelInfo(NULL) { }
-
- PlayerClassLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1
-};
-
struct PlayerLevelInfo
{
PlayerLevelInfo() { for (uint8 i=0; i < MAX_STATS; ++i) stats[i] = 0; }
@@ -355,14 +492,6 @@ struct EnchantDuration
typedef std::list<EnchantDuration> EnchantDurationList;
typedef std::list<Item*> ItemDurationList;
-enum PlayerMovementType
-{
- MOVE_ROOT = 1,
- MOVE_UNROOT = 2,
- MOVE_WATER_WALK = 3,
- MOVE_LAND_WALK = 4
-};
-
enum DrunkenState
{
DRUNKEN_SOBER = 0,
@@ -375,87 +504,42 @@ enum DrunkenState
enum PlayerFlags
{
- PLAYER_FLAGS_GROUP_LEADER = 0x00000001,
- PLAYER_FLAGS_AFK = 0x00000002,
- PLAYER_FLAGS_DND = 0x00000004,
- PLAYER_FLAGS_GM = 0x00000008,
- PLAYER_FLAGS_GHOST = 0x00000010,
- PLAYER_FLAGS_RESTING = 0x00000020,
- PLAYER_FLAGS_UNK6 = 0x00000040,
- PLAYER_FLAGS_UNK7 = 0x00000080, // pre-3.0.3 PLAYER_FLAGS_FFA_PVP flag for FFA PVP state
- PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards
- PLAYER_FLAGS_IN_PVP = 0x00000200,
- PLAYER_FLAGS_HIDE_HELM = 0x00000400,
- PLAYER_FLAGS_HIDE_CLOAK = 0x00000800,
- PLAYER_FLAGS_PLAYED_LONG_TIME = 0x00001000, // played long time
- PLAYER_FLAGS_PLAYED_TOO_LONG = 0x00002000, // played too long time
- PLAYER_FLAGS_IS_OUT_OF_BOUNDS = 0x00004000,
- PLAYER_FLAGS_DEVELOPER = 0x00008000, // <Dev> prefix for something?
- PLAYER_FLAGS_UNK16 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
- PLAYER_FLAGS_TAXI_BENCHMARK = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
- PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
- PLAYER_FLAGS_UBER = 0x00080000,
- PLAYER_FLAGS_UNK20 = 0x00100000,
- PLAYER_FLAGS_UNK21 = 0x00200000,
- PLAYER_FLAGS_COMMENTATOR2 = 0x00400000,
- PLAYER_ALLOW_ONLY_ABILITY = 0x00800000, // used by bladestorm and killing spree, allowed only spells with SPELL_ATTR0_REQ_AMMO, SPELL_EFFECT_ATTACK, checked only for active player
- PLAYER_FLAGS_UNK24 = 0x01000000, // disabled all melee ability on tab include autoattack
- PLAYER_FLAGS_NO_XP_GAIN = 0x02000000,
- PLAYER_FLAGS_UNK26 = 0x04000000,
- PLAYER_FLAGS_UNK27 = 0x08000000,
- PLAYER_FLAGS_UNK28 = 0x10000000,
- PLAYER_FLAGS_UNK29 = 0x20000000,
- PLAYER_FLAGS_UNK30 = 0x40000000,
- PLAYER_FLAGS_UNK31 = 0x80000000
-};
-
-// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
-// can't use enum for uint64 values
-#define PLAYER_TITLE_DISABLED UI64LIT(0x0000000000000000)
-#define PLAYER_TITLE_NONE UI64LIT(0x0000000000000001)
-#define PLAYER_TITLE_PRIVATE UI64LIT(0x0000000000000002) // 1
-#define PLAYER_TITLE_CORPORAL UI64LIT(0x0000000000000004) // 2
-#define PLAYER_TITLE_SERGEANT_A UI64LIT(0x0000000000000008) // 3
-#define PLAYER_TITLE_MASTER_SERGEANT UI64LIT(0x0000000000000010) // 4
-#define PLAYER_TITLE_SERGEANT_MAJOR UI64LIT(0x0000000000000020) // 5
-#define PLAYER_TITLE_KNIGHT UI64LIT(0x0000000000000040) // 6
-#define PLAYER_TITLE_KNIGHT_LIEUTENANT UI64LIT(0x0000000000000080) // 7
-#define PLAYER_TITLE_KNIGHT_CAPTAIN UI64LIT(0x0000000000000100) // 8
-#define PLAYER_TITLE_KNIGHT_CHAMPION UI64LIT(0x0000000000000200) // 9
-#define PLAYER_TITLE_LIEUTENANT_COMMANDER UI64LIT(0x0000000000000400) // 10
-#define PLAYER_TITLE_COMMANDER UI64LIT(0x0000000000000800) // 11
-#define PLAYER_TITLE_MARSHAL UI64LIT(0x0000000000001000) // 12
-#define PLAYER_TITLE_FIELD_MARSHAL UI64LIT(0x0000000000002000) // 13
-#define PLAYER_TITLE_GRAND_MARSHAL UI64LIT(0x0000000000004000) // 14
-#define PLAYER_TITLE_SCOUT UI64LIT(0x0000000000008000) // 15
-#define PLAYER_TITLE_GRUNT UI64LIT(0x0000000000010000) // 16
-#define PLAYER_TITLE_SERGEANT_H UI64LIT(0x0000000000020000) // 17
-#define PLAYER_TITLE_SENIOR_SERGEANT UI64LIT(0x0000000000040000) // 18
-#define PLAYER_TITLE_FIRST_SERGEANT UI64LIT(0x0000000000080000) // 19
-#define PLAYER_TITLE_STONE_GUARD UI64LIT(0x0000000000100000) // 20
-#define PLAYER_TITLE_BLOOD_GUARD UI64LIT(0x0000000000200000) // 21
-#define PLAYER_TITLE_LEGIONNAIRE UI64LIT(0x0000000000400000) // 22
-#define PLAYER_TITLE_CENTURION UI64LIT(0x0000000000800000) // 23
-#define PLAYER_TITLE_CHAMPION UI64LIT(0x0000000001000000) // 24
-#define PLAYER_TITLE_LIEUTENANT_GENERAL UI64LIT(0x0000000002000000) // 25
-#define PLAYER_TITLE_GENERAL UI64LIT(0x0000000004000000) // 26
-#define PLAYER_TITLE_WARLORD UI64LIT(0x0000000008000000) // 27
-#define PLAYER_TITLE_HIGH_WARLORD UI64LIT(0x0000000010000000) // 28
-#define PLAYER_TITLE_GLADIATOR UI64LIT(0x0000000020000000) // 29
-#define PLAYER_TITLE_DUELIST UI64LIT(0x0000000040000000) // 30
-#define PLAYER_TITLE_RIVAL UI64LIT(0x0000000080000000) // 31
-#define PLAYER_TITLE_CHALLENGER UI64LIT(0x0000000100000000) // 32
-#define PLAYER_TITLE_SCARAB_LORD UI64LIT(0x0000000200000000) // 33
-#define PLAYER_TITLE_CONQUEROR UI64LIT(0x0000000400000000) // 34
-#define PLAYER_TITLE_JUSTICAR UI64LIT(0x0000000800000000) // 35
-#define PLAYER_TITLE_CHAMPION_OF_THE_NAARU UI64LIT(0x0000001000000000) // 36
-#define PLAYER_TITLE_MERCILESS_GLADIATOR UI64LIT(0x0000002000000000) // 37
-#define PLAYER_TITLE_OF_THE_SHATTERED_SUN UI64LIT(0x0000004000000000) // 38
-#define PLAYER_TITLE_HAND_OF_ADAL UI64LIT(0x0000008000000000) // 39
-#define PLAYER_TITLE_VENGEFUL_GLADIATOR UI64LIT(0x0000010000000000) // 40
-
-#define KNOWN_TITLES_SIZE 3
-#define MAX_TITLE_INDEX (KNOWN_TITLES_SIZE*64) // 3 uint64 fields
+ PLAYER_FLAGS_GROUP_LEADER = 0x00000001,
+ PLAYER_FLAGS_AFK = 0x00000002,
+ PLAYER_FLAGS_DND = 0x00000004,
+ PLAYER_FLAGS_GM = 0x00000008,
+ PLAYER_FLAGS_GHOST = 0x00000010,
+ PLAYER_FLAGS_RESTING = 0x00000020,
+ PLAYER_FLAGS_UNK6 = 0x00000040,
+ PLAYER_FLAGS_UNK7 = 0x00000080, // pre-3.0.3 PLAYER_FLAGS_FFA_PVP flag for FFA PVP state
+ PLAYER_FLAGS_CONTESTED_PVP = 0x00000100, // Player has been involved in a PvP combat and will be attacked by contested guards
+ PLAYER_FLAGS_IN_PVP = 0x00000200,
+ PLAYER_FLAGS_HIDE_HELM = 0x00000400,
+ PLAYER_FLAGS_HIDE_CLOAK = 0x00000800,
+ PLAYER_FLAGS_PLAYED_LONG_TIME = 0x00001000, // played long time
+ PLAYER_FLAGS_PLAYED_TOO_LONG = 0x00002000, // played too long time
+ PLAYER_FLAGS_IS_OUT_OF_BOUNDS = 0x00004000,
+ PLAYER_FLAGS_DEVELOPER = 0x00008000, // <Dev> prefix for something?
+ PLAYER_FLAGS_UNK16 = 0x00010000, // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary
+ PLAYER_FLAGS_TAXI_BENCHMARK = 0x00020000, // taxi benchmark mode (on/off) (2.0.1)
+ PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually)
+ PLAYER_FLAGS_UBER = 0x00080000,
+ PLAYER_FLAGS_UNK20 = 0x00100000,
+ PLAYER_FLAGS_UNK21 = 0x00200000,
+ PLAYER_FLAGS_COMMENTATOR2 = 0x00400000,
+ PLAYER_ALLOW_ONLY_ABILITY = 0x00800000, // used by bladestorm and killing spree, allowed only spells with SPELL_ATTR0_REQ_AMMO, SPELL_EFFECT_ATTACK, checked only for active player
+ PLAYER_FLAGS_UNK24 = 0x01000000, // disabled all melee ability on tab include autoattack
+ PLAYER_FLAGS_NO_XP_GAIN = 0x02000000,
+ PLAYER_FLAGS_UNK26 = 0x04000000,
+ PLAYER_FLAGS_AUTO_DECLINE_GUILD = 0x08000000, // Automatically declines guild invites
+ PLAYER_FLAGS_GUILD_LEVEL_ENABLED = 0x10000000, // Lua_GetGuildLevelEnabled() - enables guild leveling related UI
+ PLAYER_FLAGS_VOID_UNLOCKED = 0x20000000, // void storage
+ PLAYER_FLAGS_UNK30 = 0x40000000,
+ PLAYER_FLAGS_UNK31 = 0x80000000
+};
+
+#define KNOWN_TITLES_SIZE 4
+#define MAX_TITLE_INDEX (KNOWN_TITLES_SIZE * 64) // 4 uint64 fields
// used in PLAYER_FIELD_BYTES values
enum PlayerFieldByteFlags
@@ -477,7 +561,7 @@ enum MirrorTimerType
{
FATIGUE_TIMER = 0,
BREATH_TIMER = 1,
- FIRE_TIMER = 2
+ FIRE_TIMER = 2 // feign death
};
#define MAX_TIMERS 3
#define DISABLED_MIRROR_TIMER -1
@@ -491,7 +575,6 @@ enum PlayerExtraFlags
PLAYER_EXTRA_TAXICHEAT = 0x0008,
PLAYER_EXTRA_GM_INVISIBLE = 0x0010,
PLAYER_EXTRA_GM_CHAT = 0x0020, // Show GM badge in chat messages
- PLAYER_EXTRA_HAS_310_FLYER = 0x0040, // Marks if player already has 310% speed flying mount
// other states
PLAYER_EXTRA_PVP_DEATH = 0x0100 // store PvP death status until corpse creating.
@@ -563,7 +646,7 @@ enum PlayerSlots
// first slot for item stored (in any way in player m_items data)
PLAYER_SLOT_START = 0,
// last+1 slot for item stored (in any way in player m_items data)
- PLAYER_SLOT_END = 150,
+ PLAYER_SLOT_END = 86,
PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START)
};
@@ -625,18 +708,6 @@ enum BuyBackSlots // 12 slots
BUYBACK_SLOT_END = 86
};
-enum KeyRingSlots // 32 slots
-{
- KEYRING_SLOT_START = 86,
- KEYRING_SLOT_END = 118
-};
-
-enum CurrencyTokenSlots // 32 slots
-{
- CURRENCYTOKEN_SLOT_START = 118,
- CURRENCYTOKEN_SLOT_END = 150
-};
-
enum EquipmentSetUpdateState
{
EQUIPMENT_SET_UNCHANGED = 0,
@@ -684,22 +755,24 @@ 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_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
};
enum InstanceResetWarningType
@@ -761,7 +834,9 @@ enum PlayerChatTag
CHAT_TAG_DND = 0x02,
CHAT_TAG_GM = 0x04,
CHAT_TAG_COM = 0x08, // Commentator
- CHAT_TAG_DEV = 0x10
+ CHAT_TAG_DEV = 0x10,
+ CHAT_TAG_BOSS_SOUND = 0x20, // Plays "RaidBossEmoteWarning" sound on raid boss emote/whisper
+ CHAT_TAG_MOBILE = 0x40
};
enum PlayedTimeIndex
@@ -808,6 +883,9 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30,
PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31,
PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32,
+ PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE = 33,
+ PLAYER_LOGIN_QUERY_LOAD_CURRENCY = 34,
+ PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES = 35,
MAX_PLAYER_LOGIN_QUERY
};
@@ -824,7 +902,7 @@ enum PlayerDelayedOperations
// Player summoning auto-decline time (in secs)
#define MAX_PLAYER_SUMMON_DELAY (2*MINUTE)
-#define MAX_MONEY_AMOUNT (0x7FFFFFFF-1)
+#define MAX_MONEY_AMOUNT (UI64LIT(9999999999)) // TODO: Move this restriction to worldserver.conf, default to this value, hardcap at uint64.max
struct InstancePlayerBind
{
@@ -855,12 +933,6 @@ enum CharDeleteMethod
// the name gets freed up and appears as deleted ingame
};
-enum CurrencyItems
-{
- ITEM_HONOR_POINTS_ID = 43308,
- ITEM_ARENA_POINTS_ID = 43307
-};
-
enum ReferAFriendError
{
ERR_REFER_A_FRIEND_NONE = 0x00,
@@ -907,14 +979,14 @@ class PlayerTaxi
bool IsTaximaskNodeKnown(uint32 nodeidx) const
{
- uint8 field = uint8((nodeidx - 1) / 32);
- uint32 submask = 1 << ((nodeidx-1) % 32);
+ uint8 field = uint8((nodeidx - 1) / 8);
+ uint32 submask = 1 << ((nodeidx-1) % 8);
return (m_taximask[field] & submask) == submask;
}
bool SetTaximaskNode(uint32 nodeidx)
{
- uint8 field = uint8((nodeidx - 1) / 32);
- uint32 submask = 1 << ((nodeidx-1) % 32);
+ uint8 field = uint8((nodeidx - 1) / 8);
+ uint32 submask = 1 << ((nodeidx-1) % 8);
if ((m_taximask[field] & submask) != submask)
{
m_taximask[field] |= submask;
@@ -955,12 +1027,14 @@ class Player;
struct BGData
{
BGData() : bgInstanceID(0), bgTypeID(BATTLEGROUND_TYPE_NONE), bgAfkReportedCount(0), bgAfkReportedTimer(0),
- bgTeam(0), mountSpell(0) { ClearTaxiPath(); }
+ bgTeam(0), mountSpell(0) { bgQueuesJoinedTime.clear(); ClearTaxiPath(); }
uint32 bgInstanceID; ///< This variable is set to bg->m_InstanceID,
/// when player is teleported to BG - (it is battleground's GUID)
BattlegroundTypeId bgTypeID;
+ std::map<uint32, uint32> bgQueuesJoinedTime;
+
std::set<uint32> bgAfkReporter;
uint8 bgAfkReportedCount;
time_t bgAfkReportedTimer;
@@ -976,6 +1050,33 @@ struct BGData
bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
};
+struct VoidStorageItem
+{
+ VoidStorageItem()
+ {
+ ItemId = 0;
+ ItemEntry = 0;
+ CreatorGuid = 0;
+ ItemRandomPropertyId = 0;
+ ItemSuffixFactor = 0;
+ }
+
+ VoidStorageItem(uint64 id, uint32 entry, uint32 creator, uint32 randomPropertyId, uint32 suffixFactor)
+ {
+ ItemId = id;
+ ItemEntry = entry;
+ CreatorGuid = creator;
+ ItemRandomPropertyId = randomPropertyId;
+ ItemSuffixFactor = suffixFactor;
+ }
+
+ uint64 ItemId;
+ uint32 ItemEntry;
+ uint32 CreatorGuid;
+ uint32 ItemRandomPropertyId;
+ uint32 ItemSuffixFactor;
+};
+
class TradeData
{
public: // constructors
@@ -997,8 +1098,8 @@ class TradeData
Item* GetSpellCastItem() const;
bool HasSpellCastItem() const { return m_spellCastItem != 0; }
- uint32 GetMoney() const { return m_money; }
- void SetMoney(uint32 money);
+ uint64 GetMoney() const { return m_money; }
+ void SetMoney(uint64 money);
bool IsAccepted() const { return m_accepted; }
void SetAccepted(bool state, bool crosssend = false);
@@ -1018,7 +1119,7 @@ class TradeData
bool m_accepted; // m_player press accept for trade list
bool m_acceptProccess; // one from player/trader press accept and this processed
- uint32 m_money; // m_player place money to trade
+ uint64 m_money; // m_player place money to trade
uint32 m_spell; // m_player apply spell to non-traded slot item
uint64 m_spellCastItem; // applied spell cast by item use
@@ -1026,6 +1127,15 @@ class TradeData
uint64 m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot
};
+struct ResurrectionData
+{
+ uint64 GUID;
+ WorldLocation Location;
+ uint32 Health;
+ uint32 Mana;
+ uint32 Aura;
+};
+
class KillRewarder
{
public:
@@ -1058,6 +1168,50 @@ private:
bool _isPvP;
};
+struct PlayerTalentInfo
+{
+ PlayerTalentInfo() :
+ FreeTalentPoints(0), UsedTalentCount(0), QuestRewardedTalentCount(0),
+ ResetTalentsCost(0), ResetTalentsTime(0),
+ ActiveSpec(0), SpecsCount(1)
+ {
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ {
+ SpecInfo[i].Talents = new PlayerTalentMap();
+ memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
+ SpecInfo[i].TalentTree = 0;
+ }
+ }
+
+ ~PlayerTalentInfo()
+ {
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ {
+ for (PlayerTalentMap::const_iterator itr = SpecInfo[i].Talents->begin(); itr != SpecInfo[i].Talents->end(); ++itr)
+ delete itr->second;
+ delete SpecInfo[i].Talents;
+ }
+ }
+
+ struct TalentSpecInfo
+ {
+ PlayerTalentMap* Talents;
+ uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
+ uint32 TalentTree;
+ } SpecInfo[MAX_TALENT_SPECS];
+
+ uint32 FreeTalentPoints;
+ uint32 UsedTalentCount;
+ uint32 QuestRewardedTalentCount;
+ uint32 ResetTalentsCost;
+ time_t ResetTalentsTime;
+ uint8 ActiveSpec;
+ uint8 SpecsCount;
+
+private:
+ PlayerTalentInfo(PlayerTalentInfo const&);
+};
+
class Player : public Unit, public GridObject<Player>
{
friend class WorldSession;
@@ -1090,13 +1244,12 @@ class Player : public Unit, public GridObject<Player>
void Update(uint32 time);
- static bool BuildEnumData(PreparedQueryResult result, WorldPacket* data);
+ static bool BuildEnumData(PreparedQueryResult result, ByteBuffer* dataBuffer, ByteBuffer* bitBuffer);
void SetInWater(bool apply);
bool IsInWater() const { return m_isInWater; }
bool IsUnderWater() const;
- bool IsFalling() { return GetPositionZ() < m_lastFallZ; }
void SendInitialPacketsBeforeAddToMap();
void SendInitialPacketsAfterAddToMap();
@@ -1135,8 +1288,6 @@ class Player : public Unit, public GridObject<Player>
void SetTaxiCheater(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_TAXICHEAT; else m_ExtraFlags &= ~PLAYER_EXTRA_TAXICHEAT; }
bool isGMVisible() const { return !(m_ExtraFlags & PLAYER_EXTRA_GM_INVISIBLE); }
void SetGMVisible(bool on);
- bool Has310Flyer(bool checkAllSpells, uint32 excludeSpellId = 0);
- void SetHas310Flyer(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_HAS_310_FLYER; else m_ExtraFlags &= ~PLAYER_EXTRA_HAS_310_FLYER; }
void SetPvPDeath(bool on) { if (on) m_ExtraFlags |= PLAYER_EXTRA_PVP_DEATH; else m_ExtraFlags &= ~PLAYER_EXTRA_PVP_DEATH; }
void GiveXP(uint32 xp, Unit* victim, float group_rate=1.0f);
@@ -1177,7 +1328,8 @@ class Player : public Unit, public GridObject<Player>
Pet* GetPet() const;
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
- uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
+
+ PhaseMgr& GetPhaseMgr() { return phaseMgr; }
/// Handles said message in regular chat based on declared language and in config pre-defined Range.
void Say(std::string const& text, const uint32 language);
@@ -1187,6 +1339,7 @@ class Player : public Unit, public GridObject<Player>
void TextEmote(std::string const& text);
/// Handles whispers from Addons and players based on sender, receiver's guid and language.
void Whisper(std::string const& text, const uint32 language, uint64 receiver);
+ void WhisperAddon(std::string const& text, std::string const& prefix, Player* receiver);
/*********************************************************/
/*** STORAGE SYSTEM ***/
@@ -1257,11 +1410,36 @@ class Player : public Unit, public GridObject<Player>
void AddRefundReference(uint32 it);
void DeleteRefundReference(uint32 it);
+ /// send initialization of new currency for client
+ void SendNewCurrency(uint32 id) const;
+ /// send full data about all currencies to client
+ void SendCurrencies() const;
+ /// send conquest currency points and their cap week/arena
+ void SendPvpRewards() const;
+ /// return count of currency witch has plr
+ uint32 GetCurrency(uint32 id, bool usePrecision) const;
+ /// return count of currency gaind on current week
+ uint32 GetCurrencyOnWeek(uint32 id, bool usePrecision) const;
+ /// return week cap by currency id
+ uint32 GetCurrencyWeekCap(uint32 id, bool usePrecision) const;
+ /// return presence related currency
+ bool HasCurrency(uint32 id, uint32 count) const;
+ /// initialize currency count for custom initialization at create character
+ void SetCurrency(uint32 id, uint32 count, bool printLog = true);
+ void ResetCurrencyWeekCap();
+
+ /**
+ * @name ModifyCurrency
+ * @brief Change specific currency and send result to client
+
+ * @param id currency entry from CurrencyTypes.dbc
+ * @param count integer value for adding/removing curent currency
+ * @param printLog used on SMSG_UPDATE_CURRENCY
+ * @param ignore gain multipliers
+ */
+ void ModifyCurrency(uint32 id, int32 count, bool printLog = true, bool ignoreMultipliers = false);
+
void ApplyEquipCooldown(Item* pItem);
- void SetAmmo(uint32 item);
- void RemoveAmmo();
- float GetAmmoDPS() const { return m_ammoDPS; }
- bool CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const;
void QuickEquipItem(uint16 pos, Item* pItem);
void VisualizeItem(uint8 slot, Item* pItem);
void SetVisibleItemSlot(uint8 slot, Item* pItem);
@@ -1282,10 +1460,9 @@ class Player : public Unit, public GridObject<Player>
void AddItemToBuyBackSlot(Item* pItem);
Item* GetItemFromBuyBackSlot(uint32 slot);
void RemoveItemFromBuyBackSlot(uint32 slot, bool del);
- uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; }
void SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2 = NULL, uint32 itemid = 0);
void SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param);
- void SendSellError(SellResult msg, Creature* creature, uint64 guid, uint32 param);
+ void SendSellError(SellResult msg, Creature* creature, uint64 guid);
void AddWeaponProficiency(uint32 newflag) { m_WeaponProficiency |= newflag; }
void AddArmorProficiency(uint32 newflag) { m_ArmorProficiency |= newflag; }
uint32 GetWeaponProficiency() const { return m_WeaponProficiency; }
@@ -1294,6 +1471,7 @@ class Player : public Unit, public GridObject<Player>
bool IsTwoHandUsed() const;
void SendNewItem(Item* item, uint32 count, bool received, bool created, bool broadcast = false);
bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
+ bool BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uint32 currency, uint32 count);
bool _StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot, int32 price, ItemTemplate const* pProto, Creature* pVendor, VendorItem const* crItem, bool bStore);
float GetReputationPriceDiscount(Creature const* creature) const;
@@ -1313,6 +1491,7 @@ class Player : public Unit, public GridObject<Player>
void AddEnchantmentDuration(Item* item, EnchantmentSlot slot, uint32 duration);
void ApplyEnchantment(Item* item, EnchantmentSlot slot, bool apply, bool apply_dur = true, bool ignore_condition = false);
void ApplyEnchantment(Item* item, bool apply);
+ void ApplyReforgeEnchantment(Item* item, bool apply);
void UpdateSkillEnchantments(uint16 skill_id, uint16 curr_value, uint16 new_value);
void SendEnchantmentDurations();
void BuildEnchantmentsInfoData(WorldPacket* data);
@@ -1425,14 +1604,13 @@ class Player : public Unit, public GridObject<Player>
void UpdateForQuestWorldObjects();
bool CanShareQuest(uint32 questId) const;
- void SendQuestComplete(uint32 questId);
+ void SendQuestComplete(Quest const* quest);
void SendQuestReward(Quest const* quest, uint32 XP);
void SendQuestFailed(uint32 questId, InventoryResult reason = EQUIP_ERR_OK);
void SendQuestTimerFailed(uint32 questId);
void SendCanTakeQuestResponse(QuestFailedReason msg) const;
void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver);
void SendPushToPartyResponse(Player* player, uint8 msg);
- void SendQuestUpdateAddItem(Quest const* quest, uint32 itemIdx, uint16 count);
void SendQuestUpdateAddCreatureOrGo(Quest const* quest, uint64 guid, uint32 creatureOrGOIdx, uint16 oldCount, uint16 addCount);
void SendQuestUpdateAddPlayer(Quest const* quest, uint16 oldCount, uint16 addCount);
@@ -1445,6 +1623,17 @@ class Player : public Unit, public GridObject<Player>
void AddTimedQuest(uint32 questId) { m_timedquests.insert(questId); }
void RemoveTimedQuest(uint32 questId) { m_timedquests.erase(questId); }
+ void SaveCUFProfile(uint8 id, CUFProfile* profile) { delete _CUFProfiles[id]; _CUFProfiles[id] = profile; } ///> Replaces a CUF profile at position 0-4
+ CUFProfile* GetCUFProfile(uint8 id) const { return _CUFProfiles[id]; } ///> Retrieves a CUF profile at position 0-4
+ uint8 GetCUFProfilesCount() const
+ {
+ uint8 count = 0;
+ for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
+ if (_CUFProfiles[i])
+ ++count;
+ return count;
+ }
+
bool HasPvPForcingQuest() const;
/*********************************************************/
@@ -1462,6 +1651,8 @@ class Player : public Unit, public GridObject<Player>
static bool LoadPositionFromDB(uint32& mapid, float& x, float& y, float& z, float& o, bool& in_flight, uint64 guid);
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE; }
+ static bool IsValidClass(uint8 Class) { return (1 << (Class - 1)) & CLASSMASK_ALL_PLAYABLE; }
+ static bool IsValidRace(uint8 Race) { return (1 << (Race - 1)) & RACEMASK_ALL_PLAYABLE; }
/*********************************************************/
/*** SAVE SYSTEM ***/
@@ -1493,11 +1684,11 @@ class Player : public Unit, public GridObject<Player>
void setRegenTimerCount(uint32 time) {m_regenTimerCount = time;}
void setWeaponChangeTimer(uint32 time) {m_weaponChangeTimer = time;}
- uint32 GetMoney() const { return GetUInt32Value(PLAYER_FIELD_COINAGE); }
- bool ModifyMoney(int32 amount, bool sendError = true);
- bool HasEnoughMoney(uint32 amount) const { return (GetMoney() >= amount); }
- bool HasEnoughMoney(int32 amount) const;
- void SetMoney(uint32 value);
+ uint64 GetMoney() const { return GetUInt64Value(PLAYER_FIELD_COINAGE); }
+ bool ModifyMoney(int64 amount, bool sendError = true);
+ bool HasEnoughMoney(uint64 amount) const { return (GetMoney() >= amount); }
+ bool HasEnoughMoney(int64 amount) const;
+ void SetMoney(uint64 value);
RewardedQuestSet const& getRewardedQuests() const { return m_RewardedQuests; }
QuestStatusMap& getQuestStatusMap() { return m_QuestStatus; }
@@ -1560,6 +1751,7 @@ class Player : public Unit, public GridObject<Player>
TrainerSpellState GetTrainerSpellState(TrainerSpell const* trainer_spell) const;
bool IsSpellFitByClassAndRace(uint32 spell_id) const;
bool IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const;
+ bool IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const;
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask);
void SendInitialSpells();
@@ -1575,39 +1767,55 @@ class Player : public Unit, public GridObject<Player>
void RemoveTemporarySpell(uint32 spellId);
void SetReputation(uint32 factionentry, uint32 value);
uint32 GetReputation(uint32 factionentry) const;
- std::string const& GetGuildName();
- uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
- void SetFreeTalentPoints(uint32 points);
- bool resetTalents(bool no_cost = false);
- uint32 resetTalentsCost() const;
+ std::string GetGuildName();
+
+ // Talents
+ uint32 GetFreeTalentPoints() const { return _talentMgr->FreeTalentPoints; }
+ void SetFreeTalentPoints(uint32 points) { _talentMgr->FreeTalentPoints = points; }
+ uint32 GetUsedTalentCount() const { return _talentMgr->UsedTalentCount; }
+ void SetUsedTalentCount(uint32 talents) { _talentMgr->UsedTalentCount = talents; }
+ uint32 GetQuestRewardedTalentCount() const { return _talentMgr->QuestRewardedTalentCount; }
+ void AddQuestRewardedTalentCount(uint32 points) { _talentMgr->QuestRewardedTalentCount += points; }
+ 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_; }
+ uint32 GetPrimaryTalentTree(uint8 spec) const { return _talentMgr->SpecInfo[spec].TalentTree; }
+ void SetPrimaryTalentTree(uint8 spec, uint32 tree) { _talentMgr->SpecInfo[spec].TalentTree = tree; }
+ uint8 GetActiveSpec() const { return _talentMgr->ActiveSpec; }
+ void SetActiveSpec(uint8 spec){ _talentMgr->ActiveSpec = spec; }
+ uint8 GetSpecsCount() const { return _talentMgr->SpecsCount; }
+ void SetSpecsCount(uint8 count) { _talentMgr->SpecsCount = count; }
+
+ bool ResetTalents(bool no_cost = false);
+ uint32 GetNextResetTalentsCost() const;
void InitTalentForLevel();
void BuildPlayerTalentsInfoData(WorldPacket* data);
void BuildPetTalentsInfoData(WorldPacket* data);
void SendTalentsInfoData(bool pet);
- void LearnTalent(uint32 talentId, uint32 talentRank);
+ bool LearnTalent(uint32 talentId, uint32 talentRank);
void LearnPetTalent(uint64 petGuid, uint32 talentId, uint32 talentRank);
-
bool AddTalent(uint32 spellId, uint8 spec, bool learning);
bool HasTalent(uint32 spell_id, uint8 spec) const;
-
uint32 CalculateTalentsPoints() const;
// Dual Spec
void UpdateSpecCount(uint8 count);
- uint32 GetActiveSpec() { return m_activeSpec; }
- void SetActiveSpec(uint8 spec){ m_activeSpec = spec; }
- uint8 GetSpecsCount() { return m_specsCount; }
- void SetSpecsCount(uint8 count) { m_specsCount = count; }
void ActivateSpec(uint8 spec);
void InitGlyphsForLevel();
void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); }
- uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); }
+
+ uint32 GetGlyphSlot(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); }
void SetGlyph(uint8 slot, uint32 glyph);
- uint32 GetGlyph(uint8 slot) { return m_Glyphs[m_activeSpec][slot]; }
+ uint32 GetGlyph(uint8 spec, uint8 slot) const { return _talentMgr->SpecInfo[spec].Glyphs[slot]; }
- uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); }
- void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2, profs); }
+ PlayerTalentMap const* GetTalentMap(uint8 spec) const { return _talentMgr->SpecInfo[spec].Talents; }
+ PlayerTalentMap* GetTalentMap(uint8 spec) { return _talentMgr->SpecInfo[spec].Talents; }
+ ActionButtonList const& GetActionButtons() const { return m_actionButtons; }
+
+ uint32 GetFreePrimaryProfessionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS); }
+ void SetFreePrimaryProfessions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS, profs); }
void InitPrimaryProfessions();
PlayerSpellMap const& GetSpellMap() const { return m_spells; }
@@ -1630,11 +1838,13 @@ class Player : public Unit, public GridObject<Player>
uint32 GetSpellCooldownDelay(uint32 spell_id) const;
void AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = NULL, bool infinityCooldown = false);
void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time);
+ void ModifySpellCooldown(uint32 spellId, int32 cooldown);
void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = NULL, bool setCooldown = true);
void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs);
void RemoveSpellCooldown(uint32 spell_id, bool update = false);
void RemoveSpellCategoryCooldown(uint32 cat, bool update = false);
void SendClearCooldown(uint32 spell_id, Unit* target);
+ void SendClearAllCooldowns(Unit* target);
GlobalCooldownMgr& GetGlobalCooldownMgr() { return m_GlobalCooldownMgr; }
@@ -1647,10 +1857,22 @@ class Player : public Unit, public GridObject<Player>
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = NULL);
- void setResurrectRequestData(uint64 guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana);
- void clearResurrectRequestData() { setResurrectRequestData(0, 0, 0.0f, 0.0f, 0.0f, 0, 0); }
- bool isRessurectRequestedBy(uint64 guid) const { return m_resurrectGUID == guid; }
- bool isRessurectRequested() const { return m_resurrectGUID != 0; }
+ void SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura);
+ void ClearResurrectRequestData()
+ {
+ delete _resurrectionData;
+ _resurrectionData = NULL;
+ }
+
+ bool IsRessurectRequestedBy(uint64 guid) const
+ {
+ if (!IsRessurectRequested())
+ return false;
+
+ return _resurrectionData->GUID == guid;
+ }
+
+ bool IsRessurectRequested() const { return _resurrectionData != NULL; }
void ResurectUsingRequestData();
uint8 getCinematic() { return m_cinematic; }
@@ -1659,7 +1881,7 @@ class Player : public Unit, public GridObject<Player>
ActionButton* addActionButton(uint8 button, uint32 action, uint8 type);
void removeActionButton(uint8 button);
ActionButton const* GetActionButton(uint8 button);
- void SendInitialActionButtons() const { SendActionButtons(1); }
+ void SendInitialActionButtons() const { SendActionButtons(0); }
void SendActionButtons(uint32 state) const;
bool IsActionButtonDataValid(uint8 button, uint32 action, uint8 type);
@@ -1694,11 +1916,13 @@ class Player : public Unit, public GridObject<Player>
void RemoveFromGroup(RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT) { RemoveFromGroup(GetGroup(), GetGUID(), method); }
void SendUpdateToOutOfRangeGroupMembers();
- void SetInGuild(uint32 GuildId) { SetUInt32Value(PLAYER_GUILDID, GuildId); }
+ void SetInGuild(uint32 guildId);
void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); }
uint8 GetRank() const { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); }
+ void SetGuildLevel(uint32 level) { SetUInt32Value(PLAYER_GUILDLEVEL, level); }
+ uint32 GetGuildLevel() { return GetUInt32Value(PLAYER_GUILDLEVEL); }
void SetGuildIdInvited(uint32 GuildId) { m_GuildIdInvited = GuildId; }
- uint32 GetGuildId() const { return GetUInt32Value(PLAYER_GUILDID); }
+ uint32 GetGuildId() const { return GetUInt32Value(OBJECT_FIELD_DATA); /* return only lower part */ }
Guild* GetGuild();
static uint32 GetGuildIdFromDB(uint64 guid);
static uint8 GetRankFromDB(uint64 guid);
@@ -1714,6 +1938,7 @@ class Player : public Unit, public GridObject<Player>
uint32 GetArenaPersonalRating(uint8 slot) const { return GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (slot * ARENA_TEAM_END) + ARENA_TEAM_PERSONAL_RATING); }
void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }
uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; }
+ uint32 GetRBGPersonalRating() const { return 0; }
Difficulty GetDifficulty(bool isRaid) const { return isRaid ? m_raidDifficulty : m_dungeonDifficulty; }
Difficulty GetDungeonDifficulty() const { return m_dungeonDifficulty; }
@@ -1724,15 +1949,12 @@ class Player : public Unit, public GridObject<Player>
void StoreRaidMapDifficulty() { m_raidMapDifficulty = GetMap()->GetDifficulty(); }
bool UpdateSkill(uint32 skill_id, uint32 step);
- bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step);
+ bool UpdateSkillPro(uint16 skillId, int32 chance, uint32 step);
bool UpdateCraftSkill(uint32 spellid);
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator = 1);
bool UpdateFishingSkill();
- uint32 GetBaseDefenseSkillValue() const { return GetBaseSkillValue(SKILL_DEFENSE); }
- uint32 GetBaseWeaponSkillValue(WeaponAttackType attType) const;
-
uint32 GetSpellByProto(ItemTemplate* proto);
float GetHealthBonusFromStamina();
@@ -1745,27 +1967,26 @@ class Player : public Unit, public GridObject<Player>
void UpdateArmor();
void UpdateMaxHealth();
void UpdateMaxPower(Powers power);
- void ApplyFeralAPBonus(int32 amount, bool apply);
void UpdateAttackPowerAndDamage(bool ranged = false);
- void UpdateShieldBlockValue();
void ApplySpellPowerBonus(int32 amount, bool apply);
void UpdateSpellDamageAndHealingBonus();
void ApplyRatingMod(CombatRating cr, int32 value, bool apply);
void UpdateRating(CombatRating cr);
void UpdateAllRatings();
+ void UpdateMastery();
+ bool CanUseMastery() const;
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage) OVERRIDE;
- void UpdateDefenseBonusesMod();
inline void RecalculateRating(CombatRating cr) { ApplyRatingMod(cr, 0, true);}
float GetMeleeCritFromAgility();
void GetDodgeFromAgility(float &diminishing, float &nondiminishing);
- float GetMissPercentageFromDefence() const;
float GetSpellCritFromIntellect();
- float OCTRegenHPPerSpirit();
float OCTRegenMPPerSpirit();
float GetRatingMultiplier(CombatRating cr) const;
float GetRatingBonusValue(CombatRating cr) const;
+
+ /// Returns base spellpower bonus from spellpower stat on items, without spellpower from intellect stat
uint32 GetBaseSpellPowerBonus() const { return m_baseSpellPower; }
int32 GetSpellPenetrationItemMod() const { return m_spellPenetrationItemMod; }
@@ -1787,6 +2008,7 @@ class Player : public Unit, public GridObject<Player>
void ApplyHealthRegenBonus(int32 amount, bool apply);
void UpdateManaRegen();
void UpdateRuneRegen(RuneType rune);
+ void UpdateAllRunesRegen();
uint64 GetLootGUID() const { return m_lootGuid; }
void SetLootGUID(uint64 guid) { m_lootGuid = guid; }
@@ -1824,8 +2046,6 @@ class Player : public Unit, public GridObject<Player>
void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only);
void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr);
- void SendTeleportAckPacket();
-
Corpse* GetCorpse() const;
void SpawnCorpseBones();
void CreateCorpse();
@@ -1847,8 +2067,6 @@ class Player : public Unit, public GridObject<Player>
void StopMirrorTimers();
bool IsMirrorTimerActive(MirrorTimerType type);
- void SetMovement(PlayerMovementType pType);
-
bool CanJoinConstantChannelInZone(ChatChannelsEntry const* channel, AreaTableEntry const* zone);
void JoinedChannel(Channel* c);
@@ -1857,10 +2075,6 @@ class Player : public Unit, public GridObject<Player>
void UpdateLocalChannels(uint32 newZone);
void LeaveLFGChannel();
- void UpdateDefense();
- void UpdateWeaponSkill (WeaponAttackType attType);
- void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence);
-
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal);
uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus
uint16 GetPureMaxSkillValue(uint32 skill) const; // max
@@ -1894,7 +2108,7 @@ class Player : public Unit, public GridObject<Player>
bool IsAtRecruitAFriendDistance(WorldObject const* pOther) const;
void RewardPlayerAndGroupAtKill(Unit* victim, bool isBattleGround);
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource);
- bool isHonorOrXPTarget(Unit* victim);
+ bool isHonorOrXPTarget(Unit const* victim);
bool GetsRecruitAFriendBonus(bool forXP);
uint8 GetGrantableLevels() { return m_grantableLevels; }
@@ -1915,15 +2129,10 @@ class Player : public Unit, public GridObject<Player>
/*********************************************************/
/*** PVP SYSTEM ***/
/*********************************************************/
+ // TODO: Properly implement correncies as of Cataclysm
void UpdateHonorFields();
bool RewardHonor(Unit* victim, uint32 groupsize, int32 honor = -1, bool pvptoken = false);
- uint32 GetHonorPoints() const { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); }
- uint32 GetArenaPoints() const { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); }
- void ModifyHonorPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, honor save query will be added to trans
- void ModifyArenaPoints(int32 value, SQLTransaction* trans = NULL); //! If trans is specified, arena point save query will be added to trans
uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot) const;
- void SetHonorPoints(uint32 value);
- void SetArenaPoints(uint32 value);
//End of PvP System
@@ -1939,7 +2148,7 @@ class Player : public Unit, public GridObject<Player>
int32 CalculateCorpseReclaimDelay(bool load = false);
void SendCorpseReclaimDelay(uint32 delay);
- uint32 GetShieldBlockValue() const; // overwrite Unit version (virtual)
+ uint32 GetBlockPercent() const { return GetUInt32Value(PLAYER_SHIELD_BLOCK); }
bool CanParry() const { return m_canParry; }
void SetCanParry(bool value);
bool CanBlock() const { return m_canBlock; }
@@ -1969,7 +2178,6 @@ class Player : public Unit, public GridObject<Player>
void _ApplyAllLevelScaleItemMods(bool apply);
void _ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply, bool only_level_scale = false);
void _ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply);
- void _ApplyAmmoBonuses();
bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot);
void ToggleMetaGemsActive(uint8 exceptslot, bool apply);
void CorrectMetaGemEnchants(uint8 slot, bool apply);
@@ -2012,6 +2220,16 @@ class Player : public Unit, public GridObject<Player>
BattlegroundTypeId GetBattlegroundTypeId() const { return m_bgData.bgTypeID; }
Battleground* GetBattleground() const;
+ uint32 GetBattlegroundQueueJoinTime(uint32 bgTypeId) const { return m_bgData.bgQueuesJoinedTime.find(bgTypeId)->second; }
+ void AddBattlegroundQueueJoinTime(uint32 bgTypeId, uint32 joinTime)
+ {
+ m_bgData.bgQueuesJoinedTime[bgTypeId] = joinTime;
+ }
+ void RemoveBattlegroundQueueJoinTime(uint32 bgTypeId)
+ {
+ m_bgData.bgQueuesJoinedTime.erase(m_bgData.bgQueuesJoinedTime.find(bgTypeId)->second);
+ }
+
bool InBattlegroundQueue() const;
BattlegroundQueueTypeId GetBattlegroundQueueTypeId(uint32 index) const;
@@ -2237,7 +2455,8 @@ class Player : public Unit, public GridObject<Player>
RuneType GetBaseRune(uint8 index) const { return RuneType(m_runes->runes[index].BaseRune); }
RuneType GetCurrentRune(uint8 index) const { return RuneType(m_runes->runes[index].CurrentRune); }
uint32 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; }
- uint32 GetRuneBaseCooldown(uint8 index);
+ uint32 GetRuneBaseCooldown(uint8 index) const { return GetRuneTypeBaseCooldown(GetBaseRune(index)); }
+ uint32 GetRuneTypeBaseCooldown(RuneType runeType) const;
bool IsBaseRuneSlotsOnCooldown(RuneType runeType) const;
RuneType GetLastUsedRune() { return m_runes->lastUsedRune; }
void SetLastUsedRune(RuneType type) { m_runes->lastUsedRune = type; }
@@ -2254,11 +2473,12 @@ class Player : public Unit, public GridObject<Player>
void InitRunes();
void SendRespondInspectAchievements(Player* player) const;
+ uint32 GetAchievementPoints() const;
bool HasAchieved(uint32 achievementId) const;
void ResetAchievements();
void CheckAllAchievementCriteria();
- void ResetAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, bool evenIfCriteriaComplete = false);
- void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL);
+ void ResetAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, bool evenIfCriteriaComplete = false);
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit* unit = NULL);
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0);
void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry);
void CompletedAchievement(AchievementEntry const* entry);
@@ -2282,11 +2502,13 @@ class Player : public Unit, public GridObject<Player>
bool IsInWhisperWhiteList(uint64 guid);
void RemoveFromWhisperWhiteList(uint64 guid) { WhisperList.remove(guid); }
- bool SetDisableGravity(bool disable, bool packetOnly /* = false */);
- bool SetCanFly(bool apply);
- bool SetWaterWalking(bool apply, bool packetOnly = false);
- bool SetFeatherFall(bool apply, bool packetOnly = false);
- bool SetHover(bool enable, bool packetOnly = false);
+ void ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::ExtraMovementStatusElement* extras = NULL);
+
+ /*! These methods send different packets to the client in apply and unapply case.
+ These methods are only sent to the current unit.
+ */
+ void SendMovementSetCanTransitionBetweenSwimAndFly(bool apply);
+ void SendMovementSetCollisionHeight(float height);
bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }
@@ -2296,11 +2518,26 @@ class Player : public Unit, public GridObject<Player>
std::string GetMapAreaAndZoneString();
std::string GetCoordsMapAreaAndZoneString();
+ // Void Storage
+ bool IsVoidStorageUnlocked() const { return HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); }
+ void UnlockVoidStorage() { SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); }
+ void LockVoidStorage() { RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_VOID_UNLOCKED); }
+ uint8 GetNextVoidStorageFreeSlot() const;
+ uint8 GetNumOfVoidStorageFreeSlots() const;
+ uint8 AddVoidStorageItem(const VoidStorageItem& item);
+ void AddVoidStorageItemAtSlot(uint8 slot, const VoidStorageItem& item);
+ void DeleteVoidStorageItem(uint8 slot);
+ bool SwapVoidStorageItem(uint8 oldSlot, uint8 newSlot);
+ VoidStorageItem* GetVoidStorageItem(uint8 slot) const;
+ VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const;
+
protected:
// Gamemaster whisper whitelist
WhisperListContainer WhisperList;
uint32 m_regenTimerCount;
- float m_powerFraction[MAX_POWERS];
+ uint32 m_holyPowerRegenTimerCount;
+ uint32 m_focusRegenTimerCount;
+ float m_powerFraction[MAX_POWERS_PER_CLASS];
uint32 m_contestedPvPTimer;
/*********************************************************/
@@ -2346,6 +2583,7 @@ class Player : public Unit, public GridObject<Player>
void _LoadGlyphAuras();
void _LoadBoundInstances(PreparedQueryResult result);
void _LoadInventory(PreparedQueryResult result, uint32 timeDiff);
+ void _LoadVoidStorage(PreparedQueryResult result);
void _LoadMailInit(PreparedQueryResult resultUnread, PreparedQueryResult resultDelivery);
void _LoadMail();
void _LoadMailedItems(Mail* mail);
@@ -2368,6 +2606,8 @@ class Player : public Unit, public GridObject<Player>
void _LoadGlyphs(PreparedQueryResult result);
void _LoadTalents(PreparedQueryResult result);
void _LoadInstanceTimeRestrictions(PreparedQueryResult result);
+ void _LoadCurrency(PreparedQueryResult result);
+ void _LoadCUFProfiles(PreparedQueryResult result);
/*********************************************************/
/*** SAVE SYSTEM ***/
@@ -2376,6 +2616,7 @@ class Player : public Unit, public GridObject<Player>
void _SaveActions(SQLTransaction& trans);
void _SaveAuras(SQLTransaction& trans);
void _SaveInventory(SQLTransaction& trans);
+ void _SaveVoidStorage(SQLTransaction& trans);
void _SaveMail(SQLTransaction& trans);
void _SaveQuestStatus(SQLTransaction& trans);
void _SaveDailyQuestStatus(SQLTransaction& trans);
@@ -2390,6 +2631,8 @@ class Player : public Unit, public GridObject<Player>
void _SaveTalents(SQLTransaction& trans);
void _SaveStats(SQLTransaction& trans);
void _SaveInstanceTimeRestrictions(SQLTransaction& trans);
+ void _SaveCurrency(SQLTransaction& trans);
+ void _SaveCUFProfiles(SQLTransaction& trans);
/*********************************************************/
/*** ENVIRONMENTAL SYSTEM ***/
@@ -2421,6 +2664,29 @@ class Player : public Unit, public GridObject<Player>
Item* m_items[PLAYER_SLOTS_COUNT];
uint32 m_currentBuybackSlot;
+ PlayerCurrenciesMap _currencyStorage;
+
+ /**
+ * @name GetCurrencyWeekCap
+ * @brief return week cap for selected currency
+
+ * @param CurrencyTypesEntry for which to retrieve weekly cap
+ */
+ uint32 GetCurrencyWeekCap(CurrencyTypesEntry const* currency) const;
+
+ /*
+ * @name GetCurrencyTotalCap
+ * @brief return total cap for selected currency
+
+ * @param CurrencyTypesEntry for which to retrieve total cap
+ */
+ uint32 GetCurrencyTotalCap(CurrencyTypesEntry const* currency) const;
+
+ /// Updates weekly conquest point cap (dynamic cap)
+ void UpdateConquestCurrencyCap(uint32 currency);
+
+ VoidStorageItem* _voidStorageItems[VOID_STORAGE_MAX_SLOT];
+
std::vector<Item*> m_itemUpdateQueue;
bool m_itemUpdateQueueBlocked;
@@ -2442,22 +2708,17 @@ class Player : public Unit, public GridObject<Player>
PlayerMails m_mail;
PlayerSpellMap m_spells;
- PlayerTalentMap* m_talents[MAX_TALENT_SPECS];
uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use
GlobalCooldownMgr m_GlobalCooldownMgr;
- uint8 m_activeSpec;
- uint8 m_specsCount;
-
- uint32 m_Glyphs[MAX_TALENT_SPECS][MAX_GLYPH_SLOT_INDEX];
+ PlayerTalentInfo* _talentMgr;
ActionButtonList m_actionButtons;
float m_auraBaseMod[BASEMOD_END][MOD_END];
int16 m_baseRatingValue[MAX_COMBAT_RATING];
uint32 m_baseSpellPower;
- uint32 m_baseFeralAP;
uint32 m_baseManaRegen;
uint32 m_baseHealthRegen;
int32 m_spellPenetrationItemMod;
@@ -2471,10 +2732,7 @@ class Player : public Unit, public GridObject<Player>
void ResetTimeSync();
void SendTimeSync();
- uint64 m_resurrectGUID;
- uint32 m_resurrectMap;
- float m_resurrectX, m_resurrectY, m_resurrectZ;
- uint32 m_resurrectHealth, m_resurrectMana;
+ ResurrectionData* _resurrectionData;
WorldSession* m_session;
@@ -2509,7 +2767,6 @@ class Player : public Unit, public GridObject<Player>
bool m_canBlock;
bool m_canTitanGrip;
uint8 m_swingErrorMsg;
- float m_ammoDPS;
////////////////////Rest System/////////////////////
time_t time_inn_enter;
@@ -2520,10 +2777,6 @@ class Player : public Unit, public GridObject<Player>
float m_rest_bonus;
RestType rest_type;
////////////////////Rest System/////////////////////
- uint32 m_resetTalentsCost;
- time_t m_resetTalentsTime;
- uint32 m_usedTalentCount;
- uint32 m_questRewardTalentCount;
// Social
PlayerSocial *m_social;
@@ -2556,6 +2809,8 @@ class Player : public Unit, public GridObject<Player>
uint8 m_grantableLevels;
+ CUFProfile* _CUFProfiles[MAX_CUF_PROFILES];
+
private:
// internal common parts for CanStore/StoreItem functions
InventoryResult CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemTemplate const* pProto, uint32& count, bool swap, Item* pSrcItem) const;
@@ -2567,6 +2822,7 @@ class Player : public Unit, public GridObject<Player>
std::set<uint32> m_refundableItems;
void SendRefundInfo(Item* item);
void RefundItem(Item* item);
+ void SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, uint8 error);
// know currencies are not removed at any point (0 displayed)
void AddKnownCurrency(uint32 itemId);
@@ -2605,14 +2861,14 @@ class Player : public Unit, public GridObject<Player>
uint32 m_temporaryUnsummonedPetNumber;
uint32 m_oldpetspell;
- AchievementMgr* m_achievementMgr;
+ AchievementMgr<Player>* m_achievementMgr;
ReputationMgr* m_reputationMgr;
SpellCooldowns m_spellCooldowns;
uint32 m_ChampioningFaction;
- uint32 m_timeSyncCounter;
+ std::queue<uint32> m_timeSyncQueue;
uint32 m_timeSyncTimer;
uint32 m_timeSyncClient;
uint32 m_timeSyncServer;
@@ -2622,6 +2878,9 @@ class Player : public Unit, public GridObject<Player>
uint32 _pendingBindTimer;
uint32 _activeCheats;
+ uint32 _maxPersonalArenaRate;
+
+ PhaseMgr phaseMgr;
};
void AddItemsSetItem(Player*player, Item* item);
diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp
index 8c8e470f80b..f505c8dd64d 100644
--- a/src/server/game/Entities/Player/SocialMgr.cpp
+++ b/src/server/game/Entities/Player/SocialMgr.cpp
@@ -26,6 +26,7 @@
#include "World.h"
#include "Util.h"
#include "AccountMgr.h"
+#include "WorldSession.h"
PlayerSocial::PlayerSocial(): m_playerGUID()
{ }
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index b8f5fd1833d..92aa34371f8 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -74,12 +74,9 @@ void Totem::InitStats(uint32 duration)
// Get spell cast by totem
if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(GetSpell()))
- if (totemSpell->CalcCastTime()) // If spell has cast time -> its an active totem
+ if (totemSpell->CalcCastTime(getLevel())) // If spell has cast time -> its an active totem
m_type = TOTEM_ACTIVE;
- if (GetEntry() == SENTRY_TOTEM_ENTRY)
- SetReactState(REACT_AGGRESSIVE);
-
m_duration = duration;
SetLevel(GetOwner()->getLevel());
@@ -88,13 +85,14 @@ void Totem::InitStats(uint32 duration)
void Totem::InitSummon()
{
if (m_type == TOTEM_PASSIVE && GetSpell())
- {
CastSpell(this, GetSpell(), true);
- }
// Some totems can have both instant effect and passive spell
if (GetSpell(1))
CastSpell(this, GetSpell(1), true);
+
+ if (m_Properties->Id == SUMMON_TYPE_TOTEM_FIRE && GetOwner()->HasAura(SPELL_TOTEMIC_WRATH_TALENT))
+ CastSpell(this, SPELL_TOTEMIC_WRATH, true);
}
void Totem::UnSummon(uint32 msTime)
@@ -120,11 +118,7 @@ void Totem::UnSummon(uint32 msTime)
GetOwner()->RemoveAurasDueToSpell(GetSpell(), GetGUID());
- // Remove Sentry Totem Aura
- if (GetEntry() == SENTRY_TOTEM_ENTRY)
- GetOwner()->RemoveAurasDueToSpell(SENTRY_TOTEM_SPELLID);
-
- //remove aura all party members too
+ // remove aura all party members too
if (Player* owner = GetOwner()->ToPlayer())
{
owner->SendAutoRepeatCancel(this);
diff --git a/src/server/game/Entities/Totem/Totem.h b/src/server/game/Entities/Totem/Totem.h
index 6364157982e..c02267aef99 100644
--- a/src/server/game/Entities/Totem/Totem.h
+++ b/src/server/game/Entities/Totem/Totem.h
@@ -28,9 +28,12 @@ enum TotemType
TOTEM_STATUE = 2 // copied straight from MaNGOS, may need more implementation to work
};
// Some Totems cast spells that are not in creature DB
-#define SENTRY_TOTEM_SPELLID 6495
-
-#define SENTRY_TOTEM_ENTRY 3968
+enum TotemSpells
+{
+ // Totemic Wrath
+ SPELL_TOTEMIC_WRATH_TALENT = 77746,
+ SPELL_TOTEMIC_WRATH = 77747
+};
class Totem : public Minion
{
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index f8c38d32390..9906dc6d298 100644
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -239,7 +239,6 @@ Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data)
float o = data->orientation;
creature->SetTransport(this);
- creature->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
creature->m_movementInfo.transport.guid = GetGUID();
creature->m_movementInfo.transport.pos.Relocate(x, y, z, o);
CalculatePassengerPosition(x, y, z, &o);
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 3afa6b016d2..06179692845 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -108,9 +108,6 @@ bool Player::UpdateStats(Stats stat)
switch (stat)
{
- case STAT_STRENGTH:
- UpdateShieldBlockValue();
- break;
case STAT_AGILITY:
UpdateArmor();
UpdateAllCritPercentages();
@@ -131,24 +128,12 @@ bool Player::UpdateStats(Stats stat)
}
if (stat == STAT_STRENGTH)
- {
UpdateAttackPowerAndDamage(false);
- if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, stat))
- UpdateAttackPowerAndDamage(true);
- }
else if (stat == STAT_AGILITY)
{
UpdateAttackPowerAndDamage(false);
UpdateAttackPowerAndDamage(true);
}
- else
- {
- // Need update (exist AP from stat auras)
- if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT, stat))
- UpdateAttackPowerAndDamage(false);
- if (HasAuraTypeWithMiscvalue(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, stat))
- UpdateAttackPowerAndDamage(true);
- }
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
@@ -208,8 +193,9 @@ bool Player::UpdateAllStats()
UpdateAllRatings();
UpdateAllCritPercentages();
UpdateAllSpellCritChances();
- UpdateDefenseBonusesMod();
- UpdateShieldBlockValue();
+ UpdateBlockPercentage();
+ UpdateParryPercentage();
+ UpdateDodgePercentage();
UpdateSpellDamageAndHealingBonus();
UpdateManaRegen();
UpdateExpertise(BASE_ATTACK);
@@ -247,7 +233,6 @@ void Player::UpdateArmor()
float value = GetModifierValue(unitMod, BASE_VALUE); // base armor (from items)
value *= GetModifierValue(unitMod, BASE_PCT); // armor percent from items
- value += GetStat(STAT_AGILITY) * 2.0f; // armor bonus from stats
value += GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
@@ -271,15 +256,21 @@ void Player::UpdateArmor()
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))
+ ratio = hpBase->ratio;
+
float stamina = GetStat(STAT_STAMINA);
float baseStam = std::min(20.0f, stamina);
float moreStam = stamina - baseStam;
- return baseStam + (moreStam*10.0f);
+ return baseStam + moreStam * ratio;
}
float Player::GetManaBonusFromIntellect()
{
+ // Taken from PaperDollFrame.lua - 4.3.4.15595
float intellect = GetStat(STAT_INTELLECT);
float baseInt = std::min(20.0f, intellect);
@@ -314,140 +305,32 @@ void Player::UpdateMaxPower(Powers power)
SetMaxPower(power, uint32(value));
}
-void Player::ApplyFeralAPBonus(int32 amount, bool apply)
-{
- _ModifyUInt32(apply, m_baseFeralAP, amount);
- UpdateAttackPowerAndDamage();
-}
-
void Player::UpdateAttackPowerAndDamage(bool ranged)
{
float val2 = 0.0f;
float level = float(getLevel());
+ ChrClassesEntry const* entry = sChrClassesStore.LookupEntry(getClass());
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
uint16 index = UNIT_FIELD_ATTACK_POWER;
- uint16 index_mod = UNIT_FIELD_ATTACK_POWER_MODS;
- uint16 index_mult = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
if (ranged)
{
index = UNIT_FIELD_RANGED_ATTACK_POWER;
- index_mod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
- index_mult = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
-
- switch (getClass())
- {
- case CLASS_HUNTER:
- val2 = level * 2.0f + GetStat(STAT_AGILITY) - 10.0f;
- break;
- case CLASS_ROGUE:
- val2 = level + GetStat(STAT_AGILITY) - 10.0f;
- break;
- case CLASS_WARRIOR:
- val2 = level + GetStat(STAT_AGILITY) - 10.0f;
- break;
- case CLASS_DRUID:
- switch (GetShapeshiftForm())
- {
- case FORM_CAT:
- case FORM_BEAR:
- case FORM_DIREBEAR:
- val2 = 0.0f; break;
- default:
- val2 = GetStat(STAT_AGILITY) - 10.0f; break;
- }
- break;
- default: val2 = GetStat(STAT_AGILITY) - 10.0f; break;
- }
+ val2 = (level + std::max(GetStat(STAT_AGILITY) - 10.0f, 0.0f)) * entry->RAPPerAgility;
}
else
{
- switch (getClass())
- {
- case CLASS_WARRIOR:
- val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f;
- break;
- case CLASS_PALADIN:
- val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f;
- break;
- case CLASS_DEATH_KNIGHT:
- val2 = level * 3.0f + GetStat(STAT_STRENGTH) * 2.0f - 20.0f;
- break;
- case CLASS_ROGUE:
- val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f;
- break;
- case CLASS_HUNTER:
- val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f;
- break;
- case CLASS_SHAMAN:
- val2 = level * 2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f;
- break;
- case CLASS_DRUID:
- {
- // Check if Predatory Strikes is skilled
- float mLevelMult = 0.0f;
- float weapon_bonus = 0.0f;
- if (IsInFeralForm())
- {
- Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_DUMMY);
- for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
- {
- AuraEffect* aurEff = *itr;
- if (aurEff->GetSpellInfo()->SpellIconID == 1563)
- {
- switch (aurEff->GetEffIndex())
- {
- case 0: // Predatory Strikes (effect 0)
- mLevelMult = CalculatePct(1.0f, aurEff->GetAmount());
- break;
- case 1: // Predatory Strikes (effect 1)
- if (Item* mainHand = m_items[EQUIPMENT_SLOT_MAINHAND])
- {
- // also gains % attack power from equipped weapon
- ItemTemplate const* proto = mainHand->GetTemplate();
- if (!proto)
- continue;
-
- weapon_bonus = CalculatePct(float(proto->getFeralBonus()), aurEff->GetAmount());
- }
- break;
- default:
- break;
- }
- }
- }
- }
-
- switch (GetShapeshiftForm())
- {
- case FORM_CAT:
- val2 = getLevel() * (mLevelMult + 2.0f) + GetStat(STAT_STRENGTH) * 2.0f + GetStat(STAT_AGILITY) - 20.0f + weapon_bonus + m_baseFeralAP;
- break;
- case FORM_BEAR:
- case FORM_DIREBEAR:
- val2 = getLevel() * (mLevelMult + 3.0f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + weapon_bonus + m_baseFeralAP;
- break;
- case FORM_MOONKIN:
- val2 = getLevel() * (mLevelMult + 1.5f) + GetStat(STAT_STRENGTH) * 2.0f - 20.0f + m_baseFeralAP;
- break;
- default:
- val2 = GetStat(STAT_STRENGTH) * 2.0f - 20.0f;
- break;
- }
- break;
- }
- case CLASS_MAGE:
- val2 = GetStat(STAT_STRENGTH) - 10.0f;
- break;
- case CLASS_PRIEST:
- val2 = GetStat(STAT_STRENGTH) - 10.0f;
- break;
- case CLASS_WARLOCK:
- val2 = GetStat(STAT_STRENGTH) - 10.0f;
- break;
- }
+ float strengthValue = std::max((GetStat(STAT_STRENGTH) - 10.0f) * entry->APPerStrenth, 0.0f);
+ float agilityValue = std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerAgility, 0.0f);
+
+ SpellShapeshiftFormEntry const* form = sSpellShapeshiftFormStore.LookupEntry(GetShapeshiftForm());
+ // Directly taken from client, SHAPESHIFT_FLAG_AP_FROM_STRENGTH ?
+ if (form && form->flags1 & 0x20)
+ agilityValue += std::max((GetStat(STAT_AGILITY) - 10.0f) * entry->APPerStrenth, 0.0f);
+
+ val2 = strengthValue + agilityValue;
}
SetModifierValue(unitMod, BASE_VALUE, val2);
@@ -456,32 +339,15 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
- if (ranged)
+ if (!ranged)
{
- if ((getClassMask() & CLASSMASK_WAND_USERS) == 0)
- {
- AuraEffectList const& mRAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
- for (AuraEffectList::const_iterator i = mRAPbyStat.begin(); i != mRAPbyStat.end(); ++i)
- attPowerMod += CalculatePct(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount());
- }
- }
- else
- {
- AuraEffectList const& mAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
- for (AuraEffectList::const_iterator i = mAPbyStat.begin(); i != mAPbyStat.end(); ++i)
- attPowerMod += CalculatePct(GetStat(Stats((*i)->GetMiscValue())), (*i)->GetAmount());
-
AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR);
for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter)
// always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL)
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
}
- float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
-
SetInt32Value(index, (uint32)base_attPower); //UNIT_FIELD_(RANGED)_ATTACK_POWER field
- SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
- SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
Pet* pet = GetPet(); //update pet's AP
Guardian* guardian = GetGuardianPet();
@@ -508,11 +374,6 @@ void Player::UpdateAttackPowerAndDamage(bool ranged)
}
}
-void Player::UpdateShieldBlockValue()
-{
- SetUInt32Value(PLAYER_SHIELD_BLOCK, GetShieldBlockValue());
-}
-
void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage)
{
UnitMods unitMod;
@@ -543,12 +404,20 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
if (IsInFeralForm()) // check if player is druid and in cat or bear forms
{
- uint8 lvl = getLevel();
- if (lvl > 60)
- lvl = 60;
+ float weaponSpeed = BASE_ATTACK_TIME / 1000.f;
+ if (Item* weapon = GetWeaponForAttack(BASE_ATTACK, true))
+ weaponSpeed = weapon->GetTemplate()->Delay / 1000;
- weaponMinDamage = lvl * 0.85f * attackSpeedMod;
- weaponMaxDamage = lvl * 1.25f * attackSpeedMod;
+ if (GetShapeshiftForm() == FORM_CAT)
+ {
+ weaponMinDamage = weaponMinDamage / weaponSpeed;
+ weaponMaxDamage = weaponMaxDamage / weaponSpeed;
+ }
+ else if (GetShapeshiftForm() == FORM_BEAR)
+ {
+ weaponMinDamage = weaponMinDamage / weaponSpeed + weaponMinDamage / 2.5;
+ weaponMaxDamage = weaponMinDamage / weaponSpeed + weaponMaxDamage / 2.5;
+ }
}
else if (!CanUseAttackType(attType)) // check if player not in form but still can't use (disarm case)
{
@@ -562,23 +431,18 @@ void Player::CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bo
weaponMinDamage = BASE_MINDAMAGE;
weaponMaxDamage = BASE_MAXDAMAGE;
}
+ /*
+ TODO: Is this still needed after ammo has been removed?
else if (attType == RANGED_ATTACK) // add ammo DPS to ranged damage
{
weaponMinDamage += GetAmmoDPS() * attackSpeedMod;
weaponMaxDamage += GetAmmoDPS() * attackSpeedMod;
- }
+ }*/
minDamage = ((weaponMinDamage + baseValue) * basePct + totalValue) * totalPct;
maxDamage = ((weaponMaxDamage + baseValue) * basePct + totalValue) * totalPct;
}
-void Player::UpdateDefenseBonusesMod()
-{
- UpdateBlockPercentage();
- UpdateParryPercentage();
- UpdateDodgePercentage();
-}
-
void Player::UpdateBlockPercentage()
{
// No block
@@ -587,8 +451,6 @@ void Player::UpdateBlockPercentage()
{
// Base value
value = 5.0f;
- // Modify value from defense skill
- value += (int32(GetDefenseSkillValue()) - int32(GetMaxSkillValueForLevel())) * 0.04f;
// Increase from SPELL_AURA_MOD_BLOCK_PERCENT aura
value += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT);
// Increase from rating
@@ -630,7 +492,7 @@ void Player::UpdateCritPercentage(WeaponAttackType attType)
float value = GetTotalPercentageModValue(modGroup) + GetRatingBonusValue(cr);
// Modify crit from weapon skill and maximized defense skill of same level victim difference
- value += (int32(GetWeaponSkillValue(attType)) - int32(GetMaxSkillValueForLevel())) * 0.04f;
+ value += (int32(GetMaxSkillValueForLevel()) - int32(GetMaxSkillValueForLevel())) * 0.04f;
if (sWorld->getBoolConfig(CONFIG_STATS_LIMITS_ENABLE))
value = value > sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) ? sWorld->getFloatConfig(CONFIG_STATS_LIMITS_CRIT) : value;
@@ -652,6 +514,44 @@ void Player::UpdateAllCritPercentages()
UpdateCritPercentage(RANGED_ATTACK);
}
+void Player::UpdateMastery()
+{
+ if (!CanUseMastery())
+ {
+ SetFloatValue(PLAYER_MASTERY, 0.0f);
+ return;
+ }
+
+ float value = GetTotalAuraModifier(SPELL_AURA_MASTERY);
+ value += GetRatingBonusValue(CR_MASTERY);
+ SetFloatValue(PLAYER_MASTERY, value);
+
+ TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec()));
+ if (!talentTab)
+ return;
+
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ {
+ if (!talentTab->MasterySpellId[i])
+ continue;
+
+ if (Aura* aura = GetAura(talentTab->MasterySpellId[i]))
+ {
+ for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
+ {
+ if (!aura->HasEffect(j))
+ continue;
+
+ float mult = aura->GetSpellInfo()->Effects[j].BonusMultiplier;
+ if (G3D::fuzzyEq(mult, 0.0f))
+ continue;
+
+ aura->GetEffect(j)->ChangeAmount(int32(value * aura->GetSpellInfo()->Effects[j].BonusMultiplier));
+ }
+ }
+ }
+}
+
const float m_diminishing_k[MAX_CLASSES] =
{
0.9560f, // Warrior
@@ -667,43 +567,16 @@ const float m_diminishing_k[MAX_CLASSES] =
0.9720f // Druid
};
-float Player::GetMissPercentageFromDefence() const
-{
- float const miss_cap[MAX_CLASSES] =
- {
- 16.00f, // Warrior //correct
- 16.00f, // Paladin //correct
- 16.00f, // Hunter //?
- 16.00f, // Rogue //?
- 16.00f, // Priest //?
- 16.00f, // DK //correct
- 16.00f, // Shaman //?
- 16.00f, // Mage //?
- 16.00f, // Warlock //?
- 0.0f, // ??
- 16.00f // Druid //?
- };
-
- float diminishing = 0.0f, nondiminishing = 0.0f;
- // Modify value from defense skill (only bonus from defense rating diminishes)
- nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
- diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;
-
- // apply diminishing formula to diminishing miss chance
- uint32 pclass = getClass()-1;
- return nondiminishing + (diminishing * miss_cap[pclass] / (diminishing + miss_cap[pclass] * m_diminishing_k[pclass]));
-}
-
void Player::UpdateParryPercentage()
{
const float parry_cap[MAX_CLASSES] =
{
- 47.003525f, // Warrior
- 47.003525f, // Paladin
+ 65.631440f, // Warrior
+ 65.631440f, // Paladin
145.560408f, // Hunter
145.560408f, // Rogue
0.0f, // Priest
- 47.003525f, // DK
+ 65.631440f, // DK
145.560408f, // Shaman
0.0f, // Mage
0.0f, // Warlock
@@ -719,9 +592,6 @@ void Player::UpdateParryPercentage()
float nondiminishing = 5.0f;
// Parry from rating
float diminishing = GetRatingBonusValue(CR_PARRY);
- // Modify value from defense skill (only bonus from defense rating diminishes)
- nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
- diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;
// Parry from SPELL_AURA_MOD_PARRY_PERCENT aura
nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT);
// apply diminishing formula to diminishing parry chance
@@ -739,12 +609,12 @@ void Player::UpdateDodgePercentage()
{
const float dodge_cap[MAX_CLASSES] =
{
- 88.129021f, // Warrior
- 88.129021f, // Paladin
+ 65.631440f, // Warrior
+ 65.631440f, // Paladin
145.560408f, // Hunter
145.560408f, // Rogue
150.375940f, // Priest
- 88.129021f, // DK
+ 65.631440f, // DK
145.560408f, // Shaman
150.375940f, // Mage
150.375940f, // Warlock
@@ -754,9 +624,6 @@ void Player::UpdateDodgePercentage()
float diminishing = 0.0f, nondiminishing = 0.0f;
GetDodgeFromAgility(diminishing, nondiminishing);
- // Modify value from defense skill (only bonus from defense rating diminishes)
- nondiminishing += (GetSkillValue(SKILL_DEFENSE) - GetMaxSkillValueForLevel()) * 0.04f;
- diminishing += (int32(GetRatingBonusValue(CR_DEFENSE_SKILL))) * 0.04f;
// Dodge from SPELL_AURA_MOD_DODGE_PERCENT aura
nondiminishing += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT);
// Dodge from rating
@@ -876,29 +743,23 @@ void Player::ApplyHealthRegenBonus(int32 amount, bool apply)
void Player::UpdateManaRegen()
{
- float Intellect = GetStat(STAT_INTELLECT);
- // Mana regen from spirit and intellect
- float power_regen = sqrt(Intellect) * OCTRegenMPPerSpirit();
+ // Mana regen from spirit
+ float spirit_regen = OCTRegenMPPerSpirit();
// Apply PCT bonus from SPELL_AURA_MOD_POWER_REGEN_PERCENT aura on spirit base regen
- power_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
+ spirit_regen *= GetTotalAuraMultiplierByMiscValue(SPELL_AURA_MOD_POWER_REGEN_PERCENT, POWER_MANA);
- // Mana regen from SPELL_AURA_MOD_POWER_REGEN aura
- float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f;
+ // SpiritRegen(SPI, INT, LEVEL) = (0.001 + (SPI x sqrt(INT) x BASE_REGEN[LEVEL])) x 5
+ if (GetStat(STAT_INTELLECT) > 0.0f)
+ spirit_regen *= sqrt(GetStat(STAT_INTELLECT));
- // Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura
- AuraEffectList const& regenAura = GetAuraEffectsByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
- for (AuraEffectList::const_iterator i = regenAura.begin(); i != regenAura.end(); ++i)
- {
- power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f;
- }
+ // CombatRegen = 5% of Base Mana
+ float base_regen = GetCreateMana() * 0.01f + GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) / 5.0f;
// Set regen rate in cast state apply only on spirit based regen
int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);
- if (modManaRegenInterrupt > 100)
- modManaRegenInterrupt = 100;
- SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + CalculatePct(power_regen, modManaRegenInterrupt));
- SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, base_regen + CalculatePct(spirit_regen, modManaRegenInterrupt));
+ SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, 0.001f + spirit_regen + base_regen);
}
void Player::UpdateRuneRegen(RuneType rune)
@@ -922,6 +783,13 @@ void Player::UpdateRuneRegen(RuneType rune)
SetFloatValue(PLAYER_RUNE_REGEN_1 + uint8(rune), regen);
}
+void Player::UpdateAllRunesRegen()
+{
+ for (uint8 i = 0; i < NUM_RUNE_TYPES; ++i)
+ if (uint32 cooldown = GetRuneTypeBaseCooldown(RuneType(i)))
+ SetFloatValue(PLAYER_RUNE_REGEN_1 + i, float(1 * IN_MILLISECONDS) / float(cooldown));
+}
+
void Player::_ApplyAllStatBonuses()
{
SetCanModifyStats(false);
@@ -1007,22 +875,18 @@ void Creature::UpdateAttackPowerAndDamage(bool ranged)
UnitMods unitMod = ranged ? UNIT_MOD_ATTACK_POWER_RANGED : UNIT_MOD_ATTACK_POWER;
uint16 index = UNIT_FIELD_ATTACK_POWER;
- uint16 indexMod = UNIT_FIELD_ATTACK_POWER_MODS;
uint16 indexMulti = UNIT_FIELD_ATTACK_POWER_MULTIPLIER;
if (ranged)
{
index = UNIT_FIELD_RANGED_ATTACK_POWER;
- indexMod = UNIT_FIELD_RANGED_ATTACK_POWER_MODS;
indexMulti = UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER;
}
float baseAttackPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attackPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attackPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
SetInt32Value(index, uint32(baseAttackPower)); // UNIT_FIELD_(RANGED)_ATTACK_POWER
- SetInt32Value(indexMod, uint32(attackPowerMod)); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS
SetFloatValue(indexMulti, attackPowerMultiplier); // UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER
// automatically update weapon damage after attack power modification
@@ -1122,7 +986,7 @@ bool Guardian::UpdateStats(Stats stat)
if (aurEff)
{
SpellInfo const* spellInfo = aurEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value
- AddPct(mod, spellInfo->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale
+ AddPct(mod, spellInfo->Effects[EFFECT_1].CalcValue(owner)); // Ravenous Dead edits the original scale
}
// Glyph of the Ghoul
aurEff = owner->GetAuraEffect(58686, 0);
@@ -1133,29 +997,8 @@ bool Guardian::UpdateStats(Stats stat)
}
else if (stat == STAT_STAMINA)
{
- if (owner->getClass() == CLASS_WARLOCK && IsPet())
- {
- ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 75);
- value += ownersBonus;
- }
- else
- {
- mod = 0.45f;
- if (IsPet())
- {
- PetSpellMap::const_iterator itr = (ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
- if (itr == ToPet()->m_spells.end())
- itr = ToPet()->m_spells.find(62762); // Wild Hunt rank 2
-
- if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
- AddPct(mod, spellInfo->Effects[EFFECT_0].CalcValue());
- }
- }
- ownersBonus = float(owner->GetStat(stat)) * mod;
- value += ownersBonus;
- }
+ ownersBonus = CalculatePct(owner->GetStat(STAT_STAMINA), 30);
+ value += ownersBonus;
}
//warlock's and mage's pets gain 30% of owner's intellect
else if (stat == STAT_INTELLECT)
@@ -1227,13 +1070,14 @@ void Guardian::UpdateArmor()
float bonus_armor = 0.0f;
UnitMods unitMod = UNIT_MOD_ARMOR;
- // hunter and warlock pets gain 35% of owner's armor value
- if (IsPet())
- bonus_armor = float(CalculatePct(m_owner->GetArmor(), 35));
+ // hunter pets gain 35% of owner's armor value, warlock pets gain 100% of owner's armor
+ if (IsHunterPet())
+ bonus_armor = float(CalculatePct(m_owner->GetArmor(), 70));
+ else if (IsPet())
+ bonus_armor = m_owner->GetArmor();
value = GetModifierValue(unitMod, BASE_VALUE);
value *= GetModifierValue(unitMod, BASE_PCT);
- value += GetStat(STAT_AGILITY) * 2.0f;
value += GetModifierValue(unitMod, TOTAL_VALUE) + bonus_armor;
value *= GetModifierValue(unitMod, TOTAL_PCT);
@@ -1310,19 +1154,6 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
if (IsHunterPet()) //hunter pets benefit from owner's attack power
{
float mod = 1.0f; //Hunter contribution modifier
- if (IsPet())
- {
- PetSpellMap::const_iterator itr = ToPet()->m_spells.find(62758); //Wild Hunt rank 1
- if (itr == ToPet()->m_spells.end())
- itr = ToPet()->m_spells.find(62762); //Wild Hunt rank 2
-
- if (itr != ToPet()->m_spells.end()) // If pet has Wild Hunt
- {
- SpellInfo const* sProto = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
- mod += CalculatePct(1.0f, sProto->Effects[1].CalcValue());
- }
- }
-
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
SetBonusDamage(int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod));
}
@@ -1342,8 +1173,8 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
//demons benefit from warlocks shadow or fire damage
else if (IsPet())
{
- int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
- int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
+ int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) + owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) + owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
int32 maximum = (fire > shadow) ? fire : shadow;
if (maximum < 0)
maximum = 0;
@@ -1353,7 +1184,7 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
//water elementals benefit from mage's frost damage
else if (GetEntry() == ENTRY_WATER_ELEMENTAL)
{
- int32 frost = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FROST);
+ int32 frost = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FROST)) + owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FROST);
if (frost < 0)
frost = 0;
SetBonusDamage(int32(frost * 0.4f));
@@ -1364,13 +1195,10 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
//in BASE_VALUE of UNIT_MOD_ATTACK_POWER for creatures we store data of meleeattackpower field in DB
float base_attPower = GetModifierValue(unitMod, BASE_VALUE) * GetModifierValue(unitMod, BASE_PCT);
- float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);
float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f;
//UNIT_FIELD_(RANGED)_ATTACK_POWER field
SetInt32Value(UNIT_FIELD_ATTACK_POWER, (int32)base_attPower);
- //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
- SetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS, (int32)attPowerMod);
//UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
SetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER, attPowerMultiplier);
@@ -1389,14 +1217,14 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
//force of nature
if (GetEntry() == ENTRY_TREANT)
{
- int32 spellDmg = int32(m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) - m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE);
+ int32 spellDmg = int32(m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_NATURE)) + m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_NATURE);
if (spellDmg > 0)
bonusDamage = spellDmg * 0.09f;
}
//greater fire elemental
else if (GetEntry() == ENTRY_FIRE_ELEMENTAL)
{
- int32 spellDmg = int32(m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 spellDmg = int32(m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) + m_owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
if (spellDmg > 0)
bonusDamage = spellDmg * 0.4f;
}
@@ -1417,27 +1245,6 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
float mindamage = ((base_value + weapon_mindamage) * base_pct + total_value) * total_pct;
float maxdamage = ((base_value + weapon_maxdamage) * base_pct + total_value) * total_pct;
- // Pet's base damage changes depending on happiness
- if (IsHunterPet() && attType == BASE_ATTACK)
- {
- switch (ToPet()->GetHappinessState())
- {
- case HAPPY:
- // 125% of normal damage
- mindamage = mindamage * 1.25f;
- maxdamage = maxdamage * 1.25f;
- break;
- case CONTENT:
- // 100% of normal damage, nothing to modify
- break;
- case UNHAPPY:
- // 75% of normal damage
- mindamage = mindamage * 0.75f;
- maxdamage = maxdamage * 0.75f;
- break;
- }
- }
-
/// @todo: remove this
Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACKSPEED);
for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e0bf7019acb..49b7543da85 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -35,7 +35,6 @@
#include "Log.h"
#include "MapManager.h"
#include "MoveSpline.h"
-#include "MoveSplineInit.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Opcodes.h"
@@ -59,6 +58,7 @@
#include "Vehicle.h"
#include "World.h"
#include "WorldPacket.h"
+#include "MovementStructures.h"
#include "WorldSession.h"
#include <math.h>
@@ -175,7 +175,7 @@ Unit::Unit(bool isWorldObject) :
m_objectType |= TYPEMASK_UNIT;
m_objectTypeId = TYPEID_UNIT;
- m_updateFlag = (UPDATEFLAG_LIVING | UPDATEFLAG_STATIONARY_POSITION);
+ m_updateFlag = UPDATEFLAG_LIVING;
m_attackTimer[BASE_ATTACK] = 0;
m_attackTimer[OFF_ATTACK] = 0;
@@ -187,7 +187,7 @@ Unit::Unit(bool isWorldObject) :
m_extraAttacks = 0;
m_canDualWield = false;
- m_rootTimes = 0;
+ m_movementCounter = 0;
m_state = 0;
m_deathState = ALIVE;
@@ -236,7 +236,6 @@ Unit::Unit(bool isWorldObject) :
m_baseSpellCritChance = 5;
m_CombatTimer = 0;
- m_lastManaUse = 0;
for (uint8 i = 0; i < MAX_SPELL_SCHOOL; ++i)
m_threatModifier[i] = 1.0f;
@@ -413,7 +412,7 @@ void Unit::UpdateSplinePosition()
pos.m_positionX = loc.x;
pos.m_positionY = loc.y;
pos.m_positionZ = loc.z;
- pos.m_orientation = loc.orientation;
+ pos.SetOrientation(loc.orientation);
if (TransportBase* transport = GetDirectTransport())
transport->CalculatePassengerPosition(loc.x, loc.y, loc.z, &loc.orientation);
@@ -427,7 +426,7 @@ void Unit::UpdateSplinePosition()
void Unit::DisableSpline()
{
- m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD));
+ m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD);
movespline->_Interrupt();
}
@@ -630,32 +629,13 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
// Rage from Damage made (only from direct weapon damage)
if (cleanDamage && damagetype == DIRECT_DAMAGE && this != victim && getPowerType() == POWER_RAGE)
{
- uint32 weaponSpeedHitFactor;
- uint32 rage_damage = damage + cleanDamage->absorbed_damage;
-
+ uint32 rage = uint32(GetAttackTime(cleanDamage->attackType) / 1000 * 8.125f);
switch (cleanDamage->attackType)
{
- case BASE_ATTACK:
- {
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType) / 1000.0f * 3.5f);
- if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor *= 2;
-
- RewardRage(rage_damage, weaponSpeedHitFactor, true);
-
- break;
- }
case OFF_ATTACK:
- {
- weaponSpeedHitFactor = uint32(GetAttackTime(cleanDamage->attackType) / 1000.0f * 1.75f);
- if (cleanDamage->hitOutCome == MELEE_HIT_CRIT)
- weaponSpeedHitFactor *= 2;
-
- RewardRage(rage_damage, weaponSpeedHitFactor, true);
-
- break;
- }
- case RANGED_ATTACK:
+ rage /= 2;
+ case BASE_ATTACK:
+ RewardRage(rage, true);
break;
default:
break;
@@ -666,7 +646,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
{
// Rage from absorbed damage
if (cleanDamage && cleanDamage->absorbed_damage && victim->getPowerType() == POWER_RAGE)
- victim->RewardRage(cleanDamage->absorbed_damage, 0, false);
+ victim->RewardRage(cleanDamage->absorbed_damage, false);
return 0;
}
@@ -711,7 +691,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (Battleground* bg = killer->GetBattleground())
bg->UpdatePlayerScore(killer, SCORE_DAMAGE_DONE, damage);
- killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, victim);
+ killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE, damage, 0, 0, victim);
killer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT, damage);
}
@@ -767,7 +747,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
if (this != victim && victim->getPowerType() == POWER_RAGE)
{
uint32 rage_damage = damage + (cleanDamage ? cleanDamage->absorbed_damage : 0);
- victim->RewardRage(rage_damage, 0, false);
+ victim->RewardRage(rage_damage, false);
}
if (GetTypeId() == TYPEID_PLAYER)
@@ -983,7 +963,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
return;
SpellSchoolMask damageSchoolMask = SpellSchoolMask(damageInfo->schoolMask);
- uint32 crTypeMask = victim->GetCreatureTypeMask();
if (IsDamageReducedByArmor(damageSchoolMask, spellInfo))
damage = CalcArmorReducedDamage(victim, damage, spellInfo, attackType);
@@ -1024,9 +1003,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
critPctDamageMod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellInfo->GetSchoolMask()) - 1.0f) * 100;
- // Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
- critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
-
if (critPctDamageMod != 0)
AddPct(damage, critPctDamageMod);
}
@@ -1034,19 +1010,15 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
// Spell weapon based damage CAN BE crit & blocked at same time
if (blocked)
{
- damageInfo->blocked = victim->GetShieldBlockValue();
// double blocked amount if block is critical
+ uint32 value = victim->GetBlockPercent();
if (victim->isBlockCritical())
- damageInfo->blocked += damageInfo->blocked;
- if (damage < int32(damageInfo->blocked))
- damageInfo->blocked = uint32(damage);
+ value *= 2; // double blocked percent
+ damageInfo->blocked = CalculatePct(damage, value);
damage -= damageInfo->blocked;
}
- if (attackType != RANGED_ATTACK)
- ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_MELEE);
- else
- ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_RANGED);
+ ApplyResilience(victim, &damage);
break;
}
// Magical Attacks
@@ -1060,7 +1032,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
damage = SpellCriticalDamageBonus(spellInfo, damage, victim);
}
- ApplyResilience(victim, NULL, &damage, crit, CR_CRIT_TAKEN_SPELL);
+ ApplyResilience(victim, &damage);
break;
}
default:
@@ -1218,10 +1190,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
// Increase crit damage from SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, damageInfo->damageSchoolMask) - 1.0f) * 100;
- uint32 crTypeMask = damageInfo->target->GetCreatureTypeMask();
-
- // Increase crit damage from SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
- mod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask);
if (mod != 0)
AddPct(damageInfo->damage, mod);
break;
@@ -1241,19 +1209,9 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
case MELEE_HIT_BLOCK:
damageInfo->TargetState = VICTIMSTATE_HIT;
damageInfo->HitInfo |= HITINFO_BLOCK;
- damageInfo->procEx |= PROC_EX_BLOCK;
- damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();
- // double blocked amount if block is critical
- if (damageInfo->target->isBlockCritical())
- damageInfo->blocked_amount+=damageInfo->blocked_amount;
- if (damageInfo->blocked_amount >= damageInfo->damage)
- {
- damageInfo->TargetState = VICTIMSTATE_BLOCKS;
- damageInfo->blocked_amount = damageInfo->damage;
- damageInfo->procEx |= PROC_EX_FULL_BLOCK;
- }
- else
- damageInfo->procEx |= PROC_EX_NORMAL_HIT;
+ damageInfo->procEx |= PROC_EX_BLOCK | PROC_EX_NORMAL_HIT;
+ // 30% damage blocked, double blocked amount if block is critical
+ damageInfo->blocked_amount = CalculatePct(damageInfo->damage, damageInfo->target->isBlockCritical() ? damageInfo->target->GetBlockPercent() * 2 : damageInfo->target->GetBlockPercent());
damageInfo->damage -= damageInfo->blocked_amount;
damageInfo->cleanDamage += damageInfo->blocked_amount;
break;
@@ -1286,10 +1244,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam
damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM;
int32 resilienceReduction = damageInfo->damage;
- if (attackType != RANGED_ATTACK)
- ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE);
- else
- ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_RANGED);
+ ApplyResilience(victim, &resilienceReduction);
resilienceReduction = damageInfo->damage - resilienceReduction;
damageInfo->damage -= resilienceReduction;
damageInfo->cleanDamage += resilienceReduction;
@@ -1378,8 +1333,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
if (victim->getLevel() < 30)
Probability = 0.65f * victim->getLevel() + 0.5f;
- uint32 VictimDefense=victim->GetDefenseSkillValue();
- uint32 AttackerMeleeSkill=GetUnitMeleeSkill();
+ uint32 VictimDefense = victim->GetMaxSkillValueForLevel(this);
+ uint32 AttackerMeleeSkill = GetMaxSkillValueForLevel();
Probability *= AttackerMeleeSkill/(float)VictimDefense*0.16;
@@ -1439,6 +1394,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
int32 overkill = int32(damage) - int32(GetHealth());
data << uint32(overkill > 0 ? overkill : 0); // Overkill
data << uint32(i_spellProto->SchoolMask);
+ data << uint32(0); // FIX ME: Send resisted damage, both fully resisted and partly resisted
victim->SendMessageToSet(&data, true);
victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
@@ -1481,6 +1437,14 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
{
float armor = float(victim->GetArmor());
+ // bypass enemy armor by SPELL_AURA_BYPASS_ARMOR_FOR_CASTER
+ int32 armorBypassPct = 0;
+ AuraEffectList const & reductionAuras = victim->GetAuraEffectsByType(SPELL_AURA_BYPASS_ARMOR_FOR_CASTER);
+ for (AuraEffectList::const_iterator i = reductionAuras.begin(); i != reductionAuras.end(); ++i)
+ if ((*i)->GetCasterGUID() == GetGUID())
+ armorBypassPct += (*i)->GetAmount();
+ armor = CalculatePct(armor, 100 - std::min(armorBypassPct, 100));
+
// Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura
armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL);
@@ -1488,14 +1452,6 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
- AuraEffectList const& resIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
- for (AuraEffectList::const_iterator j = resIgnoreAurasAb.begin(); j != resIgnoreAurasAb.end(); ++j)
- {
- if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL
- && (*j)->IsAffectedOnSpell(spellInfo))
- armor = floor(AddPct(armor, -(*j)->GetAmount()));
- }
-
AuraEffectList const& resIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator j = resIgnoreAuras.begin(); j != resIgnoreAuras.end(); ++j)
{
@@ -1503,27 +1459,9 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
armor = floor(AddPct(armor, -(*j)->GetAmount()));
}
- // Apply Player CR_ARMOR_PENETRATION rating and buffs from stances\specializations etc.
+ // Apply Player CR_ARMOR_PENETRATION rating
if (GetTypeId() == TYPEID_PLAYER)
{
- float bonusPct = 0;
- AuraEffectList const& armorPenAuras = GetAuraEffectsByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
- for (AuraEffectList::const_iterator itr = armorPenAuras.begin(); itr != armorPenAuras.end(); ++itr)
- {
- if ((*itr)->GetSpellInfo()->EquippedItemClass == -1)
- {
- if (!spellInfo || (*itr)->IsAffectedOnSpell(spellInfo) || (*itr)->GetMiscValue() & spellInfo->GetSchoolMask())
- bonusPct += (*itr)->GetAmount();
- else if (!(*itr)->GetMiscValue() && !(*itr)->HasSpellClassMask())
- bonusPct += (*itr)->GetAmount();
- }
- else
- {
- if (ToPlayer()->HasItemFitToSpellRequirements((*itr)->GetSpellInfo()))
- bonusPct += (*itr)->GetAmount();
- }
- }
-
float maxArmorPen = 0;
if (victim->getLevel() < 60)
maxArmorPen = float(400 + 85 * victim->getLevel());
@@ -1533,7 +1471,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo
// Cap armor penetration to this number
maxArmorPen = std::min((armor + maxArmorPen) / 3, armor);
// Figure out how much armor do we ignore
- float armorPen = CalculatePct(maxArmorPen, bonusPct + ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION));
+ float armorPen = CalculatePct(maxArmorPen, ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION));
// Got the value, apply it
armor -= std::min(armorPen, maxArmorPen);
}
@@ -1566,13 +1504,13 @@ uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, Spell
if (spellInfo && spellInfo->AttributesEx4 & SPELL_ATTR4_IGNORE_RESISTANCES)
return 0;
- uint32 const BOSS_LEVEL = 83;
- uint32 const BOSS_RESISTANCE_CONSTANT = 510;
+ uint8 const bossLevel = 83;
+ uint32 const bossResistanceConstant = 510;
uint32 resistanceConstant = 0;
uint8 level = victim->getLevel();
- if (level == BOSS_LEVEL)
- resistanceConstant = BOSS_RESISTANCE_CONSTANT;
+ if (level == bossLevel)
+ resistanceConstant = bossResistanceConstant;
else
resistanceConstant = level * 5;
@@ -1589,11 +1527,6 @@ uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, Spell
{
int32 ignoredResistance = 0;
- AuraEffectList const& ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
- for (AuraEffectList::const_iterator itr = ResIgnoreAurasAb.begin(); itr != ResIgnoreAurasAb.end(); ++itr)
- if (((*itr)->GetMiscValue() & schoolMask) && (*itr)->IsAffectedOnSpell(spellInfo))
- ignoredResistance += (*itr)->GetAmount();
-
AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator itr = ResIgnoreAuras.begin(); itr != ResIgnoreAuras.end(); ++itr)
if ((*itr)->GetMiscValue() & schoolMask)
@@ -1661,7 +1594,7 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
if (!((*itr)->GetMiscValue() & schoolMask))
continue;
- if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(spellInfo))
+ if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectingSpell(spellInfo))
auraAbsorbMod = float((*itr)->GetAmount());
}
@@ -1785,40 +1718,6 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
{
// We're going to call functions which can modify content of the list during iteration over it's elements
// Let's copy the list so we can prevent iterator invalidation
- AuraEffectList vSplitDamageFlatCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT));
- for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
- {
- // Check if aura was removed during iteration - we don't need to work on such auras
- if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID())))
- continue;
- // check damage school mask
- if (!((*itr)->GetMiscValue() & schoolMask))
- continue;
-
- // Damage can be splitted only if aura has an alive caster
- Unit* caster = (*itr)->GetCaster();
- if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive())
- continue;
-
- int32 splitDamage = (*itr)->GetAmount();
-
- // absorb must be smaller than the damage itself
- splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
-
- dmgInfo.AbsorbDamage(splitDamage);
-
- uint32 splitted = splitDamage;
- uint32 splitted_absorb = 0;
- DealDamageMods(caster, splitted, &splitted_absorb);
-
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
-
- CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
- }
-
- // We're going to call functions which can modify content of the list during iteration over it's elements
- // Let's copy the list so we can prevent iterator invalidation
AuraEffectList vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr)
{
@@ -1981,7 +1880,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackTy
// Miss chance based on melee
//float miss_chance = MeleeMissChanceCalc(victim, attType);
- float miss_chance = MeleeSpellMissChance(victim, attType, int32(GetWeaponSkillValue(attType, victim)) - int32(GetMaxSkillValueForLevel(this)), 0);
+ float miss_chance = MeleeSpellMissChance(victim, attType, 0);
// Critical hit chance
float crit_chance = GetUnitCriticalChance(attType, victim);
@@ -2005,11 +1904,8 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
int32 victimMaxSkillValueForLevel = victim->GetMaxSkillValueForLevel(this);
- int32 attackerWeaponSkill = GetWeaponSkillValue(attType, victim);
- int32 victimDefenseSkill = victim->GetDefenseSkillValue(this);
-
// bonus from skills is 0.04%
- int32 skillBonus = 4 * (attackerWeaponSkill - victimMaxSkillValueForLevel);
+ int32 skillBonus = 4 * (attackerMaxSkillValueForLevel - victimMaxSkillValueForLevel);
int32 sum = 0, tmp = 0;
int32 roll = urand (0, 10000);
@@ -2118,11 +2014,9 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
getLevel() < victim->getLevelForTarget(this))
{
// cap possible value (with bonuses > max skill)
- int32 skill = attackerWeaponSkill;
- int32 maxskill = attackerMaxSkillValueForLevel;
- skill = (skill > maxskill) ? maxskill : skill;
+ int32 skill = attackerMaxSkillValueForLevel;
- tmp = (10 + (victimDefenseSkill - skill)) * 100;
+ tmp = (10 + (victimMaxSkillValueForLevel - skill)) * 100;
tmp = tmp > 4000 ? 4000 : tmp;
if (roll < (sum += tmp))
{
@@ -2138,10 +2032,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
!(GetTypeId() == TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH))
{
// when their weapon skill is 15 or more above victim's defense skill
- tmp = victimDefenseSkill;
- int32 tmpmax = victimMaxSkillValueForLevel;
- // having defense above your maximum (from items, talents etc.) has no effect
- tmp = tmp > tmpmax ? tmpmax : tmp;
+ tmp = victimMaxSkillValueForLevel;
// tmp = mob's level * 5 - player's current defense skill
tmp = attackerMaxSkillValueForLevel - tmp;
if (tmp >= 15)
@@ -2237,7 +2128,7 @@ void Unit::SendMeleeAttackStop(Unit* victim)
TC_LOG_INFO("entities.unit", "%s %u stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow());
}
-bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType)
+bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType /*attackType*/)
{
// These spells can't be blocked
if (spellProto && spellProto->Attributes & SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)
@@ -2250,9 +2141,7 @@ bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttac
victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK)
return false;
- float blockChance = victim->GetUnitBlockChance();
- blockChance += (int32(GetWeaponSkillValue(attackType)) - int32(victim->GetMaxSkillValueForLevel())) * 0.04f;
- if (roll_chance_f(blockChance))
+ if (roll_chance_f(victim->GetUnitBlockChance()))
return true;
}
return false;
@@ -2317,19 +2206,10 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED)
attType = RANGED_ATTACK;
- int32 attackerWeaponSkill;
- // skill value for these spells (for example judgements) is 5* level
- if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_RANGED && !spellInfo->IsRangedWeaponSpell())
- attackerWeaponSkill = getLevel() * 5;
- // bonus from skills is 0.04% per skill Diff
- else
- attackerWeaponSkill = int32(GetWeaponSkillValue(attType, victim));
-
- int32 skillDiff = attackerWeaponSkill - int32(victim->GetMaxSkillValueForLevel(this));
+ uint32 roll = urand(0, 10000);
- uint32 roll = urand (0, 10000);
+ uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, spellInfo->Id) * 100.0f);
- uint32 missChance = uint32(MeleeSpellMissChance(victim, attType, skillDiff, spellInfo->Id) * 100.0f);
// Roll miss
uint32 tmp = missChance;
if (roll < tmp)
@@ -2416,7 +2296,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
AuraEffectList const& ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
{
- if (!(*i)->IsAffectedOnSpell(spellInfo))
+ if (!(*i)->IsAffectingSpell(spellInfo))
continue;
switch ((*i)->GetMiscValue())
{
@@ -2438,7 +2318,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canDodge)
{
// Roll dodge
- int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f) - skillDiff * 4;
+ int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f);
// Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
dodgeChance += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE) * 100;
dodgeChance = int32(float(dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
@@ -2457,7 +2337,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canParry)
{
// Roll parry
- int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f) - skillDiff * 4;
+ int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f);
// Reduce parry chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
parryChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
@@ -2473,7 +2353,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canBlock)
{
- int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f) - skillDiff * 4;
+ int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f);
if (blockChance < 0)
blockChance = 0;
tmp += blockChance;
@@ -2511,18 +2391,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance);
- // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras
- modHitChance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT, schoolMask);
-
- // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
- modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask);
- // Reduce spell hit chance for Area of effect spells from victim SPELL_AURA_MOD_AOE_AVOIDANCE aura
- if (spellInfo->IsTargetingArea())
- modHitChance -= victim->GetTotalAuraModifier(SPELL_AURA_MOD_AOE_AVOIDANCE);
-
- // Decrease hit chance from victim rating bonus
- if (victim->GetTypeId() == TYPEID_PLAYER)
- modHitChance -= int32(victim->ToPlayer()->GetRatingBonusValue(CR_HIT_TAKEN_SPELL));
+ // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects
+ if (!(spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_HIT_RESULT))
+ {
+ // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras
+ modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask);
+ }
int32 HitChance = modHitChance * 100;
// Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings
@@ -2541,26 +2415,6 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
int32 resist_chance = victim->GetMechanicResistChance(spellInfo) * 100;
tmp += resist_chance;
- // Chance resist debuff
- if (!spellInfo->IsPositive())
- {
- bool hasAura = false;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if (spellInfo->Effects[i].IsAura())
- {
- hasAura = true;
- break;
- }
- }
-
- if (hasAura)
- {
- tmp += victim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100;
- tmp += victim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spellInfo->Dispel)) * 100;
- }
- }
-
// Roll chance
if (rand < tmp)
return SPELL_MISS_RESIST;
@@ -2636,41 +2490,11 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, boo
return SPELL_MISS_NONE;
}
-uint32 Unit::GetShieldBlockValue(uint32 soft_cap, uint32 hard_cap) const
-{
- uint32 value = GetShieldBlockValue();
- if (value >= hard_cap)
- {
- value = (soft_cap + hard_cap) / 2;
- }
- else if (value > soft_cap)
- {
- value = soft_cap + ((value - soft_cap) / 2);
- }
-
- return value;
-}
-
uint32 Unit::GetUnitMeleeSkill(Unit const* target) const
{
return (target ? getLevelForTarget(target) : getLevel()) * 5;
}
-uint32 Unit::GetDefenseSkillValue(Unit const* target) const
-{
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // in PvP use full skill instead current skill value
- uint32 value = (target && target->GetTypeId() == TYPEID_PLAYER)
- ? ToPlayer()->GetMaxSkillValue(SKILL_DEFENSE)
- : ToPlayer()->GetSkillValue(SKILL_DEFENSE);
- value += uint32(ToPlayer()->GetRatingBonusValue(CR_DEFENSE_SKILL));
- return value;
- }
- else
- return GetUnitMeleeSkill(target);
-}
-
float Unit::GetUnitDodgeChance() const
{
if (IsNonMeleeSpellCast(false) || HasUnitState(UNIT_STATE_CONTROLLED))
@@ -2726,9 +2550,6 @@ float Unit::GetUnitMissChance(WeaponAttackType attType) const
{
float miss_chance = 5.00f;
- if (Player const* player = ToPlayer())
- miss_chance += player->GetMissPercentageFromDefence();
-
if (attType == RANGED_ATTACK)
miss_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE);
else
@@ -2747,7 +2568,7 @@ float Unit::GetUnitBlockChance() const
if (player->CanBlock())
{
Item* tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
- if (tmpitem && !tmpitem->IsBroken() && tmpitem->GetTemplate()->Block)
+ if (tmpitem && !tmpitem->IsBroken())
return GetFloatValue(PLAYER_BLOCK_PERCENTAGE);
}
// is player but has no block ability or no not broken shield equipped
@@ -2804,65 +2625,11 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victi
crit += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
- // reduce crit chance from Rating for players
- if (attackType != RANGED_ATTACK)
- {
- ApplyResilience(victim, &crit, NULL, false, CR_CRIT_TAKEN_MELEE);
- // Glyph of barkskin
- if (victim->HasAura(63057) && victim->HasAura(22812))
- crit -= 25.0f;
- }
- else
- ApplyResilience(victim, &crit, NULL, false, CR_CRIT_TAKEN_RANGED);
-
- // Apply crit chance from defence skill
- crit += (int32(GetMaxSkillValueForLevel(victim)) - int32(victim->GetDefenseSkillValue(this))) * 0.04f;
-
if (crit < 0.0f)
crit = 0.0f;
return crit;
}
-uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target) const
-{
- uint32 value = 0;
- if (Player const* player = ToPlayer())
- {
- Item* item = player->GetWeaponForAttack(attType, true);
-
- // feral or unarmed skill only for base attack
- if (attType != BASE_ATTACK && !item)
- return 0;
-
- if (IsInFeralForm())
- return GetMaxSkillValueForLevel(); // always maximized SKILL_FERAL_COMBAT in fact
-
- // weapon skill or (unarmed for base attack and fist weapons)
- uint32 skill;
- if (item && item->GetSkill() != SKILL_FIST_WEAPONS)
- skill = item->GetSkill();
- else
- skill = SKILL_UNARMED;
-
- // in PvP use full skill instead current skill value
- value = (target && target->IsControlledByPlayer())
- ? player->GetMaxSkillValue(skill)
- : player->GetSkillValue(skill);
- // Modify value from ratings
- value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL));
- switch (attType)
- {
- case BASE_ATTACK: value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_MAINHAND)); break;
- case OFF_ATTACK: value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_OFFHAND)); break;
- case RANGED_ATTACK: value += uint32(player->GetRatingBonusValue(CR_WEAPON_SKILL_RANGED)); break;
- default: break;
- }
- }
- else
- value = GetUnitMeleeSkill(target);
- return value;
-}
-
void Unit::_DeleteRemovedAuras()
{
while (!m_removedAuras.empty())
@@ -2931,7 +2698,9 @@ void Unit::_UpdateSpells(uint32 time)
void Unit::_UpdateAutoRepeatSpell()
{
// check "realtime" interrupts
- if ((GetTypeId() == TYPEID_PLAYER && ToPlayer()->isMoving()) || IsNonMeleeSpellCast(false, false, true, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == 75))
+ // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
+ if (((GetTypeId() == TYPEID_PLAYER && ToPlayer()->isMoving()) || IsNonMeleeSpellCast(false, false, true, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id == 75)) &&
+ !HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo))
{
// cancel wand shoot
if (m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
@@ -3910,7 +3679,8 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
{
Aura* aura = (*iter)->GetBase();
++iter;
- if ((aura->GetSpellInfo()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except))
+ if ((aura->GetSpellInfo()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except)
+ && !(flag & AURA_INTERRUPT_FLAG_MOVE && HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, aura->GetSpellInfo())))
{
uint32 removedAuras = m_removedAurasCount;
RemoveAura(aura);
@@ -3923,7 +3693,8 @@ void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING
&& (spell->m_spellInfo->ChannelInterruptFlags & flag)
- && spell->m_spellInfo->Id != except)
+ && spell->m_spellInfo->Id != except
+ && !(flag & AURA_INTERRUPT_FLAG_MOVE && HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, spell->GetSpellInfo())))
InterruptNonMeleeSpells(false);
UpdateInterruptMask();
@@ -4360,7 +4131,7 @@ bool Unit::HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affecte
{
AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- if ((*i)->IsAffectedOnSpell(affectedSpell))
+ if ((*i)->IsAffectingSpell(affectedSpell))
return true;
return false;
}
@@ -4420,7 +4191,7 @@ AuraEffect* Unit::IsScriptOverriden(SpellInfo const* spell, int32 script) const
for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
{
if ((*i)->GetMiscValue() == script)
- if ((*i)->IsAffectedOnSpell(spell))
+ if ((*i)->IsAffectingSpell(spell))
return (*i);
}
return NULL;
@@ -4678,7 +4449,7 @@ int32 Unit::GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const*
AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
{
- if ((*i)->IsAffectedOnSpell(affectedSpell))
+ if ((*i)->IsAffectingSpell(affectedSpell))
if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
modifier += (*i)->GetAmount();
}
@@ -4697,7 +4468,7 @@ float Unit::GetTotalAuraMultiplierByAffectMask(AuraType auratype, SpellInfo cons
AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
{
- if ((*i)->IsAffectedOnSpell(affectedSpell))
+ if ((*i)->IsAffectingSpell(affectedSpell))
if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
AddPct(multiplier, (*i)->GetAmount());
}
@@ -4715,7 +4486,7 @@ int32 Unit::GetMaxPositiveAuraModifierByAffectMask(AuraType auratype, SpellInfo
AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
{
- if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() > modifier)
+ if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() > modifier)
modifier = (*i)->GetAmount();
}
@@ -4729,7 +4500,7 @@ int32 Unit::GetMaxNegativeAuraModifierByAffectMask(AuraType auratype, SpellInfo
AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
{
- if ((*i)->IsAffectedOnSpell(affectedSpell) && (*i)->GetAmount() < modifier)
+ if ((*i)->IsAffectingSpell(affectedSpell) && (*i)->GetAmount() < modifier)
modifier = (*i)->GetAmount();
}
@@ -5106,8 +4877,11 @@ void Unit::SendAttackStateUpdate(CalcDamageInfo* damageInfo)
data << float(0);
data << float(0);
data << float(0);
- data << float(0); // Found in a loop with 1 iteration
- data << float(0); // ditto ^
+ for (uint8 i = 0; i < 2; ++i)
+ {
+ data << float(0);
+ data << float(0);
+ }
data << uint32(0);
}
@@ -5129,6 +4903,133 @@ 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() && 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)
{
@@ -5401,18 +5302,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
victim->RemoveAurasWithMechanic(1<<MECHANIC_STUN, AURA_REMOVE_BY_ENEMY_SPELL);
return true;
}
- // Glyph of Scourge Strike
- case 58642:
- {
- triggered_spell_id = 69961; // Glyph of Scourge Strike
- break;
- }
- // Glyph of Life Tap
- case 63320:
- {
- triggered_spell_id = 63321; // Life Tap
- break;
- }
// Purified Shard of the Scale - Onyxia 10 Caster Trinket
case 69755:
{
@@ -5529,41 +5418,25 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
instance->DoCastSpellOnPlayers(65037); // Achievement criteria marker
break;
}
+ case 47020: // Enter vehicle XT-002 (Scrapbot)
+ {
+ if (GetTypeId() != TYPEID_UNIT)
+ return false;
+
+ Unit* vehicleBase = GetVehicleBase();
+ if (!vehicleBase)
+ return false;
+
+ // Todo: Check if this amount is blizzlike
+ vehicleBase->ModifyHealth(int32(vehicleBase->CountPctFromMaxHealth(1)));
+ break;
+ }
}
break;
}
case SPELLFAMILY_MAGE:
{
- // Magic Absorption
- if (dummySpell->SpellIconID == 459) // only this spell has SpellIconID == 459 and dummy aura
- {
- if (getPowerType() != POWER_MANA)
- return false;
-
- // mana reward
- basepoints0 = CalculatePct(int32(GetMaxPower(POWER_MANA)), triggerAmount);
- target = this;
- triggered_spell_id = 29442;
- break;
- }
- // Arcane Potency
- if (dummySpell->SpellIconID == 2120)
- {
- if (!procSpell)
- return false;
-
- target = this;
- switch (dummySpell->Id)
- {
- case 31571: triggered_spell_id = 57529; break;
- case 31572: triggered_spell_id = 57531; break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: %u", dummySpell->Id);
- return false;
- }
- break;
- }
- // Hot Streak
+ // Hot Streak & Improved Hot Streak
if (dummySpell->SpellIconID == 2999)
{
if (effIndex != 0)
@@ -5576,7 +5449,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (procEx & PROC_EX_CRITICAL_HIT)
{
counter->SetAmount(counter->GetAmount() * 2);
- if (counter->GetAmount() < 100) // not enough
+ if (counter->GetAmount() < 100 && dummySpell->Id != 44445) // not enough or Hot Streak spell
return true;
// Crititcal counted -> roll chance
if (roll_chance_i(triggerAmount))
@@ -5595,109 +5468,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 37436;
break;
}
- switch (dummySpell->Id)
- {
- // Glyph of Polymorph
- case 56375:
- {
- if (!target)
- return false;
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(32409)); // SW:D shall not be removed.
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
- return true;
- }
- // Glyph of Icy Veins
- case 56374:
- {
- RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, 0, 0, true, false);
- RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
- return true;
- }
- // Glyph of Ice Block
- case 56372:
- {
- Player* player = ToPlayer();
- if (!player)
- return false;
-
- SpellCooldowns const cooldowns = player->GetSpellCooldowns();
- // remove cooldowns on all ranks of Frost Nova
- for (SpellCooldowns::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr)
- {
- SpellInfo const* cdSpell = sSpellMgr->GetSpellInfo(itr->first);
- // Frost Nova
- if (cdSpell && cdSpell->SpellFamilyName == SPELLFAMILY_MAGE
- && cdSpell->SpellFamilyFlags[0] & 0x00000040)
- player->RemoveSpellCooldown(cdSpell->Id, true);
- }
- break;
- }
- case 47020: // Enter vehicle XT-002 (Scrapbot)
- {
- if (GetTypeId() != TYPEID_UNIT)
- return false;
-
- Unit* vehicleBase = GetVehicleBase();
- if (!vehicleBase)
- return false;
-
- /// @todo Check if this amount is blizzlike
- vehicleBase->ModifyHealth(int32(vehicleBase->CountPctFromMaxHealth(1)));
- break;
- }
- }
- break;
- }
- case SPELLFAMILY_WARRIOR:
- {
- switch (dummySpell->Id)
- {
- // Victorious
- case 32216:
- {
- RemoveAura(dummySpell->Id);
- return false;
- }
- // Improved Spell Reflection
- case 59088:
- case 59089:
- {
- triggered_spell_id = 59725;
- target = this;
- break;
- }
- }
- // Second Wind
- if (dummySpell->SpellIconID == 1697)
- {
- // only for spells and hit/crit (trigger start always) and not start from self cast spells (5530 Mace Stun Effect for example)
- if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == victim)
- return false;
- // Need stun or root mechanic
- if (!(procSpell->GetAllEffectsMechanicMask() & ((1<<MECHANIC_ROOT)|(1<<MECHANIC_STUN))))
- return false;
-
- switch (dummySpell->Id)
- {
- case 29838: triggered_spell_id=29842; break;
- case 29834: triggered_spell_id=29841; break;
- case 42770: triggered_spell_id=42771; break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: %u (SW)", dummySpell->Id);
- return false;
- }
-
- target = this;
- break;
- }
- // Glyph of Blocking
- if (dummySpell->Id == 58375)
- {
- triggered_spell_id = 58374;
- break;
- }
- break;
}
case SPELLFAMILY_WARLOCK:
{
@@ -5750,54 +5520,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
switch (dummySpell->Id)
{
- // Nightfall
- case 18094:
- case 18095:
- // Glyph of corruption
- case 56218:
- {
- target = this;
- triggered_spell_id = 17941;
- break;
- }
- // Soul Leech
- case 30293:
- case 30295:
- case 30296:
- {
- // Improved Soul Leech
- AuraEffectList const& SoulLeechAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
- for (Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin(); i != SoulLeechAuras.end(); ++i)
- {
- if ((*i)->GetId() == 54117 || (*i)->GetId() == 54118)
- {
- if ((*i)->GetEffIndex() != 0)
- continue;
- basepoints0 = int32((*i)->GetAmount());
- target = GetGuardianPet();
- if (target)
- {
- // regen mana for pet
- CastCustomSpell(target, 54607, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- }
- // regen mana for caster
- CastCustomSpell(this, 59117, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- // Get second aura of spell for replenishment effect on party
- if (AuraEffect const* aurEff = (*i)->GetBase()->GetEffect(EFFECT_1))
- {
- // Replenishment - roll chance
- if (roll_chance_i(aurEff->GetAmount()))
- CastSpell(this, 57669, true, castItem, triggeredByAura);
- }
- break;
- }
- }
- // health
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- target = this;
- triggered_spell_id = 30294;
- break;
- }
// Shadowflame (Voidheart Raiment set bonus)
case 37377:
{
@@ -5822,63 +5544,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 37378;
break;
}
- // Glyph of Succubus
- case 56250:
- {
- if (!target)
- return false;
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(32409)); // SW:D shall not be removed.
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
- target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
- return true;
- }
}
break;
}
case SPELLFAMILY_PRIEST:
{
- // Vampiric Touch
- if (dummySpell->SpellFamilyFlags[1] & 0x00000400)
- {
- if (!victim || !victim->IsAlive())
- return false;
-
- if (effIndex != 0)
- return false;
-
- // victim is caster of aura
- if (triggeredByAura->GetCasterGUID() != victim->GetGUID())
- return false;
-
- // Energize 0.25% of max. mana
- victim->CastSpell(victim, 57669, true, castItem, triggeredByAura);
- return true; // no hidden cooldown
- }
- // Body and Soul
- if (dummySpell->SpellIconID == 2218)
- {
- // Proc only from Abolish desease on self cast
- if (procSpell->Id != 552 || victim != this || !roll_chance_i(triggerAmount))
- return false;
- triggered_spell_id = 64136;
- target = this;
- break;
- }
switch (dummySpell->Id)
{
- // Vampiric Embrace
- case 15286:
- {
- if (!victim || !victim->IsAlive() || procSpell->SpellFamilyFlags[1] & 0x80000)
- return false;
-
- // heal amount
- int32 total = CalculatePct(int32(damage), triggerAmount);
- int32 team = total / 5;
- int32 self = total - team;
- CastCustomSpell(this, 15290, &team, &self, NULL, true, castItem, triggeredByAura);
- return true; // no hidden cooldown
- }
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
case 40438:
{
@@ -5894,29 +5566,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = this;
break;
}
- // Improved Shadowform
- case 47570:
- case 47569:
- {
- if (!roll_chance_i(triggerAmount))
- return false;
-
- RemoveMovementImpairingAuras();
- break;
- }
- // Glyph of Dispel Magic
- case 55677:
- {
- // Dispel Magic shares spellfamilyflag with abolish disease
- if (procSpell->SpellIconID != 74)
- return false;
- if (!target || !target->IsFriendlyTo(this))
- return false;
-
- basepoints0 = int32(target->CountPctFromMaxHealth(triggerAmount));
- triggered_spell_id = 56131;
- break;
- }
// Oracle Healing Bonus ("Garments of the Oracle" set)
case 26169:
{
@@ -5963,25 +5612,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
{
switch (dummySpell->Id)
{
- // Glyph of Innervate
- case 54832:
- {
- if (procSpell->SpellIconID != 62)
- return false;
-
- int32 mana_perc = triggeredByAura->GetSpellInfo()->Effects[triggeredByAura->GetEffIndex()].CalcValue();
- basepoints0 = int32(CalculatePct(GetCreatePowers(POWER_MANA), mana_perc) / 10);
- triggered_spell_id = 54833;
- target = this;
- break;
- }
- // Glyph of Starfire
- case 54845:
- {
- triggered_spell_id = 54846;
- break;
- }
- // Glyph of Shred
+ // Glyph of Bloodletting
case 54815:
{
if (!target)
@@ -5990,15 +5621,14 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// try to find spell Rip on the target
if (AuraEffect const* AurEff = target->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00800000, 0x0, 0x0, GetGUID()))
{
- // Rip's max duration, note: spells which modifies Rip's duration also counted like Glyph of Rip
+ // Rip's max duration, note: spells which modifies Rip's duration also counted
uint32 CountMin = AurEff->GetBase()->GetMaxDuration();
// just Rip's max duration without other spells
uint32 CountMax = AurEff->GetSpellInfo()->GetMaxDuration();
// add possible auras' and Glyph of Shred's max duration
- CountMax += 3 * triggerAmount * IN_MILLISECONDS; // Glyph of Shred -> +6 seconds
- CountMax += HasAura(54818) ? 4 * IN_MILLISECONDS : 0; // Glyph of Rip -> +4 seconds
+ CountMax += 3 * triggerAmount * IN_MILLISECONDS; // Glyph of Bloodletting -> +6 seconds
CountMax += HasAura(60141) ? 4 * IN_MILLISECONDS : 0; // Rip Duration/Lacerate Damage -> +4 seconds
// if min < max -> that means caster didn't cast 3 shred yet
@@ -6013,19 +5643,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// if not found Rip
return false;
}
- // Glyph of Rake
- case 54821:
- {
- if (procSpell->SpellVisual[0] == 750 && procSpell->Effects[1].ApplyAuraName == 3)
- {
- if (target && target->GetTypeId() == TYPEID_UNIT)
- {
- triggered_spell_id = 54820;
- break;
- }
- }
- return false;
- }
// Leader of the Pack
case 24932:
{
@@ -6034,13 +5651,9 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
target = this;
triggered_spell_id = 34299;
- if (triggeredByAura->GetCasterGUID() != GetGUID())
- break;
- int32 basepoints1 = triggerAmount * 2;
- // Improved Leader of the Pack
- // Check cooldown of heal spell cooldown
- if (GetTypeId() == TYPEID_PLAYER && !ToPlayer()->HasSpellCooldown(34299))
- CastCustomSpell(this, 60889, &basepoints1, 0, 0, true, 0, triggeredByAura);
+ // Regenerate 4% mana
+ int32 mana = CalculatePct(GetCreateMana(), triggerAmount);
+ CastCustomSpell(this, 68285, &mana, NULL, NULL, true, castItem, triggeredByAura);
break;
}
// Healing Touch (Dreamwalker Raiment set)
@@ -6052,15 +5665,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 28742;
break;
}
- // Glyph of Rejuvenation
- case 54754:
- {
- if (!victim || !victim->HealthBelowPct(uint32(triggerAmount)))
- return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- triggered_spell_id = 54755;
- break;
- }
// Healing Touch Refund (Idol of Longevity trinket)
case 28847:
{
@@ -6108,13 +5712,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = this;
break;
}
- // Maim Interrupt
- case 44835:
- {
- // Deadly Interrupt Effect
- triggered_spell_id = 32747;
- break;
- }
// Item - Druid T10 Balance 4P Bonus
case 70723:
{
@@ -6148,245 +5745,15 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return true;
}
}
- // Eclipse
- if (dummySpell->SpellIconID == 2856 && GetTypeId() == TYPEID_PLAYER)
- {
- if (!procSpell || effIndex != 0)
- return false;
-
- bool isWrathSpell = (procSpell->SpellFamilyFlags[0] & 1);
-
- if (!roll_chance_f(dummySpell->ProcChance * (isWrathSpell ? 0.6f : 1.0f)))
- return false;
-
- target = this;
- if (target->HasAura(isWrathSpell ? 48517 : 48518))
- return false;
-
- triggered_spell_id = isWrathSpell ? 48518 : 48517;
- break;
- }
- break;
- }
- case SPELLFAMILY_ROGUE:
- {
- switch (dummySpell->Id)
- {
- case 56800: // Glyph of Backstab
- {
- triggered_spell_id = 63975;
- break;
- }
- case 32748: // Deadly Throw Interrupt
- {
- // Prevent cast Deadly Throw Interrupt on self from last effect (apply dummy) of Deadly Throw
- if (this == victim)
- return false;
-
- triggered_spell_id = 32747;
- break;
- }
- }
-
- switch (dummySpell->SpellIconID)
- {
- case 2116: // Quick Recovery
- {
- if (!procSpell)
- return false;
-
- // energy cost save
- basepoints0 = CalculatePct(int32(procSpell->ManaCost), triggerAmount);
- if (basepoints0 <= 0)
- return false;
-
- target = this;
- triggered_spell_id = 31663;
- break;
- }
- case 2909: // Cut to the Chase
- {
- // "refresh your Slice and Dice duration to its 5 combo point maximum"
- // lookup Slice and Dice
- if (AuraEffect const* aur = GetAuraEffect(SPELL_AURA_MOD_MELEE_HASTE, SPELLFAMILY_ROGUE, 0x40000, 0, 0))
- {
- aur->GetBase()->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
- return true;
- }
- return false;
- }
- case 2963: // Deadly Brew
- {
- triggered_spell_id = 3409;
- break;
- }
- }
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- switch (dummySpell->SpellIconID)
- {
- case 2236: // Thrill of the Hunt
- {
- if (!procSpell)
- return false;
-
- Spell* spell = ToPlayer()->m_spellModTakingSpell;
-
- // Disable charge drop because of Lock and Load
- ToPlayer()->SetSpellModTakingSpell(spell, false);
-
- // Explosive Shot
- if (procSpell->SpellFamilyFlags[2] & 0x200)
- {
- if (!victim)
- return false;
- if (AuraEffect const* pEff = victim->GetAuraEffect(SPELL_AURA_PERIODIC_DUMMY, SPELLFAMILY_HUNTER, 0x0, 0x80000000, 0x0, GetGUID()))
- basepoints0 = pEff->GetSpellInfo()->CalcPowerCost(this, SpellSchoolMask(pEff->GetSpellInfo()->SchoolMask)) * 4/10/3;
- }
- else
- basepoints0 = procSpell->CalcPowerCost(this, SpellSchoolMask(procSpell->SchoolMask)) * 4/10;
-
- ToPlayer()->SetSpellModTakingSpell(spell, true);
-
- if (basepoints0 <= 0)
- return false;
-
- target = this;
- triggered_spell_id = 34720;
- break;
- }
- case 3406: // Hunting Party
- {
- triggered_spell_id = 57669;
- target = this;
- break;
- }
- case 3560: // Rapid Recuperation
- {
- // This effect only from Rapid Killing (mana regen)
- if (!(procSpell->SpellFamilyFlags[1] & 0x01000000))
- return false;
-
- target = this;
-
- switch (dummySpell->Id)
- {
- case 53228: // Rank 1
- triggered_spell_id = 56654;
- break;
- case 53232: // Rank 2
- triggered_spell_id = 58882;
- break;
- }
- break;
- }
- case 3579: // Lock and Load
- {
- // Proc only from periodic (from trap activation proc another aura of this spell)
- if (!(procFlag & PROC_FLAG_DONE_PERIODIC) || !roll_chance_i(triggerAmount))
- return false;
- triggered_spell_id = 56453;
- target = this;
- break;
- }
- }
-
- switch (dummySpell->Id)
- {
- case 57870: // Glyph of Mend Pet
- {
- victim->CastSpell(victim, 57894, true, NULL, NULL, GetGUID());
- return true;
- }
- }
break;
}
case SPELLFAMILY_PALADIN:
{
- // Light's Beacon - Beacon of Light
- if (dummySpell->Id == 53651)
- {
- if (!victim)
- return false;
- triggered_spell_id = 0;
- Unit* beaconTarget = NULL;
- if (GetTypeId() != TYPEID_PLAYER)
- {
- beaconTarget = triggeredByAura->GetBase()->GetCaster();
- if (!beaconTarget || beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID())))
- return false;
- basepoints0 = int32(damage);
- triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
- }
- else
- { // Check Party/Raid Group
- if (Group* group = ToPlayer()->GetGroup())
- {
- for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- if (Player* member = itr->GetSource())
- {
- // check if it was heal by paladin which cast this beacon of light
- if (member->GetAura(53563, victim->GetGUID()))
- {
- // do not proc when target of beacon of light is healed
- if (member == this)
- return false;
-
- beaconTarget = member;
- basepoints0 = int32(damage);
- triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(635)) ? 53652 : 53654;
- break;
- }
- }
- }
- }
- }
-
- if (triggered_spell_id && beaconTarget)
- {
- victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true);
- return true;
- }
-
- return false;
- }
// Judgements of the Wise
if (dummySpell->SpellIconID == 3017)
{
target = this;
triggered_spell_id = 31930;
- // replenishment
- CastSpell(this, 57669, true, castItem, triggeredByAura);
- break;
- }
- // Sanctified Wrath
- if (dummySpell->SpellIconID == 3029)
- {
- triggered_spell_id = 57318;
- target = this;
- basepoints0 = triggerAmount;
- CastCustomSpell(target, triggered_spell_id, &basepoints0, &basepoints0, NULL, true, castItem, triggeredByAura);
- return true;
- }
- // Righteous Vengeance
- if (dummySpell->SpellIconID == 3025)
- {
- // 4 damage tick
- basepoints0 = triggerAmount * damage / 400;
- triggered_spell_id = 61840;
- // Add remaining ticks to damage done
- basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
- break;
- }
- // Sheath of Light
- if (dummySpell->SpellIconID == 3030)
- {
- // 4 healing tick
- basepoints0 = triggerAmount * damage / 400;
- triggered_spell_id = 54203;
break;
}
switch (dummySpell->Id)
@@ -6408,38 +5775,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = this;
break;
}
- // Heart of the Crusader
- case 20335: // rank 1
- triggered_spell_id = 21183;
- break;
- case 20336: // rank 2
- triggered_spell_id = 54498;
- break;
- case 20337: // rank 3
- triggered_spell_id = 54499;
- break;
- // Judgement of Light
- case 20185:
- {
- if (!victim)
- return false;
-
- // 2% of maximum health
- basepoints0 = int32(victim->CountPctFromMaxHealth(2));
- victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura);
- return true;
- }
- // Judgement of Wisdom
- case 20186:
- {
- if (victim && victim->IsAlive() && victim->getPowerType() == POWER_MANA)
- {
- // 2% of base mana
- basepoints0 = int32(CalculatePct(victim->GetCreateMana(), 2));
- victim->CastCustomSpell(victim, 20268, &basepoints0, NULL, NULL, true, 0, triggeredByAura);
- }
- return true;
- }
// Holy Power (Redemption Armor set)
case 28789:
{
@@ -6471,10 +5806,9 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
break;
}
- // Seal of Vengeance (damage calc on apply aura)
case 31801:
{
- if (effIndex != 0) // effect 1, 2 used by seal unleashing code
+ if (effIndex != 0) // effect 2 used by seal unleashing code
return false;
// At melee attack or Hammer of the Righteous spell damage considered as melee attack
@@ -6487,7 +5821,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 31803;
- // On target with 5 stacks of Holy Vengeance direct damage is done
+ // On target with 5 stacks of Censure direct damage is done
if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID()))
{
if (aur->GetStackAmount() == 5)
@@ -6503,61 +5837,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
break;
}
- // Seal of Corruption
- case 53736:
- {
- if (effIndex != 0) // effect 1, 2 used by seal unleashing code
- return false;
-
- // At melee attack or Hammer of the Righteous spell damage considered as melee attack
- bool stacker = !procSpell || procSpell->Id == 53595;
- // spells with SPELL_DAMAGE_CLASS_MELEE excluding Judgements
- bool damager = procSpell && (procSpell->EquippedItemClass != -1 || (procSpell->SpellIconID == 243 && procSpell->SpellVisual[0] == 39));
-
- if (!stacker && !damager)
- return false;
-
- triggered_spell_id = 53742;
-
- // On target with 5 stacks of Blood Corruption direct damage is done
- if (Aura* aur = victim->GetAura(triggered_spell_id, GetGUID()))
- {
- if (aur->GetStackAmount() == 5)
- {
- if (stacker)
- aur->RefreshDuration();
- CastSpell(victim, 53739, true);
- return true;
- }
- }
-
- if (!stacker)
- return false;
- break;
- }
- // Spiritual Attunement
- case 31785:
- case 33776:
- {
- // if healed by another unit (victim)
- if (this == victim)
- return false;
-
- // heal amount
- basepoints0 = int32(CalculatePct(std::min(damage, GetMaxHealth() - GetHealth()), triggerAmount));
- target = this;
-
- if (basepoints0)
- triggered_spell_id = 31786;
- break;
- }
// Paladin Tier 6 Trinket (Ashtongue Talisman of Zeal)
case 40470:
{
if (!procSpell)
return false;
- float chance;
+ float chance;
// Flash of light/Holy light
if (procSpell->SpellFamilyFlags[0] & 0xC0000000)
@@ -6579,13 +5865,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
break;
}
- // Glyph of Holy Light
- case 54937:
- {
- triggered_spell_id = 54968;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- break;
- }
// Item - Paladin T8 Holy 2P Bonus
case 64890:
{
@@ -6665,14 +5944,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
{
switch (dummySpell->Id)
{
- // Tidal Force
- case 55198:
- {
- // Remove aura stack from caster
- RemoveAuraFromStack(55166);
- // drop charges
- return false;
- }
// Totemic Power (The Earthshatterer set)
case 28823:
{
@@ -6745,26 +6016,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
// Now amount of extra power stored in 1 effect of Enchant spell
- // Get it by item enchant id
- uint32 spellId;
- switch (castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)))
- {
- case 283: spellId = 8232; break; // 1 Rank
- case 284: spellId = 8235; break; // 2 Rank
- case 525: spellId = 10486; break; // 3 Rank
- case 1669:spellId = 16362; break; // 4 Rank
- case 2636:spellId = 25505; break; // 5 Rank
- case 3785:spellId = 58801; break; // 6 Rank
- case 3786:spellId = 58803; break; // 7 Rank
- case 3787:spellId = 58804; break; // 8 Rank
- default:
- {
- TC_LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled item enchantment (rank?) %u for spell id: %u (Windfury)",
- castItem->GetEnchantmentId(EnchantmentSlot(TEMP_ENCHANTMENT_SLOT)), dummySpell->Id);
- return false;
- }
- }
-
+ uint32 spellId = 8232;
SpellInfo const* windfurySpellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!windfurySpellInfo)
{
@@ -6824,17 +6076,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = this;
break;
}
- // Glyph of Healing Wave
- case 55440:
- {
- // Not proc from self heals
- if (this == victim)
- return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- target = this;
- triggered_spell_id = 55533;
- break;
- }
// Spirit Hunt
case 58877:
{
@@ -6932,23 +6173,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
// if not found Flame Shock
return false;
}
- case 63280: // Glyph of Totem of Wrath
- {
- if (procSpell->SpellIconID != 2019)
- return false;
-
- if (Creature* totem = GetMap()->GetCreature(m_SummonSlot[1])) // Fire totem summon slot
- {
- if (SpellInfo const* totemSpell = sSpellMgr->GetSpellInfo(totem->m_spells[0]))
- {
- int32 bp0 = CalculatePct(totemSpell->Effects[EFFECT_0].CalcValue(), triggerAmount);
- int32 bp1 = CalculatePct(totemSpell->Effects[EFFECT_1].CalcValue(), triggerAmount);
- CastCustomSpell(this, 63283, &bp0, &bp1, NULL, true);
- return true;
- }
- }
- return false;
- }
break;
}
// Frozen Power
@@ -6965,14 +6189,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = 63685;
break;
}
- // Ancestral Awakening
- if (dummySpell->SpellIconID == 3065)
- {
- triggered_spell_id = 52759;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- target = this;
- break;
- }
// Flametongue Weapon (Passive)
if (dummySpell->SpellFamilyFlags[0] & 0x200000)
{
@@ -7020,109 +6236,19 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
CastCustomSpell(victim, triggered_spell_id, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
return true;
}
- // Improved Water Shield
- if (dummySpell->SpellIconID == 2287)
- {
- // Default chance for Healing Wave and Riptide
- float chance = (float)triggeredByAura->GetAmount();
-
- if (procSpell->SpellFamilyFlags[0] & 0x80)
- // Lesser Healing Wave - 0.6 of default
- chance *= 0.6f;
- else if (procSpell->SpellFamilyFlags[0] & 0x100)
- // Chain heal - 0.3 of default
- chance *= 0.3f;
-
- if (!roll_chance_f(chance))
- return false;
-
- // Water Shield
- if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020, 0))
- {
- uint32 spell = aurEff->GetSpellInfo()->Effects[aurEff->GetEffIndex()].TriggerSpell;
- CastSpell(this, spell, true, castItem, triggeredByAura);
- return true;
- }
- return false;
- }
- // Lightning Overload
- if (dummySpell->SpellIconID == 2018) // only this spell has SpellFamily Shaman SpellIconID == 2018 and dummy aura
- {
- if (!procSpell || GetTypeId() != TYPEID_PLAYER || !victim)
- return false;
-
- // custom cooldown processing case
- if (cooldown && GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(dummySpell->Id))
- return false;
-
- uint32 spellId = 0;
- // Every Lightning Bolt and Chain Lightning spell have duplicate vs half damage and zero cost
- switch (procSpell->Id)
- {
- // Lightning Bolt
- case 403: spellId = 45284; break; // Rank 1
- case 529: spellId = 45286; break; // Rank 2
- case 548: spellId = 45287; break; // Rank 3
- case 915: spellId = 45288; break; // Rank 4
- case 943: spellId = 45289; break; // Rank 5
- case 6041: spellId = 45290; break; // Rank 6
- case 10391: spellId = 45291; break; // Rank 7
- case 10392: spellId = 45292; break; // Rank 8
- case 15207: spellId = 45293; break; // Rank 9
- case 15208: spellId = 45294; break; // Rank 10
- case 25448: spellId = 45295; break; // Rank 11
- case 25449: spellId = 45296; break; // Rank 12
- case 49237: spellId = 49239; break; // Rank 13
- case 49238: spellId = 49240; break; // Rank 14
- // Chain Lightning
- case 421: spellId = 45297; break; // Rank 1
- case 930: spellId = 45298; break; // Rank 2
- case 2860: spellId = 45299; break; // Rank 3
- case 10605: spellId = 45300; break; // Rank 4
- case 25439: spellId = 45301; break; // Rank 5
- case 25442: spellId = 45302; break; // Rank 6
- case 49270: spellId = 49268; break; // Rank 7
- case 49271: spellId = 49269; break; // Rank 8
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id);
- return false;
- }
-
- // Chain Lightning
- if (procSpell->SpellFamilyFlags[0] & 0x2)
- {
- // Chain lightning has [LightOverload_Proc_Chance] / [Max_Number_of_Targets] chance to proc of each individual target hit.
- // A maxed LO would have a 33% / 3 = 11% chance to proc of each target.
- // LO chance was already "accounted" at the proc chance roll, now need to divide the chance by [Max_Number_of_Targets]
- float chance = 100.0f / procSpell->Effects[effIndex].ChainTarget;
- if (!roll_chance_f(chance))
- return false;
-
- // Remove cooldown (Chain Lightning - has Category Recovery time)
- ToPlayer()->RemoveSpellCooldown(spellId);
- }
-
- CastSpell(victim, spellId, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(dummySpell->Id, 0, time(NULL) + cooldown);
-
- return true;
- }
// Static Shock
if (dummySpell->SpellIconID == 3059)
{
// Lightning Shield
- if (AuraEffect const* aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0))
+ if (GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0))
{
- uint32 spell = sSpellMgr->GetSpellWithRank(26364, aurEff->GetSpellInfo()->GetRank());
+ uint32 spell = 26364;
// custom cooldown processing case
if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->HasSpellCooldown(spell))
ToPlayer()->RemoveSpellCooldown(spell);
CastSpell(target, spell, true, castItem, triggeredByAura);
- aurEff->GetBase()->DropCharge();
return true;
}
return false;
@@ -7131,7 +6257,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
}
case SPELLFAMILY_DEATHKNIGHT:
{
- // Blood-Caked Strike - Blood-Caked Blade
+ // Blood-Caked Blade
if (dummySpell->SpellIconID == 138)
{
if (!target || !target->IsAlive())
@@ -7140,22 +6266,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
triggered_spell_id = dummySpell->Effects[effIndex].TriggerSpell;
break;
}
- // Improved Blood Presence
- if (dummySpell->SpellIconID == 2636)
- {
- if (GetTypeId() != TYPEID_PLAYER)
- return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- break;
- }
- // Butchery
- if (dummySpell->SpellIconID == 2664)
- {
- basepoints0 = triggerAmount;
- triggered_spell_id = 50163;
- target = this;
- break;
- }
// Dancing Rune Weapon
if (dummySpell->Id == 49028)
{
@@ -7181,13 +6291,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
else
return false;
}
- // Mark of Blood
- if (dummySpell->Id == 49005)
- {
- /// @todo need more info (cooldowns/PPM)
- triggered_spell_id = 61607;
- break;
- }
// Unholy Blight
if (dummySpell->Id == 49194)
{
@@ -7206,21 +6309,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
basepoints0 += victim->GetRemainingPeriodicAmount(GetGUID(), triggered_spell_id, SPELL_AURA_PERIODIC_DAMAGE);
break;
}
- // Vendetta
- if (dummySpell->SpellFamilyFlags[0] & 0x10000)
- {
- basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
- triggered_spell_id = 50181;
- target = this;
- break;
- }
- // Necrosis
- if (dummySpell->SpellIconID == 2709)
- {
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- triggered_spell_id = 51460;
- break;
- }
// Threat of Thassarian
if (dummySpell->SpellIconID == 2023)
{
@@ -7233,45 +6321,12 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
switch (procSpell->Id)
{
- // Obliterate
- case 49020: triggered_spell_id = 66198; break; // Rank 1
- case 51423: triggered_spell_id = 66972; break; // Rank 2
- case 51424: triggered_spell_id = 66973; break; // Rank 3
- case 51425: triggered_spell_id = 66974; break; // Rank 4
-
- // Frost Strike
- case 49143: triggered_spell_id = 66196; break; // Rank 1
- case 51416: triggered_spell_id = 66958; break; // Rank 2
- case 51417: triggered_spell_id = 66959; break; // Rank 3
- case 51418: triggered_spell_id = 66960; break; // Rank 4
- case 51419: triggered_spell_id = 66961; break; // Rank 5
- case 55268: triggered_spell_id = 66962; break; // Rank 6
-
- // Plague Strike
- case 45462: triggered_spell_id = 66216; break; // Rank 1
- case 49917: triggered_spell_id = 66988; break; // Rank 2
- case 49918: triggered_spell_id = 66989; break; // Rank 3
- case 49919: triggered_spell_id = 66990; break; // Rank 4
- case 49920: triggered_spell_id = 66991; break; // Rank 5
- case 49921: triggered_spell_id = 66992; break; // Rank 6
-
- // Death Strike
- case 49998: triggered_spell_id = 66188; break; // Rank 1
- case 49999: triggered_spell_id = 66950; break; // Rank 2
- case 45463: triggered_spell_id = 66951; break; // Rank 3
- case 49923: triggered_spell_id = 66952; break; // Rank 4
- case 49924: triggered_spell_id = 66953; break; // Rank 5
-
- // Rune Strike
- case 56815: triggered_spell_id = 66217; break; // Rank 1
-
- // Blood Strike
- case 45902: triggered_spell_id = 66215; break; // Rank 1
- case 49926: triggered_spell_id = 66975; break; // Rank 2
- case 49927: triggered_spell_id = 66976; break; // Rank 3
- case 49928: triggered_spell_id = 66977; break; // Rank 4
- case 49929: triggered_spell_id = 66978; break; // Rank 5
- case 49930: triggered_spell_id = 66979; break; // Rank 6
+ case 49020: triggered_spell_id = 66198; break; // Obliterate
+ case 49143: triggered_spell_id = 66196; break; // Frost Strike
+ case 45462: triggered_spell_id = 66216; break; // Plague Strike
+ case 49998: triggered_spell_id = 66188; break; // Death Strike
+ case 56815: triggered_spell_id = 66217; break; // Rune Strike
+ case 45902: triggered_spell_id = 66215; break; // Blood Strike
default:
return false;
}
@@ -7290,79 +6345,6 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
target = this;
break;
}
- // Wandering Plague
- if (dummySpell->SpellIconID == 1614)
- {
- if (!roll_chance_f(GetUnitCriticalChance(BASE_ATTACK, victim)))
- return false;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- triggered_spell_id = 50526;
- break;
- }
- // Sudden Doom
- if (dummySpell->SpellIconID == 1939 && GetTypeId() == TYPEID_PLAYER)
- {
- SpellChainNode const* chain = NULL;
- // get highest rank of the Death Coil spell
- PlayerSpellMap const& sp_list = ToPlayer()->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- // check if shown in spell book
- if (!itr->second->active || itr->second->disabled || itr->second->state == PLAYERSPELL_REMOVED)
- continue;
-
- SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(itr->first);
- if (!spellProto)
- continue;
-
- if (spellProto->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT
- && spellProto->SpellFamilyFlags[0] & 0x2000)
- {
- SpellChainNode const* newChain = sSpellMgr->GetSpellChainNode(itr->first);
-
- // No chain entry or entry lower than found entry
- if (!chain || !newChain || (chain->rank < newChain->rank))
- {
- triggered_spell_id = itr->first;
- chain = newChain;
- }
- else
- continue;
- // Found spell is last in chain - do not need to look more
- // Optimisation for most common case
- if (chain && chain->last->Id == itr->first)
- break;
- }
- }
- }
- break;
- }
- case SPELLFAMILY_POTION:
- {
- // alchemist's stone
- if (dummySpell->Id == 17619)
- {
- if (procSpell->SpellFamilyName == SPELLFAMILY_POTION)
- {
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
- {
- if (procSpell->Effects[i].Effect == SPELL_EFFECT_HEAL)
- {
- triggered_spell_id = 21399;
- }
- else if (procSpell->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
- {
- triggered_spell_id = 21400;
- }
- else
- continue;
-
- basepoints0 = int32(CalculateSpellDamage(this, procSpell, i) * 0.4f);
- CastCustomSpell(this, triggered_spell_id, &basepoints0, NULL, NULL, true, NULL, triggeredByAura);
- }
- return true;
- }
- }
break;
}
case SPELLFAMILY_PET:
@@ -7425,9 +6407,13 @@ 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)
+bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura, SpellInfo const* procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown, bool * handled)
{
SpellInfo const* dummySpell = triggeredByAura->GetSpellInfo();
@@ -7485,30 +6471,8 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
break;
case SPELLFAMILY_PALADIN:
{
- // Infusion of Light
- if (procSpell && dummySpell->SpellIconID == 3021)
- {
- // Flash of Light HoT on Flash of Light when Sacred Shield active
- if (procSpell->SpellFamilyFlags[0] & 0x40000000 && procSpell->SpellIconID == 242)
- {
- *handled = true;
- if (victim && victim->HasAura(53601))
- {
- int32 bp0 = CalculatePct(int32(damage / 12), dummySpell->Effects[EFFECT_2].CalcValue());
- // Item - Paladin T9 Holy 4P Bonus
- if (AuraEffect const* aurEff = GetAuraEffect(67191, 0))
- AddPct(bp0, aurEff->GetAmount());
- CastCustomSpell(victim, 66922, &bp0, NULL, NULL, true);
- return true;
- }
- }
- // but should not proc on non-critical Holy Shocks
- else if ((procSpell->SpellFamilyFlags[0] & 0x200000 || procSpell->SpellFamilyFlags[1] & 0x10000) && !(procEx & PROC_EX_CRITICAL_HIT))
- *handled = true;
- break;
- }
// Judgements of the Just
- else if (dummySpell->SpellIconID == 3015)
+ if (dummySpell->SpellIconID == 3015)
{
*handled = true;
CastSpell(victim, 68055, true);
@@ -7539,24 +6503,8 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
}
case SPELLFAMILY_MAGE:
{
- // Combustion
switch (dummySpell->Id)
{
- case 11129:
- {
- *handled = true;
- Unit* caster = triggeredByAura->GetCaster();
- if (!caster || !damage)
- return false;
-
- // last charge and crit
- if (triggeredByAura->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT))
- return true; // charge counting (will removed)
-
- CastSpell(this, 28682, true);
-
- return (procEx & PROC_EX_CRITICAL_HIT);
- }
// Empowered Fire
case 31656:
case 31657:
@@ -7647,13 +6595,6 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 damage, Aura* triggeredByAura, Sp
}
return true;
}
- // Hungering Cold aura drop
- case 51209:
- *handled = true;
- // Drop only in not disease case
- if (procSpell && procSpell->Dispel == DISPEL_DISEASE)
- return false;
- return true;
}
break;
}
@@ -7782,85 +6723,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
}
break;
- case SPELLFAMILY_MAGE:
- if (auraSpellInfo->SpellIconID == 2127) // Blazing Speed
- {
- switch (auraSpellInfo->Id)
- {
- case 31641: // Rank 1
- case 31642: // Rank 2
- trigger_spell_id = 31643;
- break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u miss posibly Blazing Speed", auraSpellInfo->Id);
- return false;
- }
- }
- break;
- case SPELLFAMILY_WARLOCK:
- {
- // Drain Soul
- if (auraSpellInfo->SpellFamilyFlags[0] & 0x4000)
- {
- // Improved Drain Soul
- Unit::AuraEffectList const& mAddFlatModifier = GetAuraEffectsByType(SPELL_AURA_DUMMY);
- for (Unit::AuraEffectList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
- {
- if ((*i)->GetMiscValue() == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellInfo()->SpellIconID == 113)
- {
- int32 value2 = CalculateSpellDamage(this, (*i)->GetSpellInfo(), 2);
- basepoints0 = int32(CalculatePct(GetMaxPower(POWER_MANA), value2));
- // Drain Soul
- CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura);
- break;
- }
- }
- // Not remove charge (aura removed on death in any cases)
- // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura
- return false;
- }
- // Nether Protection
- else if (auraSpellInfo->SpellIconID == 1985)
- {
- if (!procSpell)
- return false;
- switch (GetFirstSchoolInMask(procSpell->GetSchoolMask()))
- {
- case SPELL_SCHOOL_NORMAL:
- return false; // ignore
- case SPELL_SCHOOL_HOLY: trigger_spell_id = 54370; break;
- case SPELL_SCHOOL_FIRE: trigger_spell_id = 54371; break;
- case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break;
- case SPELL_SCHOOL_FROST: trigger_spell_id = 54372; break;
- case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break;
- case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break;
- default:
- return false;
- }
- }
- break;
- }
- case SPELLFAMILY_PRIEST:
- {
- // Blessed Recovery
- if (auraSpellInfo->SpellIconID == 1875)
- {
- switch (auraSpellInfo->Id)
- {
- case 27811: trigger_spell_id = 27813; break;
- case 27815: trigger_spell_id = 27817; break;
- case 27816: trigger_spell_id = 27818; break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u not handled in BR", auraSpellInfo->Id);
- return false;
- }
- basepoints0 = CalculatePct(int32(damage), triggerAmount) / 3;
- target = this;
- // Add remaining ticks to healing done
- basepoints0 += GetRemainingPeriodicAmount(GetGUID(), trigger_spell_id, SPELL_AURA_PERIODIC_HEAL);
- }
- break;
- }
case SPELLFAMILY_DRUID:
{
switch (auraSpellInfo->Id)
@@ -7872,8 +6734,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
{
case FORM_NONE: trigger_spell_id = 37344; break;
case FORM_CAT: trigger_spell_id = 37341; break;
- case FORM_BEAR:
- case FORM_DIREBEAR: trigger_spell_id = 37340; break;
+ case FORM_BEAR: trigger_spell_id = 37340; break;
case FORM_TREE: trigger_spell_id = 37342; break;
case FORM_MOONKIN: trigger_spell_id = 37343; break;
default:
@@ -7887,8 +6748,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
switch (GetShapeshiftForm())
{
case FORM_CAT: trigger_spell_id = 67355; break;
- case FORM_BEAR:
- case FORM_DIREBEAR: trigger_spell_id = 67354; break;
+ case FORM_BEAR: trigger_spell_id = 67354; break;
default:
return false;
}
@@ -7997,124 +6857,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
break;
}
default:
- // Illumination
- if (auraSpellInfo->SpellIconID == 241)
- {
- if (!procSpell)
- return false;
- // procspell is triggered spell but we need mana cost of original cast spell
- uint32 originalSpellId = procSpell->Id;
- // Holy Shock heal
- if (procSpell->SpellFamilyFlags[1] & 0x00010000)
- {
- switch (procSpell->Id)
- {
- case 25914: originalSpellId = 20473; break;
- case 25913: originalSpellId = 20929; break;
- case 25903: originalSpellId = 20930; break;
- case 27175: originalSpellId = 27174; break;
- case 33074: originalSpellId = 33072; break;
- case 48820: originalSpellId = 48824; break;
- case 48821: originalSpellId = 48825; break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u not handled in HShock", procSpell->Id);
- return false;
- }
- }
- SpellInfo const* originalSpell = sSpellMgr->GetSpellInfo(originalSpellId);
- if (!originalSpell)
- {
- TC_LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu", originalSpellId);
- return false;
- }
- // percent stored in effect 1 (class scripts) base points
- int32 cost = int32(originalSpell->ManaCost + CalculatePct(GetCreateMana(), originalSpell->ManaCostPercentage));
- basepoints0 = CalculatePct(cost, auraSpellInfo->Effects[1].CalcValue());
- trigger_spell_id = 20272;
- target = this;
- }
break;
}
break;
}
- case SPELLFAMILY_SHAMAN:
- {
- switch (auraSpellInfo->Id)
- {
- case 30881: // Nature's Guardian Rank 1
- case 30883: // Nature's Guardian Rank 2
- case 30884: // Nature's Guardian Rank 3
- case 30885: // Nature's Guardian Rank 4
- case 30886: // Nature's Guardian Rank 5
- {
- if (HealthBelowPct(30))
- {
- basepoints0 = int32(auraSpellInfo->Effects[EFFECT_0].CalcValue() * GetMaxHealth() / 100.0f);
- target = this;
- trigger_spell_id = 31616;
- /// @todo Threat part
- }
- else
- return false;
- break;
- }
- default:
- {
- // Lightning Shield (overwrite non existing triggered spell call in spell.dbc
- if (auraSpellInfo->SpellFamilyFlags[0] & 0x400)
- {
- trigger_spell_id = sSpellMgr->GetSpellWithRank(26364, auraSpellInfo->GetRank());
- }
- // Nature's Guardian
- else if (auraSpellInfo->SpellIconID == 2013)
- {
- // Check health condition - should drop to less 30% (damage deal after this!)
- if (!HealthBelowPctDamaged(30, damage))
- return false;
-
- if (victim && victim->IsAlive())
- victim->getThreatManager().modifyThreatPercent(this, -10);
-
- basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
- trigger_spell_id = 31616;
- target = this;
- }
- }
- }
- break;
- }
case SPELLFAMILY_DEATHKNIGHT:
{
- // Acclimation
- if (auraSpellInfo->SpellIconID == 1930)
- {
- if (!procSpell)
- return false;
- switch (GetFirstSchoolInMask(procSpell->GetSchoolMask()))
- {
- case SPELL_SCHOOL_NORMAL:
- return false; // ignore
- case SPELL_SCHOOL_HOLY: trigger_spell_id = 50490; break;
- case SPELL_SCHOOL_FIRE: trigger_spell_id = 50362; break;
- case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break;
- case SPELL_SCHOOL_FROST: trigger_spell_id = 50485; break;
- case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break;
- case SPELL_SCHOOL_ARCANE: trigger_spell_id = 50486; break;
- default:
- return false;
- }
- }
- // Blood Presence (Improved)
- else if (auraSpellInfo->Id == 63611)
- {
- if (GetTypeId() != TYPEID_PLAYER)
- return false;
-
- trigger_spell_id = 50475;
- basepoints0 = CalculatePct(int32(damage), triggerAmount);
- }
// Item - Death Knight T10 Melee 4P Bonus
- else if (auraSpellInfo->Id == 70656)
+ if (auraSpellInfo->Id == 70656)
{
if (GetTypeId() != TYPEID_PLAYER || getClass() != CLASS_DEATH_KNIGHT)
return false;
@@ -8182,7 +6932,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
ItemTemplate const* weapon = item->GetTemplate();
- float weaponDPS = weapon->getDPS();
+ float weaponDPS = weapon->DPS;
float attackPower = GetTotalAttackPowerValue(BASE_ATTACK) / 14.0f;
float weaponSpeed = float(weapon->Delay) / 1000.0f;
basepoints0 = int32((weaponDPS + attackPower) * weaponSpeed);
@@ -8207,7 +6957,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
// Deflection
case 52420:
{
- if (!HealthBelowPct(35))
+ if (!HealthBelowPctDamaged(35, damage))
return false;
break;
}
@@ -8220,16 +6970,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
break;
}
- // Deadly Swiftness (Rank 1)
- case 31255:
- {
- // whenever you deal damage to a target who is below 20% health.
- if (!victim || !victim->IsAlive() || victim->HealthAbovePct(20))
- return false;
-
- target = this;
- trigger_spell_id = 22588;
- }
// Greater Heal Refund (Avatar Raiment set)
case 37594:
{
@@ -8252,36 +6992,17 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
break;
}
- // Rapid Recuperation
- case 53228:
- case 53232:
- {
- // This effect only from Rapid Fire (ability cast)
- if (!(procSpell->SpellFamilyFlags[0] & 0x20))
- return false;
- break;
- }
// Decimation
case 63156:
case 63158:
- // Can proc only if target has hp below 35%
- if (!victim || !victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, procSpell, this))
+ // Can proc only if target has hp below 25%
+ if (!victim || !victim->HealthBelowPct(auraSpellInfo->Effects[EFFECT_1].CalcValue()))
return false;
break;
// Deathbringer Saurfang - Blood Beast's Blood Link
case 72176:
basepoints0 = 3;
break;
- case 15337: // Improved Spirit Tap (Rank 1)
- case 15338: // Improved Spirit Tap (Rank 2)
- {
- if (procSpell->SpellFamilyFlags[0] & 0x800000)
- if ((procSpell->Id != 58381) || !roll_chance_i(50))
- return false;
-
- target = victim;
- break;
- }
// Professor Putricide - Ooze Spell Tank Protection
case 71770:
if (victim)
@@ -8302,52 +7023,11 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
break;
}
- // Blade Barrier
- if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 85 && procSpell)
- {
- Player* player = ToPlayer();
- if (!player || player->getClass() != CLASS_DEATH_KNIGHT)
- return false;
-
- if (!player->IsBaseRuneSlotsOnCooldown(RUNE_BLOOD))
- return false;
- }
-
- // Rime
- else if (auraSpellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && auraSpellInfo->SpellIconID == 56)
- {
- if (GetTypeId() != TYPEID_PLAYER)
- return false;
-
- // Howling Blast
- ToPlayer()->RemoveSpellCategoryCooldown(1248, true);
- }
-
// Custom basepoints/target for exist spell
// dummy basepoints or other customs
switch (trigger_spell_id)
{
// Auras which should proc on area aura source (caster in this case):
- // Turn the Tables
- case 52914:
- case 52915:
- case 52910:
- // Honor Among Thieves
- case 52916:
- {
- target = triggeredByAura->GetBase()->GetCaster();
- if (!target)
- return false;
-
- if (cooldown && target->GetTypeId() == TYPEID_PLAYER && target->ToPlayer()->HasSpellCooldown(trigger_spell_id))
- return false;
-
- target->CastSpell(target, trigger_spell_id, true, castItem, triggeredByAura);
-
- if (cooldown && GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->AddSpellCooldown(trigger_spell_id, 0, time(NULL) + cooldown);
- return true;
- }
// Cast positive spell on enemy target
case 7099: // Curse of Mending
case 39703: // Curse of Mending
@@ -8357,14 +7037,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
target = victim;
break;
}
- // Combo points add triggers (need add combopoint only for main target, and after possible combopoints reset)
- case 15250: // Rogue Setup
- {
- // applied only for main target
- if (!victim || (GetTypeId() == TYPEID_PLAYER && victim != ToPlayer()->GetSelectedUnit()))
- return false;
- break; // continue normal case
- }
// Finish movies that add combo
case 14189: // Seal Fate (Netherblade set)
case 14157: // Ruthlessness
@@ -8381,12 +7053,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(this, 70721, true);
break;
}
- // Shamanistic Rage triggered spell
- case 30824:
- {
- basepoints0 = int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), triggerAmount));
- break;
- }
// Enlightenment (trigger only from mana cost spells)
case 35095:
{
@@ -8394,22 +7060,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
break;
}
- // Demonic Pact
- case 48090:
- {
- // Get talent aura from owner
- if (IsPet())
- if (Unit* owner = GetOwner())
- {
- if (AuraEffect* aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0))
- {
- basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonusDone(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f); /// @todo Is it right?
- CastCustomSpell(this, trigger_spell_id, &basepoints0, &basepoints0, NULL, true, castItem, triggeredByAura);
- return true;
- }
- }
- break;
- }
case 46916: // Slam! (Bloodsurge proc)
case 52437: // Sudden Death
{
@@ -8424,14 +7074,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
}
break;
}
- // Sword and Board
- case 50227:
- {
- // Remove cooldown on Shield Slam
- if (GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->RemoveSpellCategoryCooldown(1209, true);
- break;
- }
// Maelstrom Weapon
case 53817:
{
@@ -8448,35 +7090,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(this, 70831, true, castItem, triggeredByAura);
break;
}
- // Astral Shift
- case 52179:
- {
- if (procSpell == 0 || !(procEx & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) || this == victim)
- return false;
-
- // Need stun, fear or silence mechanic
- if (!(procSpell->GetAllEffectsMechanicMask() & ((1<<MECHANIC_SILENCE)|(1<<MECHANIC_STUN)|(1<<MECHANIC_FEAR))))
- return false;
- break;
- }
- // Burning Determination
- case 54748:
- {
- if (!procSpell)
- return false;
- // Need Interrupt or Silenced mechanic
- if (!(procSpell->GetAllEffectsMechanicMask() & ((1<<MECHANIC_INTERRUPT)|(1<<MECHANIC_SILENCE))))
- return false;
- break;
- }
- // Lock and Load
- case 56453:
- {
- // Proc only from Frost/Freezing trap activation or from Freezing Arrow (the periodic dmg proc handled elsewhere)
- if (!(procFlags & PROC_FLAG_DONE_TRAP_ACTIVATION) || !procSpell || !(procSpell->SchoolMask & SPELL_SCHOOL_MASK_FROST) || !roll_chance_i(triggerAmount))
- return false;
- break;
- }
// Glyph of Death's Embrace
case 58679:
{
@@ -8485,14 +7098,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return false;
break;
}
- // Glyph of Death Grip
- case 58628:
- {
- // remove cooldown of Death Grip
- if (GetTypeId() == TYPEID_PLAYER)
- ToPlayer()->RemoveSpellCooldown(49576, true);
- return true;
- }
// Savage Defense
case 62606:
{
@@ -8539,7 +7144,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
return true;
}
-bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 cooldown)
+bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, AuraEffect* triggeredByAura, SpellInfo const* /*procSpell*/, uint32 cooldown)
{
int32 scriptId = triggeredByAura->GetMiscValue();
@@ -8553,27 +7158,6 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
switch (scriptId)
{
- case 836: // Improved Blizzard (Rank 1)
- {
- if (!procSpell || procSpell->SpellVisual[0] != 9487)
- return false;
- triggered_spell_id = 12484;
- break;
- }
- case 988: // Improved Blizzard (Rank 2)
- {
- if (!procSpell || procSpell->SpellVisual[0] != 9487)
- return false;
- triggered_spell_id = 12485;
- break;
- }
- case 989: // Improved Blizzard (Rank 3)
- {
- if (!procSpell || procSpell->SpellVisual[0] != 9487)
- return false;
- triggered_spell_id = 12486;
- break;
- }
case 4533: // Dreamwalker Raiment 2 pieces bonus
{
// Chance 50%
@@ -8593,26 +7177,6 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit* victim, uint32 /*damage*/, Au
case 4537: // Dreamwalker Raiment 6 pieces bonus
triggered_spell_id = 28750; // Blessing of the Claw
break;
- case 5497: // Improved Mana Gems
- triggered_spell_id = 37445; // Mana Surge
- break;
- case 7010: // Revitalize - can proc on full hp target
- case 7011:
- case 7012:
- {
- if (!roll_chance_i(triggeredByAura->GetAmount()))
- return false;
- switch (victim->getPowerType())
- {
- case POWER_MANA: triggered_spell_id = 48542; break;
- case POWER_RAGE: triggered_spell_id = 48541; break;
- case POWER_ENERGY: triggered_spell_id = 48540; break;
- case POWER_RUNIC_POWER: triggered_spell_id = 48543; break;
- default:
- break;
- }
- break;
- }
default:
break;
}
@@ -8676,10 +7240,6 @@ void Unit::setPowerType(Powers new_powertype)
case POWER_ENERGY:
SetMaxPower(POWER_ENERGY, GetCreatePowers(POWER_ENERGY));
break;
- case POWER_HAPPINESS:
- SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
- SetPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS));
- break;
}
}
@@ -9152,7 +7712,7 @@ bool Unit::HasAuraState(AuraStateType flag, SpellInfo const* spellProto, Unit co
{
AuraEffectList const& stateAuras = Caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(spellProto))
+ if ((*j)->IsAffectingSpell(spellProto))
return true;
}
// Check per caster aura state
@@ -9186,7 +7746,7 @@ void Unit::SetOwnerGUID(uint64 owner)
SetFieldNotifyFlag(UF_FLAG_OWNER);
- UpdateData udata;
+ UpdateData udata(GetMapId());
WorldPacket packet;
BuildValuesUpdateBlockForPlayer(&udata, player);
udata.BuildPacket(&packet);
@@ -9231,7 +7791,7 @@ Player* Unit::GetAffectingPlayer() const
return NULL;
}
-Minion *Unit::GetFirstMinion() const
+Minion* Unit::GetFirstMinion() const
{
if (uint64 pet_guid = GetMinionGUID())
{
@@ -9497,10 +8057,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
_isWalkingBeforeCharm = charm->IsWalking();
if (_isWalkingBeforeCharm)
- {
charm->SetWalk(false);
- charm->SendMovementFlagUpdate();
- }
m_Controlled.insert(charm);
}
@@ -9535,10 +8092,7 @@ void Unit::SetCharm(Unit* charm, bool apply)
}
if (charm->IsWalking() != _isWalkingBeforeCharm)
- {
charm->SetWalk(_isWalkingBeforeCharm);
- charm->SendMovementFlagUpdate(true); // send packet to self, to update movement state on player.
- }
if (charm->GetTypeId() == TYPEID_PLAYER
|| !charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_MINION)
@@ -9577,7 +8131,7 @@ int32 Unit::DealHeal(Unit* victim, uint32 addhealth)
// use the actual gain, as the overheal shall not be counted, skip gain 0 (it ignored anyway in to criteria)
if (gain)
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, victim);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE, gain, 0, 0, victim);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CAST, addhealth);
}
@@ -9894,26 +8448,40 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
if (victim->HasAuraState(AuraStateType((*i)->GetMiscValue())))
AddPct(DoneTotalMod, (*i)->GetAmount());
+ // Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus
+ AddPct(DoneTotalMod, GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC, spellProto->Mechanic));
+
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!(*i)->IsAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectingSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
case 4920: // Molten Fury
case 4919:
- case 6917: // Death's Embrace
- case 6926:
- case 6928:
{
if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
+ case 6917: // Death's Embrace damage effect
+ case 6926:
+ case 6928:
+ {
+ // 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());
+ }
+ case 6916: // Death's Embrace heal effect
+ case 6925:
+ case 6927:
+ if (HealthBelowPct(CalculateSpellDamage(this, (*i)->GetSpellInfo(), EFFECT_2)))
+ AddPct(DoneTotalMod, (*i)->GetAmount());
+ break;
// Soul Siphon
case 4992:
case 4993:
@@ -9941,12 +8509,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
AddPct(DoneTotalMod, modPercent);
break;
}
- case 6916: // Death's Embrace
- case 6925:
- case 6927:
- if (HasAuraState(AURA_STATE_HEALTHLESS_20_PERCENT, spellProto, this))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
case 5481: // Starfire Bonus
{
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002, 0, 0))
@@ -9965,65 +8527,6 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
DoneTotal += (*i)->GetAmount();
break;
}
- // Tundra Stalker
- // Merciless Combat
- case 7277:
- {
- // Merciless Combat
- if ((*i)->GetSpellInfo()->SpellIconID == 2656)
- {
- if (!victim->HealthAbovePct(35))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- }
- // Tundra Stalker
- else
- {
- // Frost Fever (target debuff)
- if (victim->HasAura(55095))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
- break;
- }
- // Rage of Rivendare
- case 7293:
- {
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0x02000000, 0))
- AddPct(DoneTotalMod, (*i)->GetSpellInfo()->GetRank() * 2.0f);
- break;
- }
- // Twisted Faith
- case 7377:
- {
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, GetGUID()))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
- // Marked for Death
- case 7598:
- case 7599:
- case 7600:
- case 7601:
- case 7602:
- {
- if (victim->GetAuraEffect(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0, 0))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
- // Dirty Deeds
- case 6427:
- case 6428:
- case 6579:
- case 6580:
- {
- if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
- {
- // effect 0 has expected value but in negative state
- int32 bonus = -(*i)->GetBase()->GetEffect(0)->GetAmount();
- AddPct(DoneTotalMod, bonus);
- }
- break;
- }
}
}
@@ -10033,89 +8536,35 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
case SPELLFAMILY_MAGE:
// Ice Lance
if (spellProto->SpellIconID == 186)
- {
if (victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
- {
- // Glyph of Ice Lance
- if (owner->HasAura(56377) && victim->getLevel() > owner->getLevel())
- DoneTotalMod *= 4.0f;
- else
- DoneTotalMod *= 3.0f;
- }
- }
+ DoneTotalMod *= 2.0f;
// Torment the weak
- if (spellProto->SpellFamilyFlags[0] & 0x20600021 || spellProto->SpellFamilyFlags[1] & 0x9000)
+ if (spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_ARCANE)
+ {
if (victim->HasAuraWithMechanic((1<<MECHANIC_SNARE)|(1<<MECHANIC_SLOW_ATTACK)))
{
AuraEffectList const& mDumyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDumyAuras.begin(); i != mDumyAuras.end(); ++i)
- if ((*i)->GetSpellInfo()->SpellIconID == 3263)
+ {
+ if ((*i)->GetSpellInfo()->SpellIconID == 2215)
{
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
}
+ }
}
+ }
break;
case SPELLFAMILY_PRIEST:
- // Mind Flay
- if (spellProto->SpellFamilyFlags[0] & 0x800000)
- {
- // Glyph of Shadow Word: Pain
- if (AuraEffect* aurEff = GetAuraEffect(55687, 0))
- // Increase Mind Flay damage if Shadow Word: Pain present on target
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, GetGUID()))
- AddPct(DoneTotalMod, aurEff->GetAmount());
-
- // Twisted Faith - Mind Flay part
- if (AuraEffect* aurEff = GetAuraEffect(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS, SPELLFAMILY_PRIEST, 2848, 1))
- // Increase Mind Flay damage if Shadow Word: Pain present on target
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, GetGUID()))
- AddPct(DoneTotalMod, aurEff->GetAmount());
- }
// Smite
- else if (spellProto->SpellFamilyFlags[0] & 0x80)
+ if (spellProto->SpellFamilyFlags[0] & 0x80)
{
// Glyph of Smite
if (AuraEffect* aurEff = GetAuraEffect(55692, 0))
if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x100000, 0, 0, GetGUID()))
AddPct(DoneTotalMod, aurEff->GetAmount());
}
- // Shadow Word: Death
- else if (spellProto->SpellFamilyFlags[1] & 0x2)
- {
- // Glyph of Shadow Word: Death
- if (AuraEffect* aurEff = GetAuraEffect(55682, 1))
- if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT))
- AddPct(DoneTotalMod, aurEff->GetAmount());
- }
- break;
- case SPELLFAMILY_PALADIN:
- // Judgement of Vengeance/Judgement of Corruption
- if ((spellProto->SpellFamilyFlags[1] & 0x400000) && spellProto->SpellIconID == 2292)
- {
- // Get stack of Holy Vengeance/Blood Corruption on the target added by caster
- uint32 stacks = 0;
- Unit::AuraEffectList const& auras = victim->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
- for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- if (((*itr)->GetId() == 31803 || (*itr)->GetId() == 53742) && (*itr)->GetCasterGUID() == GetGUID())
- {
- stacks = (*itr)->GetBase()->GetStackAmount();
- break;
- }
- // + 10% for each application of Holy Vengeance/Blood Corruption on the target
- if (stacks)
- AddPct(DoneTotalMod, 10 * stacks);
- }
- break;
- case SPELLFAMILY_DRUID:
- // Thorns
- if (spellProto->SpellFamilyFlags[0] & 0x100)
- {
- // Brambles
- if (AuraEffect* aurEff = GetAuraEffectOfRankedSpell(16836, 0))
- AddPct(DoneTotalMod, aurEff->GetAmount());
- }
break;
case SPELLFAMILY_WARLOCK:
// Fire and Brimstone
@@ -10133,59 +8582,17 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// Drain Soul - increased damage for targets under 25 % HP
if (spellProto->SpellFamilyFlags[0] & 0x00004000)
if (HasAura(100001))
- DoneTotalMod *= 4;
- // Shadow Bite (15% increase from each dot)
+ DoneTotalMod *= 2;
+ // Shadow Bite (30% increase from each dot)
if (spellProto->SpellFamilyFlags[1] & 0x00400000 && IsPet())
if (uint8 count = victim->GetDoTsByCaster(GetOwnerGUID()))
- AddPct(DoneTotalMod, 15 * count);
- break;
- case SPELLFAMILY_HUNTER:
- // Steady Shot
- if (spellProto->SpellFamilyFlags[1] & 0x1)
- if (AuraEffect* aurEff = GetAuraEffect(56826, 0)) // Glyph of Steady Shot
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_HUNTER, 0x00004000, 0, 0, GetGUID()))
- AddPct(DoneTotalMod, aurEff->GetAmount());
+ AddPct(DoneTotalMod, 30 * count);
break;
case SPELLFAMILY_DEATHKNIGHT:
- // Improved Icy Touch
- if (spellProto->SpellFamilyFlags[0] & 0x2)
- if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2721, 0))
- AddPct(DoneTotalMod, aurEff->GetAmount());
-
// Sigil of the Vengeful Heart
if (spellProto->SpellFamilyFlags[0] & 0x2000)
if (AuraEffect* aurEff = GetAuraEffect(64962, EFFECT_1))
- AddPct(DoneTotal, aurEff->GetAmount());
-
- // Glacier Rot
- if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
- if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0))
- if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0)
- AddPct(DoneTotalMod, aurEff->GetAmount());
-
- // 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;
- }
- }
- }
+ DoneTotal += aurEff->GetAmount();
break;
}
@@ -10282,8 +8689,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
{
if (GetTypeId() != TYPEID_PLAYER)
continue;
- float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
- AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
+ AddPct(TakenTotalMod, (*i)->GetAmount());
}
break;
}
@@ -10292,7 +8698,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
// From caster spells
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
- if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
+ if ((*i)->GetCasterGUID() == caster->GetGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
// Mod damage from spell mechanic
@@ -10367,6 +8773,10 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
// Base value
DoneAdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
+ // Check if we are ever using mana - PaperDollFrame.lua
+ if (GetPowerIndex(POWER_MANA) != MAX_POWERS)
+ DoneAdvertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect
+
// Damage bonus from stats
AuraEffectList const& mDamageDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin(); i != mDamageDoneOfStatPercent.end(); ++i)
@@ -10449,24 +8859,21 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
crit_chance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE, schoolMask);
// Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE
crit_chance += victim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE);
- ApplyResilience(victim, &crit_chance, NULL, false, CR_CRIT_TAKEN_SPELL);
}
// scripted (increase crit chance ... against ... target by x%
AuraEffectList const& mOverrideClassScript = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!((*i)->IsAffectedOnSpell(spellProto)))
+ if (!((*i)->IsAffectingSpell(spellProto)))
continue;
- int32 modChance = 0;
+
switch ((*i)->GetMiscValue())
{
- // Shatter
- case 911: modChance+= 16;
- case 910: modChance+= 17;
- case 849: modChance+= 17;
+ // Shatter
+ case 911:
if (!victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this))
break;
- crit_chance+=modChance;
+ AddPct(crit_chance, (*i)->GetAmount()*20);
break;
case 7917: // Glyph of Shadowburn
if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
@@ -10562,16 +8969,6 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
break;
}
break;
- case SPELLFAMILY_WARRIOR:
- // Victory Rush
- if (spellProto->SpellFamilyFlags[1] & 0x100)
- {
- // Glyph of Victory Rush
- if (AuraEffect const* aurEff = GetAuraEffect(58382, 0))
- crit_chance += aurEff->GetAmount();
- break;
- }
- break;
}
}
/// Intentional fallback. Calculate critical strike chance for both Ranged and Melee spells
@@ -10592,13 +8989,18 @@ bool Unit::isSpellCrit(Unit* victim, SpellInfo const* spellProto, SpellSchoolMas
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance);
+ AuraEffectList const& critAuras = victim->GetAuraEffectsByType(SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER);
+ for (AuraEffectList::const_iterator i = critAuras.begin(); i != critAuras.end(); ++i)
+ if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectingSpell(spellProto))
+ crit_chance += (*i)->GetAmount();
+
crit_chance = crit_chance > 0.0f ? crit_chance : 0.0f;
if (roll_chance_f(crit_chance))
return true;
return false;
}
-uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim)
+uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* /*victim*/)
{
// Calculate critical bonus
int32 crit_bonus = damage;
@@ -10618,9 +9020,6 @@ uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage
crit_mod += (GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS, spellProto->GetSchoolMask()) - 1.0f) * 100;
- if (victim)
- crit_mod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, victim->GetCreatureTypeMask());
-
if (crit_bonus != 0)
AddPct(crit_bonus, crit_mod);
@@ -10638,30 +9037,12 @@ uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage
return crit_bonus;
}
-uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim)
+uint32 Unit::SpellCriticalHealingBonus(SpellInfo const* /*spellProto*/, uint32 damage, Unit* /*victim*/)
{
// Calculate critical bonus
- int32 crit_bonus;
- switch (spellProto->DmgClass)
- {
- case SPELL_DAMAGE_CLASS_MELEE: // for melee based spells is 100%
- case SPELL_DAMAGE_CLASS_RANGED:
- /// @todo write here full calculation for melee/ranged spells
- crit_bonus = damage;
- break;
- default:
- crit_bonus = damage / 2; // for spells is 50%
- break;
- }
-
- if (victim)
- {
- uint32 creatureTypeMask = victim->GetCreatureTypeMask();
- crit_bonus = int32(crit_bonus * GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, creatureTypeMask));
- }
+ int32 crit_bonus = damage;
- if (crit_bonus > 0)
- damage += crit_bonus;
+ damage += crit_bonus;
damage = int32(float(damage) * GetTotalAuraMultiplier(SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT));
@@ -10692,7 +9073,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!(*i)->IsAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectingSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
@@ -10707,12 +9088,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
if (victim->HealthBelowPct(50))
AddPct(DoneTotalMod, (*i)->GetAmount());
break;
- case 7798: // Glyph of Regrowth
- {
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0, 0))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
case 8477: // Nourish Heal Boost
{
int32 stepPercent = (*i)->GetAmount();
@@ -10732,12 +9107,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
AddPct(DoneTotalMod, modPercent);
break;
}
- case 7871: // Glyph of Lesser Healing Wave
- {
- if (victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0, 0x00000400, 0, GetGUID()))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
default:
break;
}
@@ -10789,10 +9158,6 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
coeff /= 100.0f;
}
- // Earthliving - 0.45% of normal hot coeff
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
- factorMod *= 0.45f;
-
DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod);
}
@@ -10851,18 +9216,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
TakenTotalMod *= 1.2f;
}
- if (damagetype == DOT)
- {
- // Healing over time taken percent
- float minval_hot = float(GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT));
- if (minval_hot)
- AddPct(TakenTotalMod, minval_hot);
-
- float maxval_hot = float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT));
- if (maxval_hot)
- AddPct(TakenTotalMod, maxval_hot);
- }
-
// Check for table values
SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id);
float coeff = 0;
@@ -10893,16 +9246,12 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
coeff /= 100.0f;
}
- // Earthliving - 0.45% of normal hot coeff
- if (spellProto->SpellFamilyName == SPELLFAMILY_SHAMAN && spellProto->SpellFamilyFlags[1] & 0x80000)
- factorMod *= 0.45f;
-
TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod);
}
AuraEffectList const& mHealingGet= GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED);
for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
- if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto))
+ if (caster->GetGUID() == (*i)->GetCasterGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
@@ -10939,6 +9288,10 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const
// Base value
advertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus();
+ // Check if we are ever using mana - PaperDollFrame.lua
+ if (GetPowerIndex(POWER_MANA) != MAX_POWERS)
+ advertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect
+
// Healing bonus from stats
AuraEffectList const& mHealingDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
@@ -11203,80 +9556,13 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType
if (victim->HasAuraState(AuraStateType((*i)->GetMiscValue())))
AddPct(DoneTotalMod, (*i)->GetAmount());
- // done scripted mod (take it from owner)
- Unit* owner = GetOwner() ? GetOwner() : this;
- AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
- {
- if (!(*i)->IsAffectedOnSpell(spellProto))
- continue;
-
- switch ((*i)->GetMiscValue())
- {
- // Tundra Stalker
- // Merciless Combat
- case 7277:
- {
- // Merciless Combat
- if ((*i)->GetSpellInfo()->SpellIconID == 2656)
- {
- if (!victim->HealthAbovePct(35))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- }
- // Tundra Stalker
- else
- {
- // Frost Fever (target debuff)
- if (victim->HasAura(55095))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- }
- break;
- }
- // Rage of Rivendare
- case 7293:
- {
- if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0x02000000, 0))
- AddPct(DoneTotalMod, (*i)->GetSpellInfo()->GetRank() * 2.0f);
- break;
- }
- // Marked for Death
- case 7598:
- case 7599:
- case 7600:
- case 7601:
- case 7602:
- {
- if (victim->GetAuraEffect(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0, 0))
- AddPct(DoneTotalMod, (*i)->GetAmount());
- break;
- }
- // Dirty Deeds
- case 6427:
- case 6428:
- {
- if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
- {
- // effect 0 has expected value but in negative state
- int32 bonus = -(*i)->GetBase()->GetEffect(0)->GetAmount();
- AddPct(DoneTotalMod, bonus);
- }
- break;
- }
- }
- }
-
- // Custom scripted damage
+ // Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus
if (spellProto)
- switch (spellProto->SpellFamilyName)
- {
- case SPELLFAMILY_DEATHKNIGHT:
- // Glacier Rot
- if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
- if (AuraEffect* aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0))
- if (victim->GetDiseasesByCaster(owner->GetGUID()) > 0)
- AddPct(DoneTotalMod, aurEff->GetAmount());
- break;
- }
+ AddPct(DoneTotalMod, GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC, spellProto->Mechanic));
+
+ // done scripted mod (take it from owner)
+ // Unit* owner = GetOwner() ? GetOwner() : this;
+ // AuraEffectList const& mOverrideClassScript = owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
float tmpDamage = float(int32(pdamage) + DoneFlatBenefit) * DoneTotalMod;
@@ -11329,7 +9615,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
// From caster spells
AuraEffectList const& mOwnerTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
- if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
+ if ((*i)->GetCasterGUID() == attacker->GetGUID() && (*i)->IsAffectingSpell(spellProto))
AddPct(TakenTotalMod, (*i)->GetAmount());
// Mod damage from spell mechanic
@@ -11360,7 +9646,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
{
if (GetTypeId() != TYPEID_PLAYER)
continue;
- float mod = ToPlayer()->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE) * (-8.0f);
+ float mod = ToPlayer()->GetRatingBonusValue(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN) * (-8.0f);
AddPct(TakenTotalMod, std::max(mod, float((*i)->GetAmount())));
}
break;
@@ -11510,8 +9796,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
data << uint32(VehicleId);
SendMessageToSet(&data, true);
- data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0);
- player->GetSession()->SendPacket(&data);
+ player->SendOnCancelExpectedVehicleRideAura();
// mounts can also have accessories
GetVehicleKit()->InstallAllAccessories(false);
@@ -11530,11 +9815,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry)
player->UnsummonPetTemporaryIfAny();
}
- WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
- data.append(GetPackGUID());
- data << uint32(sWorld->GetGameTime()); // Packet counter
- data << player->GetCollisionHeight(true);
- player->GetSession()->SendPacket(&data);
+ player->SendMovementSetCollisionHeight(player->GetCollisionHeight(true));
}
RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT);
@@ -11549,13 +9830,7 @@ void Unit::Dismount()
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_MOUNT);
if (Player* thisPlayer = ToPlayer())
- {
- WorldPacket data(SMSG_MOVE_SET_COLLISION_HGT, GetPackGUID().size() + 4 + 4);
- data.append(GetPackGUID());
- data << uint32(sWorld->GetGameTime()); // Packet counter
- data << thisPlayer->GetCollisionHeight(false);
- thisPlayer->GetSession()->SendPacket(&data);
- }
+ thisPlayer->SendMovementSetCollisionHeight(thisPlayer->GetCollisionHeight(false));
WorldPacket data(SMSG_DISMOUNT, 8);
data.appendPackGUID(GetGUID());
@@ -11590,6 +9865,64 @@ void Unit::Dismount()
}
}
+MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
+{
+ if (!mountType)
+ return NULL;
+
+ MountTypeEntry const* mountTypeEntry = sMountTypeStore.LookupEntry(mountType);
+ if (!mountTypeEntry)
+ return NULL;
+
+ uint32 zoneId, areaId;
+ GetZoneAndAreaId(zoneId, areaId);
+ uint32 ridingSkill = 5000;
+ if (GetTypeId() == TYPEID_PLAYER)
+ ridingSkill = ToPlayer()->GetSkillValue(SKILL_RIDING);
+
+ for (uint32 i = MAX_MOUNT_CAPABILITIES; i > 0; --i)
+ {
+ MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(mountTypeEntry->MountCapability[i - 1]);
+ if (!mountCapability)
+ continue;
+
+ if (ridingSkill < mountCapability->RequiredRidingSkill)
+ continue;
+
+ if (HasExtraUnitMovementFlag(MOVEMENTFLAG2_FULL_SPEED_PITCHING))
+ {
+ if (!(mountCapability->Flags & MOUNT_FLAG_CAN_PITCH))
+ continue;
+ }
+ else if (HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING))
+ {
+ if (!(mountCapability->Flags & MOUNT_FLAG_CAN_SWIM))
+ continue;
+ }
+ else if (!(mountCapability->Flags & 0x1)) // unknown flags, checked in 4.2.2 14545 client
+ {
+ if (!(mountCapability->Flags & 0x2))
+ continue;
+ }
+
+ if (mountCapability->RequiredMap != -1 && int32(GetMapId()) != mountCapability->RequiredMap)
+ continue;
+
+ if (mountCapability->RequiredArea && (mountCapability->RequiredArea != zoneId && mountCapability->RequiredArea != areaId))
+ continue;
+
+ if (mountCapability->RequiredAura && !HasAura(mountCapability->RequiredAura))
+ continue;
+
+ if (mountCapability->RequiredSpell && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->HasSpell(mountCapability->RequiredSpell)))
+ continue;
+
+ return mountCapability;
+ }
+
+ return NULL;
+}
+
bool Unit::IsServiceProvider() const
{
return HasFlag(UNIT_NPC_FLAGS,
@@ -11793,13 +10126,17 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo
if (playerAttacker->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_UBER))
return false;
}
+
// check flags
if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_TAXI_FLIGHT | UNIT_FLAG_NOT_ATTACKABLE_1 | UNIT_FLAG_UNK_16)
|| (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC))
- || (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC))
- || (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
+ || (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC)))
+ return false;
+
+ if ((!bySpell || !(bySpell->AttributesEx8 & SPELL_ATTR8_ATTACK_IGNORE_IMMUNE_TO_PC_FLAG))
+ && (HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
// check if this is a world trigger cast - GOs are using world triggers to cast their spells, so we need to ignore their immunity flag here, this is a temp workaround, needs removal when go cast is implemented properly
- || (GetEntry() != WORLD_TRIGGER && target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE) && HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC)))
+ && GetEntry() != WORLD_TRIGGER)
return false;
// CvC case - can attack each other only when one of them is hostile
@@ -12026,16 +10363,16 @@ int32 Unit::ModifyPower(Powers power, int32 dVal)
if (dVal == 0)
return 0;
- int32 curPower = (int32)GetPower(power);
+ int32 curPower = GetPower(power);
int32 val = dVal + curPower;
- if (val <= 0)
+ if (val <= GetMinPower(power))
{
- SetPower(power, 0);
+ SetPower(power, GetMinPower(power));
return -curPower;
}
- int32 maxPower = (int32)GetMaxPower(power);
+ int32 maxPower = GetMaxPower(power);
if (val < maxPower)
{
@@ -12057,7 +10394,7 @@ int32 Unit::ModifyPowerPct(Powers power, float pct, bool apply)
float amount = (float)GetMaxPower(power);
ApplyPercentModFloatVar(amount, pct, apply);
- return ModifyPower(power, (int32)amount - (int32)GetMaxPower(power));
+ return ModifyPower(power, (int32)amount - GetMaxPower(power));
}
uint32 Unit::GetAttackTime(WeaponAttackType att) const
@@ -12270,100 +10607,35 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
propagateSpeedChange();
- WorldPacket data;
- if (!forced)
+ static Opcodes const moveTypeToOpcode[MAX_MOVE_TYPE][3] =
+ {
+ {SMSG_SPLINE_MOVE_SET_WALK_SPEED, SMSG_MOVE_SET_WALK_SPEED, SMSG_MOVE_UPDATE_WALK_SPEED },
+ {SMSG_SPLINE_MOVE_SET_RUN_SPEED, SMSG_MOVE_SET_RUN_SPEED, SMSG_MOVE_UPDATE_RUN_SPEED },
+ {SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, SMSG_MOVE_SET_RUN_BACK_SPEED, SMSG_MOVE_UPDATE_RUN_BACK_SPEED },
+ {SMSG_SPLINE_MOVE_SET_SWIM_SPEED, SMSG_MOVE_SET_SWIM_SPEED, SMSG_MOVE_UPDATE_SWIM_SPEED },
+ {SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, SMSG_MOVE_SET_SWIM_BACK_SPEED, SMSG_MOVE_UPDATE_SWIM_BACK_SPEED },
+ {SMSG_SPLINE_MOVE_SET_TURN_RATE, SMSG_MOVE_SET_TURN_RATE, SMSG_MOVE_UPDATE_TURN_RATE },
+ {SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, SMSG_MOVE_SET_FLIGHT_SPEED, SMSG_MOVE_UPDATE_FLIGHT_SPEED },
+ {SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, SMSG_MOVE_SET_FLIGHT_BACK_SPEED, SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED},
+ {SMSG_SPLINE_MOVE_SET_PITCH_RATE, SMSG_MOVE_SET_PITCH_RATE, SMSG_MOVE_UPDATE_PITCH_RATE },
+ };
+
+ if (GetTypeId() == TYPEID_PLAYER)
{
- switch (mtype)
- {
- case MOVE_WALK:
- data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_RUN:
- data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_RUN_BACK:
- data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_SWIM:
- data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_SWIM_BACK:
- data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_TURN_RATE:
- data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_FLIGHT:
- data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_FLIGHT_BACK:
- data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);
- break;
- case MOVE_PITCH_RATE:
- data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4);
- break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype);
- return;
- }
+ // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
+ // and do it only for real sent packets and use run for run/mounted as client expected
+ ++ToPlayer()->m_forced_speed_changes[mtype];
- BuildMovementPacket(&data);
- data << float(GetSpeed(mtype));
- SendMessageToSet(&data, true);
+ if (!IsInCombat())
+ if (Pet* pet = ToPlayer()->GetPet())
+ pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
}
- else
- {
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // register forced speed changes for WorldSession::HandleForceSpeedChangeAck
- // and do it only for real sent packets and use run for run/mounted as client expected
- ++ToPlayer()->m_forced_speed_changes[mtype];
- if (!IsInCombat())
- if (Pet* pet = ToPlayer()->GetPet())
- pet->SetSpeed(mtype, m_speed_rate[mtype], forced);
- }
+ static MovementStatusElements const speedVal = MSEExtraFloat;
+ Movement::ExtraMovementStatusElement extra(&speedVal);
+ extra.Data.floatData = GetSpeed(mtype);
- switch (mtype)
- {
- case MOVE_WALK:
- data.Initialize(SMSG_FORCE_WALK_SPEED_CHANGE, 16);
- break;
- case MOVE_RUN:
- data.Initialize(SMSG_FORCE_RUN_SPEED_CHANGE, 17);
- break;
- case MOVE_RUN_BACK:
- data.Initialize(SMSG_FORCE_RUN_BACK_SPEED_CHANGE, 16);
- break;
- case MOVE_SWIM:
- data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, 16);
- break;
- case MOVE_SWIM_BACK:
- data.Initialize(SMSG_FORCE_SWIM_BACK_SPEED_CHANGE, 16);
- break;
- case MOVE_TURN_RATE:
- data.Initialize(SMSG_FORCE_TURN_RATE_CHANGE, 16);
- break;
- case MOVE_FLIGHT:
- data.Initialize(SMSG_FORCE_FLIGHT_SPEED_CHANGE, 16);
- break;
- case MOVE_FLIGHT_BACK:
- data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16);
- break;
- case MOVE_PITCH_RATE:
- data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16);
- break;
- default:
- TC_LOG_ERROR("entities.unit", "Unit::SetSpeed: Unsupported move type (%d), data not sent to client.", mtype);
- return;
- }
- data.append(GetPackGUID());
- data << (uint32)0; // moveEvent, NUM_PMOVE_EVTS = 0x39
- if (mtype == MOVE_RUN)
- data << uint8(0); // new 2.1.0
- data << float(GetSpeed(mtype));
- SendMessageToSet(&data, true);
- }
+ Movement::PacketSender(this, moveTypeToOpcode[mtype][0], moveTypeToOpcode[mtype][1], moveTypeToOpcode[mtype][2], &extra).Send();
}
void Unit::setDeathState(DeathState s)
@@ -12810,20 +11082,6 @@ int32 Unit::ModSpellDuration(SpellInfo const* spellProto, Unit const* target, in
duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
}
break;
- case SPELLFAMILY_PALADIN:
- if ((spellProto->SpellFamilyFlags[0] & 0x00000002) && spellProto->SpellIconID == 298)
- {
- // Glyph of Blessing of Might
- if (AuraEffect* aurEff = GetAuraEffect(57958, 0))
- duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
- }
- else if ((spellProto->SpellFamilyFlags[0] & 0x00010000) && spellProto->SpellIconID == 306)
- {
- // Glyph of Blessing of Wisdom
- if (AuraEffect* aurEff = GetAuraEffect(57979, 0))
- duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS;
- }
- break;
}
}
return std::max(duration, 0);
@@ -13004,7 +11262,7 @@ uint32 Unit::GetCreatureType() const
if (GetTypeId() == TYPEID_PLAYER)
{
ShapeshiftForm form = GetShapeshiftForm();
- SpellShapeshiftEntry const* ssEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* ssEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (ssEntry && ssEntry->creatureType > 0)
return ssEntry->creatureType;
else
@@ -13028,7 +11286,7 @@ void Unit::SetShapeshiftForm(ShapeshiftForm form)
bool Unit::IsInFeralForm() const
{
ShapeshiftForm form = GetShapeshiftForm();
- return form == FORM_CAT || form == FORM_BEAR || form == FORM_DIREBEAR;
+ return form == FORM_CAT || form == FORM_BEAR;
}
bool Unit::IsInDisallowedMountForm() const
@@ -13084,7 +11342,6 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f
case UNIT_MOD_RAGE:
case UNIT_MOD_FOCUS:
case UNIT_MOD_ENERGY:
- case UNIT_MOD_HAPPINESS:
case UNIT_MOD_RUNE:
case UNIT_MOD_RUNIC_POWER: UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod)); break;
@@ -13204,8 +11461,7 @@ Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const
case UNIT_MOD_RAGE: return POWER_RAGE;
case UNIT_MOD_FOCUS: return POWER_FOCUS;
case UNIT_MOD_ENERGY: return POWER_ENERGY;
- case UNIT_MOD_HAPPINESS: return POWER_HAPPINESS;
- case UNIT_MOD_RUNE: return POWER_RUNE;
+ case UNIT_MOD_RUNE: return POWER_RUNES;
case UNIT_MOD_RUNIC_POWER: return POWER_RUNIC_POWER;
default:
case UNIT_MOD_MANA: return POWER_MANA;
@@ -13216,14 +11472,14 @@ float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const
{
if (attType == RANGED_ATTACK)
{
- int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER_MODS);
+ int32 ap = GetInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER);
if (ap < 0)
return 0.0f;
return ap * (1.0f + GetFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER));
}
else
{
- int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER) + GetInt32Value(UNIT_FIELD_ATTACK_POWER_MODS);
+ int32 ap = GetInt32Value(UNIT_FIELD_ATTACK_POWER);
if (ap < 0)
return 0.0f;
return ap * (1.0f + GetFloatValue(UNIT_FIELD_ATTACK_POWER_MULTIPLIER));
@@ -13318,22 +11574,45 @@ void Unit::SetMaxHealth(uint32 val)
SetHealth(val);
}
-void Unit::SetPower(Powers power, uint32 val)
+int32 Unit::GetPower(Powers power) const
+{
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS)
+ return 0;
+
+ return GetUInt32Value(UNIT_FIELD_POWER1 + powerIndex);
+}
+
+int32 Unit::GetMaxPower(Powers power) const
{
- if (GetPower(power) == val)
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS)
+ return 0;
+
+ return GetInt32Value(UNIT_FIELD_MAXPOWER1 + powerIndex);
+}
+
+void Unit::SetPower(Powers power, int32 val)
+{
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS)
return;
- uint32 maxPower = GetMaxPower(power);
+ int32 maxPower = int32(GetMaxPower(power));
if (maxPower < val)
val = maxPower;
- SetStatInt32Value(UNIT_FIELD_POWER1 + power, val);
+ SetInt32Value(UNIT_FIELD_POWER1 + powerIndex, val);
- WorldPacket data(SMSG_POWER_UPDATE);
- data.append(GetPackGUID());
- data << uint8(power);
- data << uint32(val);
- SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER);
+ if (IsInWorld())
+ {
+ WorldPacket data(SMSG_POWER_UPDATE, 8 + 4 + 1 + 4);
+ data.append(GetPackGUID());
+ data << uint32(1); //power count
+ data << uint8(powerIndex);
+ data << int32(val);
+ SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER);
+ }
// group update
if (Player* player = ToPlayer())
@@ -13349,17 +11628,17 @@ void Unit::SetPower(Powers power, uint32 val)
if (owner && (owner->GetTypeId() == TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
owner->ToPlayer()->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PET_CUR_POWER);
}
-
- // Update the pet's character sheet with happiness damage bonus
- if (pet->getPetType() == HUNTER_PET && power == POWER_HAPPINESS)
- pet->UpdateDamagePhysical(BASE_ATTACK);
}
}
-void Unit::SetMaxPower(Powers power, uint32 val)
+void Unit::SetMaxPower(Powers power, int32 val)
{
- uint32 cur_power = GetPower(power);
- SetStatInt32Value(UNIT_FIELD_MAXPOWER1 + power, val);
+ uint32 powerIndex = GetPowerIndex(power);
+ if (powerIndex == MAX_POWERS)
+ return;
+
+ int32 cur_power = GetPower(power);
+ SetInt32Value(UNIT_FIELD_MAXPOWER1 + powerIndex, val);
// group update
if (GetTypeId() == TYPEID_PLAYER)
@@ -13381,19 +11660,45 @@ void Unit::SetMaxPower(Powers power, uint32 val)
SetPower(power, val);
}
-uint32 Unit::GetCreatePowers(Powers power) const
+uint32 Unit::GetPowerIndex(uint32 powerType) const
+{
+ /// This is here because hunter pets are of the warrior class.
+ /// With the current implementation, the core only gives them
+ /// POWER_RAGE, so we enforce the class to hunter so that they
+ /// effectively get focus power.
+ uint32 classId = getClass();
+ if (ToPet() && ToPet()->getPetType() == HUNTER_PET)
+ classId = CLASS_HUNTER;
+
+ return GetPowerIndexByClass(powerType, classId);
+}
+
+int32 Unit::GetCreatePowers(Powers power) const
{
- // Only hunter pets have POWER_FOCUS and POWER_HAPPINESS
switch (power)
{
- case POWER_MANA: return GetCreateMana();
- case POWER_RAGE: return 1000;
- case POWER_FOCUS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100);
- case POWER_ENERGY: return 100;
- case POWER_HAPPINESS: return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 1050000);
- case POWER_RUNIC_POWER: return 1000;
- case POWER_RUNE: return 0;
- case POWER_HEALTH: return 0;
+ case POWER_MANA:
+ return GetCreateMana();
+ case POWER_RAGE:
+ return 1000;
+ case POWER_FOCUS:
+ if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_HUNTER)
+ return 100;
+ return (GetTypeId() == TYPEID_PLAYER || !((Creature const*)this)->IsPet() || ((Pet const*)this)->getPetType() != HUNTER_PET ? 0 : 100);
+ case POWER_ENERGY:
+ return 100;
+ case POWER_RUNIC_POWER:
+ return 1000;
+ case POWER_RUNES:
+ return 0;
+ case POWER_SOUL_SHARDS:
+ return 3;
+ case POWER_ECLIPSE:
+ return 100;
+ case POWER_HOLY_POWER:
+ return 3;
+ case POWER_HEALTH:
+ return 0;
default:
break;
}
@@ -13819,6 +12124,7 @@ bool InitTriggerAuraData()
isNonTriggerAura[i] = false;
isAlwaysTriggeredAura[i] = false;
}
+ isTriggerAura[SPELL_AURA_PROC_ON_POWER_AMOUNT] = true;
isTriggerAura[SPELL_AURA_DUMMY] = true;
isTriggerAura[SPELL_AURA_MOD_CONFUSE] = true;
isTriggerAura[SPELL_AURA_MOD_THREAT] = true;
@@ -13843,11 +12149,13 @@ bool InitTriggerAuraData()
isTriggerAura[SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN] = true;
isTriggerAura[SPELL_AURA_SPELL_MAGNET] = true;
isTriggerAura[SPELL_AURA_MOD_ATTACK_POWER] = true;
+ isTriggerAura[SPELL_AURA_MOD_POWER_REGEN_PERCENT] = true;
isTriggerAura[SPELL_AURA_ADD_CASTER_HIT_TRIGGER] = true;
isTriggerAura[SPELL_AURA_OVERRIDE_CLASS_SCRIPTS] = true;
isTriggerAura[SPELL_AURA_MOD_MECHANIC_RESISTANCE] = true;
isTriggerAura[SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS] = true;
isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE] = true;
+ isTriggerAura[SPELL_AURA_MOD_MELEE_HASTE_3] = true;
isTriggerAura[SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE] = true;
isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE] = true;
isTriggerAura[SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE] = true;
@@ -13917,19 +12225,6 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
// For melee/ranged based attack need update skills and set some Aura states if victim present
if (procFlag & MELEE_BASED_TRIGGER_MASK && target)
{
- // Update skills here for players
- if (GetTypeId() == TYPEID_PLAYER)
- {
- // On melee based hit/miss/resist need update skill (for victim and attacker)
- if (procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_MISS|PROC_EX_RESIST))
- {
- if (target->GetTypeId() != TYPEID_PLAYER && target->GetCreatureType() != CREATURE_TYPE_CRITTER)
- ToPlayer()->UpdateCombatSkills(target, attType, isVictim);
- }
- // Update defence if player is victim and parry/dodge/block
- else if (isVictim && procExtra & (PROC_EX_DODGE|PROC_EX_PARRY|PROC_EX_BLOCK))
- ToPlayer()->UpdateCombatSkills(target, attType, true);
- }
// If exist crit/parry/dodge/block need update aura state (for victim and attacker)
if (procExtra & (PROC_EX_CRITICAL_HIT|PROC_EX_PARRY|PROC_EX_DODGE|PROC_EX_BLOCK))
{
@@ -14110,6 +12405,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
switch (triggeredByAura->GetAuraType())
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
+ case SPELL_AURA_PROC_TRIGGER_SPELL_2:
{
TC_LOG_DEBUG("spells", "ProcDamageAndSpell: casting spell %u (triggered by %s aura of spell %u)", spellInfo->Id, (isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
// Don`t drop charge or add cooldown for not started trigger
@@ -14135,10 +12431,19 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
takeCharges = true;
break;
}
+ 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;
+ break;
+ }
case SPELL_AURA_OBS_MOD_POWER:
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
+ case SPELL_AURA_MOD_POWER_REGEN_PERCENT:
case SPELL_AURA_MOD_MELEE_HASTE:
+ case SPELL_AURA_MOD_MELEE_HASTE_3:
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());
takeCharges = true;
break;
@@ -14177,7 +12482,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
}
case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK:
// Skip melee hits or instant cast spells
- if (procSpell && procSpell->CalcCastTime() != 0)
+ if (procSpell && procSpell->CalcCastTime(getLevel()) > 0)
takeCharges = true;
break;
case SPELL_AURA_REFLECT_SPELLS_SCHOOL:
@@ -14418,13 +12723,6 @@ void Unit::StopMoving()
init.Stop();
}
-void Unit::SendMovementFlagUpdate(bool self /* = false */)
-{
- WorldPacket data;
- BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, self);
-}
-
bool Unit::IsSitState() const
{
uint8 s = getStandState();
@@ -14608,11 +12906,27 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply
{
ApplyPercentModFloatVar(m_modAttackSpeedPct[att], val, !apply);
ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att, val, !apply);
+
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ if (att == BASE_ATTACK)
+ ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE, val, !apply);
+ else if (att == RANGED_ATTACK)
+ ApplyPercentModFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE, val, !apply);
+ }
}
else
{
ApplyPercentModFloatVar(m_modAttackSpeedPct[att], -val, apply);
ApplyPercentModFloatValue(UNIT_FIELD_BASEATTACKTIME+att, -val, apply);
+
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ if (att == BASE_ATTACK)
+ ApplyPercentModFloatValue(PLAYER_FIELD_MOD_HASTE, -val, apply);
+ else if (att == RANGED_ATTACK)
+ ApplyPercentModFloatValue(PLAYER_FIELD_MOD_RANGED_HASTE, -val, apply);
+ }
}
m_attackTimer[att] = uint32(GetAttackTime(att) * m_modAttackSpeedPct[att] * remainingTimePct);
}
@@ -14620,9 +12934,15 @@ void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply
void Unit::ApplyCastTimePercentMod(float val, bool apply)
{
if (val > 0)
+ {
ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED, val, !apply);
+ ApplyPercentModFloatValue(UNIT_MOD_CAST_HASTE, val, !apply);
+ }
else
+ {
ApplyPercentModFloatValue(UNIT_MOD_CAST_SPEED, -val, apply);
+ ApplyPercentModFloatValue(UNIT_MOD_CAST_HASTE, -val, apply);
+ }
}
uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const
@@ -14680,7 +13000,7 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp
if (overTime > 0 && CastingTime > 0 && DirectDamage)
{
// mainly for DoTs which are 3500 here otherwise
- uint32 OriginalCastTime = spellProto->CalcCastTime();
+ uint32 OriginalCastTime = spellProto->CalcCastTime(getLevel());
if (OriginalCastTime > 7000) OriginalCastTime = 7000;
if (OriginalCastTime < 1500) OriginalCastTime = 1500;
// Portion to Over Time
@@ -14769,7 +13089,7 @@ float Unit::CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffect
DotFactor /= DotTicks;
}
- int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime();
+ int32 CastingTime = spellInfo->IsChanneled() ? spellInfo->GetDuration() : spellInfo->CalcCastTime(getLevel());
// Distribute Damage over multiple effects, reduce by AoE
CastingTime = GetCastingTimeForBonus(spellInfo, damagetype, CastingTime);
@@ -14802,11 +13122,6 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
}
}
-bool Unit::IsUnderLastManaUseEffect() const
-{
- return getMSTimeDiff(m_lastManaUse, getMSTime()) < 5000;
-}
-
void Unit::SetContestedPvP(Player* attackedPlayer)
{
Player* player = GetCharmerOrOwnerPlayerOrPlayerItself();
@@ -15111,6 +13426,21 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
return true;
}
+void Unit::SendDurabilityLoss(Player* receiver, uint32 percent)
+{
+ WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 4);
+ data << uint32(percent);
+ receiver->GetSession()->SendPacket(&data);
+}
+
+void Unit::PlayOneShotAnimKit(uint32 id)
+{
+ WorldPacket data(SMSG_PLAY_ONE_SHOT_ANIM_KIT, 7+2);
+ data.appendPackGUID(GetGUID());
+ data << uint16(id);
+ SendMessageToSet(&data, true);
+}
+
void Unit::Kill(Unit* victim, bool durabilityLoss)
{
// Prevent killing unit twice (and giving reward from kill twice)
@@ -15210,7 +13540,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
// update get killing blow achievements, must be done before setDeathState to be able to require auras on target
// and before Spirit of Redemption as it also removes auras
if (player)
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, victim);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, 0, victim);
// if talent known but not triggered (check priest class for speedup check)
bool spiritOfRedemption = false;
@@ -15266,11 +13596,13 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
// only if not player and not controlled by player pet. And not at BG
if ((durabilityLoss && !player && !victim->ToPlayer()->InBattleground()) || (player && sWorld->getBoolConfig(CONFIG_DURABILITY_LOSS_IN_PVP)))
{
- TC_LOG_DEBUG("entities.unit", "We are dead, losing %f percent durability", sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH));
- plrVictim->DurabilityLossAll(sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH), false);
+ double baseLoss = sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH);
+ uint32 loss = uint32(baseLoss - (baseLoss * plrVictim->GetTotalAuraMultiplier(SPELL_AURA_MOD_DURABILITY_LOSS)));
+ TC_LOG_DEBUG("entities.unit", "We are dead, losing %u percent durability", loss);
+ // Durability loss is calculated more accurately again for each item in Player::DurabilityLoss
+ plrVictim->DurabilityLossAll(baseLoss, false);
// durability lost message
- WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0);
- plrVictim->GetSession()->SendPacket(&data);
+ SendDurabilityLoss(plrVictim, loss);
}
// Call KilledUnit for creatures
if (GetTypeId() == TYPEID_UNIT && IsAIEnabled)
@@ -15451,7 +13783,8 @@ void Unit::SetControlled(bool apply, UnitState state)
if (HasAuraType(SPELL_AURA_MOD_ROOT) || GetVehicle())
return;
- SetRooted(false);
+ if (!HasUnitState(UNIT_STATE_STUNNED))
+ SetRooted(false);
break;
case UNIT_STATE_CONFUSED:
if (HasAuraType(SPELL_AURA_MOD_CONFUSE))
@@ -15493,22 +13826,13 @@ void Unit::SetStunned(bool apply)
SetTarget(0);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
- // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
- // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
- // setting MOVEMENTFLAG_ROOT
- RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
- AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
-
// Creature specific
if (GetTypeId() != TYPEID_PLAYER)
StopMoving();
else
SetStandState(UNIT_STAND_STATE_STAND);
- WorldPacket data(SMSG_FORCE_MOVE_ROOT, 8);
- data.append(GetPackGUID());
- data << uint32(0);
- SendMessageToSet(&data, true);
+ SetRooted(true);
CastStop();
}
@@ -15523,66 +13847,30 @@ void Unit::SetStunned(bool apply)
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
if (!HasUnitState(UNIT_STATE_ROOT)) // prevent moving if it also has root effect
- {
- WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 8+4);
- data.append(GetPackGUID());
- data << uint32(0);
- SendMessageToSet(&data, true);
-
- RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
- }
+ SetRooted(false);
}
}
-void Unit::SetRooted(bool apply)
+void Unit::SetRooted(bool apply, bool packetOnly /*= false*/)
{
- if (apply)
+ if (!packetOnly)
{
- if (m_rootTimes > 0) // blizzard internal check?
- m_rootTimes++;
-
- // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
- // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
- // setting MOVEMENTFLAG_ROOT
- RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
- AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
-
- if (GetTypeId() == TYPEID_PLAYER)
+ if (apply)
{
- WorldPacket data(SMSG_FORCE_MOVE_ROOT, 10);
- data.append(GetPackGUID());
- data << m_rootTimes;
- SendMessageToSet(&data, true);
+ // MOVEMENTFLAG_ROOT cannot be used in conjunction with MOVEMENTFLAG_MASK_MOVING (tested 3.3.5a)
+ // this will freeze clients. That's why we remove MOVEMENTFLAG_MASK_MOVING before
+ // setting MOVEMENTFLAG_ROOT
+ RemoveUnitMovementFlag(MOVEMENTFLAG_MASK_MOVING);
+ AddUnitMovementFlag(MOVEMENTFLAG_ROOT);
}
else
- {
- WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8);
- data.append(GetPackGUID());
- SendMessageToSet(&data, true);
- StopMoving();
- }
- }
- else
- {
- if (!HasUnitState(UNIT_STATE_STUNNED)) // prevent moving if it also has stun effect
- {
- if (GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_FORCE_MOVE_UNROOT, 10);
- data.append(GetPackGUID());
- data << ++m_rootTimes;
- SendMessageToSet(&data, true);
- }
- else
- {
- WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
- data.append(GetPackGUID());
- SendMessageToSet(&data, true);
- }
-
RemoveUnitMovementFlag(MOVEMENTFLAG_ROOT);
- }
}
+
+ if (apply)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_ROOT, SMSG_MOVE_ROOT, SMSG_MOVE_ROOT).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNROOT, SMSG_MOVE_UNROOT, SMSG_MOVE_UNROOT).Send();
}
void Unit::SetFeared(bool apply)
@@ -16119,33 +14407,43 @@ void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack)
aura->SetStackAmount(stack);
}
-void Unit::SendPlaySpellVisual(uint32 id)
-{
- WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 8 + 4);
- data << uint64(GetGUID());
- data << uint32(id); // SpellVisualKit.dbc index
- SendMessageToSet(&data, false);
-}
-
-void Unit::SendPlaySpellImpact(uint64 guid, uint32 id)
-{
- WorldPacket data(SMSG_PLAY_SPELL_IMPACT, 8 + 4);
- data << uint64(guid); // target
- data << uint32(id); // SpellVisualKit.dbc index
- SendMessageToSet(&data, false);
+void Unit::SendPlaySpellVisualKit(uint32 id, uint32 unkParam)
+{
+ ObjectGuid guid = GetGUID();
+
+ WorldPacket data(SMSG_PLAY_SPELL_VISUAL_KIT, 4 + 4+ 4 + 8);
+ data << uint32(0);
+ data << uint32(id); // SpellVisualKit.dbc index
+ data << uint32(unkParam);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.FlushBits();
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[5]);
+ SendMessageToSet(&data, true);
}
-void Unit::ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type) const
+void Unit::ApplyResilience(Unit const* victim, int32* damage) const
{
// player mounted on multi-passenger mount is also classified as vehicle
if (IsVehicle() || (victim->IsVehicle() && victim->GetTypeId() != TYPEID_PLAYER))
return;
- Unit const* source = NULL;
- if (GetTypeId() == TYPEID_PLAYER)
- source = this;
- else if (GetTypeId() == TYPEID_UNIT && GetOwner() && GetOwner()->GetTypeId() == TYPEID_PLAYER)
- source = GetOwner();
+ // Don't consider resilience if not in PvP - player or pet
+ if (!GetCharmerOrOwnerPlayerOrPlayerItself())
+ return;
Unit const* target = NULL;
if (victim->GetTypeId() == TYPEID_PLAYER)
@@ -16156,49 +14454,12 @@ void Unit::ApplyResilience(Unit const* victim, float* crit, int32* damage, bool
if (!target)
return;
- switch (type)
- {
- case CR_CRIT_TAKEN_MELEE:
- // Crit chance reduction works against nonpets
- if (crit)
- *crit -= target->GetMeleeCritChanceReduction();
- if (source && damage)
- {
- if (isCrit)
- *damage -= target->GetMeleeCritDamageReduction(*damage);
- *damage -= target->GetMeleeDamageReduction(*damage);
- }
- break;
- case CR_CRIT_TAKEN_RANGED:
- // Crit chance reduction works against nonpets
- if (crit)
- *crit -= target->GetRangedCritChanceReduction();
- if (source && damage)
- {
- if (isCrit)
- *damage -= target->GetRangedCritDamageReduction(*damage);
- *damage -= target->GetRangedDamageReduction(*damage);
- }
- break;
- case CR_CRIT_TAKEN_SPELL:
- // Crit chance reduction works against nonpets
- if (crit)
- *crit -= target->GetSpellCritChanceReduction();
- if (source && damage)
- {
- if (isCrit)
- *damage -= target->GetSpellCritDamageReduction(*damage);
- *damage -= target->GetSpellDamageReduction(*damage);
- }
- break;
- default:
- break;
- }
+ *damage -= target->GetDamageReduction(*damage);
}
// Melee based spells can be miss, parry or dodge on this step
// Crit or block - determined on damage calculation phase! (and can be both in some time)
-float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const
+float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, uint32 spellId) const
{
//calculate miss chance
float missChance = victim->GetUnitMissChance(attType);
@@ -16206,14 +14467,6 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, i
if (!spellId && haveOffhandWeapon())
missChance += 19;
- // bonus from skills is 0.04%
- //miss_chance -= skillDiff * 0.04f;
- int32 diff = -skillDiff;
- if (victim->GetTypeId() == TYPEID_PLAYER)
- missChance += diff > 0 ? diff * 0.04f : diff * 0.02f;
- else
- missChance += diff > 10 ? 1 + (diff - 10) * 0.4f : diff * 0.1f;
-
// Calculate hit chance
float hitChance = 100.0f;
@@ -16309,6 +14562,42 @@ void Unit::UpdateObjectVisibility(bool forced)
}
}
+void Unit::SendMoveKnockBack(Player* player, float speedXY, float speedZ, float vcos, float vsin)
+{
+ ObjectGuid guid = GetGUID();
+ WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4));
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[4]);
+
+ data.WriteByteSeq(guid[1]);
+
+ data << float(vsin);
+ data << uint32(0);
+
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[7]);
+
+ data << float(speedXY);
+
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[3]);
+
+ data << float(speedZ);
+ data << float(vcos);
+
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[0]);
+
+ player->GetSession()->SendPacket(&data);
+}
+
void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
{
Player* player = ToPlayer();
@@ -16323,23 +14612,12 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
}
if (!player)
- {
GetMotionMaster()->MoveKnockbackFrom(x, y, speedXY, speedZ);
- }
else
{
float vcos, vsin;
GetSinCos(x, y, vsin, vcos);
-
- WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
- data.append(GetPackGUID());
- data << uint32(0); // counter
- data << float(vcos); // x direction
- data << float(vsin); // y direction
- data << float(speedXY); // Horizontal speed
- data << float(-speedZ); // Z Movement speed (vertical)
-
- player->GetSession()->SendPacket(&data);
+ SendMoveKnockBack(player, speedXY, -speedZ, vcos, vsin);
}
}
@@ -16389,6 +14667,72 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
return 892;
}
}
+ else if (getRace() == RACE_TROLL)
+ {
+ uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
+ switch (hairColor)
+ {
+ case 0: // Red
+ case 1:
+ return 33668;
+ case 2: // Yellow
+ case 3:
+ return 33667;
+ case 4: // Blue
+ case 5:
+ case 6:
+ return 33666;
+ case 7: // Purple
+ case 10:
+ return 33665;
+ default: // original - white
+ return 33669;
+ }
+ }
+ else if (getRace() == RACE_WORGEN)
+ {
+ // Based on Skin color
+ uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
+ // Male
+ if (getGender() == GENDER_MALE)
+ {
+ switch (skinColor)
+ {
+ case 1: // Brown
+ return 33662;
+ case 2: // Black
+ case 7:
+ return 33661;
+ case 4: // yellow
+ return 33664;
+ case 3: // White
+ case 5:
+ return 33663;
+ default: // original - Gray
+ return 33660;
+ }
+ }
+ // Female
+ else
+ {
+ switch (skinColor)
+ {
+ case 5: // Brown
+ case 6:
+ return 33662;
+ case 7: // Black
+ case 8:
+ return 33661;
+ case 3: // yellow
+ case 4:
+ return 33664;
+ case 2: // White
+ return 33663;
+ default: // original - Gray
+ return 33660;
+ }
+ }
+ }
// Based on Skin color
else if (getRace() == RACE_TAUREN)
{
@@ -16423,30 +14767,32 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
}
}
// Female
- else switch (skinColor)
+ else
{
- case 10: // White
- return 29409;
- case 6: // Light Brown
- case 7:
- return 29410;
- case 4: // Brown
- case 5:
- return 29411;
- case 0: // Dark
- case 1:
- case 2:
- case 3:
- return 29412;
- default: // original - Grey
- return 8571;
+ switch (skinColor)
+ {
+ case 10: // White
+ return 29409;
+ case 6: // Light Brown
+ case 7:
+ return 29410;
+ case 4: // Brown
+ case 5:
+ return 29411;
+ case 0: // Dark
+ case 1:
+ case 2:
+ case 3:
+ return 29412;
+ default: // original - Grey
+ return 8571;
+ }
}
}
else if (Player::TeamForRace(getRace()) == ALLIANCE)
return 892;
else
return 8571;
- case FORM_DIREBEAR:
case FORM_BEAR:
// Based on Hair color
if (getRace() == RACE_NIGHTELF)
@@ -16468,6 +14814,73 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
return 2281;
}
}
+ else if (getRace() == RACE_TROLL)
+ {
+ uint8 hairColor = GetByteValue(PLAYER_BYTES, 3);
+ switch (hairColor)
+ {
+ case 0: // Red
+ case 1:
+ return 33657;
+ case 2: // Yellow
+ case 3:
+ return 33659;
+ case 7: // Purple
+ case 10:
+ return 33656;
+ case 8: // White
+ case 9:
+ case 11:
+ case 12:
+ return 33658;
+ default: // original - Blue
+ return 33655;
+ }
+ }
+ else if (getRace() == RACE_WORGEN)
+ {
+ // Based on Skin color
+ uint8 skinColor = GetByteValue(PLAYER_BYTES, 0);
+ // Male
+ if (getGender() == GENDER_MALE)
+ {
+ switch (skinColor)
+ {
+ case 1: // Brown
+ return 33652;
+ case 2: // Black
+ case 7:
+ return 33651;
+ case 4: // Yellow
+ return 33653;
+ case 3: // White
+ case 5:
+ return 33654;
+ default: // original - Gray
+ return 33650;
+ }
+ }
+ // Female
+ else
+ {
+ switch (skinColor)
+ {
+ case 5: // Brown
+ case 6:
+ return 33652;
+ case 7: // Black
+ case 8:
+ return 33651;
+ case 3: // yellow
+ case 4:
+ return 33654;
+ case 2: // White
+ return 33653;
+ default: // original - Gray
+ return 33650;
+ }
+ }
+ }
// Based on Skin color
else if (getRace() == RACE_TAUREN)
{
@@ -16502,23 +14915,26 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
}
}
// Female
- else switch (skinColor)
+ else
{
- case 0: // Dark (Black)
- case 1:
- return 29418;
- case 2: // White
- case 3:
- return 29419;
- case 6: // Light Brown/Grey
- case 7:
- case 8:
- case 9:
- return 29420;
- case 10: // Completly White
- return 29421;
- default: // original - Brown
- return 2289;
+ switch (skinColor)
+ {
+ case 0: // Dark (Black)
+ case 1:
+ return 29418;
+ case 2: // White
+ case 3:
+ return 29419;
+ case 6: // Light Brown/Grey
+ case 7:
+ case 8:
+ case 9:
+ return 29420;
+ case 10: // Completly White
+ return 29421;
+ default: // original - Brown
+ return 2289;
+ }
}
}
else if (Player::TeamForRace(getRace()) == ALLIANCE)
@@ -16531,15 +14947,25 @@ uint32 Unit::GetModelForForm(ShapeshiftForm form) const
return 20872;
case FORM_FLIGHT_EPIC:
if (Player::TeamForRace(getRace()) == ALLIANCE)
- return 21243;
+ return (getRace() == RACE_WORGEN ? 37729 : 21243);
+ if (getRace() == RACE_TROLL)
+ return 37730;
return 21244;
+ case FORM_MOONKIN:
+ if (getRace() == RACE_TROLL)
+ return 37174;
+ if (getRace() == RACE_WORGEN)
+ return 37173;
+ case FORM_GHOSTWOLF:
+ if (HasAura(58135)) //! Glyph of Arctic Wolf
+ return 27312;
default:
break;
}
}
uint32 modelid = 0;
- SpellShapeshiftEntry const* formEntry = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* formEntry = sSpellShapeshiftFormStore.LookupEntry(form);
if (formEntry && formEntry->modelID_A)
{
// Take the alliance modelid as default
@@ -16640,6 +15066,21 @@ uint32 Unit::GetModelForTotem(PlayerTotemType totemType)
}
break;
}
+ case RACE_GOBLIN:
+ {
+ switch (totemType)
+ {
+ case SUMMON_TYPE_TOTEM_FIRE: // fire
+ return 30783;
+ case SUMMON_TYPE_TOTEM_EARTH: // earth
+ return 30782;
+ case SUMMON_TYPE_TOTEM_WATER: // water
+ return 30784;
+ case SUMMON_TYPE_TOTEM_AIR: // air
+ return 30781;
+ }
+ break;
+ }
}
return 0;
}
@@ -16653,16 +15094,7 @@ void Unit::JumpTo(float speedXY, float speedZ, bool forward)
{
float vcos = std::cos(angle+GetOrientation());
float vsin = std::sin(angle+GetOrientation());
-
- WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4));
- data.append(GetPackGUID());
- data << uint32(0); // Sequence
- data << float(vcos); // x direction
- data << float(vsin); // y direction
- data << float(speedXY); // Horizontal speed
- data << float(-speedZ); // Z Movement speed (vertical)
-
- ToPlayer()->GetSession()->SendPacket(&data);
+ SendMoveKnockBack(ToPlayer(), speedXY, -speedZ, vcos, vsin);
}
}
@@ -16869,12 +15301,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
if (player)
player->SetFallInformation(0, GetPositionZ());
- else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
- {
- WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
- data.append(GetPackGUID());
- SendMessageToSet(&data, false);
- }
float height = pos.GetPositionZ();
@@ -16907,58 +15333,6 @@ void Unit::_ExitVehicle(Position const* exitPosition)
}
}
-void Unit::BuildMovementPacket(ByteBuffer *data) const
-{
- *data << uint32(GetUnitMovementFlags()); // movement flags
- *data << uint16(GetExtraUnitMovementFlags()); // 2.3.0
- *data << uint32(getMSTime()); // time / counter
- *data << GetPositionX();
- *data << GetPositionY();
- *data << GetPositionZMinusOffset();
- *data << GetOrientation();
-
- // 0x00000200
- if (GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT)
- {
- if (m_vehicle)
- data->append(m_vehicle->GetBase()->GetPackGUID());
- else if (GetTransport())
- data->append(GetTransport()->GetPackGUID());
- else
- *data << (uint8)0;
-
- *data << float (GetTransOffsetX());
- *data << float (GetTransOffsetY());
- *data << float (GetTransOffsetZ());
- *data << float (GetTransOffsetO());
- *data << uint32(GetTransTime());
- *data << uint8 (GetTransSeat());
-
- if (GetExtraUnitMovementFlags() & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT)
- *data << uint32(m_movementInfo.transport.time2);
- }
-
- // 0x02200000
- if ((GetUnitMovementFlags() & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING))
- || (m_movementInfo.flags2 & MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
- *data << (float)m_movementInfo.pitch;
-
- *data << (uint32)m_movementInfo.fallTime;
-
- // 0x00001000
- if (GetUnitMovementFlags() & MOVEMENTFLAG_FALLING)
- {
- *data << (float)m_movementInfo.jump.zspeed;
- *data << (float)m_movementInfo.jump.sinAngle;
- *data << (float)m_movementInfo.jump.cosAngle;
- *data << (float)m_movementInfo.jump.xyspeed;
- }
-
- // 0x04000000
- if (GetUnitMovementFlags() & MOVEMENTFLAG_SPLINE_ELEVATION)
- *data << (float)m_movementInfo.splineElevation;
-}
-
bool Unit::IsFalling() const
{
return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR) || movespline->isFalling();
@@ -16978,20 +15352,304 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas
}
}
+void Unit::WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusElement* extras /*= NULL*/)
+{
+ MovementInfo const& mi = m_movementInfo;
+
+ bool hasMovementFlags = GetUnitMovementFlags() != 0;
+ bool hasMovementFlags2 = GetExtraUnitMovementFlags() != 0;
+ bool hasTimestamp = true;
+ bool hasOrientation = !G3D::fuzzyEq(GetOrientation(), 0.0f);
+ bool hasTransportData = GetTransGUID() != 0;
+ bool hasSpline = IsSplineEnabled();
+
+ bool hasTransportTime2 = hasTransportData && m_movementInfo.transport.time2 != 0;
+ bool hasTransportTime3 = false;
+ bool hasPitch = HasUnitMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || HasExtraUnitMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING);
+ bool hasFallDirection = HasUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ bool hasFallData = hasFallDirection || m_movementInfo.jump.fallTime != 0;
+ bool hasSplineElevation = HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION);
+
+ MovementStatusElements const* sequence = GetMovementStatusElementsSequence(data.GetOpcode());
+ if (!sequence)
+ {
+ TC_LOG_ERROR("network", "Unit::WriteMovementInfo: No movement sequence found for opcode %s", GetOpcodeNameForLogging(data.GetOpcode()).c_str());
+ return;
+ }
+
+ ObjectGuid guid = GetGUID();
+ ObjectGuid tguid = hasTransportData ? GetTransGUID() : 0;
+
+ for (; *sequence != MSEEnd; ++sequence)
+ {
+ MovementStatusElements const& element = *sequence;
+
+ switch (element)
+ {
+ case MSEHasGuidByte0:
+ case MSEHasGuidByte1:
+ case MSEHasGuidByte2:
+ case MSEHasGuidByte3:
+ case MSEHasGuidByte4:
+ case MSEHasGuidByte5:
+ case MSEHasGuidByte6:
+ case MSEHasGuidByte7:
+ data.WriteBit(guid[element - MSEHasGuidByte0]);
+ break;
+ case MSEHasTransportGuidByte0:
+ case MSEHasTransportGuidByte1:
+ case MSEHasTransportGuidByte2:
+ case MSEHasTransportGuidByte3:
+ case MSEHasTransportGuidByte4:
+ case MSEHasTransportGuidByte5:
+ case MSEHasTransportGuidByte6:
+ case MSEHasTransportGuidByte7:
+ if (hasTransportData)
+ data.WriteBit(tguid[element - MSEHasTransportGuidByte0]);
+ break;
+ case MSEGuidByte0:
+ case MSEGuidByte1:
+ case MSEGuidByte2:
+ case MSEGuidByte3:
+ case MSEGuidByte4:
+ case MSEGuidByte5:
+ case MSEGuidByte6:
+ case MSEGuidByte7:
+ data.WriteByteSeq(guid[element - MSEGuidByte0]);
+ break;
+ case MSETransportGuidByte0:
+ case MSETransportGuidByte1:
+ case MSETransportGuidByte2:
+ case MSETransportGuidByte3:
+ case MSETransportGuidByte4:
+ case MSETransportGuidByte5:
+ case MSETransportGuidByte6:
+ case MSETransportGuidByte7:
+ if (hasTransportData)
+ data.WriteByteSeq(tguid[element - MSETransportGuidByte0]);
+ break;
+ case MSEHasMovementFlags:
+ data.WriteBit(!hasMovementFlags);
+ break;
+ case MSEHasMovementFlags2:
+ data.WriteBit(!hasMovementFlags2);
+ break;
+ case MSEHasTimestamp:
+ data.WriteBit(!hasTimestamp);
+ break;
+ case MSEHasOrientation:
+ data.WriteBit(!hasOrientation);
+ break;
+ case MSEHasTransportData:
+ data.WriteBit(hasTransportData);
+ break;
+ case MSEHasTransportTime2:
+ if (hasTransportData)
+ data.WriteBit(hasTransportTime2);
+ break;
+ case MSEHasTransportTime3:
+ if (hasTransportData)
+ data.WriteBit(hasTransportTime3);
+ break;
+ case MSEHasPitch:
+ data.WriteBit(!hasPitch);
+ break;
+ case MSEHasFallData:
+ data.WriteBit(hasFallData);
+ break;
+ case MSEHasFallDirection:
+ if (hasFallData)
+ data.WriteBit(hasFallDirection);
+ break;
+ case MSEHasSplineElevation:
+ data.WriteBit(!hasSplineElevation);
+ break;
+ case MSEHasSpline:
+ data.WriteBit(hasSpline);
+ break;
+ case MSEMovementFlags:
+ if (hasMovementFlags)
+ data.WriteBits(GetUnitMovementFlags(), 30);
+ break;
+ case MSEMovementFlags2:
+ if (hasMovementFlags2)
+ data.WriteBits(GetExtraUnitMovementFlags(), 12);
+ break;
+ case MSETimestamp:
+ if (hasTimestamp)
+ data << getMSTime();
+ break;
+ case MSEPositionX:
+ data << GetPositionX();
+ break;
+ case MSEPositionY:
+ data << GetPositionY();
+ break;
+ case MSEPositionZ:
+ data << GetPositionZ();
+ break;
+ case MSEOrientation:
+ if (hasOrientation)
+ data << GetOrientation();
+ break;
+ case MSETransportPositionX:
+ if (hasTransportData)
+ data << GetTransOffsetX();
+ break;
+ case MSETransportPositionY:
+ if (hasTransportData)
+ data << GetTransOffsetY();
+ break;
+ case MSETransportPositionZ:
+ if (hasTransportData)
+ data << GetTransOffsetZ();
+ break;
+ case MSETransportOrientation:
+ if (hasTransportData)
+ data << GetTransOffsetO();
+ break;
+ case MSETransportSeat:
+ if (hasTransportData)
+ data << GetTransSeat();
+ break;
+ case MSETransportTime:
+ if (hasTransportData)
+ data << GetTransTime();
+ break;
+ case MSETransportTime2:
+ if (hasTransportData && hasTransportTime2)
+ data << mi.transport.time2;
+ break;
+ case MSETransportTime3:
+ if (hasTransportData && hasTransportTime3)
+ data << mi.transport.time3;
+ break;
+ case MSEPitch:
+ if (hasPitch)
+ data << mi.pitch;
+ break;
+ case MSEFallTime:
+ if (hasFallData)
+ data << mi.jump.fallTime;
+ break;
+ case MSEFallVerticalSpeed:
+ if (hasFallData)
+ data << mi.jump.zspeed;
+ break;
+ case MSEFallCosAngle:
+ if (hasFallData && hasFallDirection)
+ data << mi.jump.cosAngle;
+ break;
+ case MSEFallSinAngle:
+ if (hasFallData && hasFallDirection)
+ data << mi.jump.sinAngle;
+ break;
+ case MSEFallHorizontalSpeed:
+ if (hasFallData && hasFallDirection)
+ data << mi.jump.xyspeed;
+ break;
+ case MSESplineElevation:
+ if (hasSplineElevation)
+ data << mi.splineElevation;
+ break;
+ case MSECounter:
+ data << m_movementCounter++;
+ break;
+ case MSEZeroBit:
+ data.WriteBit(0);
+ break;
+ case MSEOneBit:
+ data.WriteBit(1);
+ break;
+ case MSEExtraElement:
+ extras->WriteNextElement(data);
+ break;
+ default:
+ ASSERT(Movement::PrintInvalidSequenceElement(element, __FUNCTION__));
+ break;
+ }
+ }
+}
+
void Unit::SendTeleportPacket(Position& pos)
{
- Position oldPos = { GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation() };
- if (GetTypeId() == TYPEID_UNIT)
- Relocate(&pos);
+ // SMSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport
+ // MSG_MOVE_TELEPORT is sent to self in order to trigger MSG_MOVE_TELEPORT_ACK and update the position server side
+
+ // This oldPos actually contains the destination position if the Unit is a Player.
+ Position oldPos = {GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), GetOrientation()};
- WorldPacket data2(MSG_MOVE_TELEPORT, 38);
- data2.append(GetPackGUID());
- BuildMovementPacket(&data2);
if (GetTypeId() == TYPEID_UNIT)
- Relocate(&oldPos);
+ 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);
+
+ 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(uint64(transGuid));
+ data2.WriteBit(guid[1]);
+ if (transGuid)
+ {
+ 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();
+
+ if (transGuid)
+ {
+ 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.
+ }
+
+ // Relocate the player/creature to its old position, so we can broadcast to nearby players correctly
if (GetTypeId() == TYPEID_PLAYER)
Relocate(&pos);
- SendMessageToSet(&data2, false);
+ else
+ Relocate(&oldPos);
+
+ // Broadcast the packet to everyone except self.
+ SendMessageToSet(&data, false);
}
bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool teleport)
@@ -17055,7 +15713,7 @@ void Unit::SendThreatListUpdate()
{
uint32 count = getThreatManager().getThreatList().size();
- //TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message");
+ TC_LOG_DEBUG("entities.unit", "WORLD: Send SMSG_THREAT_UPDATE Message");
WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8);
data.append(GetPackGUID());
data << uint32(count);
@@ -17107,27 +15765,22 @@ void Unit::SendRemoveFromThreatListOpcode(HostileReference* pHostileReference)
SendMessageToSet(&data, false);
}
-void Unit::RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker)
+// baseRage means damage taken when attacker = false
+void Unit::RewardRage(uint32 baseRage, bool attacker)
{
float addRage;
- float rageconversion = ((0.0091107836f * getLevel() * getLevel()) + 3.225598133f * getLevel()) + 4.2652911f;
-
- // Unknown if correct, but lineary adjust rage conversion above level 70
- if (getLevel() > 70)
- rageconversion += 13.27f * (getLevel() - 70);
-
if (attacker)
{
- addRage = (damage / rageconversion * 7.5f + weaponSpeedHitFactor) / 2;
-
+ addRage = baseRage;
// talent who gave more rage on attack
AddPct(addRage, GetTotalAuraModifier(SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT));
}
else
{
- addRage = damage / rageconversion * 2.5f;
-
+ // Calculate rage from health and damage taken
+ //! ToDo: Check formula
+ addRage = floor(0.5f + (25.7f * baseRage / GetMaxHealth()));
// Berserker Rage effect
if (HasAura(18499))
addRage *= 2.0f;
@@ -17323,7 +15976,7 @@ void Unit::SetFacingTo(float ori)
{
Movement::MoveSplineInit init(this);
init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset(), false);
- if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && GetTransGUID())
+ if (GetTransport())
init.DisableTransportPathTransformations(); // It makes no sense to target global orientation
init.SetFacing(ori);
init.Launch();
@@ -17352,28 +16005,56 @@ bool Unit::SetWalk(bool enable)
else
RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ ///@ TODO: Find proper opcode for walk mode setting in player mind controlling a player case
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WALK_MODE, SMSG_SPLINE_MOVE_SET_WALK_MODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_RUN_MODE, SMSG_SPLINE_MOVE_SET_RUN_MODE).Send();
+
return true;
}
-bool Unit::SetDisableGravity(bool disable, bool /*packetOnly = false*/)
+bool Unit::SetDisableGravity(bool disable, bool packetOnly /*= false*/)
{
- if (disable == IsLevitating())
- return false;
-
- if (disable)
+ if (!packetOnly)
{
- AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ if (disable == IsLevitating())
+ return false;
+
+ if (disable)
+ {
+ AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
+ SetFall(false);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
+ if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
+ SetFall(true);
+ }
}
+
+ if (disable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_DISABLE, SMSG_MOVE_GRAVITY_DISABLE).Send();
else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_GRAVITY_ENABLE, SMSG_MOVE_GRAVITY_ENABLE).Send();
+
+ return true;
+}
+
+bool Unit::SetFall(bool enable)
+{
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING))
+ return false;
+
+ if (enable)
{
- RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- if (!HasUnitMovementFlag(MOVEMENTFLAG_CAN_FLY))
- {
- m_movementInfo.SetFallTime(0);
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- }
+ AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ m_movementInfo.SetFallTime(0);
}
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR);
return true;
}
@@ -17388,6 +16069,11 @@ bool Unit::SetSwim(bool enable)
else
RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_START_SWIM, NULL_OPCODE).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_STOP_SWIM, NULL_OPCODE).Send();
+
return true;
}
@@ -17399,90 +16085,161 @@ bool Unit::SetCanFly(bool enable)
if (enable)
{
AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
- RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING);
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_SPLINE_ELEVATION);
+ SetFall(false);
}
else
{
RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_MASK_MOVING_FLY);
if (!IsLevitating())
- {
- m_movementInfo.SetFallTime(0);
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- }
+ SetFall(true);
}
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FLYING, SMSG_MOVE_SET_CAN_FLY).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_FLYING, SMSG_MOVE_UNSET_CAN_FLY).Send();
+
return true;
}
-bool Unit::SetWaterWalking(bool enable, bool /*packetOnly = false */)
+bool Unit::SetWaterWalking(bool enable, bool packetOnly /*= false */)
{
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
- return false;
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ }
if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_WATER_WALK, SMSG_MOVE_WATER_WALK).Send();
else
- RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_LAND_WALK, SMSG_MOVE_LAND_WALK).Send();
return true;
}
-bool Unit::SetFeatherFall(bool enable, bool /*packetOnly = false */)
+bool Unit::SetFeatherFall(bool enable, bool packetOnly /*= false */)
{
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
- return false;
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW))
+ return false;
+
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ }
if (enable)
- AddUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_FEATHER_FALL, SMSG_MOVE_FEATHER_FALL).Send();
else
- RemoveUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_NORMAL_FALL, SMSG_MOVE_NORMAL_FALL).Send();
return true;
}
-bool Unit::SetHover(bool enable, bool /*packetOnly = false*/)
+bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
{
- if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
- return false;
+ if (!packetOnly)
+ {
+ if (enable == HasUnitMovementFlag(MOVEMENTFLAG_HOVER))
+ return false;
- float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
+ float hoverHeight = GetFloatValue(UNIT_FIELD_HOVERHEIGHT);
- if (enable)
- {
- //! No need to check height on ascent
- AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (hoverHeight)
- UpdateHeight(GetPositionZ() + hoverHeight);
- }
- else
- {
- RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
- if (hoverHeight)
+ if (enable)
{
- float newZ = GetPositionZ() - hoverHeight;
- UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
- UpdateHeight(newZ);
+ //! No need to check height on ascent
+ AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (hoverHeight)
+ UpdateHeight(GetPositionZ() + hoverHeight);
+ }
+ else
+ {
+ RemoveUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ if (hoverHeight)
+ {
+ float newZ = GetPositionZ() - hoverHeight;
+ UpdateAllowedPositionZ(GetPositionX(), GetPositionY(), newZ);
+ UpdateHeight(newZ);
+ }
}
}
+ if (enable)
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_SET_HOVER, SMSG_MOVE_SET_HOVER).Send();
+ else
+ Movement::PacketSender(this, SMSG_SPLINE_MOVE_UNSET_HOVER, SMSG_MOVE_UNSET_HOVER).Send();
+
return true;
}
+void Unit::SendSetPlayHoverAnim(bool enable)
+{
+ ObjectGuid guid = GetGUID();
+ WorldPacket data(SMSG_SET_PLAY_HOVER_ANIM, 10);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(enable);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[6]);
+
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[6]);
+
+ SendMessageToSet(&data, true);
+}
+
+void Unit::SendMovementSetSplineAnim(Movement::AnimType anim)
+{
+ WorldPacket data(SMSG_SPLINE_MOVE_SET_ANIM, 8 + 4);
+ data.append(GetPackGUID());
+ data << uint32(anim);
+ SendMessageToSet(&data, false);
+}
+
+bool Unit::IsSplineEnabled() const
+{
+ return movespline->Initialized() && !movespline->Finalized();
+}
+
+
void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
{
if (!target)
return;
ByteBuffer fieldBuffer;
-
UpdateMask updateMask;
- updateMask.SetCount(m_valuesCount);
+
+ uint32 valCount = m_valuesCount;
uint32* flags = UnitUpdateFieldFlags;
uint32 visibleFlag = UF_FLAG_PUBLIC;
if (target == this)
visibleFlag |= UF_FLAG_PRIVATE;
+ else if (GetTypeId() == TYPEID_PLAYER)
+ valCount = PLAYER_END_NOT_SELF;
+
+ updateMask.SetCount(valCount);
Player* plr = GetCharmerOrOwnerPlayerOrPlayerItself();
if (GetOwnerGUID() == target->GetGUID())
@@ -17496,7 +16253,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target)
visibleFlag |= UF_FLAG_PARTY_MEMBER;
Creature const* creature = ToCreature();
- for (uint16 index = 0; index < m_valuesCount; ++index)
+ for (uint16 index = 0; index < valCount; ++index)
{
if (_fieldNotifyFlags & flags[index] ||
((flags[index] & visibleFlag) & UF_FLAG_SPECIAL_INFO) ||
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 41b181e54f8..ac892373a86 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -28,6 +28,7 @@
#include "Object.h"
#include "SpellAuraDefines.h"
#include "ThreatManager.h"
+#include "MoveSplineInit.h"
#define WORLD_TRIGGER 12999
@@ -210,7 +211,7 @@ enum ShapeshiftForm
FORM_BEAR = 0x05,
FORM_AMBIENT = 0x06,
FORM_GHOUL = 0x07,
- FORM_DIREBEAR = 0x08,
+ FORM_DIREBEAR = 0x08, // Removed in 4.0.1
FORM_STEVES_GHOUL = 0x09,
FORM_THARONJA_SKELETON = 0x0A,
FORM_TEST_OF_STRENGTH = 0x0B,
@@ -354,6 +355,11 @@ class Vehicle;
class VehicleJoinEvent;
class TransportBase;
class SpellCastTargets;
+namespace Movement
+{
+ class ExtraMovementStatusElement;
+ class MoveSpline;
+}
typedef std::list<Unit*> UnitList;
typedef std::list< std::pair<Aura*, uint8> > DispelChargesList;
@@ -418,6 +424,7 @@ enum TriggerCastFlags
TRIGGERED_DISALLOW_PROC_EVENTS = 0x00020000, //! Disallows proc events from triggered spell (default)
TRIGGERED_DONT_REPORT_CAST_ERROR = 0x00040000, //! Will return SPELL_FAILED_DONT_REPORT in CheckCast functions
TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT = 0x00080000, //! Will ignore equipped item requirements
+ TRIGGERED_IGNORE_TARGET_CHECK = 0x00100000, //! Will ignore most target checks (mostly DBC target checks)
TRIGGERED_FULL_MASK = 0xFFFFFFFF
};
@@ -433,9 +440,13 @@ enum UnitMods
UNIT_MOD_RAGE,
UNIT_MOD_FOCUS,
UNIT_MOD_ENERGY,
- UNIT_MOD_HAPPINESS,
+ UNIT_MOD_UNUSED, // Old UNIT_MOD_HAPPINESS
UNIT_MOD_RUNE,
UNIT_MOD_RUNIC_POWER,
+ UNIT_MOD_SOUL_SHARDS,
+ UNIT_MOD_ECLIPSE,
+ UNIT_MOD_HOLY_POWER,
+ UNIT_MOD_ALTERNATIVE,
UNIT_MOD_ARMOR, // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum.
UNIT_MOD_RESISTANCE_HOLY,
UNIT_MOD_RESISTANCE_FIRE,
@@ -455,7 +466,7 @@ enum UnitMods
UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,
UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,
UNIT_MOD_POWER_START = UNIT_MOD_MANA,
- UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1
+ UNIT_MOD_POWER_END = UNIT_MOD_ALTERNATIVE + 1
};
enum BaseModGroup
@@ -554,34 +565,35 @@ enum WeaponAttackType
enum CombatRating
{
- CR_WEAPON_SKILL = 0,
- CR_DEFENSE_SKILL = 1,
- CR_DODGE = 2,
- CR_PARRY = 3,
- CR_BLOCK = 4,
- CR_HIT_MELEE = 5,
- CR_HIT_RANGED = 6,
- CR_HIT_SPELL = 7,
- CR_CRIT_MELEE = 8,
- CR_CRIT_RANGED = 9,
- CR_CRIT_SPELL = 10,
- CR_HIT_TAKEN_MELEE = 11,
- CR_HIT_TAKEN_RANGED = 12,
- CR_HIT_TAKEN_SPELL = 13,
- CR_CRIT_TAKEN_MELEE = 14,
- CR_CRIT_TAKEN_RANGED = 15,
- CR_CRIT_TAKEN_SPELL = 16,
- CR_HASTE_MELEE = 17,
- CR_HASTE_RANGED = 18,
- CR_HASTE_SPELL = 19,
- CR_WEAPON_SKILL_MAINHAND = 20,
- CR_WEAPON_SKILL_OFFHAND = 21,
- CR_WEAPON_SKILL_RANGED = 22,
- CR_EXPERTISE = 23,
- CR_ARMOR_PENETRATION = 24
-};
-
-#define MAX_COMBAT_RATING 25
+ CR_WEAPON_SKILL = 0,
+ CR_DEFENSE_SKILL = 1, // Removed in 4.0.1
+ CR_DODGE = 2,
+ CR_PARRY = 3,
+ CR_BLOCK = 4,
+ CR_HIT_MELEE = 5,
+ CR_HIT_RANGED = 6,
+ CR_HIT_SPELL = 7,
+ CR_CRIT_MELEE = 8,
+ CR_CRIT_RANGED = 9,
+ CR_CRIT_SPELL = 10,
+ CR_HIT_TAKEN_MELEE = 11, // Deprecated since Cataclysm
+ CR_HIT_TAKEN_RANGED = 12, // Deprecated since Cataclysm
+ CR_HIT_TAKEN_SPELL = 13, // Deprecated since Cataclysm
+ CR_RESILIENCE_CRIT_TAKEN = 14,
+ CR_RESILIENCE_PLAYER_DAMAGE_TAKEN = 15,
+ CR_CRIT_TAKEN_SPELL = 16, // Deprecated since Cataclysm
+ CR_HASTE_MELEE = 17,
+ CR_HASTE_RANGED = 18,
+ CR_HASTE_SPELL = 19,
+ CR_WEAPON_SKILL_MAINHAND = 20,
+ CR_WEAPON_SKILL_OFFHAND = 21,
+ CR_WEAPON_SKILL_RANGED = 22,
+ CR_EXPERTISE = 23,
+ CR_ARMOR_PENETRATION = 24,
+ CR_MASTERY = 25,
+};
+
+#define MAX_COMBAT_RATING 26
enum DamageEffectType
{
@@ -659,7 +671,7 @@ enum NPCFlags
{
UNIT_NPC_FLAG_NONE = 0x00000000,
UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100%
- UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok
+ UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // 100%
UNIT_NPC_FLAG_UNK1 = 0x00000004,
UNIT_NPC_FLAG_UNK2 = 0x00000008,
UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100%
@@ -684,7 +696,10 @@ enum NPCFlags
UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode
UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click)
UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set
- UNIT_NPC_FLAG_MAILBOX = 0x04000000 //
+ UNIT_NPC_FLAG_MAILBOX = 0x04000000, // mailbox
+ UNIT_NPC_FLAG_REFORGER = 0x08000000, // reforging
+ UNIT_NPC_FLAG_TRANSMOGRIFIER = 0x10000000, // transmogrification
+ UNIT_NPC_FLAG_VAULTKEEPER = 0x20000000 // void storage
};
enum MovementFlags
@@ -699,28 +714,27 @@ enum MovementFlags
MOVEMENTFLAG_PITCH_UP = 0x00000040,
MOVEMENTFLAG_PITCH_DOWN = 0x00000080,
MOVEMENTFLAG_WALKING = 0x00000100, // Walking
- MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures
- MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible.
- MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING
- MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling
- MOVEMENTFLAG_FALLING_FAR = 0x00002000,
- MOVEMENTFLAG_PENDING_STOP = 0x00004000,
- MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000,
- MOVEMENTFLAG_PENDING_FORWARD = 0x00010000,
- MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000,
- MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000,
- MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000,
- MOVEMENTFLAG_PENDING_ROOT = 0x00100000,
- MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also
- MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying
- MOVEMENTFLAG_DESCENDING = 0x00800000,
- MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk
- MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity
- MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths
- MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths
- MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water
- MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive)
- MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump
+ MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000200, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible.
+ MOVEMENTFLAG_ROOT = 0x00000400, // Must not be set along with MOVEMENTFLAG_MASK_MOVING
+ MOVEMENTFLAG_FALLING = 0x00000800, // damage dealt on that type of falling
+ MOVEMENTFLAG_FALLING_FAR = 0x00001000,
+ MOVEMENTFLAG_PENDING_STOP = 0x00002000,
+ MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00004000,
+ MOVEMENTFLAG_PENDING_FORWARD = 0x00008000,
+ MOVEMENTFLAG_PENDING_BACKWARD = 0x00010000,
+ MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00020000,
+ MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00040000,
+ MOVEMENTFLAG_PENDING_ROOT = 0x00080000,
+ MOVEMENTFLAG_SWIMMING = 0x00100000, // appears with fly flag also
+ MOVEMENTFLAG_ASCENDING = 0x00200000, // press "space" when flying
+ MOVEMENTFLAG_DESCENDING = 0x00400000,
+ MOVEMENTFLAG_CAN_FLY = 0x00800000, // Appears when unit can fly AND also walk
+ MOVEMENTFLAG_FLYING = 0x01000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity
+ MOVEMENTFLAG_SPLINE_ELEVATION = 0x02000000, // used for flight paths
+ MOVEMENTFLAG_WATERWALKING = 0x04000000, // prevent unit from falling through water
+ MOVEMENTFLAG_FALLING_SLOW = 0x08000000, // active rogue safe fall spell (passive)
+ MOVEMENTFLAG_HOVER = 0x10000000, // hover, cannot jump
+ MOVEMENTFLAG_DISABLE_COLLISION = 0x20000000,
/// @todo Check if PITCH_UP and PITCH_DOWN really belong here..
MOVEMENTFLAG_MASK_MOVING =
@@ -734,6 +748,12 @@ enum MovementFlags
MOVEMENTFLAG_MASK_MOVING_FLY =
MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING,
+ // Movement flags allowed for creature in CreateObject - we need to keep all other enabled serverside
+ // to properly calculate all movement
+ MOVEMENTFLAG_MASK_CREATURE_ALLOWED =
+ MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | MOVEMENTFLAG_SWIMMING |
+ MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER,
+
/// @todo if needed: add more flags to this masks that are exclusive to players
MOVEMENTFLAG_MASK_PLAYER_ONLY =
MOVEMENTFLAG_FLYING,
@@ -748,20 +768,20 @@ enum MovementFlags2
MOVEMENTFLAG2_NONE = 0x00000000,
MOVEMENTFLAG2_NO_STRAFE = 0x00000001,
MOVEMENTFLAG2_NO_JUMPING = 0x00000002,
- MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks
- MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008,
- MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010,
- MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020,
- MOVEMENTFLAG2_UNK7 = 0x00000040,
- MOVEMENTFLAG2_UNK8 = 0x00000080,
- MOVEMENTFLAG2_UNK9 = 0x00000100,
- MOVEMENTFLAG2_UNK10 = 0x00000200,
- MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400,
- MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800,
- MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000,
- MOVEMENTFLAG2_UNK14 = 0x00002000,
- MOVEMENTFLAG2_UNK15 = 0x00004000,
- MOVEMENTFLAG2_UNK16 = 0x00008000
+ MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000004,
+ MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000008,
+ MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000010,
+ MOVEMENTFLAG2_UNK5 = 0x00000020,
+ MOVEMENTFLAG2_UNK6 = 0x00000040,
+ MOVEMENTFLAG2_UNK7 = 0x00000080,
+ MOVEMENTFLAG2_UNK8 = 0x00000100,
+ MOVEMENTFLAG2_UNK9 = 0x00000200,
+ MOVEMENTFLAG2_CAN_SWIM_TO_FLY_TRANS = 0x00000400,
+ MOVEMENTFLAG2_UNK11 = 0x00000800,
+ MOVEMENTFLAG2_UNK12 = 0x00001000,
+ MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00002000,
+ MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00004000,
+ MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00008000
};
enum UnitTypeMask
@@ -779,10 +799,6 @@ enum UnitTypeMask
UNIT_MASK_ACCESSORY = 0x00000200
};
-namespace Movement{
- class MoveSpline;
-}
-
struct DiminishingReturn
{
DiminishingReturn(DiminishingGroup group, uint32 t, uint32 count)
@@ -1072,7 +1088,8 @@ enum CommandStates
COMMAND_STAY = 0,
COMMAND_FOLLOW = 1,
COMMAND_ATTACK = 2,
- COMMAND_ABANDON = 3
+ COMMAND_ABANDON = 3,
+ COMMAND_MOVE_TO = 4
};
#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF)
@@ -1372,10 +1389,12 @@ class Unit : public WorldObject
Powers getPowerType() const { return Powers(GetByteValue(UNIT_FIELD_BYTES_0, 3)); }
void setPowerType(Powers power);
- uint32 GetPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_POWER1 +power); }
- uint32 GetMaxPower(Powers power) const { return GetUInt32Value(UNIT_FIELD_MAXPOWER1+power); }
- void SetPower(Powers power, uint32 val);
- void SetMaxPower(Powers power, uint32 val);
+ int32 GetPower(Powers power) const;
+ int32 GetMinPower(Powers power) const { return power == POWER_ECLIPSE ? -100 : 0; }
+ int32 GetMaxPower(Powers power) const;
+ int32 CountPctFromMaxPower(Powers power, int32 pct) const { return CalculatePct(GetMaxPower(power), pct); }
+ void SetPower(Powers power, int32 val);
+ void SetMaxPower(Powers power, int32 val);
// returns the change in power
int32 ModifyPower(Powers power, int32 val);
int32 ModifyPowerPct(Powers power, float pct, bool apply = true);
@@ -1422,6 +1441,10 @@ class Unit : public WorldObject
uint32 GetMountID() const { return GetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID); }
void Mount(uint32 mount, uint32 vehicleId = 0, uint32 creatureEntry = 0);
void Dismount();
+ MountCapabilityEntry const* GetMountCapability(uint32 mountType) const;
+
+ void SendDurabilityLoss(Player* receiver, uint32 percent);
+ void PlayOneShotAnimKit(uint32 id);
uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; }
void DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb);
@@ -1451,23 +1474,11 @@ class Unit : public WorldObject
void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss);
// player or player's pet resilience (-1%)
- float GetMeleeCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_MELEE); }
- float GetRangedCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_RANGED); }
- float GetSpellCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_SPELL); }
-
- // player or player's pet resilience (-1%)
- uint32 GetMeleeCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.2f, 33.0f, damage); }
- uint32 GetRangedCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.2f, 33.0f, damage); }
- uint32 GetSpellCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.2f, 33.0f, damage); }
+ uint32 GetDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_RESILIENCE_PLAYER_DAMAGE_TAKEN, 1.0f, 100.0f, damage); }
- // player or player's pet resilience (-1%), cap 100%
- uint32 GetMeleeDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.0f, 100.0f, damage); }
- uint32 GetRangedDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.0f, 100.0f, damage); }
- uint32 GetSpellDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.0f, 100.0f, damage); }
+ void ApplyResilience(Unit const* victim, int32* damage) const;
- void ApplyResilience(Unit const* victim, float* crit, int32* damage, bool isCrit, CombatRating type) const;
-
- float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const;
+ float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, uint32 spellId) const;
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo);
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo);
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool canReflect = false);
@@ -1480,11 +1491,10 @@ class Unit : public WorldObject
int32 GetMechanicResistChance(SpellInfo const* spellInfo) const;
bool CanUseAttackType(uint8 attacktype) const;
- virtual uint32 GetShieldBlockValue() const =0;
- uint32 GetShieldBlockValue(uint32 soft_cap, uint32 hard_cap) const;
+ virtual uint32 GetBlockPercent() const { return 30; }
+
uint32 GetUnitMeleeSkill(Unit const* target = NULL) const;
- uint32 GetDefenseSkillValue(Unit const* target = NULL) const;
- uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = NULL) const;
+
float GetWeaponProcChance() const;
float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spellProto) const;
@@ -1545,7 +1555,7 @@ class Unit : public WorldObject
void SendHealSpellLog(Unit* victim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false);
int32 HealBySpell(Unit* victim, SpellInfo const* spellInfo, uint32 addHealth, bool critical = false);
- void SendEnergizeSpellLog(Unit* victim, uint32 spellID, int32 damage, Powers powerType);
+ 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);
@@ -1563,8 +1573,7 @@ class Unit : public WorldObject
Aura* AddAura(uint32 spellId, Unit* target);
Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
- void SendPlaySpellVisual(uint32 id);
- void SendPlaySpellImpact(uint64 guid, uint32 id);
+ void SendPlaySpellVisualKit(uint32 id, uint32 unkParam);
void DeMorph();
@@ -1585,24 +1594,27 @@ class Unit : public WorldObject
void UpdateOrientation(float orientation);
void UpdateHeight(float newZ);
+ void SendMoveKnockBack(Player* player, float speedXY, float speedZ, float vcos, float vsin);
void KnockbackFrom(float x, float y, float speedXY, float speedZ);
void JumpTo(float speedXY, float speedZ, bool forward = true);
void JumpTo(WorldObject* obj, float speedZ);
void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false);
- //void SetFacing(float ori, WorldObject* obj = NULL);
- //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
- void SendMovementFlagUpdate(bool self = false);
+
+
+ void SendSetPlayHoverAnim(bool enable);
+ void SendMovementSetSplineAnim(Movement::AnimType anim);
bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); }
bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING); }
- virtual bool SetWalk(bool enable);
- virtual bool SetDisableGravity(bool disable, bool packetOnly = false);
- virtual bool SetSwim(bool enable);
- virtual bool SetCanFly(bool enable);
- virtual bool SetWaterWalking(bool enable, bool packetOnly = false);
- virtual bool SetFeatherFall(bool enable, bool packetOnly = false);
- virtual bool SetHover(bool enable, bool packetOnly = false);
+ bool SetWalk(bool enable);
+ bool SetDisableGravity(bool disable, bool packetOnly = false);
+ bool SetFall(bool enable);
+ bool SetSwim(bool enable);
+ bool SetCanFly(bool enable);
+ bool SetWaterWalking(bool enable, bool packetOnly = false);
+ bool SetFeatherFall(bool enable, bool packetOnly = false);
+ bool SetHover(bool enable, bool packetOnly = false);
void SetInFront(WorldObject const* target);
void SetFacingTo(float ori);
@@ -1615,8 +1627,6 @@ class Unit : public WorldObject
void SendClearTarget();
- void BuildHeartBeatMsg(WorldPacket* data) const;
-
bool IsAlive() const { return (m_deathState == ALIVE); }
bool isDying() const { return (m_deathState == JUST_DIED); }
bool isDead() const { return (m_deathState == DEAD || m_deathState == CORPSE); }
@@ -1813,7 +1823,8 @@ class Unit : public WorldObject
uint32 GetCreateHealth() const { return GetUInt32Value(UNIT_FIELD_BASE_HEALTH); }
void SetCreateMana(uint32 val) { SetUInt32Value(UNIT_FIELD_BASE_MANA, val); }
uint32 GetCreateMana() const { return GetUInt32Value(UNIT_FIELD_BASE_MANA); }
- uint32 GetCreatePowers(Powers power) const;
+ uint32 GetPowerIndex(uint32 powerType) const;
+ int32 GetCreatePowers(Powers power) const;
float GetPosStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_POSSTAT0+stat); }
float GetNegStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_NEGSTAT0+stat); }
float GetCreateStat(Stats stat) const { return m_createStats[stat]; }
@@ -1966,9 +1977,6 @@ class Unit : public WorldObject
uint32 SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
uint32 SpellCriticalHealingBonus(SpellInfo const* spellProto, uint32 damage, Unit* victim);
- void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; }
- bool IsUnderLastManaUseEffect() const;
-
void SetContestedPvP(Player* attackedPlayer = NULL);
uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const;
@@ -2014,17 +2022,18 @@ class Unit : public WorldObject
bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); }
void StopMoving();
- void AddUnitMovementFlag(uint32 f) { m_movementInfo.flags |= f; }
- void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.flags &= ~f; }
- bool HasUnitMovementFlag(uint32 f) const { return (m_movementInfo.flags & f) == f; }
- uint32 GetUnitMovementFlags() const { return m_movementInfo.flags; }
- void SetUnitMovementFlags(uint32 f) { m_movementInfo.flags = f; }
+ void AddUnitMovementFlag(uint32 f) { m_movementInfo.AddMovementFlag(f); }
+ void RemoveUnitMovementFlag(uint32 f) { m_movementInfo.RemoveMovementFlag(f); }
+ bool HasUnitMovementFlag(uint32 f) const { return m_movementInfo.HasMovementFlag(f); }
+ uint32 GetUnitMovementFlags() const { return m_movementInfo.GetMovementFlags(); }
+ void SetUnitMovementFlags(uint32 f) { m_movementInfo.SetMovementFlags(f); }
- void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 |= f; }
- void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.flags2 &= ~f; }
- uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.flags2 & f; }
- uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.flags2; }
- void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.flags2 = f; }
+ void AddExtraUnitMovementFlag(uint16 f) { m_movementInfo.AddExtraMovementFlag(f); }
+ void RemoveExtraUnitMovementFlag(uint16 f) { m_movementInfo.RemoveExtraMovementFlag(f); }
+ uint16 HasExtraUnitMovementFlag(uint16 f) const { return m_movementInfo.HasExtraMovementFlag(f); }
+ uint16 GetExtraUnitMovementFlags() const { return m_movementInfo.GetExtraMovementFlags(); }
+ void SetExtraUnitMovementFlags(uint16 f) { m_movementInfo.SetExtraMovementFlags(f); }
+ bool IsSplineEnabled() const;
float GetPositionZMinusOffset() const;
@@ -2096,7 +2105,7 @@ class Unit : public WorldObject
void _ExitVehicle(Position const* exitPosition = NULL);
void _EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp = NULL);
- void BuildMovementPacket(ByteBuffer *data) const;
+ void WriteMovementInfo(WorldPacket& data, Movement::ExtraMovementStatusElement* extras = NULL);
bool isMoving() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_MOVING); }
bool isTurning() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_MASK_TURNING); }
@@ -2104,7 +2113,7 @@ class Unit : public WorldObject
bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_DISABLE_GRAVITY); }
bool IsFalling() const;
- void RewardRage(uint32 damage, uint32 weaponSpeedHitFactor, bool attacker);
+ void RewardRage(uint32 baseRage, bool attacker);
virtual float GetFollowAngle() const { return static_cast<float>(M_PI/2); }
@@ -2209,6 +2218,7 @@ 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);
@@ -2223,16 +2233,18 @@ class Unit : public WorldObject
float GetCombatRatingReduction(CombatRating cr) const;
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const;
+ protected:
void SetFeared(bool apply);
void SetConfused(bool apply);
void SetStunned(bool apply);
- void SetRooted(bool apply);
+ void SetRooted(bool apply, bool packetOnly = false);
- uint32 m_rootTimes;
+ uint32 m_movementCounter; ///< Incrementing counter used in movement packets
+
+ private:
uint32 m_state; // Even derived shouldn't modify
uint32 m_CombatTimer;
- uint32 m_lastManaUse; // msecs
TimeTrackerSmall m_movesplineTimer;
Diminishing m_Diminishing;
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index fae4f0c6b6a..e40f23fc25c 100755..100644
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -522,10 +522,7 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit)
if (_me->IsInWorld())
{
if (!_me->GetTransport())
- {
- unit->RemoveUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
- unit->m_movementInfo.transport.Reset();
- }
+ unit->m_movementInfo.ResetTransport();
else
unit->m_movementInfo.transport = _me->m_movementInfo.transport;
}
@@ -567,6 +564,7 @@ void Vehicle::RelocatePassengers()
float px, py, pz, po;
passenger->m_movementInfo.transport.pos.GetPosition(px, py, pz, po);
CalculatePassengerPosition(px, py, pz, &po);
+
passenger->UpdatePosition(px, py, pz, po);
}
}
@@ -824,7 +822,6 @@ bool VehicleJoinEvent::Execute(uint64, uint32)
if (Seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_PASSENGER_NOT_SELECTABLE)
Passenger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Passenger->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
VehicleSeatEntry const* veSeat = Seat->second.SeatInfo;
Passenger->m_movementInfo.transport.pos.Relocate(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
Passenger->m_movementInfo.transport.time = 0;
diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h
index 4acd1fe209a..2c466255dc0 100644
--- a/src/server/game/Entities/Vehicle/VehicleDefines.h
+++ b/src/server/game/Entities/Vehicle/VehicleDefines.h
@@ -32,7 +32,29 @@ enum PowerType
POWER_HEAT = 101,
POWER_OOZE = 121,
POWER_BLOOD = 141,
- POWER_WRATH = 142
+ POWER_WRATH = 142,
+ POWER_ARCANE_ENERGY = 143,
+ POWER_LIFE_ENERGY = 144,
+ POWER_SUN_ENERGY = 145,
+ POWER_SWING_VELOCITY = 146,
+ POWER_SHADOWFLAME_ENERGY = 147,
+ POWER_BLUE_POWER = 148,
+ POWER_PURPLE_POWER = 149,
+ POWER_GREEN_POWER = 150,
+ POWER_ORANGE_POWER = 151,
+ POWER_ENERGY_2 = 153,
+ POWER_ARCANEENERGY = 161,
+ POWER_WIND_POWER_1 = 162,
+ POWER_WIND_POWER_2 = 163,
+ POWER_WIND_POWER_3 = 164,
+ POWER_FUEL = 165,
+ POWER_SUN_POWER = 166,
+ POWER_TWILIGHT_ENERGY = 169,
+ POWER_VENOM = 174,
+ POWER_ORANGE_POWER_2 = 176,
+ POWER_CONSUMING_FLAME = 177,
+ POWER_PYROCLASTIC_FRENZY = 178,
+ POWER_FLASHFIRE = 179,
};
enum VehicleFlags
diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp
index 95d4c7e2503..4404f8036af 100644
--- a/src/server/game/Events/GameEventMgr.cpp
+++ b/src/server/game/Events/GameEventMgr.cpp
@@ -777,8 +777,8 @@ void GameEventMgr::LoadFromDB()
{
uint32 oldMSTime = getMSTime();
- // 0 1 2 3 4 5
- QueryResult result = WorldDatabase.Query("SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost FROM game_event_npc_vendor ORDER BY guid, slot ASC");
+ // 0 1 2 3 4 5 6
+ QueryResult result = WorldDatabase.Query("SELECT eventEntry, guid, item, maxcount, incrtime, ExtendedCost, type FROM game_event_npc_vendor ORDER BY guid, slot ASC");
if (!result)
TC_LOG_INFO("server.loading", ">> Loaded 0 vendor additions in game events. DB table `game_event_npc_vendor` is empty.");
@@ -804,6 +804,7 @@ void GameEventMgr::LoadFromDB()
newEntry.maxcount = fields[3].GetUInt32();
newEntry.incrtime = fields[4].GetUInt32();
newEntry.ExtendedCost = fields[5].GetUInt32();
+ newEntry.Type = fields[6].GetUInt8();
// get the event npc flag for checking if the npc will be vendor during the event or not
uint32 event_npc_flag = 0;
NPCFlagList& flist = mGameEventNPCFlags[event_id];
@@ -822,7 +823,7 @@ void GameEventMgr::LoadFromDB()
newEntry.entry = data->id;
// check validity with event's npcflag
- if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, NULL, NULL, event_npc_flag))
+ if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, newEntry.Type, NULL, NULL, event_npc_flag))
continue;
vendors.push_back(newEntry);
@@ -1151,9 +1152,9 @@ void GameEventMgr::UpdateEventNPCVendor(uint16 event_id, bool activate)
for (NPCVendorList::iterator itr = mGameEventVendors[event_id].begin(); itr != mGameEventVendors[event_id].end(); ++itr)
{
if (activate)
- sObjectMgr->AddVendorItem(itr->entry, itr->item, itr->maxcount, itr->incrtime, itr->ExtendedCost, false);
+ sObjectMgr->AddVendorItem(itr->entry, itr->item, itr->maxcount, itr->incrtime, itr->ExtendedCost, itr->Type, false);
else
- sObjectMgr->RemoveVendorItem(itr->entry, itr->item, false);
+ sObjectMgr->RemoveVendorItem(itr->entry, itr->item, itr->Type, false);
}
}
diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h
index ea6f9359ea3..b30ea8fc0ef 100644
--- a/src/server/game/Events/GameEventMgr.h
+++ b/src/server/game/Events/GameEventMgr.h
@@ -87,6 +87,7 @@ struct NPCVendorEntry
int32 maxcount; // 0 for infinite
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
+ uint8 Type; // 1 item, 2 currency
};
class Player;
diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp
index ca173865570..af2c1ef290a 100644
--- a/src/server/game/Globals/ObjectAccessor.cpp
+++ b/src/server/game/Globals/ObjectAccessor.cpp
@@ -90,6 +90,7 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, uint64 guid)
case HIGHGUID_UNIT: return GetCreature(p, guid);
case HIGHGUID_PET: return GetPet(p, guid);
case HIGHGUID_DYNAMICOBJECT: return GetDynamicObject(p, guid);
+ case HIGHGUID_AREATRIGGER: return GetAreaTrigger(p, guid);
case HIGHGUID_CORPSE: return GetCorpse(p, guid);
default: return NULL;
}
@@ -126,6 +127,9 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, uint64 guid, u
if (typemask & TYPEMASK_DYNAMICOBJECT)
return GetDynamicObject(p, guid);
break;
+ case HIGHGUID_AREATRIGGER:
+ if (typemask & TYPEMASK_AREATRIGGER)
+ return GetAreaTrigger(p, guid);
case HIGHGUID_CORPSE:
break;
}
@@ -157,6 +161,11 @@ DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, uint64 gui
return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL);
}
+AreaTrigger* ObjectAccessor::GetAreaTrigger(WorldObject const& u, uint64 guid)
+{
+ return GetObjectInMap(guid, u.GetMap(), (AreaTrigger*)NULL);
+}
+
Unit* ObjectAccessor::GetUnit(WorldObject const& u, uint64 guid)
{
return GetObjectInMap(guid, u.GetMap(), (Unit*)NULL);
diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h
index 4943c648b93..1fa8c7dff0c 100644
--- a/src/server/game/Globals/ObjectAccessor.h
+++ b/src/server/game/Globals/ObjectAccessor.h
@@ -148,6 +148,7 @@ class ObjectAccessor
static GameObject* GetGameObject(WorldObject const& u, uint64 guid);
static Transport* GetTransport(WorldObject const& u, uint64 guid);
static DynamicObject* GetDynamicObject(WorldObject const& u, uint64 guid);
+ static AreaTrigger* GetAreaTrigger(WorldObject const& u, uint64 guid);
static Unit* GetUnit(WorldObject const&, uint64 guid);
static Creature* GetCreature(WorldObject const& u, uint64 guid);
static Pet* GetPet(WorldObject const&, uint64 guid);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 04f3395653d..3f15ec87392 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -23,6 +23,8 @@
#include "Chat.h"
#include "Common.h"
#include "DatabaseEnv.h"
+#include "DB2Structure.h"
+#include "DB2Stores.h"
#include "DisableMgr.h"
#include "GameEventMgr.h"
#include "GossipDef.h"
@@ -171,7 +173,9 @@ LanguageDesc lang_description[LANGUAGES_COUNT] =
{ LANG_DRAENEI, 29932, SKILL_LANG_DRAENEI },
{ LANG_ZOMBIE, 0, 0 },
{ LANG_GNOMISH_BINARY, 0, 0 },
- { LANG_GOBLIN_BINARY, 0, 0 }
+ { LANG_GOBLIN_BINARY, 0, 0 },
+ { LANG_WORGEN, 69270, SKILL_LANG_WORGEN },
+ { LANG_GOBLIN, 69269, SKILL_LANG_GOBLIN }
};
LanguageDesc const* GetLanguageDescByID(uint32 lang)
@@ -226,6 +230,7 @@ ObjectMgr::ObjectMgr():
_itemTextId(1),
_mailId(1),
_hiPetNumber(1),
+ _voidItemId(1),
_hiCharGuid(1),
_hiCreatureGuid(1),
_hiPetGuid(1),
@@ -234,15 +239,13 @@ ObjectMgr::ObjectMgr():
_hiGoGuid(1),
_hiDoGuid(1),
_hiCorpseGuid(1),
+ _hiAreaTriggerGuid(1),
_hiMoTransGuid(1),
DBCLocaleIndex(LOCALE_enUS)
{
for (uint8 i = 0; i < MAX_CLASSES; ++i)
- {
- _playerClassInfo[i] = NULL;
for (uint8 j = 0; j < MAX_RACES; ++j)
_playerInfo[j][i] = NULL;
- }
}
ObjectMgr::~ObjectMgr()
@@ -253,14 +256,6 @@ ObjectMgr::~ObjectMgr()
for (PetLevelInfoContainer::iterator i = _petInfoStore.begin(); i != _petInfoStore.end(); ++i)
delete[] i->second;
- // free only if loaded
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- if (_playerClassInfo[class_])
- delete[] _playerClassInfo[class_]->levelInfo;
- delete _playerClassInfo[class_];
- }
-
for (int race = 0; race < MAX_RACES; ++race)
{
for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
@@ -275,6 +270,7 @@ ObjectMgr::~ObjectMgr()
itr->second.Clear();
_cacheTrainerSpellStore.clear();
+ _graveyardOrientations.clear();
for (DungeonEncounterContainer::iterator itr =_dungeonEncounterStore.begin(); itr != _dungeonEncounterStore.end(); ++itr)
for (DungeonEncounterList::iterator encounterItr = itr->second.begin(); encounterItr != itr->second.end(); ++encounterItr)
@@ -295,6 +291,34 @@ void ObjectMgr::AddLocaleString(std::string const& s, LocaleConstant locale, Str
}
}
+void ObjectMgr::LoadGraveyardOrientations()
+{
+ uint32 oldMSTime = getMSTime();
+
+ _graveyardOrientations.clear();
+
+ QueryResult result = WorldDatabase.Query("SELECT id, orientation FROM graveyard_orientation");
+
+ if (!result)
+ return;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 id = fields[0].GetUInt32();
+ if (!sWorldSafeLocsStore.LookupEntry(id))
+ {
+ TC_LOG_ERROR("server.loading", "Graveyard %u referenced in graveyard_orientation doesn't exist.", id);
+ continue;
+ }
+ _graveyardOrientations[id] = fields[1].GetFloat();
+
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %lu graveyard orientations in %u ms", (unsigned long)_graveyardOrientations.size(), GetMSTimeDiffToNow(oldMSTime));
+}
+
void ObjectMgr::LoadCreatureLocales()
{
uint32 oldMSTime = getMSTime();
@@ -393,19 +417,19 @@ void ObjectMgr::LoadCreatureTemplates()
// 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, "
- // 9 10 11 12 13 14 15 16 17 18 19 20 21
- "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, "
- // 22 23 24 25 26 27 28 29 30 31 32 33
- "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, "
- // 34 35 36 37 38 39 40 41 42 43
- "dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, "
- // 44 45 46 47 48 49 50 51 52 53 54
- "type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, "
- // 55 56 57 58 59 60 61 62 63 64 65 66 67
- "spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
- // 68 69 70 71 72 73 74 75 76 77 78
- "InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, "
- // 79 80 81 82 83 84
+ // 9 10 11 12 13 14 15 16 17 18 19 20 21
+ "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, "
+ // 22 23 24 25 26 27 28 29 30 31 32 33 34
+ "speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, "
+ // 35 36 37 38 39 40 41 42 43
+ "dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, "
+ // 44 45 46 47 48 49 50 51 52 53 54
+ "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, "
+ // 55 56 57 58 59 60 61 62 63 64 65 66 67 68
+ "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, "
+ // 69 70 71 72 73 74 75 76 77 78 79 80
+ "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, "
+ // 81 82 83 84 85 86
" questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName "
"FROM creature_template;");
@@ -445,27 +469,27 @@ void ObjectMgr::LoadCreatureTemplates()
creatureTemplate.minlevel = fields[14].GetUInt8();
creatureTemplate.maxlevel = fields[15].GetUInt8();
creatureTemplate.expansion = uint32(fields[16].GetInt16());
- creatureTemplate.faction_A = uint32(fields[17].GetUInt16());
- creatureTemplate.faction_H = uint32(fields[18].GetUInt16());
- creatureTemplate.npcflag = fields[19].GetUInt32();
- creatureTemplate.speed_walk = fields[20].GetFloat();
- creatureTemplate.speed_run = fields[21].GetFloat();
- creatureTemplate.scale = fields[22].GetFloat();
- creatureTemplate.rank = uint32(fields[23].GetUInt8());
- creatureTemplate.mindmg = fields[24].GetFloat();
- creatureTemplate.maxdmg = fields[25].GetFloat();
- creatureTemplate.dmgschool = uint32(fields[26].GetInt8());
- creatureTemplate.attackpower = fields[27].GetUInt32();
- creatureTemplate.dmg_multiplier = fields[28].GetFloat();
- creatureTemplate.baseattacktime = fields[29].GetUInt32();
- creatureTemplate.rangeattacktime = fields[30].GetUInt32();
- creatureTemplate.unit_class = uint32(fields[31].GetUInt8());
- creatureTemplate.unit_flags = fields[32].GetUInt32();
- creatureTemplate.unit_flags2 = fields[33].GetUInt32();
- creatureTemplate.dynamicflags = fields[34].GetUInt32();
- creatureTemplate.family = uint32(fields[35].GetUInt8());
- creatureTemplate.trainer_type = uint32(fields[36].GetUInt8());
- creatureTemplate.trainer_spell = fields[37].GetUInt32();
+ creatureTemplate.expansionUnknown = uint32(fields[17].GetUInt16());
+ creatureTemplate.faction_A = uint32(fields[18].GetUInt16());
+ creatureTemplate.faction_H = uint32(fields[19].GetUInt16());
+ creatureTemplate.npcflag = fields[20].GetUInt32();
+ creatureTemplate.speed_walk = fields[21].GetFloat();
+ creatureTemplate.speed_run = fields[22].GetFloat();
+ creatureTemplate.scale = fields[23].GetFloat();
+ creatureTemplate.rank = uint32(fields[24].GetUInt8());
+ creatureTemplate.mindmg = fields[25].GetFloat();
+ creatureTemplate.maxdmg = fields[26].GetFloat();
+ creatureTemplate.dmgschool = uint32(fields[27].GetInt8());
+ creatureTemplate.attackpower = fields[28].GetUInt32();
+ creatureTemplate.dmg_multiplier = fields[29].GetFloat();
+ creatureTemplate.baseattacktime = fields[30].GetUInt32();
+ creatureTemplate.rangeattacktime = fields[31].GetUInt32();
+ creatureTemplate.unit_class = uint32(fields[32].GetUInt8());
+ creatureTemplate.unit_flags = fields[33].GetUInt32();
+ creatureTemplate.unit_flags2 = fields[34].GetUInt32();
+ creatureTemplate.dynamicflags = fields[35].GetUInt32();
+ creatureTemplate.family = uint32(fields[36].GetUInt8());
+ creatureTemplate.trainer_type = uint32(fields[37].GetUInt8());
creatureTemplate.trainer_class = uint32(fields[38].GetUInt8());
creatureTemplate.trainer_race = uint32(fields[39].GetUInt8());
creatureTemplate.minrangedmg = fields[40].GetFloat();
@@ -473,37 +497,39 @@ void ObjectMgr::LoadCreatureTemplates()
creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16());
creatureTemplate.type = uint32(fields[43].GetUInt8());
creatureTemplate.type_flags = fields[44].GetUInt32();
- creatureTemplate.lootid = fields[45].GetUInt32();
- creatureTemplate.pickpocketLootId = fields[46].GetUInt32();
- creatureTemplate.SkinLootId = fields[47].GetUInt32();
+ creatureTemplate.type_flags2 = fields[45].GetUInt32();
+ creatureTemplate.lootid = fields[46].GetUInt32();
+ creatureTemplate.pickpocketLootId = fields[47].GetUInt32();
+ creatureTemplate.SkinLootId = fields[48].GetUInt32();
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- creatureTemplate.resistance[i] = fields[48 + i -1].GetInt16();
+ creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16();
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
- creatureTemplate.spells[i] = fields[54 + i].GetUInt32();
-
- creatureTemplate.PetSpellDataId = fields[62].GetUInt32();
- creatureTemplate.VehicleId = fields[63].GetUInt32();
- creatureTemplate.mingold = fields[64].GetUInt32();
- creatureTemplate.maxgold = fields[65].GetUInt32();
- creatureTemplate.AIName = fields[66].GetString();
- creatureTemplate.MovementType = uint32(fields[67].GetUInt8());
- creatureTemplate.InhabitType = uint32(fields[68].GetUInt8());
- creatureTemplate.HoverHeight = fields[69].GetFloat();
- creatureTemplate.ModHealth = fields[70].GetFloat();
- creatureTemplate.ModMana = fields[71].GetFloat();
- creatureTemplate.ModArmor = fields[72].GetFloat();
- creatureTemplate.RacialLeader = fields[73].GetBool();
+ creatureTemplate.spells[i] = fields[55 + i].GetUInt32();
+
+ creatureTemplate.PetSpellDataId = fields[63].GetUInt32();
+ creatureTemplate.VehicleId = fields[64].GetUInt32();
+ creatureTemplate.mingold = fields[65].GetUInt32();
+ creatureTemplate.maxgold = fields[66].GetUInt32();
+ creatureTemplate.AIName = fields[67].GetString();
+ creatureTemplate.MovementType = uint32(fields[68].GetUInt8());
+ creatureTemplate.InhabitType = uint32(fields[69].GetUInt8());
+ creatureTemplate.HoverHeight = fields[70].GetFloat();
+ creatureTemplate.ModHealth = fields[71].GetFloat();
+ creatureTemplate.ModMana = fields[72].GetFloat();
+ creatureTemplate.ModManaExtra = fields[73].GetFloat();
+ creatureTemplate.ModArmor = fields[74].GetFloat();
+ creatureTemplate.RacialLeader = fields[75].GetBool();
for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
- creatureTemplate.questItems[i] = fields[74 + i].GetUInt32();
+ creatureTemplate.questItems[i] = fields[76 + i].GetUInt32();
- creatureTemplate.movementId = fields[80].GetUInt32();
- creatureTemplate.RegenHealth = fields[81].GetBool();
- creatureTemplate.MechanicImmuneMask = fields[82].GetUInt32();
- creatureTemplate.flags_extra = fields[83].GetUInt32();
- creatureTemplate.ScriptID = GetScriptId(fields[84].GetCString());
+ creatureTemplate.movementId = fields[82].GetUInt32();
+ creatureTemplate.RegenHealth = fields[83].GetBool();
+ creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32();
+ creatureTemplate.flags_extra = fields[85].GetUInt32();
+ creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString());
++count;
}
@@ -693,12 +719,6 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
continue;
}
- if (cInfo->trainer_spell != difficultyInfo->trainer_spell)
- {
- TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has different `trainer_spell` in difficulty %u mode (Entry: %u).", cInfo->Entry, diff + 1, cInfo->DifficultyEntry[diff]);
- continue;
- }
-
if (cInfo->type != difficultyInfo->type)
{
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u, type %u) has different `type` in difficulty %u mode (Entry: %u, type %u).",
@@ -927,10 +947,16 @@ void ObjectMgr::CheckCreatureTemplate(CreatureTemplate const* cInfo)
if (cInfo->expansion > (MAX_EXPANSIONS - 1))
{
- TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with expansion %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
+ TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with `exp` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansion);
const_cast<CreatureTemplate*>(cInfo)->expansion = 0;
}
+ if (cInfo->expansionUnknown > MAX_EXPANSIONS)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with `exp_unk` %u. Ignored and set to 0.", cInfo->Entry, cInfo->expansionUnknown);
+ const_cast<CreatureTemplate*>(cInfo)->expansionUnknown = 0;
+ }
+
if (uint32 badFlags = (cInfo->flags_extra & ~CREATURE_FLAG_EXTRA_DB_ALLOWED))
{
TC_LOG_ERROR("sql.sql", "Table `creature_template` lists creature (Entry: %u) with disallowed `flags_extra` %u, removing incorrect flag.", cInfo->Entry, badFlags);
@@ -1645,7 +1671,7 @@ void ObjectMgr::LoadCreatures()
// Skip spawnMask check for transport maps
if (!_transportMaps.count(data.mapid) && data.spawnMask & ~spawnMasks[data.mapid])
- TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u).", guid, data.spawnMask, data.mapid);
+ TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u) spawnMasks[data.mapid]: %u.", guid, data.spawnMask, data.mapid, spawnMasks[data.mapid]);
bool ok = true;
for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff)
@@ -1984,7 +2010,7 @@ void ObjectMgr::LoadGameobjects()
data.phaseMask = fields[15].GetUInt32();
int16 gameEvent = fields[16].GetInt8();
- uint32 PoolId = fields[17].GetUInt32();
+ uint32 PoolId = fields[17].GetUInt32();
if (data.rotation2 < -1.0f || data.rotation2 > 1.0f)
{
@@ -2186,582 +2212,504 @@ void ObjectMgr::LoadItemLocales()
TC_LOG_INFO("server.loading", ">> Loaded %lu Item locale strings in %u ms", (unsigned long)_itemLocaleStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadItemTemplates()
+void FillItemDamageFields(float* minDamage, float* maxDamage, float* dps, uint32 itemLevel, uint32 itemClass, uint32 itemSubClass, uint32 quality, uint32 delay, float statScalingFactor, uint32 inventoryType, uint32 flags2)
{
- uint32 oldMSTime = getMSTime();
-
- // 0 1 2 3 4 5 6 7 8 9 10 11 12
- QueryResult result = WorldDatabase.Query("SELECT entry, class, subclass, SoundOverrideSubclass, name, displayid, Quality, Flags, FlagsExtra, BuyCount, BuyPrice, SellPrice, InventoryType, "
- // 13 14 15 16 17 18 19 20
- "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, requiredspell, requiredhonorrank, "
- // 21 22 23 24 25 26 27 28
- "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, maxcount, stackable, ContainerSlots, StatsCount, stat_type1, "
- // 29 30 31 32 33 34 35 36 37 38
- "stat_value1, stat_type2, stat_value2, stat_type3, stat_value3, stat_type4, stat_value4, stat_type5, stat_value5, stat_type6, "
- // 39 40 41 42 43 44 45 46 47
- "stat_value6, stat_type7, stat_value7, stat_type8, stat_value8, stat_type9, stat_value9, stat_type10, stat_value10, "
- // 48 49 50 51 52 53 54 55 56 57 58
- "ScalingStatDistribution, ScalingStatValue, dmg_min1, dmg_max1, dmg_type1, dmg_min2, dmg_max2, dmg_type2, armor, holy_res, fire_res, "
- // 59 60 61 62 63 64 65 66 67 68
- "nature_res, frost_res, shadow_res, arcane_res, delay, ammo_type, RangedModRange, spellid_1, spelltrigger_1, spellcharges_1, "
- // 69 70 71 72 73 74 75
- "spellppmRate_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, spellid_2, spelltrigger_2, spellcharges_2, "
- // 76 77 78 79 80 81 82
- "spellppmRate_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, spellid_3, spelltrigger_3, spellcharges_3, "
- // 83 84 85 86 87 88 89
- "spellppmRate_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, spellid_4, spelltrigger_4, spellcharges_4, "
- // 90 91 92 93 94 95 96
- "spellppmRate_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, spellid_5, spelltrigger_5, spellcharges_5, "
- // 97 98 99 100 101 102 103 104 105
- "spellppmRate_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, bonding, description, PageText, LanguageID, PageMaterial, "
- // 106 107 108 109 110 111 112 113 114 115 116 117
- "startquest, lockid, Material, sheath, RandomProperty, RandomSuffix, block, itemset, MaxDurability, area, Map, BagFamily, "
- // 118 119 120 121 122 123 124 125
- "TotemCategory, socketColor_1, socketContent_1, socketColor_2, socketContent_2, socketColor_3, socketContent_3, socketBonus, "
- // 126 127 128 129 130 131 132 133
- "GemProperties, RequiredDisenchantSkill, ArmorDamageModifier, duration, ItemLimitCategory, HolidayId, ScriptName, DisenchantID, "
- // 134 135 136
- "FoodType, minMoneyLoot, maxMoneyLoot, flagsCustom FROM item_template");
-
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 item templates. DB table `item_template` is empty.");
+ *minDamage = *maxDamage = *dps = 0.0f;
+ if (itemClass != ITEM_CLASS_WEAPON || quality > ITEM_QUALITY_ARTIFACT)
return;
- }
- _itemTemplateStore.rehash(result->GetRowCount());
- uint32 count = 0;
- bool enforceDBCAttributes = sWorld->getBoolConfig(CONFIG_DBC_ENFORCE_ITEM_ATTRIBUTES);
+ DBCStorage<ItemDamageEntry>* store = NULL;
+ // get the right store here
+ if (inventoryType > 0xD + 13)
+ return;
- do
+ switch (inventoryType)
{
- Field* fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
-
- ItemTemplate& itemTemplate = _itemTemplateStore[entry];
-
- itemTemplate.ItemId = entry;
- itemTemplate.Class = uint32(fields[1].GetUInt8());
- itemTemplate.SubClass = uint32(fields[2].GetUInt8());
- itemTemplate.SoundOverrideSubclass = int32(fields[3].GetInt8());
- itemTemplate.Name1 = fields[4].GetString();
- itemTemplate.DisplayInfoID = fields[5].GetUInt32();
- itemTemplate.Quality = uint32(fields[6].GetUInt8());
- itemTemplate.Flags = fields[7].GetUInt32();
- itemTemplate.Flags2 = fields[8].GetUInt32();
- itemTemplate.BuyCount = uint32(fields[9].GetUInt8());
- itemTemplate.BuyPrice = int32(fields[10].GetInt64());
- itemTemplate.SellPrice = fields[11].GetUInt32();
- itemTemplate.InventoryType = uint32(fields[12].GetUInt8());
- itemTemplate.AllowableClass = fields[13].GetInt32();
- itemTemplate.AllowableRace = fields[14].GetInt32();
- itemTemplate.ItemLevel = uint32(fields[15].GetUInt16());
- itemTemplate.RequiredLevel = uint32(fields[16].GetUInt8());
- itemTemplate.RequiredSkill = uint32(fields[17].GetUInt16());
- itemTemplate.RequiredSkillRank = uint32(fields[18].GetUInt16());
- itemTemplate.RequiredSpell = fields[19].GetUInt32();
- itemTemplate.RequiredHonorRank = fields[20].GetUInt32();
- itemTemplate.RequiredCityRank = fields[21].GetUInt32();
- itemTemplate.RequiredReputationFaction = uint32(fields[22].GetUInt16());
- itemTemplate.RequiredReputationRank = uint32(fields[23].GetUInt16());
- itemTemplate.MaxCount = fields[24].GetInt32();
- itemTemplate.Stackable = fields[25].GetInt32();
- itemTemplate.ContainerSlots = uint32(fields[26].GetUInt8());
- itemTemplate.StatsCount = uint32(fields[27].GetUInt8());
-
- for (uint8 i = 0; i < itemTemplate.StatsCount; ++i)
- {
- itemTemplate.ItemStat[i].ItemStatType = uint32(fields[28 + i*2].GetUInt8());
- itemTemplate.ItemStat[i].ItemStatValue = int32(fields[29 + i*2].GetInt16());
- }
-
- itemTemplate.ScalingStatDistribution = uint32(fields[48].GetUInt16());
- itemTemplate.ScalingStatValue = fields[49].GetInt32();
-
- for (uint8 i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
- {
- itemTemplate.Damage[i].DamageMin = fields[50 + i*3].GetFloat();
- itemTemplate.Damage[i].DamageMax = fields[51 + i*3].GetFloat();
- itemTemplate.Damage[i].DamageType = uint32(fields[52 + i*3].GetUInt8());
- }
-
- itemTemplate.Armor = uint32(fields[56].GetUInt16());
- itemTemplate.HolyRes = uint32(fields[57].GetUInt8());
- itemTemplate.FireRes = uint32(fields[58].GetUInt8());
- itemTemplate.NatureRes = uint32(fields[59].GetUInt8());
- itemTemplate.FrostRes = uint32(fields[60].GetUInt8());
- itemTemplate.ShadowRes = uint32(fields[61].GetUInt8());
- itemTemplate.ArcaneRes = uint32(fields[62].GetUInt8());
- itemTemplate.Delay = uint32(fields[63].GetUInt16());
- itemTemplate.AmmoType = uint32(fields[64].GetUInt8());
- itemTemplate.RangedModRange = fields[65].GetFloat();
-
- for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
- {
- itemTemplate.Spells[i].SpellId = fields[66 + i*7 ].GetInt32();
- itemTemplate.Spells[i].SpellTrigger = uint32(fields[67 + i*7].GetUInt8());
- itemTemplate.Spells[i].SpellCharges = int32(fields[68 + i*7].GetInt16());
- itemTemplate.Spells[i].SpellPPMRate = fields[69 + i*7].GetFloat();
- itemTemplate.Spells[i].SpellCooldown = fields[70 + i*7].GetInt32();
- itemTemplate.Spells[i].SpellCategory = uint32(fields[71 + i*7].GetUInt16());
- itemTemplate.Spells[i].SpellCategoryCooldown = fields[72 + i*7].GetInt32();
- }
-
- itemTemplate.Bonding = uint32(fields[101].GetUInt8());
- itemTemplate.Description = fields[102].GetString();
- itemTemplate.PageText = fields[103].GetUInt32();
- itemTemplate.LanguageID = uint32(fields[104].GetUInt8());
- itemTemplate.PageMaterial = uint32(fields[105].GetUInt8());
- itemTemplate.StartQuest = fields[106].GetUInt32();
- itemTemplate.LockID = fields[107].GetUInt32();
- itemTemplate.Material = int32(fields[108].GetInt8());
- itemTemplate.Sheath = uint32(fields[109].GetUInt8());
- itemTemplate.RandomProperty = fields[110].GetUInt32();
- itemTemplate.RandomSuffix = fields[111].GetInt32();
- itemTemplate.Block = fields[112].GetUInt32();
- itemTemplate.ItemSet = fields[113].GetUInt32();
- itemTemplate.MaxDurability = uint32(fields[114].GetUInt16());
- itemTemplate.Area = fields[115].GetUInt32();
- itemTemplate.Map = uint32(fields[116].GetUInt16());
- itemTemplate.BagFamily = fields[117].GetUInt32();
- itemTemplate.TotemCategory = fields[118].GetUInt32();
-
- for (uint8 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
- {
- itemTemplate.Socket[i].Color = uint32(fields[119 + i*2].GetUInt8());
- itemTemplate.Socket[i].Content = fields[120 + i*2].GetUInt32();
- }
-
- itemTemplate.socketBonus = fields[125].GetUInt32();
- itemTemplate.GemProperties = fields[126].GetUInt32();
- itemTemplate.RequiredDisenchantSkill = uint32(fields[127].GetInt16());
- itemTemplate.ArmorDamageModifier = fields[128].GetFloat();
- itemTemplate.Duration = fields[129].GetUInt32();
- itemTemplate.ItemLimitCategory = uint32(fields[130].GetInt16());
- itemTemplate.HolidayId = fields[131].GetUInt32();
- itemTemplate.ScriptId = sObjectMgr->GetScriptId(fields[132].GetCString());
- itemTemplate.DisenchantID = fields[133].GetUInt32();
- itemTemplate.FoodType = uint32(fields[134].GetUInt8());
- itemTemplate.MinMoneyLoot = fields[135].GetUInt32();
- itemTemplate.MaxMoneyLoot = fields[136].GetUInt32();
- itemTemplate.FlagsCu = fields[137].GetUInt32();
-
- // Checks
-
- ItemEntry const* dbcitem = sItemStore.LookupEntry(entry);
-
- if (dbcitem)
- {
- if (itemTemplate.Class != dbcitem->Class)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct class %u, must be %u .", entry, itemTemplate.Class, dbcitem->Class);
- if (enforceDBCAttributes)
- itemTemplate.Class = dbcitem->Class;
- }
-
- if (itemTemplate.SoundOverrideSubclass != dbcitem->SoundOverrideSubclass)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct SoundOverrideSubclass (%i), must be %i .", entry, itemTemplate.SoundOverrideSubclass, dbcitem->SoundOverrideSubclass);
- if (enforceDBCAttributes)
- itemTemplate.SoundOverrideSubclass = dbcitem->SoundOverrideSubclass;
- }
- if (itemTemplate.Material != dbcitem->Material)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct material (%i), must be %i .", entry, itemTemplate.Material, dbcitem->Material);
- if (enforceDBCAttributes)
- itemTemplate.Material = dbcitem->Material;
- }
- if (itemTemplate.InventoryType != dbcitem->InventoryType)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct inventory type (%u), must be %u .", entry, itemTemplate.InventoryType, dbcitem->InventoryType);
- if (enforceDBCAttributes)
- itemTemplate.InventoryType = dbcitem->InventoryType;
- }
- if (itemTemplate.DisplayInfoID != dbcitem->DisplayId)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct display id (%u), must be %u .", entry, itemTemplate.DisplayInfoID, dbcitem->DisplayId);
- if (enforceDBCAttributes)
- itemTemplate.DisplayInfoID = dbcitem->DisplayId;
- }
- if (itemTemplate.Sheath != dbcitem->Sheath)
+ case INVTYPE_AMMO:
+ store = &sItemDamageAmmoStore;
+ break;
+ case INVTYPE_2HWEAPON:
+ if (flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON)
+ store = &sItemDamageTwoHandCasterStore;
+ else
+ store = &sItemDamageTwoHandStore;
+ break;
+ case INVTYPE_RANGED:
+ case INVTYPE_THROWN:
+ case INVTYPE_RANGEDRIGHT:
+ switch (itemSubClass)
{
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have a correct sheathid (%u), must be %u .", entry, itemTemplate.Sheath, dbcitem->Sheath);
- if (enforceDBCAttributes)
- itemTemplate.Sheath = dbcitem->Sheath;
+ case ITEM_SUBCLASS_WEAPON_WAND:
+ store = &sItemDamageWandStore;
+ break;
+ case ITEM_SUBCLASS_WEAPON_THROWN:
+ store = &sItemDamageThrownStore;
+ break;
+ case ITEM_SUBCLASS_WEAPON_BOW:
+ case ITEM_SUBCLASS_WEAPON_GUN:
+ case ITEM_SUBCLASS_WEAPON_CROSSBOW:
+ store = &sItemDamageRangedStore;
+ break;
+ default:
+ return;
}
+ break;
+ case INVTYPE_WEAPON:
+ case INVTYPE_WEAPONMAINHAND:
+ case INVTYPE_WEAPONOFFHAND:
+ if (flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON)
+ store = &sItemDamageOneHandCasterStore;
+ else
+ store = &sItemDamageOneHandStore;
+ break;
+ default:
+ return;
+ }
- }
- else
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not exist in item.dbc! (not correct id?).", entry);
-
- if (itemTemplate.Class >= MAX_ITEM_CLASS)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Class value (%u)", entry, itemTemplate.Class);
- itemTemplate.Class = ITEM_CLASS_MISC;
- }
-
- if (itemTemplate.SubClass >= MaxItemSubclassValues[itemTemplate.Class])
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Subclass value (%u) for class %u", entry, itemTemplate.SubClass, itemTemplate.Class);
- itemTemplate.SubClass = 0;// exist for all item classes
- }
-
- if (itemTemplate.Quality >= MAX_ITEM_QUALITY)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Quality value (%u)", entry, itemTemplate.Quality);
- itemTemplate.Quality = ITEM_QUALITY_NORMAL;
- }
-
- if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY)
- {
- if (FactionEntry const* faction = sFactionStore.LookupEntry(HORDE))
- if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, item cannot be equipped or used by these races.",
- entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_HORDE_ONLY);
-
- if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `Flags2` flags (ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) and ITEM_FLAGS_EXTRA_HORDE_ONLY (%u) in Flags field, this is a wrong combination.",
- entry, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY, ITEM_FLAGS_EXTRA_HORDE_ONLY);
- }
- else if (itemTemplate.Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY)
- {
- if (FactionEntry const* faction = sFactionStore.LookupEntry(ALLIANCE))
- if ((itemTemplate.AllowableRace & faction->BaseRepRaceMask[0]) == 0)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has value (%u) in `AllowableRace` races, not compatible with ITEM_FLAGS_EXTRA_ALLIANCE_ONLY (%u) in Flags field, item cannot be equipped or used by these races.",
- entry, itemTemplate.AllowableRace, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY);
- }
-
- if (itemTemplate.BuyCount <= 0)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong BuyCount value (%u), set to default(1).", entry, itemTemplate.BuyCount);
- itemTemplate.BuyCount = 1;
- }
-
- if (itemTemplate.InventoryType >= MAX_INVTYPE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong InventoryType value (%u)", entry, itemTemplate.InventoryType);
- itemTemplate.InventoryType = INVTYPE_NON_EQUIP;
- }
-
- if (itemTemplate.RequiredSkill >= MAX_SKILL_TYPE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong RequiredSkill value (%u)", entry, itemTemplate.RequiredSkill);
- itemTemplate.RequiredSkill = 0;
- }
-
- {
- // can be used in equip slot, as page read use in inventory, or spell casting at use
- bool req = itemTemplate.InventoryType != INVTYPE_NON_EQUIP || itemTemplate.PageText;
- if (!req)
- for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
- {
- if (itemTemplate.Spells[j].SpellId)
- {
- req = true;
- break;
- }
- }
-
- if (req)
- {
- if (!(itemTemplate.AllowableClass & CLASSMASK_ALL_PLAYABLE))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have any playable classes (%u) in `AllowableClass` and can't be equipped or used.", entry, itemTemplate.AllowableClass);
+ if (!store)
+ return;
- if (!(itemTemplate.AllowableRace & RACEMASK_ALL_PLAYABLE))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have any playable races (%u) in `AllowableRace` and can't be equipped or used.", entry, itemTemplate.AllowableRace);
- }
- }
+ ItemDamageEntry const* damageInfo = store->LookupEntry(itemLevel);
+ if (!damageInfo)
+ return;
- if (itemTemplate.RequiredSpell && !sSpellMgr->GetSpellInfo(itemTemplate.RequiredSpell))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has a wrong (non-existing) spell in RequiredSpell (%u)", entry, itemTemplate.RequiredSpell);
- itemTemplate.RequiredSpell = 0;
- }
+ *dps = damageInfo->DPS[quality];
+ float avgDamage = *dps * delay * 0.001f;
+ *minDamage = (statScalingFactor * -0.5f + 1.0f) * avgDamage;
+ *maxDamage = floor(float(avgDamage* (statScalingFactor * 0.5f + 1.0f) + 0.5f));
+}
- if (itemTemplate.RequiredReputationRank >= MAX_REPUTATION_RANK)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong reputation rank in RequiredReputationRank (%u), item can't be used.", entry, itemTemplate.RequiredReputationRank);
+uint32 FillItemArmor(uint32 itemlevel, uint32 itemClass, uint32 itemSubclass, uint32 quality, uint32 inventoryType)
+{
+ if (quality > ITEM_QUALITY_ARTIFACT)
+ return 0;
- if (itemTemplate.RequiredReputationFaction)
- {
- if (!sFactionStore.LookupEntry(itemTemplate.RequiredReputationFaction))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) faction in RequiredReputationFaction (%u)", entry, itemTemplate.RequiredReputationFaction);
- itemTemplate.RequiredReputationFaction = 0;
- }
+ // all items but shields
+ if (itemClass != ITEM_CLASS_ARMOR || itemSubclass != ITEM_SUBCLASS_ARMOR_SHIELD)
+ {
+ ItemArmorQualityEntry const* armorQuality = sItemArmorQualityStore.LookupEntry(itemlevel);
+ ItemArmorTotalEntry const* armorTotal = sItemArmorTotalStore.LookupEntry(itemlevel);
+ if (!armorQuality || !armorTotal)
+ return 0;
- if (itemTemplate.RequiredReputationRank == MIN_REPUTATION_RANK)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has min. reputation rank in RequiredReputationRank (0) but RequiredReputationFaction > 0, faction setting is useless.", entry);
- }
+ if (inventoryType == INVTYPE_ROBE)
+ inventoryType = INVTYPE_CHEST;
- if (itemTemplate.MaxCount < -1)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large negative in maxcount (%i), replace by value (-1) no storing limits.", entry, itemTemplate.MaxCount);
- itemTemplate.MaxCount = -1;
- }
+ ArmorLocationEntry const* location = sArmorLocationStore.LookupEntry(inventoryType);
+ if (!location)
+ return 0;
- if (itemTemplate.Stackable == 0)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong value in stackable (%i), replace by default 1.", entry, itemTemplate.Stackable);
- itemTemplate.Stackable = 1;
- }
- else if (itemTemplate.Stackable < -1)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large negative in stackable (%i), replace by value (-1) no stacking limits.", entry, itemTemplate.Stackable);
- itemTemplate.Stackable = -1;
- }
+ if (itemSubclass < ITEM_SUBCLASS_ARMOR_CLOTH || itemSubclass > ITEM_SUBCLASS_ARMOR_PLATE)
+ return 0;
- if (itemTemplate.ContainerSlots > MAX_BAG_SIZE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in ContainerSlots (%u), replace by hardcoded limit (%u).", entry, itemTemplate.ContainerSlots, MAX_BAG_SIZE);
- itemTemplate.ContainerSlots = MAX_BAG_SIZE;
- }
+ return uint32(armorQuality->Value[quality] * armorTotal->Value[itemSubclass - 1] * location->Value[itemSubclass - 1] + 0.5f);
+ }
- if (itemTemplate.StatsCount > MAX_ITEM_PROTO_STATS)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).", entry, itemTemplate.StatsCount, MAX_ITEM_PROTO_STATS);
- itemTemplate.StatsCount = MAX_ITEM_PROTO_STATS;
- }
+ // shields
+ ItemArmorShieldEntry const* shield = sItemArmorShieldStore.LookupEntry(itemlevel);
+ if (!shield)
+ return 0;
- for (uint8 j = 0; j < itemTemplate.StatsCount; ++j)
- {
- // for ItemStatValue != 0
- if (itemTemplate.ItemStat[j].ItemStatValue && itemTemplate.ItemStat[j].ItemStatType >= MAX_ITEM_MOD)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (non-existing?) stat_type%d (%u)", entry, j+1, itemTemplate.ItemStat[j].ItemStatType);
- itemTemplate.ItemStat[j].ItemStatType = 0;
- }
+ return uint32(shield->Value[quality] + 0.5f);
+}
- switch (itemTemplate.ItemStat[j].ItemStatType)
- {
- case ITEM_MOD_SPELL_HEALING_DONE:
- case ITEM_MOD_SPELL_DAMAGE_DONE:
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has deprecated stat_type%d (%u)", entry, j+1, itemTemplate.ItemStat[j].ItemStatType);
- break;
- default:
- break;
- }
- }
+uint32 FillMaxDurability(uint32 itemClass, uint32 itemSubClass, uint32 inventoryType, uint32 quality, uint32 itemLevel)
+{
+ if (itemClass != ITEM_CLASS_ARMOR && itemClass != ITEM_CLASS_WEAPON)
+ return 0;
- for (uint8 j = 0; j < MAX_ITEM_PROTO_DAMAGES; ++j)
- {
- if (itemTemplate.Damage[j].DamageType >= MAX_SPELL_SCHOOL)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong dmg_type%d (%u)", entry, j+1, itemTemplate.Damage[j].DamageType);
- itemTemplate.Damage[j].DamageType = 0;
- }
- }
+ static float const qualityMultipliers[MAX_ITEM_QUALITY] =
+ {
+ 1.0f, 1.0f, 1.0f, 1.17f, 1.37f, 1.68f, 0.0f, 0.0f
+ };
- // special format
- if ((itemTemplate.Spells[0].SpellId == 483) || (itemTemplate.Spells[0].SpellId == 55884))
- {
- // spell_1
- if (itemTemplate.Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format", entry, 0+1, itemTemplate.Spells[0].SpellTrigger);
- itemTemplate.Spells[0].SpellId = 0;
- itemTemplate.Spells[0].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- itemTemplate.Spells[1].SpellId = 0;
- itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
+ static float const armorMultipliers[MAX_INVTYPE] =
+ {
+ 0.00f, // INVTYPE_NON_EQUIP
+ 0.59f, // INVTYPE_HEAD
+ 0.00f, // INVTYPE_NECK
+ 0.59f, // INVTYPE_SHOULDERS
+ 0.00f, // INVTYPE_BODY
+ 1.00f, // INVTYPE_CHEST
+ 0.35f, // INVTYPE_WAIST
+ 0.75f, // INVTYPE_LEGS
+ 0.49f, // INVTYPE_FEET
+ 0.35f, // INVTYPE_WRISTS
+ 0.35f, // INVTYPE_HANDS
+ 0.00f, // INVTYPE_FINGER
+ 0.00f, // INVTYPE_TRINKET
+ 0.00f, // INVTYPE_WEAPON
+ 1.00f, // INVTYPE_SHIELD
+ 0.00f, // INVTYPE_RANGED
+ 0.00f, // INVTYPE_CLOAK
+ 0.00f, // INVTYPE_2HWEAPON
+ 0.00f, // INVTYPE_BAG
+ 0.00f, // INVTYPE_TABARD
+ 1.00f, // INVTYPE_ROBE
+ 0.00f, // INVTYPE_WEAPONMAINHAND
+ 0.00f, // INVTYPE_WEAPONOFFHAND
+ 0.00f, // INVTYPE_HOLDABLE
+ 0.00f, // INVTYPE_AMMO
+ 0.00f, // INVTYPE_THROWN
+ 0.00f, // INVTYPE_RANGEDRIGHT
+ 0.00f, // INVTYPE_QUIVER
+ 0.00f, // INVTYPE_RELIC
+ };
- // spell_2 have learning spell
- if (itemTemplate.Spells[1].SpellTrigger != ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u) for special learning format.", entry, 1+1, itemTemplate.Spells[1].SpellTrigger);
- itemTemplate.Spells[0].SpellId = 0;
- itemTemplate.Spells[1].SpellId = 0;
- itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else if (!itemTemplate.Spells[1].SpellId)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not have an expected spell in spellid_%d in special learning format.", entry, 1+1);
- itemTemplate.Spells[0].SpellId = 0;
- itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else if (itemTemplate.Spells[1].SpellId != -1)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[1].SpellId);
- if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[1].SpellId, NULL))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, 1+1, itemTemplate.Spells[1].SpellId);
- itemTemplate.Spells[0].SpellId = 0;
- itemTemplate.Spells[1].SpellId = 0;
- itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- // allowed only in special format
- else if ((itemTemplate.Spells[1].SpellId == 483) || (itemTemplate.Spells[1].SpellId == 55884))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, 1+1, itemTemplate.Spells[1].SpellId);
- itemTemplate.Spells[0].SpellId = 0;
- itemTemplate.Spells[1].SpellId = 0;
- itemTemplate.Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- }
+ static float const weaponMultipliers[MAX_ITEM_SUBCLASS_WEAPON] =
+ {
+ 0.89f, // ITEM_SUBCLASS_WEAPON_AXE
+ 1.03f, // ITEM_SUBCLASS_WEAPON_AXE2
+ 0.77f, // ITEM_SUBCLASS_WEAPON_BOW
+ 0.77f, // ITEM_SUBCLASS_WEAPON_GUN
+ 0.89f, // ITEM_SUBCLASS_WEAPON_MACE
+ 1.03f, // ITEM_SUBCLASS_WEAPON_MACE2
+ 1.03f, // ITEM_SUBCLASS_WEAPON_POLEARM
+ 0.89f, // ITEM_SUBCLASS_WEAPON_SWORD
+ 1.03f, // ITEM_SUBCLASS_WEAPON_SWORD2
+ 0.00f, // ITEM_SUBCLASS_WEAPON_Obsolete
+ 1.03f, // ITEM_SUBCLASS_WEAPON_STAFF
+ 0.00f, // ITEM_SUBCLASS_WEAPON_EXOTIC
+ 0.00f, // ITEM_SUBCLASS_WEAPON_EXOTIC2
+ 0.64f, // ITEM_SUBCLASS_WEAPON_FIST_WEAPON
+ 0.00f, // ITEM_SUBCLASS_WEAPON_MISCELLANEOUS
+ 0.64f, // ITEM_SUBCLASS_WEAPON_DAGGER
+ 0.64f, // ITEM_SUBCLASS_WEAPON_THROWN
+ 0.00f, // ITEM_SUBCLASS_WEAPON_SPEAR
+ 0.77f, // ITEM_SUBCLASS_WEAPON_CROSSBOW
+ 0.64f, // ITEM_SUBCLASS_WEAPON_WAND
+ 0.64f, // ITEM_SUBCLASS_WEAPON_FISHING_POLE
+ };
- // spell_3*, spell_4*, spell_5* is empty
- for (uint8 j = 2; j < MAX_ITEM_PROTO_SPELLS; ++j)
- {
- if (itemTemplate.Spells[j].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j+1, itemTemplate.Spells[j].SpellTrigger);
- itemTemplate.Spells[j].SpellId = 0;
- itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
- else if (itemTemplate.Spells[j].SpellId != 0)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong spell in spellid_%d (%d) for learning special format", entry, j+1, itemTemplate.Spells[j].SpellId);
- itemTemplate.Spells[j].SpellId = 0;
- }
- }
- }
- // normal spell list
- else
- {
- for (uint8 j = 0; j < MAX_ITEM_PROTO_SPELLS; ++j)
- {
- if (itemTemplate.Spells[j].SpellTrigger >= MAX_ITEM_SPELLTRIGGER || itemTemplate.Spells[j].SpellTrigger == ITEM_SPELLTRIGGER_LEARN_SPELL_ID)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong item spell trigger value in spelltrigger_%d (%u)", entry, j+1, itemTemplate.Spells[j].SpellTrigger);
- itemTemplate.Spells[j].SpellId = 0;
- itemTemplate.Spells[j].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;
- }
+ float levelPenalty = 1.0f;
+ if (itemLevel <= 28)
+ levelPenalty = 0.966f - float(28u - itemLevel) / 54.0f;
- if (itemTemplate.Spells[j].SpellId && itemTemplate.Spells[j].SpellId != -1)
- {
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itemTemplate.Spells[j].SpellId);
- if (!spellInfo && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, itemTemplate.Spells[j].SpellId, NULL))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong (not existing) spell in spellid_%d (%d)", entry, j+1, itemTemplate.Spells[j].SpellId);
- itemTemplate.Spells[j].SpellId = 0;
- }
- // allowed only in special format
- else if ((itemTemplate.Spells[j].SpellId == 483) || (itemTemplate.Spells[j].SpellId == 55884))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has broken spell in spellid_%d (%d)", entry, j+1, itemTemplate.Spells[j].SpellId);
- itemTemplate.Spells[j].SpellId = 0;
- }
- }
- }
- }
+ if (itemClass == ITEM_CLASS_ARMOR)
+ {
+ if (inventoryType > INVTYPE_ROBE)
+ return 0;
- if (itemTemplate.Bonding >= MAX_BIND_TYPE)
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Bonding value (%u)", entry, itemTemplate.Bonding);
+ return 5 * uint32(23.0f * qualityMultipliers[quality] * armorMultipliers[inventoryType] * levelPenalty + 0.5f);
+ }
- if (itemTemplate.PageText && !GetPageText(itemTemplate.PageText))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has non existing first page (Id:%u)", entry, itemTemplate.PageText);
+ return 5 * uint32(17.0f * qualityMultipliers[quality] * weaponMultipliers[itemSubClass] * levelPenalty + 0.5f);
+};
- if (itemTemplate.LockID && !sLockStore.LookupEntry(itemTemplate.LockID))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong LockID (%u)", entry, itemTemplate.LockID);
+void FillDisenchantFields(uint32* disenchantID, uint32* requiredDisenchantSkill, ItemTemplate const& itemTemplate)
+{
+ *disenchantID = 0;
+ *(int32*)requiredDisenchantSkill = -1;
+ if ((itemTemplate.Flags & (ITEM_PROTO_FLAG_CONJURED | ITEM_PROTO_FLAG_UNK6)) ||
+ itemTemplate.Bonding == BIND_QUEST_ITEM || itemTemplate.Area || itemTemplate.Map ||
+ itemTemplate.Stackable > 1 ||
+ itemTemplate.Quality < ITEM_QUALITY_UNCOMMON || itemTemplate.Quality > ITEM_QUALITY_EPIC ||
+ !(itemTemplate.Class == ITEM_CLASS_ARMOR || itemTemplate.Class == ITEM_CLASS_WEAPON) ||
+ !(Item::GetSpecialPrice(&itemTemplate) || sItemCurrencyCostStore.LookupEntry(itemTemplate.ItemId)))
+ return;
- if (itemTemplate.Sheath >= MAX_SHEATHETYPE)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Sheath (%u)", entry, itemTemplate.Sheath);
- itemTemplate.Sheath = SHEATHETYPE_NONE;
- }
+ for (uint32 i = 0; i < sItemDisenchantLootStore.GetNumRows(); ++i)
+ {
+ ItemDisenchantLootEntry const* disenchant = sItemDisenchantLootStore.LookupEntry(i);
+ if (!disenchant)
+ continue;
- if (itemTemplate.RandomProperty)
+ if (disenchant->ItemClass == itemTemplate.Class &&
+ disenchant->ItemQuality == itemTemplate.Quality &&
+ disenchant->MinItemLevel <= itemTemplate.ItemLevel &&
+ disenchant->MaxItemLevel >= itemTemplate.ItemLevel)
{
- // To be implemented later
- if (itemTemplate.RandomProperty == -1)
- itemTemplate.RandomProperty = 0;
-
- else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomProperty)))
+ if (disenchant->Id == 60 || disenchant->Id == 61) // epic item disenchant ilvl range 66-99 (classic)
{
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)", entry, itemTemplate.RandomProperty);
- itemTemplate.RandomProperty = 0;
+ if (itemTemplate.RequiredLevel > 60 || itemTemplate.RequiredSkillRank > 300)
+ continue; // skip to epic item disenchant ilvl range 90-199 (TBC)
}
- }
-
- if (itemTemplate.RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(itemTemplate.RandomSuffix)))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong RandomSuffix (%u)", entry, itemTemplate.RandomSuffix);
- itemTemplate.RandomSuffix = 0;
- }
-
- if (itemTemplate.ItemSet && !sItemSetStore.LookupEntry(itemTemplate.ItemSet))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) have wrong ItemSet (%u)", entry, itemTemplate.ItemSet);
- itemTemplate.ItemSet = 0;
- }
-
- if (itemTemplate.Area && !GetAreaEntryByAreaID(itemTemplate.Area))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Area (%u)", entry, itemTemplate.Area);
-
- if (itemTemplate.Map && !sMapStore.LookupEntry(itemTemplate.Map))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong Map (%u)", entry, itemTemplate.Map);
-
- if (itemTemplate.BagFamily)
- {
- // check bits
- for (uint32 j = 0; j < sizeof(itemTemplate.BagFamily)*8; ++j)
+ else if (disenchant->Id == 66 || disenchant->Id == 67) // epic item disenchant ilvl range 90-199 (TBC)
{
- uint32 mask = 1 << j;
- if ((itemTemplate.BagFamily & mask) == 0)
- continue;
-
- ItemBagFamilyEntry const* bf = sItemBagFamilyStore.LookupEntry(j+1);
- if (!bf)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has bag family bit set not listed in ItemBagFamily.dbc, remove bit", entry);
- itemTemplate.BagFamily &= ~mask;
+ if (itemTemplate.RequiredLevel <= 60 || (itemTemplate.RequiredSkill && itemTemplate.RequiredSkillRank <= 300))
continue;
- }
-
- if (BAG_FAMILY_MASK_CURRENCY_TOKENS & mask)
- {
- CurrencyTypesEntry const* ctEntry = sCurrencyTypesStore.LookupEntry(itemTemplate.ItemId);
- if (!ctEntry)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has currency bag family bit set in BagFamily but not listed in CurrencyTypes.dbc, remove bit", entry);
- itemTemplate.BagFamily &= ~mask;
- }
- }
}
- }
-
- if (itemTemplate.TotemCategory && !sTotemCategoryStore.LookupEntry(itemTemplate.TotemCategory))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong TotemCategory (%u)", entry, itemTemplate.TotemCategory);
- for (uint8 j = 0; j < MAX_ITEM_PROTO_SOCKETS; ++j)
- {
- if (itemTemplate.Socket[j].Color && (itemTemplate.Socket[j].Color & SOCKET_COLOR_ALL) != itemTemplate.Socket[j].Color)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong socketColor_%d (%u)", entry, j+1, itemTemplate.Socket[j].Color);
- itemTemplate.Socket[j].Color = 0;
- }
+ *disenchantID = disenchant->Id;
+ *requiredDisenchantSkill = disenchant->RequiredDisenchantSkill;
+ return;
}
+ }
+}
- if (itemTemplate.GemProperties && !sGemPropertiesStore.LookupEntry(itemTemplate.GemProperties))
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong GemProperties (%u)", entry, itemTemplate.GemProperties);
-
- if (itemTemplate.FoodType >= MAX_PET_DIET)
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong FoodType value (%u)", entry, itemTemplate.FoodType);
- itemTemplate.FoodType = 0;
- }
+void ObjectMgr::LoadItemTemplates()
+{
+ uint32 oldMSTime = getMSTime();
+ uint32 sparseCount = 0;
+ uint32 dbCount = 0;
- if (itemTemplate.ItemLimitCategory && !sItemLimitCategoryStore.LookupEntry(itemTemplate.ItemLimitCategory))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong LimitCategory value (%u)", entry, itemTemplate.ItemLimitCategory);
- itemTemplate.ItemLimitCategory = 0;
- }
+ for (uint32 itemId = 0; itemId < sItemSparseStore.GetNumRows(); ++itemId)
+ {
+ ItemSparseEntry const* sparse = sItemSparseStore.LookupEntry(itemId);
+ ItemEntry const* db2Data = sItemStore.LookupEntry(itemId);
+ if (!sparse || !db2Data)
+ continue;
- if (itemTemplate.HolidayId && !sHolidaysStore.LookupEntry(itemTemplate.HolidayId))
- {
- TC_LOG_ERROR("sql.sql", "Item (Entry: %u) has wrong HolidayId value (%u)", entry, itemTemplate.HolidayId);
- itemTemplate.HolidayId = 0;
- }
+ ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
+
+ itemTemplate.ItemId = itemId;
+ itemTemplate.Class = db2Data->Class;
+ itemTemplate.SubClass = db2Data->SubClass;
+ itemTemplate.SoundOverrideSubclass = db2Data->SoundOverrideSubclass;
+ itemTemplate.Name1 = sparse->Name->Str[sWorld->GetDefaultDbcLocale()];
+ itemTemplate.DisplayInfoID = db2Data->DisplayId;
+ itemTemplate.Quality = sparse->Quality;
+ itemTemplate.Flags = sparse->Flags;
+ itemTemplate.Flags2 = sparse->Flags2;
+ itemTemplate.Unk430_1 = sparse->Unk430_1;
+ itemTemplate.Unk430_2 = sparse->Unk430_2;
+ itemTemplate.BuyCount = std::max(sparse->BuyCount, 1u);
+ itemTemplate.BuyPrice = sparse->BuyPrice;
+ itemTemplate.SellPrice = sparse->SellPrice;
+ itemTemplate.InventoryType = db2Data->InventoryType;
+ itemTemplate.AllowableClass = sparse->AllowableClass;
+ itemTemplate.AllowableRace = sparse->AllowableRace;
+ itemTemplate.ItemLevel = sparse->ItemLevel;
+ itemTemplate.RequiredLevel = sparse->RequiredLevel;
+ itemTemplate.RequiredSkill = sparse->RequiredSkill;
+ itemTemplate.RequiredSkillRank = sparse->RequiredSkillRank;
+ itemTemplate.RequiredSpell = sparse->RequiredSpell;
+ itemTemplate.RequiredHonorRank = sparse->RequiredHonorRank;
+ itemTemplate.RequiredCityRank = sparse->RequiredCityRank;
+ itemTemplate.RequiredReputationFaction = sparse->RequiredReputationFaction;
+ itemTemplate.RequiredReputationRank = sparse->RequiredReputationRank;
+ itemTemplate.MaxCount = sparse->MaxCount;
+ itemTemplate.Stackable = sparse->Stackable;
+ itemTemplate.ContainerSlots = sparse->ContainerSlots;
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
+ {
+ itemTemplate.ItemStat[i].ItemStatType = sparse->ItemStatType[i];
+ itemTemplate.ItemStat[i].ItemStatValue = sparse->ItemStatValue[i];
+ itemTemplate.ItemStat[i].ItemStatUnk1 = sparse->ItemStatUnk1[i];
+ itemTemplate.ItemStat[i].ItemStatUnk2 = sparse->ItemStatUnk2[i];
+ }
+
+ itemTemplate.ScalingStatDistribution = sparse->ScalingStatDistribution;
+
+ // cache item damage
+ FillItemDamageFields(&itemTemplate.DamageMin, &itemTemplate.DamageMax, &itemTemplate.DPS, sparse->ItemLevel,
+ db2Data->Class, db2Data->SubClass, sparse->Quality, sparse->Delay, sparse->StatScalingFactor,
+ sparse->InventoryType, sparse->Flags2);
+
+ itemTemplate.DamageType = sparse->DamageType;
+ itemTemplate.Armor = FillItemArmor(sparse->ItemLevel, db2Data->Class, db2Data->SubClass, sparse->Quality, sparse->InventoryType);
+ itemTemplate.Delay = sparse->Delay;
+ itemTemplate.RangedModRange = sparse->RangedModRange;
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ {
+ itemTemplate.Spells[i].SpellId = sparse->SpellId[i];
+ itemTemplate.Spells[i].SpellTrigger = sparse->SpellTrigger[i];
+ itemTemplate.Spells[i].SpellCharges = sparse->SpellCharges[i];
+ itemTemplate.Spells[i].SpellCooldown = sparse->SpellCooldown[i];
+ itemTemplate.Spells[i].SpellCategory = sparse->SpellCategory[i];
+ itemTemplate.Spells[i].SpellCategoryCooldown = sparse->SpellCategoryCooldown[i];
+ }
+
+ itemTemplate.SpellPPMRate = 0.0f;
+ itemTemplate.Bonding = sparse->Bonding;
+ itemTemplate.Description = sparse->Description->Str[sWorld->GetDefaultDbcLocale()];
+ itemTemplate.PageText = sparse->PageText;
+ itemTemplate.LanguageID = sparse->LanguageID;
+ itemTemplate.PageMaterial = sparse->PageMaterial;
+ itemTemplate.StartQuest = sparse->StartQuest;
+ itemTemplate.LockID = sparse->LockID;
+ itemTemplate.Material = sparse->Material;
+ itemTemplate.Sheath = sparse->Sheath;
+ itemTemplate.RandomProperty = sparse->RandomProperty;
+ itemTemplate.RandomSuffix = sparse->RandomSuffix;
+ itemTemplate.ItemSet = sparse->ItemSet;
+ itemTemplate.MaxDurability = FillMaxDurability(db2Data->Class, db2Data->SubClass, sparse->InventoryType, sparse->Quality, sparse->ItemLevel);
+ itemTemplate.Area = sparse->Area;
+ itemTemplate.Map = sparse->Map;
+ itemTemplate.BagFamily = sparse->BagFamily;
+ itemTemplate.TotemCategory = sparse->TotemCategory;
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
+ {
+ itemTemplate.Socket[i].Color = sparse->Color[i];
+ itemTemplate.Socket[i].Content = sparse->Content[i];
+ }
+
+ itemTemplate.socketBonus = sparse->SocketBonus;
+ itemTemplate.GemProperties = sparse->GemProperties;
+ FillDisenchantFields(&itemTemplate.DisenchantID, &itemTemplate.RequiredDisenchantSkill, itemTemplate);
+
+ itemTemplate.ArmorDamageModifier = sparse->ArmorDamageModifier;
+ itemTemplate.Duration = sparse->Duration;
+ itemTemplate.ItemLimitCategory = sparse->ItemLimitCategory;
+ itemTemplate.HolidayId = sparse->HolidayId;
+ itemTemplate.StatScalingFactor = sparse->StatScalingFactor;
+ itemTemplate.CurrencySubstitutionId = sparse->CurrencySubstitutionId;
+ itemTemplate.CurrencySubstitutionCount = sparse->CurrencySubstitutionCount;
+ itemTemplate.ScriptId = 0;
+ itemTemplate.FoodType = 0;
+ itemTemplate.MinMoneyLoot = 0;
+ itemTemplate.MaxMoneyLoot = 0;
+ ++sparseCount;
+ }
+
+ // Load missing items from item_template AND overwrite data from Item-sparse.db2 (item_template is supposed to contain Item-sparse.adb data)
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ QueryResult result = WorldDatabase.Query("SELECT entry, Class, SubClass, SoundOverrideSubclass, Name, DisplayId, Quality, Flags, FlagsExtra, Unk430_1, Unk430_2, BuyCount, BuyPrice, SellPrice, "
+ // 14 15 16 17 18 19 20 21
+ "InventoryType, AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, RequiredSpell, "
+ // 22 23 24 25 26 27 28
+ "RequiredHonorRank, RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, MaxCount, Stackable, ContainerSlots, "
+ // 29 30 31 32 33 34 35 36
+ "stat_type1, stat_value1, stat_unk1_1, stat_unk2_1, stat_type2, stat_value2, stat_unk1_2, stat_unk2_2, "
+ // 37 38 39 40 41 42 43 44
+ "stat_type3, stat_value3, stat_unk1_3, stat_unk2_3, stat_type4, stat_value4, stat_unk1_4, stat_unk2_4, "
+ // 45 46 47 48 49 50 51 52
+ "stat_type5, stat_value5, stat_unk1_5, stat_unk2_5, stat_type6, stat_value6, stat_unk1_6, stat_unk2_6, "
+ // 53 54 55 56 57 58 59 60
+ "stat_type7, stat_value7, stat_unk1_7, stat_unk2_7, stat_type8, stat_value8, stat_unk1_8, stat_unk2_8, "
+ // 61 62 63 64 65 66 67 68
+ "stat_type9, stat_value9, stat_unk1_9, stat_unk2_9, stat_type10, stat_value10, stat_unk1_10, stat_unk2_10, "
+ // 69 70 71 72
+ "ScalingStatDistribution, DamageType, Delay, RangedModRange, "
+ // 73 74 75 76 77 78
+ "spellid_1, spelltrigger_1, spellcharges_1, spellcooldown_1, spellcategory_1, spellcategorycooldown_1, "
+ // 79 80 81 82 83 84
+ "spellid_2, spelltrigger_2, spellcharges_2, spellcooldown_2, spellcategory_2, spellcategorycooldown_2, "
+ // 85 86 87 88 89 90
+ "spellid_3, spelltrigger_3, spellcharges_3, spellcooldown_3, spellcategory_3, spellcategorycooldown_3, "
+ // 91 92 93 94 95 96
+ "spellid_4, spelltrigger_4, spellcharges_4, spellcooldown_4, spellcategory_4, spellcategorycooldown_4, "
+ // 97 98 99 100 101 102
+ "spellid_5, spelltrigger_5, spellcharges_5, spellcooldown_5, spellcategory_5, spellcategorycooldown_5, "
+ // 103 104 105 106 107 108 109 110
+ "Bonding, Description, PageText, LanguageID, PageMaterial, StartQuest, LockID, Material, "
+ // 111 112 113 114 115 116 117 118
+ "Sheath, RandomProperty, RandomSuffix, ItemSet, Area, Map, BagFamily, TotemCategory, "
+ // 119 120 121 122 123 124 125
+ "SocketColor_1, SocketContent_1, SocketColor_2, SocketContent_2, SocketColor_3, SocketContent_3, SocketBonus, "
+ // 126 127 128 129 130 131
+ "GemProperties, ArmorDamageModifier, Duration, ItemLimitCategory, HolidayId, StatScalingFactor, "
+ // 132 133
+ "CurrencySubstitutionId, CurrencySubstitutionCount "
+ "FROM item_template");
- if (itemTemplate.FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME && !itemTemplate.Duration)
+ if (result)
+ {
+ do
{
- TC_LOG_ERROR("sql.sql", "Item (Entry %u) has flag ITEM_FLAGS_CU_DURATION_REAL_TIME but it does not have duration limit", entry);
- itemTemplate.FlagsCu &= ~ITEM_FLAGS_CU_DURATION_REAL_TIME;
- }
-
- ++count;
+ Field* fields = result->Fetch();
+ uint32 itemId = fields[0].GetUInt32();
+ if (_itemTemplateStore.find(itemId) != _itemTemplateStore.end())
+ --sparseCount;
+
+ ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
+
+ itemTemplate.ItemId = itemId;
+ itemTemplate.Class = uint32(fields[1].GetUInt8());
+ itemTemplate.SubClass = uint32(fields[2].GetUInt8());
+ itemTemplate.SoundOverrideSubclass = fields[3].GetInt32();
+ itemTemplate.Name1 = fields[4].GetString();
+ itemTemplate.DisplayInfoID = fields[5].GetUInt32();
+ itemTemplate.Quality = uint32(fields[6].GetUInt8());
+ itemTemplate.Flags = fields[7].GetUInt32();
+ itemTemplate.Flags2 = fields[8].GetUInt32();
+ itemTemplate.Unk430_1 = fields[9].GetFloat();
+ itemTemplate.Unk430_2 = fields[10].GetFloat();
+ itemTemplate.BuyCount = uint32(fields[11].GetUInt8());
+ itemTemplate.BuyPrice = int32(fields[12].GetInt64());
+ itemTemplate.SellPrice = fields[13].GetUInt32();
+
+ itemTemplate.InventoryType = uint32(fields[14].GetUInt8());
+ itemTemplate.AllowableClass = fields[15].GetInt32();
+ itemTemplate.AllowableRace = fields[16].GetInt32();
+ itemTemplate.ItemLevel = uint32(fields[17].GetUInt16());
+ itemTemplate.RequiredLevel = uint32(fields[18].GetUInt8());
+ itemTemplate.RequiredSkill = uint32(fields[19].GetUInt16());
+ itemTemplate.RequiredSkillRank = uint32(fields[20].GetUInt16());
+ itemTemplate.RequiredSpell = fields[21].GetUInt32();
+ itemTemplate.RequiredHonorRank = fields[22].GetUInt32();
+ itemTemplate.RequiredCityRank = fields[23].GetUInt32();
+ itemTemplate.RequiredReputationFaction = uint32(fields[24].GetUInt16());
+ itemTemplate.RequiredReputationRank = uint32(fields[25].GetUInt16());
+ itemTemplate.MaxCount = fields[26].GetInt32();
+ itemTemplate.Stackable = fields[27].GetInt32();
+ itemTemplate.ContainerSlots = uint32(fields[28].GetUInt8());
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
+ {
+ itemTemplate.ItemStat[i].ItemStatType = uint32(fields[29 + i * 4 + 0].GetUInt8());
+ itemTemplate.ItemStat[i].ItemStatValue = int32(fields[29 + i * 4 + 1].GetInt16());
+ itemTemplate.ItemStat[i].ItemStatUnk1 = fields[29 + i * 4 + 2].GetInt32();
+ itemTemplate.ItemStat[i].ItemStatUnk2 = fields[29 + i * 4 + 3].GetInt32();
+ }
+
+ itemTemplate.ScalingStatDistribution = uint32(fields[69].GetUInt16());
+
+ // cache item damage
+ FillItemDamageFields(&itemTemplate.DamageMin, &itemTemplate.DamageMax, &itemTemplate.DPS, itemTemplate.ItemLevel,
+ itemTemplate.Class, itemTemplate.SubClass, itemTemplate.Quality, fields[71].GetUInt16(),
+ fields[131].GetFloat(), itemTemplate.InventoryType, itemTemplate.Flags2);
+
+ itemTemplate.DamageType = fields[70].GetUInt8();
+ itemTemplate.Armor = FillItemArmor(itemTemplate.ItemLevel, itemTemplate.Class,
+ itemTemplate.SubClass, itemTemplate.Quality,
+ itemTemplate.InventoryType);
+
+ itemTemplate.Delay = fields[71].GetUInt16();
+ itemTemplate.RangedModRange = fields[72].GetFloat();
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
+ {
+ itemTemplate.Spells[i].SpellId = fields[73 + 6 * i + 0].GetInt32();
+ itemTemplate.Spells[i].SpellTrigger = uint32(fields[73 + 6 * i + 1].GetUInt8());
+ itemTemplate.Spells[i].SpellCharges = int32(fields[73 + 6 * i + 2].GetInt16());
+ itemTemplate.Spells[i].SpellCooldown = fields[73 + 6 * i + 3].GetInt32();
+ itemTemplate.Spells[i].SpellCategory = uint32(fields[73 + 6 * i + 4].GetUInt16());
+ itemTemplate.Spells[i].SpellCategoryCooldown = fields[73 + 6 * i + 5].GetInt32();
+ }
+
+ itemTemplate.SpellPPMRate = 0.0f;
+ itemTemplate.Bonding = uint32(fields[103].GetUInt8());
+ itemTemplate.Description = fields[104].GetString();
+ itemTemplate.PageText = fields[105].GetUInt32();
+ itemTemplate.LanguageID = uint32(fields[106].GetUInt8());
+ itemTemplate.PageMaterial = uint32(fields[107].GetUInt8());
+ itemTemplate.StartQuest = fields[108].GetUInt32();
+ itemTemplate.LockID = fields[109].GetUInt32();
+ itemTemplate.Material = int32(fields[110].GetInt8());
+ itemTemplate.Sheath = uint32(fields[111].GetUInt8());
+ itemTemplate.RandomProperty = fields[112].GetUInt32();
+ itemTemplate.RandomSuffix = fields[113].GetInt32();
+ itemTemplate.ItemSet = fields[114].GetUInt32();
+ itemTemplate.MaxDurability = FillMaxDurability(itemTemplate.Class, itemTemplate.SubClass,
+ itemTemplate.InventoryType, itemTemplate.Quality, itemTemplate.ItemLevel);
+
+ itemTemplate.Area = fields[115].GetUInt32();
+ itemTemplate.Map = uint32(fields[116].GetUInt16());
+ itemTemplate.BagFamily = fields[117].GetUInt32();
+ itemTemplate.TotemCategory = fields[118].GetUInt32();
+ for (uint32 i = 0; i < MAX_ITEM_PROTO_SOCKETS; ++i)
+ {
+ itemTemplate.Socket[i].Color = uint32(fields[119 + i*2].GetUInt8());
+ itemTemplate.Socket[i].Content = fields[119 + i * 2 + 1].GetUInt32();
+ }
+
+ itemTemplate.socketBonus = fields[125].GetUInt32();
+ itemTemplate.GemProperties = fields[126].GetUInt32();
+ FillDisenchantFields(&itemTemplate.DisenchantID, &itemTemplate.RequiredDisenchantSkill, itemTemplate);
+
+ itemTemplate.ArmorDamageModifier = fields[127].GetFloat();
+ itemTemplate.Duration = fields[128].GetUInt32();
+ itemTemplate.ItemLimitCategory = uint32(fields[129].GetInt16());
+ itemTemplate.HolidayId = fields[130].GetUInt32();
+ itemTemplate.StatScalingFactor = fields[131].GetFloat();
+ itemTemplate.CurrencySubstitutionId = fields[132].GetInt32();
+ itemTemplate.CurrencySubstitutionCount = fields[133].GetInt32();
+ itemTemplate.ScriptId = 0;
+ itemTemplate.FoodType = 0;
+ itemTemplate.MinMoneyLoot = 0;
+ itemTemplate.MaxMoneyLoot = 0;
+ ++dbCount;
+ } while (result->NextRow());
}
- while (result->NextRow());
// Check if item templates for DBC referenced character start outfit are present
std::set<uint32> notFoundOutfit;
@@ -2786,124 +2734,77 @@ void ObjectMgr::LoadItemTemplates()
for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr)
TC_LOG_ERROR("sql.sql", "Item (Entry: %u) does not exist in `item_template` but is referenced in `CharStartOutfit.dbc`", *itr);
- TC_LOG_INFO("server.loading", ">> Loaded %u item templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u item templates from Item-sparse.db2 and %u from database in %u ms", sparseCount, dbCount, GetMSTimeDiffToNow(oldMSTime));
}
-ItemTemplate const* ObjectMgr::GetItemTemplate(uint32 entry)
-{
- ItemTemplateContainer::const_iterator itr = _itemTemplateStore.find(entry);
- if (itr != _itemTemplateStore.end())
- return &(itr->second);
-
- return NULL;
-}
-
-void ObjectMgr::LoadItemSetNameLocales()
+void ObjectMgr::LoadItemTemplateAddon()
{
uint32 oldMSTime = getMSTime();
+ uint32 count = 0;
- _itemSetNameLocaleStore.clear(); // need for reload case
-
- QueryResult result = WorldDatabase.Query("SELECT `entry`, `name_loc1`, `name_loc2`, `name_loc3`, `name_loc4`, `name_loc5`, `name_loc6`, `name_loc7`, `name_loc8` FROM `locales_item_set_names`");
-
- if (!result)
- return;
-
- do
+ QueryResult result = WorldDatabase.Query("SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon");
+ if (result)
{
- Field* fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
-
- ItemSetNameLocale& data = _itemSetNameLocaleStore[entry];
-
- for (uint8 i = 1; i < TOTAL_LOCALES; ++i)
- AddLocaleString(fields[i].GetString(), LocaleConstant(i), data.Name);
- } while (result->NextRow());
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemId = fields[0].GetUInt32();
+ if (!GetItemTemplate(itemId))
+ {
+ TC_LOG_ERROR("sql.sql", "Item %u specified in `item_template_addon` does not exist, skipped.", itemId);
+ continue;
+ }
- TC_LOG_INFO("server.loading", ">> Loaded " UI64FMTD " Item set name locale strings in %u ms", uint64(_itemSetNameLocaleStore.size()), GetMSTimeDiffToNow(oldMSTime));
+ uint32 minMoneyLoot = fields[3].GetUInt32();
+ uint32 maxMoneyLoot = fields[4].GetUInt32();
+ if (minMoneyLoot > maxMoneyLoot)
+ {
+ TC_LOG_ERROR("sql.sql", "Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId);
+ std::swap(minMoneyLoot, maxMoneyLoot);
+ }
+ ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
+ itemTemplate.FlagsCu = fields[1].GetUInt32();
+ itemTemplate.FoodType = fields[2].GetUInt8();
+ itemTemplate.MinMoneyLoot = minMoneyLoot;
+ itemTemplate.MaxMoneyLoot = maxMoneyLoot;
+ itemTemplate.SpellPPMRate = fields[5].GetFloat();
+ ++count;
+ } while (result->NextRow());
+ }
+ TC_LOG_INFO("server.loading", ">> Loaded %u item addon templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::LoadItemSetNames()
+void ObjectMgr::LoadItemScriptNames()
{
uint32 oldMSTime = getMSTime();
-
- _itemSetNameStore.clear(); // needed for reload case
-
- std::set<uint32> itemSetItems;
-
- // fill item set member ids
- for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId)
- {
- ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId);
- if (!setEntry)
- continue;
-
- for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i)
- if (setEntry->itemId[i])
- itemSetItems.insert(setEntry->itemId[i]);
- }
-
- // 0 1 2
- QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
-
- if (!result)
- {
- TC_LOG_INFO("server.loading", ">> Loaded 0 item set names. DB table `item_set_names` is empty.");
- return;
- }
-
- _itemSetNameStore.rehash(result->GetRowCount());
uint32 count = 0;
- do
- {
- Field* fields = result->Fetch();
-
- uint32 entry = fields[0].GetUInt32();
- if (itemSetItems.find(entry) == itemSetItems.end())
- {
- TC_LOG_ERROR("sql.sql", "Item set name (Entry: %u) not found in ItemSet.dbc, data useless.", entry);
- continue;
- }
-
- ItemSetNameEntry &data = _itemSetNameStore[entry];
- data.name = fields[1].GetString();
-
- uint32 invType = fields[2].GetUInt8();
- if (invType >= MAX_INVTYPE)
- {
- TC_LOG_ERROR("sql.sql", "Item set name (Entry: %u) has wrong InventoryType value (%u)", entry, invType);
- invType = INVTYPE_NON_EQUIP;
- }
-
- data.InventoryType = invType;
- itemSetItems.erase(entry);
- ++count;
- } while (result->NextRow());
-
- if (!itemSetItems.empty())
+ QueryResult result = WorldDatabase.Query("SELECT Id, ScriptName FROM item_script_names");
+ if (result)
{
- ItemTemplate const* pProto;
- for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr)
+ do
{
- uint32 entry = *itr;
- // add data from item_template if available
- pProto = sObjectMgr->GetItemTemplate(entry);
- if (pProto)
+ Field* fields = result->Fetch();
+ uint32 itemId = fields[0].GetUInt32();
+ if (!GetItemTemplate(itemId))
{
- TC_LOG_ERROR("sql.sql", "Item set part (Entry: %u) does not have entry in `item_set_names`, adding data from `item_template`.", entry);
- ItemSetNameEntry &data = _itemSetNameStore[entry];
- data.name = pProto->Name1;
- data.InventoryType = pProto->InventoryType;
- ++count;
+ TC_LOG_ERROR("sql.sql", "Item %u specified in `item_script_names` does not exist, skipped.", itemId);
+ continue;
}
- else
- TC_LOG_ERROR("sql.sql", "Item set part (Entry: %u) does not have entry in `item_set_names`, set will not display properly.", entry);
- }
+
+ _itemTemplateStore[itemId].ScriptId = GetScriptId(fields[1].GetCString());
+ ++count;
+ } while (result->NextRow());
}
- TC_LOG_INFO("server.loading", ">> Loaded %u item set names in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ TC_LOG_INFO("server.loading", ">> Loaded %u item script names in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+ItemTemplate const* ObjectMgr::GetItemTemplate(uint32 entry)
+{
+ ItemTemplateContainer::const_iterator itr = _itemTemplateStore.find(entry);
+ if (itr != _itemTemplateStore.end())
+ return &(itr->second);
+ return NULL;
}
void ObjectMgr::LoadVehicleTemplateAccessories()
@@ -3406,88 +3307,6 @@ void ObjectMgr::LoadPlayerInfo()
}
}
- // Loading levels data (class only dependent)
- TC_LOG_INFO("server.loading", "Loading Player Create Level HP/Mana Data...");
- {
- uint32 oldMSTime = getMSTime();
-
- // 0 1 2 3
- QueryResult result = WorldDatabase.Query("SELECT class, level, basehp, basemana FROM player_classlevelstats");
-
- if (!result)
- {
- TC_LOG_ERROR("server.loading", ">> Loaded 0 level health/mana definitions. DB table `player_classlevelstats` is empty.");
- exit(1);
- }
-
- uint32 count = 0;
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 current_class = fields[0].GetUInt8();
- if (current_class >= MAX_CLASSES)
- {
- TC_LOG_ERROR("sql.sql", "Wrong class %u in `player_classlevelstats` table, ignoring.", current_class);
- continue;
- }
-
- uint8 current_level = fields[1].GetUInt8(); // Can't be > than STRONG_MAX_LEVEL (hardcoded level maximum) due to var type
- if (current_level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
- {
- TC_LOG_INFO("misc", "Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_classlevelstats` table, ignoring.", current_level);
- ++count; // make result loading percent "expected" correct in case disabled detail mode for example.
- continue;
- }
-
- PlayerClassInfo* info = _playerClassInfo[current_class];
- if (!info)
- {
- info = new PlayerClassInfo();
- info->levelInfo = new PlayerClassLevelInfo[sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL)];
- _playerClassInfo[current_class] = info;
- }
-
- PlayerClassLevelInfo& levelInfo = info->levelInfo[current_level-1];
-
- levelInfo.basehealth = fields[2].GetUInt16();
- levelInfo.basemana = fields[3].GetUInt16();
-
- ++count;
- }
- while (result->NextRow());
-
- // Fill gaps and check integrity
- for (int class_ = 0; class_ < MAX_CLASSES; ++class_)
- {
- // skip non existed classes
- if (!sChrClassesStore.LookupEntry(class_))
- continue;
-
- PlayerClassInfo* pClassInfo = _playerClassInfo[class_];
-
- // fatal error if no level 1 data
- if (!pClassInfo->levelInfo || pClassInfo->levelInfo[0].basehealth == 0)
- {
- TC_LOG_ERROR("sql.sql", "Class %i Level 1 does not have health/mana data!", class_);
- exit(1);
- }
-
- // fill level gaps
- for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL); ++level)
- {
- if (pClassInfo->levelInfo[level].basehealth == 0)
- {
- TC_LOG_ERROR("sql.sql", "Class %i Level %i does not have health/mana data. Using stats data of level %i.", class_, level + 1, level);
- pClassInfo->levelInfo[level] = pClassInfo->levelInfo[level - 1];
- }
- }
- }
-
- TC_LOG_INFO("server.loading", ">> Loaded %u level health/mana definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
- }
-
// Loading levels data (class/race dependent)
TC_LOG_INFO("server.loading", "Loading Player Create Level Stats Data...");
{
@@ -3574,6 +3393,10 @@ void ObjectMgr::LoadPlayerInfo()
if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_WRATH_OF_THE_LICH_KING && class_ == CLASS_DEATH_KNIGHT)
continue;
+ // skip expansion races if not playing with expansion
+ if (sWorld->getIntConfig(CONFIG_EXPANSION) < EXPANSION_CATACLYSM && (race == RACE_GOBLIN || race == RACE_WORGEN))
+ continue;
+
// fatal error if no level 1 data
if (!info->levelInfo || info->levelInfo[0].stats[0] == 0)
{
@@ -3654,17 +3477,25 @@ void ObjectMgr::LoadPlayerInfo()
}
}
-void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint8 level, PlayerClassLevelInfo* info) const
+void ObjectMgr::GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& baseHP, uint32& baseMana) const
{
if (level < 1 || class_ >= MAX_CLASSES)
return;
- PlayerClassInfo const* pInfo = _playerClassInfo[class_];
-
if (level > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL))
level = sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL);
- *info = pInfo->levelInfo[level-1];
+ GtOCTBaseHPByClassEntry const* hp = sGtOCTBaseHPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1);
+ GtOCTBaseMPByClassEntry const* mp = sGtOCTBaseMPByClassStore.LookupEntry((class_-1) * GT_MAX_LEVEL + level-1);
+
+ if (!hp || !mp)
+ {
+ TC_LOG_ERROR("misc", "Tried to get non-existant Class-Level combination data for base hp/mp. Class %u Level %u", class_, level);
+ return;
+ }
+
+ baseHP = uint32(hp->ratio);
+ baseMana = uint32(mp->ratio);
}
void ObjectMgr::GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const
@@ -3776,30 +3607,34 @@ void ObjectMgr::LoadQuests()
"RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, RequiredMinRepFaction, RequiredMaxRepFaction, RequiredMinRepValue, RequiredMaxRepValue, "
// 21 22 23 24 25 26 27 28 29 30 31
"PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, "
- // 32 33 34 35 36 37 38 39 40 41 42
- "RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, RewardTitleId, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
- // 43 44 45 46 47 48 49 50
- "RewardItemId1, RewardItemId2, RewardItemId3, RewardItemId4, RewardItemCount1, RewardItemCount2, RewardItemCount3, RewardItemCount4, "
- // 51 52 53 54 55 56 57 58 59 60 61 62
+ // 32 33 34 35 36 37 38 39 40 41 42 43
+ "RewardMailTemplateId, RewardMailDelay, SourceItemId, SourceItemCount, SourceSpellId, Flags, SpecialFlags, MinimapTargetMark, RewardTitleId, RequiredPlayerKills, RewardTalents, RewardArenaPoints, "
+ // 44 45 46 47 48 49 50 51 52 53 54 55 56
+ "RewardSkillId, RewardSkillPoints, RewardReputationMask, QuestGiverPortrait, QuestTurnInPortrait, RewardItemId1, RewardItemId2, RewardItemId3, RewardItemId4, RewardItemCount1, RewardItemCount2, RewardItemCount3, RewardItemCount4, "
+ // 57 58 59 60 61 62 63 64 65 66 67 68
"RewardChoiceItemId1, RewardChoiceItemId2, RewardChoiceItemId3, RewardChoiceItemId4, RewardChoiceItemId5, RewardChoiceItemId6, RewardChoiceItemCount1, RewardChoiceItemCount2, RewardChoiceItemCount3, RewardChoiceItemCount4, RewardChoiceItemCount5, RewardChoiceItemCount6, "
- // 63 64 65 66 67 68 69 70 71 72
+ // 69 70 71 72 73 74 75 76 77 78
"RewardFactionId1, RewardFactionId2, RewardFactionId3, RewardFactionId4, RewardFactionId5, RewardFactionValueId1, RewardFactionValueId2, RewardFactionValueId3, RewardFactionValueId4, RewardFactionValueId5, "
- // 73 74 75 76 77
+ // 79 80 81 82 83
"RewardFactionValueIdOverride1, RewardFactionValueIdOverride2, RewardFactionValueIdOverride3, RewardFactionValueIdOverride4, RewardFactionValueIdOverride5, "
- // 78 79 80 81
- "PointMapId, PointX, PointY, PointOption, "
- // 82 83 84 85 86 87 88
- "Title, Objectives, Details, EndText, OfferRewardText, RequestItemsText, CompletedText, "
- // 89 90 91 92 93 94 95 96
+ // 84 85 86 87 88 89 90 91 92 93 94
+ "PointMapId, PointX, PointY, PointOption, Title, Objectives, Details, EndText, CompletedText, OfferRewardText, RequestItemsText, "
+ // 95 96 97 98 99 100 101 102
"RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, "
- // 97 98 99 100 101 102 103 104
+ // 103 104 105 106 107 108 109 110
"RequiredSourceItemId1, RequiredSourceItemId2, RequiredSourceItemId3, RequiredSourceItemId4, RequiredSourceItemCount1, RequiredSourceItemCount2, RequiredSourceItemCount3, RequiredSourceItemCount4, "
- // 105 106 107 108 109 110 111 112 113 114 115 116
+ // 111 112 113 114 115 116 117 118 119 120 121 122
"RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, "
- // 117 118 119 120 121 122 123 124 125 126 127 128 129
- "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, "
- // 130 131 132 133 134 135 136 137 138 139 140
- "EmoteOnIncomplete, EmoteOnComplete, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, WDBVerified"
+ // 123 124 125 126 127 128 129 130 131 132 133 134 135
+ "RequiredSpell, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4, RewardCurrencyId1, RewardCurrencyId2, RewardCurrencyId3, RewardCurrencyId4, RewardCurrencyCount1, RewardCurrencyCount2, RewardCurrencyCount3, RewardCurrencyCount4, "
+ // 136 137 138 139 140 141 142 143
+ "RequiredCurrencyId1, RequiredCurrencyId2, RequiredCurrencyId3, RequiredCurrencyId4, RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, "
+ // 144 145 146 147 148 149
+ "QuestGiverTextWindow, QuestGiverTargetName, QuestTurnTextWindow, QuestTurnTargetName, SoundAccept, SoundTurnIn, "
+ // 150 151 152 153 154 155 156 157 158 159
+ "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4, DetailsEmoteDelay1, DetailsEmoteDelay2, DetailsEmoteDelay3, DetailsEmoteDelay4, EmoteOnIncomplete, EmoteOnComplete, "
+ // 160 161 162 163 164 165 166 167 168
+ "OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4, OfferRewardEmoteDelay1, OfferRewardEmoteDelay2, OfferRewardEmoteDelay3, OfferRewardEmoteDelay4, WDBVerified"
" FROM quest_template");
if (!result)
{
@@ -3827,7 +3662,7 @@ void ObjectMgr::LoadQuests()
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_QUEST, iter->first, NULL))
continue;
- Quest * qinfo = iter->second;
+ Quest* qinfo = iter->second;
// additional quest integrity checks (GO, creature_template and item_template must be loaded already)
@@ -3888,6 +3723,12 @@ void ObjectMgr::LoadQuests()
}
}
+ if (qinfo->MinLevel == uint32(-1) || qinfo->MinLevel > DEFAULT_MAX_LEVEL)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u should be disabled because `MinLevel` = %i", qinfo->GetQuestId(), int32(qinfo->MinLevel));
+ // no changes needed, sending -1 in SMSG_QUEST_QUERY_RESPONSE is valid
+ }
+
// client quest log visual (area case)
if (qinfo->ZoneOrSort > 0)
{
@@ -3931,13 +3772,13 @@ void ObjectMgr::LoadQuests()
}
// RequiredRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race
if (qinfo->RequiredRaces)
- {
+ {
if (!(qinfo->RequiredRaces & RACEMASK_ALL_PLAYABLE))
{
TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `RequiredRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->RequiredRaces);
qinfo->RequiredRaces = 0;
}
- }
+ }
// RequiredSkillId, can be 0
if (qinfo->RequiredSkillId)
{
@@ -4097,7 +3938,7 @@ void ObjectMgr::LoadQuests()
qinfo->RequiredItemCount[j] = 0; // prevent incorrect work of quest
}
}
- else if (qinfo->RequiredItemCount[j]>0)
+ else if (qinfo->RequiredItemCount[j] > 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredItemId%d` = 0 but `RequiredItemCount%d` = %u, quest can't be done.",
qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredItemCount[j]);
@@ -4329,26 +4170,149 @@ void ObjectMgr::LoadQuests()
qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId());
}
+ for (uint8 j = 0; j < QUEST_REWARD_CURRENCY_COUNT; ++j)
+ {
+ if (qinfo->RewardCurrencyId[j])
+ {
+ if (qinfo->RewardCurrencyCount[j] == 0)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardCurrencyId%d` = %u but `RewardCurrencyCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(), j+1, qinfo->RewardCurrencyId[j], j+1);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if (!sCurrencyTypesStore.LookupEntry(qinfo->RewardCurrencyId[j]))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardCurrencyId%d` = %u but currency with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(), j+1, qinfo->RewardCurrencyId[j], qinfo->RewardCurrencyId[j]);
+ qinfo->RewardCurrencyCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+ else if (qinfo->RewardCurrencyCount[j] > 0)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardCurrencyId%d` = 0 but `RewardCurrencyCount%d` = %u, quest can't be done.",
+ qinfo->GetQuestId(), j+1, j+1, qinfo->RewardCurrencyCount[j]);
+ qinfo->RewardCurrencyCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+
+ for (uint8 j = 0; j < QUEST_REQUIRED_CURRENCY_COUNT; ++j)
+ {
+ if (qinfo->RequiredCurrencyId[j])
+ {
+ if (qinfo->RequiredCurrencyCount[j] == 0)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = %u but `RequiredCurrencyCount%d` = 0, quest can't be done.",
+ qinfo->GetQuestId(), j+1, qinfo->RequiredCurrencyId[j], j+1);
+ // no changes, quest can't be done for this requirement
+ }
+
+ if (!sCurrencyTypesStore.LookupEntry(qinfo->RequiredCurrencyId[j]))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = %u but currency with entry %u does not exist, quest can't be done.",
+ qinfo->GetQuestId(), j+1, qinfo->RequiredCurrencyId[j], qinfo->RequiredCurrencyId[j]);
+ qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+ else if (qinfo->RequiredCurrencyCount[j] > 0)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredCurrencyId%d` = 0 but `RequiredCurrencyCount%d` = %u, quest can't be done.",
+ qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredCurrencyCount[j]);
+ qinfo->RequiredCurrencyCount[j] = 0; // prevent incorrect work of quest
+ }
+ }
+
+ if (qinfo->SoundAccept)
+ {
+ if (!sSoundEntriesStore.LookupEntry(qinfo->SoundAccept))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `SoundAccept` = %u but sound %u does not exist, set to 0.",
+ qinfo->GetQuestId(), qinfo->SoundAccept, qinfo->SoundAccept);
+ qinfo->SoundAccept = 0; // no sound will be played
+ }
+ }
+
+ if (qinfo->SoundTurnIn)
+ {
+ if (!sSoundEntriesStore.LookupEntry(qinfo->SoundTurnIn))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `SoundTurnIn` = %u but sound %u does not exist, set to 0.",
+ qinfo->GetQuestId(), qinfo->SoundTurnIn, qinfo->SoundTurnIn);
+ qinfo->SoundTurnIn = 0; // no sound will be played
+ }
+ }
+
+ if (qinfo->RequiredSpell > 0)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RequiredSpell);
+
+ if (!spellInfo)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSpell` = %u but spell %u does not exist, quest will not require a spell.",
+ qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell);
+ qinfo->RequiredSpell = 0; // no spell will be required
+ }
+
+ else if (!SpellMgr::IsSpellValid(spellInfo))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSpell` = %u but spell %u is broken, quest will not require a spell.",
+ qinfo->GetQuestId(), qinfo->RequiredSpell, qinfo->RequiredSpell);
+ qinfo->RequiredSpell = 0; // no spell will be required
+ }
+
+ /* Can we require talents?
+ else if (GetTalentSpellCost(qinfo->RewardSpellCast))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
+ qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
+ qinfo->RewardSpellCast = 0; // no spell will be casted on player
+ }
+ }*/
+ }
+
+ if (qinfo->RewardSkillId)
+ {
+ if (!sSkillLineStore.LookupEntry(qinfo->RewardSkillId))
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillId` = %u but this skill does not exist",
+ qinfo->GetQuestId(), qinfo->RewardSkillId);
+ }
+ if (!qinfo->RewardSkillPoints)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillId` = %u but `RewardSkillPoints` is 0",
+ qinfo->GetQuestId(), qinfo->RewardSkillId);
+ }
+ }
+
+ if (qinfo->RewardSkillPoints)
+ {
+ if (qinfo->RewardSkillPoints > sWorld->GetConfigMaxSkillValue())
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillPoints` = %u but max possible skill is %u, quest can't be done.",
+ qinfo->GetQuestId(), qinfo->RewardSkillPoints, sWorld->GetConfigMaxSkillValue());
+ // no changes, quest can't be done for this requirement
+ }
+ if (!qinfo->RewardSkillId)
+ {
+ TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSkillPoints` = %u but `RewardSkillId` is 0",
+ qinfo->GetQuestId(), qinfo->RewardSkillPoints);
+ }
+ }
+
// fill additional data stores
if (qinfo->PrevQuestId)
{
if (_questTemplates.find(abs(qinfo->GetPrevQuestId())) == _questTemplates.end())
- {
TC_LOG_ERROR("sql.sql", "Quest %d has PrevQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetPrevQuestId());
- }
else
- {
qinfo->prevQuests.push_back(qinfo->PrevQuestId);
- }
}
if (qinfo->NextQuestId)
{
QuestMap::iterator qNextItr = _questTemplates.find(abs(qinfo->GetNextQuestId()));
if (qNextItr == _questTemplates.end())
- {
TC_LOG_ERROR("sql.sql", "Quest %d has NextQuestId %i, but no such quest", qinfo->GetQuestId(), qinfo->GetNextQuestId());
- }
else
{
int32 signedQuestId = qinfo->NextQuestId < 0 ? -int32(qinfo->GetQuestId()) : int32(qinfo->GetQuestId());
@@ -4404,14 +4368,14 @@ void ObjectMgr::LoadQuestLocales()
_questLocaleStore.clear(); // need for reload case
QueryResult result = WorldDatabase.Query("SELECT Id, "
- "Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, "
- "Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, "
- "Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, "
- "Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, "
- "Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, "
- "Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, "
- "Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, "
- "Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8"
+ "Title_loc1, Details_loc1, Objectives_loc1, OfferRewardText_loc1, RequestItemsText_loc1, EndText_loc1, CompletedText_loc1, ObjectiveText1_loc1, ObjectiveText2_loc1, ObjectiveText3_loc1, ObjectiveText4_loc1, QuestGiverTextWindow_loc1, QuestGiverTargetName_loc1, QuestTurnTextWindow_loc1, QuestTurnTargetName_loc1,"
+ "Title_loc2, Details_loc2, Objectives_loc2, OfferRewardText_loc2, RequestItemsText_loc2, EndText_loc2, CompletedText_loc2, ObjectiveText1_loc2, ObjectiveText2_loc2, ObjectiveText3_loc2, ObjectiveText4_loc2, QuestGiverTextWindow_loc2, QuestGiverTargetName_loc2, QuestTurnTextWindow_loc2, QuestTurnTargetName_loc2,"
+ "Title_loc3, Details_loc3, Objectives_loc3, OfferRewardText_loc3, RequestItemsText_loc3, EndText_loc3, CompletedText_loc3, ObjectiveText1_loc3, ObjectiveText2_loc3, ObjectiveText3_loc3, ObjectiveText4_loc3, QuestGiverTextWindow_loc3, QuestGiverTargetName_loc3, QuestTurnTextWindow_loc3, QuestTurnTargetName_loc3,"
+ "Title_loc4, Details_loc4, Objectives_loc4, OfferRewardText_loc4, RequestItemsText_loc4, EndText_loc4, CompletedText_loc4, ObjectiveText1_loc4, ObjectiveText2_loc4, ObjectiveText3_loc4, ObjectiveText4_loc4, QuestGiverTextWindow_loc4, QuestGiverTargetName_loc4, QuestTurnTextWindow_loc4, QuestTurnTargetName_loc4,"
+ "Title_loc5, Details_loc5, Objectives_loc5, OfferRewardText_loc5, RequestItemsText_loc5, EndText_loc5, CompletedText_loc5, ObjectiveText1_loc5, ObjectiveText2_loc5, ObjectiveText3_loc5, ObjectiveText4_loc5, QuestGiverTextWindow_loc5, QuestGiverTargetName_loc5, QuestTurnTextWindow_loc5, QuestTurnTargetName_loc5,"
+ "Title_loc6, Details_loc6, Objectives_loc6, OfferRewardText_loc6, RequestItemsText_loc6, EndText_loc6, CompletedText_loc6, ObjectiveText1_loc6, ObjectiveText2_loc6, ObjectiveText3_loc6, ObjectiveText4_loc6, QuestGiverTextWindow_loc6, QuestGiverTargetName_loc6, QuestTurnTextWindow_loc6, QuestTurnTargetName_loc6,"
+ "Title_loc7, Details_loc7, Objectives_loc7, OfferRewardText_loc7, RequestItemsText_loc7, EndText_loc7, CompletedText_loc7, ObjectiveText1_loc7, ObjectiveText2_loc7, ObjectiveText3_loc7, ObjectiveText4_loc7, QuestGiverTextWindow_loc7, QuestGiverTargetName_loc7, QuestTurnTextWindow_loc7, QuestTurnTargetName_loc7,"
+ "Title_loc8, Details_loc8, Objectives_loc8, OfferRewardText_loc8, RequestItemsText_loc8, EndText_loc8, CompletedText_loc8, ObjectiveText1_loc8, ObjectiveText2_loc8, ObjectiveText3_loc8, ObjectiveText4_loc8, QuestGiverTextWindow_loc8, QuestGiverTargetName_loc8, QuestTurnTextWindow_loc8, QuestTurnTargetName_loc8"
" FROM locales_quest");
if (!result)
@@ -4429,16 +4393,21 @@ void ObjectMgr::LoadQuestLocales()
{
LocaleConstant locale = (LocaleConstant) i;
- AddLocaleString(fields[1 + 11 * (i - 1)].GetString(), locale, data.Title);
- AddLocaleString(fields[1 + 11 * (i - 1) + 1].GetString(), locale, data.Details);
- AddLocaleString(fields[1 + 11 * (i - 1) + 2].GetString(), locale, data.Objectives);
- AddLocaleString(fields[1 + 11 * (i - 1) + 3].GetString(), locale, data.OfferRewardText);
- AddLocaleString(fields[1 + 11 * (i - 1) + 4].GetString(), locale, data.RequestItemsText);
- AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.EndText);
- AddLocaleString(fields[1 + 11 * (i - 1) + 6].GetString(), locale, data.CompletedText);
+ AddLocaleString(fields[1 + 15 * (i - 1)].GetString(), locale, data.Title);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 1].GetString(), locale, data.Details);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 2].GetString(), locale, data.Objectives);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 3].GetString(), locale, data.OfferRewardText);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 4].GetString(), locale, data.RequestItemsText);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 5].GetString(), locale, data.EndText);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 6].GetString(), locale, data.CompletedText);
for (uint8 k = 0; k < 4; ++k)
- AddLocaleString(fields[1 + 11 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveText[k]);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 7 + k].GetString(), locale, data.ObjectiveText[k]);
+
+ AddLocaleString(fields[1 + 15 * (i - 1) + 11].GetString(), locale, data.QuestGiverTextWindow);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 12].GetString(), locale, data.QuestGiverTargetName);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 13].GetString(), locale, data.QuestTurnTextWindow);
+ AddLocaleString(fields[1 + 15 * (i - 1) + 14].GetString(), locale, data.QuestTurnTargetName);
}
} while (result->NextRow());
@@ -4893,7 +4862,7 @@ void ObjectMgr::LoadSpellScriptNames()
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) does not exist.", scriptName, spellId);
+ TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) does not exist.", scriptName, fields[0].GetInt32());
continue;
}
@@ -4907,7 +4876,6 @@ void ObjectMgr::LoadSpellScriptNames()
TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is not first rank of spell.", scriptName, fields[0].GetInt32());
continue;
}
-
while (spellInfo)
{
_spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
@@ -5141,7 +5109,7 @@ void ObjectMgr::LoadInstanceEncounters()
if (lastEncounterDungeon && !sLFGMgr->GetLFGDungeonEntry(lastEncounterDungeon))
{
- TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName[0], lastEncounterDungeon);
+ TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an encounter %u (%s) marked as final for invalid dungeon id %u, skipped!", entry, dungeonEncounter->encounterName, lastEncounterDungeon);
continue;
}
@@ -5150,7 +5118,7 @@ void ObjectMgr::LoadInstanceEncounters()
{
if (itr != dungeonLastBosses.end())
{
- TC_LOG_ERROR("sql.sql", "Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName[0], itr->second->id, itr->second->encounterName[0]);
+ TC_LOG_ERROR("sql.sql", "Table `instance_encounters` specified encounter %u (%s) as last encounter but %u (%s) is already marked as one, skipped!", entry, dungeonEncounter->encounterName, itr->second->id, itr->second->encounterName);
continue;
}
@@ -5164,7 +5132,7 @@ void ObjectMgr::LoadInstanceEncounters()
CreatureTemplate const* creatureInfo = GetCreatureTemplate(creditEntry);
if (!creatureInfo)
{
- TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
+ TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid creature (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName);
continue;
}
const_cast<CreatureTemplate*>(creatureInfo)->flags_extra |= CREATURE_FLAG_EXTRA_DUNGEON_BOSS;
@@ -5173,17 +5141,32 @@ void ObjectMgr::LoadInstanceEncounters()
case ENCOUNTER_CREDIT_CAST_SPELL:
if (!sSpellMgr->GetSpellInfo(creditEntry))
{
- TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName[0]);
+ TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid spell (entry %u) linked to the encounter %u (%s), skipped!", creditEntry, entry, dungeonEncounter->encounterName);
continue;
}
break;
default:
- TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type (%u) for encounter %u (%s), skipped!", creditType, entry, dungeonEncounter->encounterName[0]);
+ TC_LOG_ERROR("sql.sql", "Table `instance_encounters` has an invalid credit type (%u) for encounter %u (%s), skipped!", creditType, entry, dungeonEncounter->encounterName);
continue;
}
- DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
- encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
+ if (dungeonEncounter->difficulty == -1)
+ {
+ for (uint32 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ if (GetMapDifficultyData(dungeonEncounter->mapId, Difficulty(i)))
+ {
+ DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, i)];
+ encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
+ }
+ }
+ }
+ else
+ {
+ DungeonEncounterList& encounters = _dungeonEncounterStore[MAKE_PAIR32(dungeonEncounter->mapId, dungeonEncounter->difficulty)];
+ encounters.push_back(new DungeonEncounter(dungeonEncounter, EncounterCreditType(creditType), creditEntry, lastEncounterDungeon));
+ }
+
++count;
} while (result->NextRow());
@@ -5347,7 +5330,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp)
bool has_items = fields[4].GetBool();
m->expire_time = time_t(fields[5].GetUInt32());
m->deliver_time = 0;
- m->COD = fields[6].GetUInt32();
+ m->COD = fields[6].GetUInt64();
m->checked = fields[7].GetUInt8();
m->mailTemplateId = fields[8].GetInt16();
@@ -5563,8 +5546,8 @@ uint32 ObjectMgr::GetNearestTaxiNode(float x, float y, float z, uint32 mapid, ui
if (!node || node->map_id != mapid || (!node->MountCreatureID[team == ALLIANCE ? 1 : 0] && node->MountCreatureID[0] != 32981)) // dk flight
continue;
- uint8 field = (uint8)((i - 1) / 32);
- uint32 submask = 1<<((i-1)%32);
+ uint8 field = (uint8)((i - 1) / 8);
+ uint32 submask = 1 << ((i-1) % 8);
// skip not taxi network nodes
if ((sTaxiNodesMask[field] & submask) == 0)
@@ -5965,7 +5948,7 @@ void ObjectMgr::LoadAreaTriggerTeleports()
uint32 Trigger_ID = fields[0].GetUInt32();
- AreaTrigger at;
+ AreaTriggerStruct at;
at.target_mapId = fields[1].GetUInt16();
at.target_X = fields[2].GetFloat();
@@ -6099,7 +6082,7 @@ void ObjectMgr::LoadAccessRequirements()
/*
* Searches for the areatrigger which teleports players out of the given map with instance_template.parent field support
*/
-AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
+AreaTriggerStruct const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
{
bool useParentDbValue = false;
uint32 parentId = 0;
@@ -6132,7 +6115,7 @@ AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const
/**
* Searches for the areatrigger which teleports players to the given map
*/
-AreaTrigger const* ObjectMgr::GetMapEntranceTrigger(uint32 Map) const
+AreaTriggerStruct const* ObjectMgr::GetMapEntranceTrigger(uint32 Map) const
{
for (AreaTriggerContainer::const_iterator itr = _areaTriggerStore.begin(); itr != _areaTriggerStore.end(); ++itr)
{
@@ -6201,6 +6184,10 @@ void ObjectMgr::SetHighestGuids()
result = CharacterDatabase.Query("SELECT MAX(guid) FROM groups");
if (result)
sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1);
+
+ result = CharacterDatabase.Query("SELECT MAX(itemId) from character_void_storage");
+ if (result)
+ _voidItemId = (*result)[0].GetUInt64()+1;
}
uint32 ObjectMgr::GenerateAuctionID()
@@ -6272,6 +6259,11 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
ASSERT(_hiCorpseGuid < 0xFFFFFFFE && "Corpse guid overflow!");
return _hiCorpseGuid++;
}
+ case HIGHGUID_AREATRIGGER:
+ {
+ ASSERT(_hiAreaTriggerGuid < 0xFFFFFFFE && "AreaTrigger guid overflow!");
+ return _hiAreaTriggerGuid++;
+ }
case HIGHGUID_DYNAMICOBJECT:
{
ASSERT(_hiDoGuid < 0xFFFFFFFE && "DynamicObject guid overflow!");
@@ -6348,7 +6340,7 @@ inline void CheckGOSpellId(GameObjectTemplate const* goInfo, uint32 dataN, uint3
goInfo->entry, goInfo->type, N, dataN, dataN);
}
-inline void CheckAndFixGOChairHeightId(GameObjectTemplate const* goInfo, uint32 const& dataN, uint32 N)
+inline void CheckAndFixGOChairHeightId(GameObjectTemplate const* goInfo, uint32& dataN, uint32 N)
{
if (dataN <= (UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR))
return;
@@ -6357,7 +6349,7 @@ inline void CheckAndFixGOChairHeightId(GameObjectTemplate const* goInfo, uint32
goInfo->entry, goInfo->type, N, dataN, UNIT_STAND_STATE_SIT_HIGH_CHAIR-UNIT_STAND_STATE_SIT_LOW_CHAIR);
// prevent client and server unexpected work
- const_cast<uint32&>(dataN) = 0;
+ dataN = 0;
}
inline void CheckGONoDamageImmuneId(GameObjectTemplate* goTemplate, uint32 dataN, uint32 N)
@@ -6387,8 +6379,10 @@ void ObjectMgr::LoadGameObjectTemplate()
QueryResult result = WorldDatabase.Query("SELECT entry, type, displayId, name, IconName, castBarCaption, unk1, faction, flags, size, questItem1, questItem2, questItem3, "
// 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
"questItem4, questItem5, questItem6, data0, data1, data2, data3, data4, data5, data6, data7, data8, data9, data10, data11, data12, "
- // 29 30 31 32 33 34 35 36 37 38 39 40 41
- "data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, AIName, ScriptName "
+ // 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
+ "data13, data14, data15, data16, data17, data18, data19, data20, data21, data22, data23, data24, data25, data26, data27, data28, "
+ // 45 46 47 48 49 50
+ "data29, data30, data31, unkInt32, AIName, ScriptName "
"FROM gameobject_template");
if (!result)
@@ -6422,10 +6416,11 @@ void ObjectMgr::LoadGameObjectTemplate()
got.questItems[i] = fields[10 + i].GetUInt32();
for (uint8 i = 0; i < MAX_GAMEOBJECT_DATA; ++i)
- got.raw.data[i] = fields[16 + i].GetInt32(); // data1 and data6 can be -1
+ got.raw.data[i] = fields[16 + i].GetUInt32();
- got.AIName = fields[40].GetString();
- got.ScriptId = GetScriptId(fields[41].GetCString());
+ got.unkInt32 = fields[48].GetInt32();
+ got.AIName = fields[49].GetString();
+ got.ScriptId = GetScriptId(fields[50].GetCString());
// Checks
@@ -6662,7 +6657,7 @@ std::string ObjectMgr::GeneratePetName(uint32 entry)
if (!cinfo)
return std::string();
- char* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
+ char const* petname = GetPetName(cinfo->family, sWorld->GetDefaultDbcLocale());
if (petname)
return std::string(petname);
else
@@ -6677,8 +6672,16 @@ uint32 ObjectMgr::GeneratePetNumber()
return ++_hiPetNumber;
}
+uint64 ObjectMgr::GenerateVoidStorageItemId()
+{
+ return ++_voidItemId;
+}
+
void ObjectMgr::LoadCorpses()
{
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
+ // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0
+
uint32 oldMSTime = getMSTime();
PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES));
@@ -6693,7 +6696,7 @@ void ObjectMgr::LoadCorpses()
{
Field* fields = result->Fetch();
uint32 guid = fields[16].GetUInt32();
- CorpseType type = CorpseType(fields[13].GetUInt8());
+ CorpseType type = CorpseType(fields[12].GetUInt8());
if (type >= MAX_CORPSE_TYPE)
{
TC_LOG_ERROR("misc", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type);
@@ -6881,8 +6884,8 @@ void ObjectMgr::LoadReputationSpilloverTemplate()
_repSpilloverTemplateStore.clear(); // for reload case
- uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12
- QueryResult result = WorldDatabase.Query("SELECT faction, faction1, rate_1, rank_1, faction2, rate_2, rank_2, faction3, rate_3, rank_3, faction4, rate_4, rank_4 FROM reputation_spillover_template");
+ uint32 count = 0; // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+ QueryResult result = WorldDatabase.Query("SELECT faction, faction1, rate_1, rank_1, faction2, rate_2, rank_2, faction3, rate_3, rank_3, faction4, rate_4, rank_4, faction5, rate_5, rank_5 FROM reputation_spillover_template");
if (!result)
{
@@ -6910,6 +6913,9 @@ void ObjectMgr::LoadReputationSpilloverTemplate()
repTemplate.faction[3] = fields[10].GetUInt16();
repTemplate.faction_rate[3] = fields[11].GetFloat();
repTemplate.faction_rank[3] = fields[12].GetUInt8();
+ repTemplate.faction[4] = fields[13].GetUInt16();
+ repTemplate.faction_rate[4] = fields[14].GetFloat();
+ repTemplate.faction_rank[4] = fields[15].GetUInt8();
FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
@@ -6975,6 +6981,12 @@ void ObjectMgr::LoadReputationSpilloverTemplate()
TC_LOG_ERROR("sql.sql", "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`", repTemplate.faction[3]);
continue;
}
+ FactionEntry const* factionEntry4 = sFactionStore.LookupEntry(repTemplate.faction[4]);
+ if (repTemplate.faction[4] && !factionEntry4)
+ {
+ TC_LOG_ERROR("sql.sql", "Faction (faction.dbc) %u does not exist but is used in `reputation_spillover_template`", repTemplate.faction[4]);
+ continue;
+ }
_repSpilloverTemplateStore[factionId] = repTemplate;
@@ -7757,12 +7769,10 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const* pSkill, bool racial)
{
switch (pSkill->categoryId)
{
- case SKILL_CATEGORY_LANGUAGES: return SKILL_RANGE_LANGUAGE;
+ case SKILL_CATEGORY_LANGUAGES:
+ return SKILL_RANGE_LANGUAGE;
case SKILL_CATEGORY_WEAPON:
- if (pSkill->id != SKILL_FIST_WEAPONS)
- return SKILL_RANGE_LEVEL;
- else
- return SKILL_RANGE_MONO;
+ return SKILL_RANGE_LEVEL;
case SKILL_CATEGORY_ARMOR:
case SKILL_CATEGORY_CLASS:
if (pSkill->id != SKILL_LOCKPICKING)
@@ -8093,7 +8103,7 @@ void ObjectMgr::LoadTrainerSpell()
if (!result)
{
- TC_LOG_ERROR("sql.sql", ">> Loaded 0 Trainers. DB table `npc_trainer` is empty!");
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 Trainers. DB table `npc_trainer` is empty!");
return;
}
@@ -8120,11 +8130,12 @@ void ObjectMgr::LoadTrainerSpell()
TC_LOG_INFO("server.loading", ">> Loaded %d Trainers in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *skip_vendors)
+int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, uint8 type, std::set<uint32> *skip_vendors)
{
// find all items from the reference vendor
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_NPC_VENDOR_REF);
stmt->setUInt32(0, uint32(item));
+ stmt->setUInt8(1, type);
PreparedQueryResult result = WorldDatabase.Query(stmt);
if (!result)
@@ -8139,19 +8150,20 @@ int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *s
// if item is a negative, its a reference
if (item_id < 0)
- count += LoadReferenceVendor(vendor, -item_id, skip_vendors);
+ count += LoadReferenceVendor(vendor, -item_id, type, skip_vendors);
else
{
- int32 maxcount = fields[1].GetUInt8();
+ int32 maxcount = fields[1].GetUInt32();
uint32 incrtime = fields[2].GetUInt32();
uint32 ExtendedCost = fields[3].GetUInt32();
+ uint8 type = fields[4].GetUInt8();
- if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, NULL, skip_vendors))
+ if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, type, NULL, skip_vendors))
continue;
VendorItemData& vList = _cacheVendorItemStore[vendor];
- vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
+ vList.AddItem(item_id, maxcount, incrtime, ExtendedCost, type);
++count;
}
} while (result->NextRow());
@@ -8170,11 +8182,11 @@ void ObjectMgr::LoadVendors()
std::set<uint32> skip_vendors;
- QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost FROM npc_vendor ORDER BY entry, slot ASC");
+ QueryResult result = WorldDatabase.Query("SELECT entry, item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor ORDER BY entry, slot ASC");
if (!result)
{
- TC_LOG_ERROR("sql.sql", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 Vendors. DB table `npc_vendor` is empty!");
return;
}
@@ -8189,19 +8201,20 @@ void ObjectMgr::LoadVendors()
// if item is a negative, its a reference
if (item_id < 0)
- count += LoadReferenceVendor(entry, -item_id, &skip_vendors);
+ count += LoadReferenceVendor(entry, -item_id, 0, &skip_vendors);
else
{
- uint32 maxcount = fields[2].GetUInt8();
+ uint32 maxcount = fields[2].GetUInt32();
uint32 incrtime = fields[3].GetUInt32();
uint32 ExtendedCost = fields[4].GetUInt32();
+ uint8 type = fields[5].GetUInt8();
- if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors))
+ if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, type, NULL, &skip_vendors))
continue;
VendorItemData& vList = _cacheVendorItemStore[entry];
- vList.AddItem(item_id, maxcount, incrtime, ExtendedCost);
+ vList.AddItem(item_id, maxcount, incrtime, ExtendedCost, type);
++count;
}
}
@@ -8257,7 +8270,7 @@ void ObjectMgr::LoadGossipMenuItems()
_gossipMenuItemsStore.clear();
QueryResult result = WorldDatabase.Query(
- // 0 1 2 3 4 5 6 7 8 9 10
+ // 0 1 2 3 4 5 6 7 8 9 10
"SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, action_menu_id, action_poi_id, box_coded, box_money, box_text "
"FROM gossip_menu_option ORDER BY menu_id, id");
@@ -8310,10 +8323,10 @@ void ObjectMgr::LoadGossipMenuItems()
TC_LOG_INFO("server.loading", ">> Loaded %u gossip_menu_option entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist /*= true*/)
+void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist /*= true*/)
{
VendorItemData& vList = _cacheVendorItemStore[entry];
- vList.AddItem(item, maxcount, incrtime, extendedCost);
+ vList.AddItem(item, maxcount, incrtime, extendedCost, type);
if (persist)
{
@@ -8324,18 +8337,19 @@ void ObjectMgr::AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32
stmt->setUInt8(2, maxcount);
stmt->setUInt32(3, incrtime);
stmt->setUInt32(4, extendedCost);
+ stmt->setUInt8(5, type);
WorldDatabase.Execute(stmt);
}
}
-bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= true*/)
+bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist /*= true*/)
{
CacheVendorItemContainer::iterator iter = _cacheVendorItemStore.find(entry);
if (iter == _cacheVendorItemStore.end())
return false;
- if (!iter->second.RemoveItem(item))
+ if (!iter->second.RemoveItem(item, type))
return false;
if (persist)
@@ -8344,6 +8358,7 @@ bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= tru
stmt->setUInt32(0, entry);
stmt->setUInt32(1, item);
+ stmt->setUInt8(2, type);
WorldDatabase.Execute(stmt);
}
@@ -8351,7 +8366,7 @@ bool ObjectMgr::RemoveVendorItem(uint32 entry, uint32 item, bool persist /*= tru
return true;
}
-bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, Player* player, std::set<uint32>* skip_vendors, uint32 ORnpcflag) const
+bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, uint8 type, Player* player, std::set<uint32>* skip_vendors, uint32 ORnpcflag) const
{
CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(vendor_entry);
if (!cInfo)
@@ -8378,12 +8393,13 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max
return false;
}
- if (!sObjectMgr->GetItemTemplate(item_id))
+ if ((type == ITEM_VENDOR_TYPE_ITEM && !sObjectMgr->GetItemTemplate(id)) ||
+ (type == ITEM_VENDOR_TYPE_CURRENCY && !sCurrencyTypesStore.LookupEntry(id)))
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id);
+ ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_NOT_FOUND, id, type);
else
- TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore", vendor_entry, item_id);
+ TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u, type %u), ignore", vendor_entry, id, type);
return false;
}
@@ -8392,37 +8408,46 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max
if (player)
ChatHandler(player->GetSession()).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost);
else
- TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", item_id, ExtendedCost, vendor_entry);
+ TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", id, ExtendedCost, vendor_entry);
return false;
}
- if (maxcount > 0 && incrtime == 0)
+ if (type == ITEM_VENDOR_TYPE_ITEM) // not applicable to currencies
{
- if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount);
- else
- TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, item_id, vendor_entry);
- return false;
- }
- else if (maxcount == 0 && incrtime > 0)
- {
- if (player)
- ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
- else
- TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", item_id, vendor_entry);
- return false;
+ if (maxcount > 0 && incrtime == 0)
+ {
+ if (player)
+ ChatHandler(player->GetSession()).PSendSysMessage("MaxCount != 0 (%u) but IncrTime == 0", maxcount);
+ else
+ TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount` (%u) for item %u of vendor (Entry: %u) but `incrtime`=0, ignore", maxcount, id, vendor_entry);
+ return false;
+ }
+ else if (maxcount == 0 && incrtime > 0)
+ {
+ if (player)
+ ChatHandler(player->GetSession()).PSendSysMessage("MaxCount == 0 but IncrTime<>= 0");
+ else
+ TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` has `maxcount`=0 for item %u of vendor (Entry: %u) but `incrtime`<>0, ignore", id, vendor_entry);
+ return false;
+ }
}
VendorItemData const* vItems = GetNpcVendorItemList(vendor_entry);
if (!vItems)
return true; // later checks for non-empty lists
- if (vItems->FindItemCostPair(item_id, ExtendedCost))
+ if (vItems->FindItemCostPair(id, ExtendedCost, type))
{
if (player)
- ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
+ ChatHandler(player->GetSession()).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, id, ExtendedCost, type);
else
- TC_LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items %u (with extended cost %u) for vendor (Entry: %u), ignoring", item_id, ExtendedCost, vendor_entry);
+ TC_LOG_ERROR("sql.sql", "Table `npc_vendor` has duplicate items %u (with extended cost %u, type %u) for vendor (Entry: %u), ignoring", id, ExtendedCost, type, vendor_entry);
+ return false;
+ }
+
+ if (type == ITEM_VENDOR_TYPE_CURRENCY && maxcount == 0)
+ {
+ TC_LOG_ERROR("sql.sql", "Table `(game_event_)npc_vendor` have Item (Entry: %u, type: %u) with missing maxcount for vendor (%u), ignore", id, type, vendor_entry);
return false;
}
@@ -8443,7 +8468,7 @@ void ObjectMgr::LoadScriptNames()
"UNION "
"SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' "
"UNION "
- "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' "
+ "SELECT DISTINCT(ScriptName) FROM item_script_names WHERE ScriptName <> '' "
"UNION "
"SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' "
"UNION "
@@ -8578,8 +8603,8 @@ CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unit
void ObjectMgr::LoadCreatureClassLevelStats()
{
uint32 oldMSTime = getMSTime();
-
- QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2 FROM creature_classlevelstats");
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13
+ QueryResult result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basehp3, basemana, basearmor, attackpower, rangedattackpower, damage_base, damage_exp1, damage_exp2, damage_exp3 FROM creature_classlevelstats");
if (!result)
{
@@ -8602,7 +8627,7 @@ void ObjectMgr::LoadCreatureClassLevelStats()
for (uint8 i = 0; i < MAX_EXPANSIONS; ++i)
{
- stats.BaseHealth[i] = fields[2 + i].GetUInt16();
+ stats.BaseHealth[i] = fields[2 + i].GetUInt32();
if (stats.BaseHealth[i] == 0)
{
@@ -8610,7 +8635,7 @@ void ObjectMgr::LoadCreatureClassLevelStats()
stats.BaseHealth[i] = 1;
}
- stats.BaseDamage[i] = fields[9 + i].GetFloat();
+ stats.BaseDamage[i] = fields[10 + i].GetFloat();
if (stats.BaseDamage[i] < 0.0f)
{
TC_LOG_ERROR("sql.sql", "Creature base stats for class %u, level %u has invalid negative base damage[%u] - set to 0.0", Class, Level, i);
@@ -8618,11 +8643,11 @@ void ObjectMgr::LoadCreatureClassLevelStats()
}
}
- stats.BaseMana = fields[5].GetUInt16();
- stats.BaseArmor = fields[6].GetUInt16();
+ stats.BaseMana = fields[6].GetUInt16();
+ stats.BaseArmor = fields[7].GetUInt16();
- stats.AttackPower = fields[7].GetUInt16();
- stats.RangedAttackPower = fields[8].GetUInt16();
+ stats.AttackPower = fields[8].GetUInt16();
+ stats.RangedAttackPower = fields[9].GetUInt16();
_creatureBaseStatsStore[MAKE_PAIR16(Level, Class)] = stats;
@@ -8783,6 +8808,74 @@ void ObjectMgr::LoadFactionChangeReputations()
TC_LOG_INFO("server.loading", ">> Loaded %u faction change reputation pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+void ObjectMgr::LoadHotfixData()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT entry, type, UNIX_TIMESTAMP(hotfixDate) FROM hotfix_data");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 hotfix info entries. DB table `hotfix_data` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ _hotfixData.reserve(result->GetRowCount());
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ HotfixInfo info;
+ info.Entry = fields[0].GetUInt32();
+ info.Type = fields[1].GetUInt32();
+ info.Timestamp = fields[2].GetUInt64();
+ _hotfixData.push_back(info);
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u hotfix info entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void ObjectMgr::LoadMissingKeyChains()
+{
+ uint32 oldMSTime = getMSTime();
+
+ QueryResult result = WorldDatabase.Query("SELECT keyId, k1, k2, k3, k4, k5, k6, k7, k8, "
+ "k9, k10, k11, k12, k13, k14, k15, k16, "
+ "k17, k18, k19, k20, k21, k22, k23, k24, "
+ "k25, k26, k27, k28, k29, k30, k31, k32 "
+ "FROM keychain_db2 ORDER BY keyId DESC");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 KeyChain entries. DB table `keychain_db2` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 id = fields[0].GetUInt32();
+
+ KeyChainEntry* kce = sKeyChainStore.CreateEntry(id, true);
+ kce->Id = id;
+ for (uint32 i = 0; i < KEYCHAIN_SIZE; ++i)
+ kce->Key[i] = fields[1 + i].GetUInt8();
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u KeyChain entries in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
void ObjectMgr::LoadFactionChangeSpells()
{
uint32 oldMSTime = getMSTime();
@@ -8853,6 +8946,99 @@ void ObjectMgr::LoadFactionChangeTitles()
TC_LOG_INFO("server.loading", ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+void ObjectMgr::LoadPhaseDefinitions()
+{
+ _PhaseDefinitionStore.clear();
+
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3 4 5
+ QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags FROM `phase_definitions` ORDER BY `entry` ASC");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 phasing definitions. DB table `phase_definitions` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ PhaseDefinition PhaseDefinition;
+
+ PhaseDefinition.zoneId = fields[0].GetUInt32();
+ PhaseDefinition.entry = fields[1].GetUInt32();
+ PhaseDefinition.phasemask = fields[2].GetUInt32();
+ PhaseDefinition.phaseId = fields[3].GetUInt32();
+ PhaseDefinition.terrainswapmap = fields[4].GetUInt32();
+ PhaseDefinition.flags = fields[5].GetUInt32();
+
+ // Checks
+ if ((PhaseDefinition.flags & PHASE_FLAG_OVERWRITE_EXISTING) && (PhaseDefinition.flags & PHASE_FLAG_NEGATE_PHASE))
+ {
+ TC_LOG_ERROR("sql.sql", "Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", PhaseDefinition.zoneId, PhaseDefinition.entry);
+ PhaseDefinition.flags &= ~PHASE_FLAG_NEGATE_PHASE;
+ }
+
+ _PhaseDefinitionStore[PhaseDefinition.zoneId].push_back(PhaseDefinition);
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void ObjectMgr::LoadSpellPhaseInfo()
+{
+ _SpellPhaseStore.clear();
+
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2
+ QueryResult result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+
+ SpellPhaseInfo spellPhaseInfo;
+ spellPhaseInfo.spellId = fields[0].GetUInt32();
+
+ SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellPhaseInfo.spellId);
+ if (!spell)
+ {
+ TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo.spellId);
+ continue;
+ }
+
+ if (!spell->HasAura(SPELL_AURA_PHASE))
+ {
+ TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE, useless value.", spellPhaseInfo.spellId);
+ continue;
+ }
+
+ spellPhaseInfo.phasemask = fields[1].GetUInt32();
+ spellPhaseInfo.terrainswapmap = fields[2].GetUInt32();
+
+ _SpellPhaseStore[spellPhaseInfo.spellId] = spellPhaseInfo;
+
+ ++count;
+ }
+ while (result->NextRow());
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell dbc infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry)
{
GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index b1f80af0567..bddf73408fa 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -42,11 +42,12 @@
#include <limits>
#include "ConditionMgr.h"
#include <functional>
+#include "PhaseMgr.h"
+#include "DB2Stores.h"
class Item;
+class PhaseMgr;
struct AccessRequirement;
-struct PlayerClassInfo;
-struct PlayerClassLevelInfo;
struct PlayerInfo;
struct PlayerLevelInfo;
@@ -401,7 +402,7 @@ struct SpellClickInfo
typedef std::multimap<uint32, SpellClickInfo> SpellClickInfoContainer;
typedef std::pair<SpellClickInfoContainer::const_iterator, SpellClickInfoContainer::const_iterator> SpellClickInfoMapBounds;
-struct AreaTrigger
+struct AreaTriggerStruct
{
uint32 target_mapId;
float target_X;
@@ -444,7 +445,6 @@ typedef std::map<TempSummonGroupKey, std::vector<TempSummonData> > TempSummonDat
typedef UNORDERED_MAP<uint32, CreatureLocale> CreatureLocaleContainer;
typedef UNORDERED_MAP<uint32, GameObjectLocale> GameObjectLocaleContainer;
typedef UNORDERED_MAP<uint32, ItemLocale> ItemLocaleContainer;
-typedef UNORDERED_MAP<uint32, ItemSetNameLocale> ItemSetNameLocaleContainer;
typedef UNORDERED_MAP<uint32, QuestLocale> QuestLocaleContainer;
typedef UNORDERED_MAP<uint32, NpcTextLocale> NpcTextLocaleContainer;
typedef UNORDERED_MAP<uint32, PageTextLocale> PageTextLocaleContainer;
@@ -585,6 +585,7 @@ struct GraveYardData
};
typedef std::multimap<uint32, GraveYardData> GraveYardContainer;
+typedef UNORDERED_MAP<uint32 /* graveyard Id */, float /* orientation */> GraveyardOrientationContainer;
typedef std::pair<GraveYardContainer::const_iterator, GraveYardContainer::const_iterator> GraveYardMapBounds;
typedef std::pair<GraveYardContainer::iterator, GraveYardContainer::iterator> GraveYardMapBoundsNonConst;
@@ -639,6 +640,15 @@ struct DungeonEncounter
typedef std::list<DungeonEncounter const*> DungeonEncounterList;
typedef UNORDERED_MAP<uint32, DungeonEncounterList> DungeonEncounterContainer;
+struct HotfixInfo
+{
+ uint32 Type;
+ uint32 Timestamp;
+ uint32 Entry;
+};
+
+typedef std::vector<HotfixInfo> HotfixData;
+
class PlayerDumpReader;
class ObjectMgr
@@ -655,7 +665,7 @@ class ObjectMgr
typedef UNORDERED_MAP<uint32, Quest*> QuestMap;
- typedef UNORDERED_MAP<uint32, AreaTrigger> AreaTriggerContainer;
+ typedef UNORDERED_MAP<uint32, AreaTriggerStruct> AreaTriggerContainer;
typedef UNORDERED_MAP<uint32, uint32> AreaTriggerScriptContainer;
@@ -675,7 +685,7 @@ class ObjectMgr
GameObjectTemplate const* GetGameObjectTemplate(uint32 entry);
GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; }
- int LoadReferenceVendor(int32 vendor, int32 item_id, std::set<uint32> *skip_vendors);
+ int LoadReferenceVendor(int32 vendor, int32 item, uint8 type, std::set<uint32> *skip_vendors);
void LoadGameObjectTemplate();
void AddGameobjectInfo(GameObjectTemplate* goinfo);
@@ -692,25 +702,11 @@ class ObjectMgr
ItemTemplate const* GetItemTemplate(uint32 entry);
ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }
- ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId)
- {
- ItemSetNameContainer::iterator itr = _itemSetNameStore.find(itemId);
- if (itr != _itemSetNameStore.end())
- return &itr->second;
- return NULL;
- }
-
InstanceTemplate const* GetInstanceTemplate(uint32 mapId);
PetLevelInfo const* GetPetLevelInfo(uint32 creature_id, uint8 level) const;
- PlayerClassInfo const* GetPlayerClassInfo(uint32 class_) const
- {
- if (class_ >= MAX_CLASSES)
- return NULL;
- return _playerClassInfo[class_];
- }
- void GetPlayerClassLevelInfo(uint32 class_, uint8 level, PlayerClassLevelInfo* info) const;
+ void GetPlayerClassLevelInfo(uint32 class_, uint8 level, uint32& baseHP, uint32& baseMana) const;
PlayerInfo const* GetPlayerInfo(uint32 race, uint32 class_) const;
@@ -775,7 +771,7 @@ class ObjectMgr
void LoadGraveyardZones();
GraveYardData const* FindGraveYardData(uint32 id, uint32 zone);
- AreaTrigger const* GetAreaTrigger(uint32 trigger) const
+ AreaTriggerStruct const* GetAreaTrigger(uint32 trigger) const
{
AreaTriggerContainer::const_iterator itr = _areaTriggerStore.find(trigger);
if (itr != _areaTriggerStore.end())
@@ -791,8 +787,8 @@ class ObjectMgr
return NULL;
}
- AreaTrigger const* GetGoBackTrigger(uint32 Map) const;
- AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const;
+ AreaTriggerStruct const* GetGoBackTrigger(uint32 Map) const;
+ AreaTriggerStruct const* GetMapEntranceTrigger(uint32 Map) const;
uint32 GetAreaTriggerScriptId(uint32 trigger_id);
SpellScriptsBounds GetSpellScriptsBounds(uint32 spellId);
@@ -910,6 +906,7 @@ class ObjectMgr
void LoadDbScriptStrings();
void LoadCreatureClassLevelStats();
void LoadCreatureLocales();
+ void LoadGraveyardOrientations();
void LoadCreatureTemplates();
void LoadCreatureTemplateAddons();
void CheckCreatureTemplate(CreatureTemplate const* cInfo);
@@ -923,9 +920,9 @@ class ObjectMgr
void LoadGameObjectLocales();
void LoadGameobjects();
void LoadItemTemplates();
+ void LoadItemTemplateAddon();
+ void LoadItemScriptNames();
void LoadItemLocales();
- void LoadItemSetNames();
- void LoadItemSetNameLocales();
void LoadQuestLocales();
void LoadNpcTextLocales();
void LoadPageTextLocales();
@@ -975,6 +972,12 @@ class ObjectMgr
void LoadTrainerSpell();
void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel);
+ void LoadPhaseDefinitions();
+ void LoadSpellPhaseInfo();
+
+ PhaseDefinitionStore const* GetPhaseDefinitionStore() { return &_PhaseDefinitionStore; }
+ SpellPhaseStore const* GetSpellPhaseStore() { return &_SpellPhaseStore; }
+
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint8 level);
uint32 GetXPForLevel(uint8 level) const;
@@ -995,6 +998,7 @@ class ObjectMgr
uint64 GenerateEquipmentSetGuid();
uint32 GenerateMailID();
uint32 GeneratePetNumber();
+ uint64 GenerateVoidStorageItemId();
typedef std::multimap<int32, uint32> ExclusiveQuestGroups;
typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds;
@@ -1074,12 +1078,6 @@ class ObjectMgr
if (itr == _itemLocaleStore.end()) return NULL;
return &itr->second;
}
- ItemSetNameLocale const* GetItemSetNameLocale(uint32 entry) const
- {
- ItemSetNameLocaleContainer::const_iterator itr = _itemSetNameLocaleStore.find(entry);
- if (itr == _itemSetNameLocaleStore.end())return NULL;
- return &itr->second;
- }
QuestLocale const* GetQuestLocale(uint32 entry) const
{
QuestLocaleContainer::const_iterator itr = _questLocaleStore.find(entry);
@@ -1183,9 +1181,19 @@ class ObjectMgr
return &iter->second;
}
- void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, bool persist = true); // for event
- bool RemoveVendorItem(uint32 entry, uint32 item, bool persist = true); // for event
- bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
+
+ float const* GetGraveyardOrientation(uint32 id) const
+ {
+ GraveyardOrientationContainer::const_iterator iter = _graveyardOrientations.find(id);
+ if (iter != _graveyardOrientations.end())
+ return &iter->second;
+
+ return NULL;
+ }
+
+ void AddVendorItem(uint32 entry, uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedCost, uint8 type, bool persist = true); // for event
+ bool RemoveVendorItem(uint32 entry, uint32 item, uint8 type, bool persist = true); // for event
+ 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; }
@@ -1240,6 +1248,21 @@ class ObjectMgr
void LoadFactionChangeSpells();
void LoadFactionChangeTitles();
+ void LoadHotfixData();
+ HotfixData const& GetHotfixData() const { return _hotfixData; }
+ time_t GetHotfixDate(uint32 entry, uint32 type) const
+ {
+ time_t ret = 0;
+ for (HotfixData::const_iterator itr = _hotfixData.begin(); itr != _hotfixData.end(); ++itr)
+ if (itr->Entry == entry && itr->Type == type)
+ if (itr->Timestamp > ret)
+ ret = itr->Timestamp;
+
+ return ret ? ret : time(NULL);
+ }
+
+ void LoadMissingKeyChains();
+
private:
// first free id for selected id type
uint32 _auctionId;
@@ -1247,6 +1270,7 @@ class ObjectMgr
uint32 _itemTextId;
uint32 _mailId;
uint32 _hiPetNumber;
+ uint64 _voidItemId;
// first free low guid for selected guid type
uint32 _hiCharGuid;
@@ -1257,6 +1281,7 @@ class ObjectMgr
uint32 _hiGoGuid;
uint32 _hiDoGuid;
uint32 _hiCorpseGuid;
+ uint32 _hiAreaTriggerGuid;
uint32 _hiMoTransGuid;
QuestMap _questTemplates;
@@ -1310,6 +1335,9 @@ class ObjectMgr
PageTextContainer _pageTextStore;
InstanceTemplateContainer _instanceTemplateStore;
+ PhaseDefinitionStore _PhaseDefinitionStore;
+ SpellPhaseStore _SpellPhaseStore;
+
private:
void LoadScripts(ScriptsType type);
void CheckScripts(ScriptsType type, std::set<int32>& ids);
@@ -1324,8 +1352,6 @@ class ObjectMgr
// PetLevelInfoContainer[creature_id][level]
PetLevelInfoContainer _petInfoStore; // [creature_id][level]
- PlayerClassInfo* _playerClassInfo[MAX_CLASSES];
-
void BuildPlayerLevelInfo(uint8 race, uint8 class_, uint8 level, PlayerLevelInfo* plinfo) const;
PlayerInfo* _playerInfo[MAX_RACES][MAX_CLASSES];
@@ -1343,9 +1369,6 @@ class ObjectMgr
HalfNameContainer _petHalfName0;
HalfNameContainer _petHalfName1;
- typedef UNORDERED_MAP<uint32, ItemSetNameEntry> ItemSetNameContainer;
- ItemSetNameContainer _itemSetNameStore;
-
MapObjectGuids _mapObjectGuidsStore;
CreatureDataContainer _creatureDataStore;
CreatureTemplateContainer _creatureTemplateStore;
@@ -1363,7 +1386,6 @@ class ObjectMgr
ItemTemplateContainer _itemTemplateStore;
ItemLocaleContainer _itemLocaleStore;
- ItemSetNameLocaleContainer _itemSetNameLocaleStore;
QuestLocaleContainer _questLocaleStore;
NpcTextLocaleContainer _npcTextLocaleStore;
PageTextLocaleContainer _pageTextLocaleStore;
@@ -1374,6 +1396,8 @@ class ObjectMgr
CacheVendorItemContainer _cacheVendorItemStore;
CacheTrainerSpellContainer _cacheTrainerSpellStore;
+ GraveyardOrientationContainer _graveyardOrientations;
+
std::set<uint32> _difficultyEntries[MAX_DIFFICULTY - 1]; // already loaded difficulty 1 value in creatures, used in CheckCreatureTemplate
std::set<uint32> _hasDifficultyEntries[MAX_DIFFICULTY - 1]; // already loaded creatures with difficulty 1 values, used in CheckCreatureTemplate
@@ -1385,6 +1409,7 @@ class ObjectMgr
GO_TO_CREATURE // GO is dependant on creature
};
+ HotfixData _hotfixData;
std::set<uint32> _transportMaps; // Helper container storing map ids that are for transports only, loaded from gameobject_template
};
diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h
index 5279f437f89..e463bb84633 100644
--- a/src/server/game/Grids/GridDefines.h
+++ b/src/server/game/Grids/GridDefines.h
@@ -30,6 +30,7 @@ class DynamicObject;
class GameObject;
class Pet;
class Player;
+class AreaTrigger;
#define MAX_NUMBER_OF_CELLS 8
@@ -57,13 +58,14 @@ class Player;
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes;
-typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes;
+typedef TYPELIST_5(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger) AllGridObjectTypes;
typedef GridRefManager<Corpse> CorpseMapType;
typedef GridRefManager<Creature> CreatureMapType;
typedef GridRefManager<DynamicObject> DynamicObjectMapType;
typedef GridRefManager<GameObject> GameObjectMapType;
typedef GridRefManager<Player> PlayerMapType;
+typedef GridRefManager<AreaTrigger> AreaTriggerMapType;
enum GridMapTypeMask
{
@@ -72,7 +74,8 @@ enum GridMapTypeMask
GRID_MAP_TYPE_MASK_DYNAMICOBJECT = 0x04,
GRID_MAP_TYPE_MASK_GAMEOBJECT = 0x08,
GRID_MAP_TYPE_MASK_PLAYER = 0x10,
- GRID_MAP_TYPE_MASK_ALL = 0x1F
+ GRID_MAP_TYPE_MASK_AREATRIGGER = 0x20,
+ GRID_MAP_TYPE_MASK_ALL = 0x3F
};
typedef Grid<Player, AllWorldObjectTypes, AllGridObjectTypes> GridType;
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
index 472497ea5f2..5cf1dc4a8ef 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp
@@ -373,3 +373,5 @@ bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
+template void ObjectUpdater::Visit<AreaTrigger>(AreaTriggerMapType &);
+
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 319b7b589b9..e229c782f49 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -25,6 +25,7 @@
#include "Corpse.h"
#include "Object.h"
+#include "AreaTrigger.h"
#include "DynamicObject.h"
#include "GameObject.h"
#include "Player.h"
@@ -45,7 +46,7 @@ namespace Trinity
std::set<Unit*> i_visibleNow;
Player::ClientGUIDs vis_guids;
- VisibleNotifier(Player &player) : i_player(player), vis_guids(player.m_clientGUIDs) { }
+ VisibleNotifier(Player &player) : i_player(player), i_data(player.GetMapId()), vis_guids(player.m_clientGUIDs) { }
template<class T> void Visit(GridRefManager<T> &m);
void SendToSelf(void);
};
@@ -118,6 +119,7 @@ namespace Trinity
void Visit(GameObjectMapType &m) { updateObjects<GameObject>(m); }
void Visit(DynamicObjectMapType &m) { updateObjects<DynamicObject>(m); }
void Visit(CorpseMapType &m) { updateObjects<Corpse>(m); }
+ void Visit(AreaTriggerMapType &m) { updateObjects<AreaTrigger>(m); }
};
struct MessageDistDeliverer
@@ -186,6 +188,7 @@ namespace Trinity
void Visit(CreatureMapType &m);
void Visit(CorpseMapType &m);
void Visit(DynamicObjectMapType &m);
+ void Visit(AreaTriggerMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
};
@@ -206,6 +209,7 @@ namespace Trinity
void Visit(CreatureMapType &m);
void Visit(CorpseMapType &m);
void Visit(DynamicObjectMapType &m);
+ void Visit(AreaTriggerMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
};
@@ -226,6 +230,7 @@ namespace Trinity
void Visit(CorpseMapType &m);
void Visit(GameObjectMapType &m);
void Visit(DynamicObjectMapType &m);
+ void Visit(AreaTriggerMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
};
@@ -284,6 +289,15 @@ namespace Trinity
i_do(itr->GetSource());
}
+ void Visit(AreaTriggerMapType &m)
+ {
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER))
+ return;
+ for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ if (itr->GetSource()->InSamePhase(i_phaseMask))
+ i_do(itr->GetSource());
+ }
+
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
};
@@ -1364,6 +1378,25 @@ namespace Trinity
uint64 _GUID;
};
+ class HeightDifferenceCheck
+ {
+ public:
+ HeightDifferenceCheck(WorldObject* go, float diff, bool reverse)
+ : _baseObject(go), _difference(diff), _reverse(reverse)
+ {
+ }
+
+ bool operator()(WorldObject* unit) const
+ {
+ return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;
+ }
+
+ private:
+ WorldObject* _baseObject;
+ float _difference;
+ bool _reverse;
+ };
+
class UnitAuraCheck
{
public:
diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
index 77b49fdfc8b..febc42af25a 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
@@ -157,6 +157,28 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
}
}
+template<class Check>
+void Trinity::WorldObjectSearcher<Check>::Visit(AreaTriggerMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER))
+ return;
+
+ // already found
+ if (i_object)
+ return;
+
+ for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->GetSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->GetSource()))
+ {
+ i_object = itr->GetSource();
+ return;
+ }
+ }
+}
template<class Check>
void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
@@ -239,6 +261,22 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m)
}
template<class Check>
+void Trinity::WorldObjectLastSearcher<Check>::Visit(AreaTriggerMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER))
+ return;
+
+ for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ {
+ if (!itr->GetSource()->InSamePhase(i_phaseMask))
+ continue;
+
+ if (i_check(itr->GetSource()))
+ i_object = itr->GetSource();
+ }
+}
+
+template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
@@ -293,6 +331,17 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
i_objects.push_back(itr->GetSource());
}
+template<class Check>
+void Trinity::WorldObjectListSearcher<Check>::Visit(AreaTriggerMapType &m)
+{
+ if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER))
+ return;
+
+ for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ if (i_check(itr->GetSource()))
+ i_objects.push_back(itr->GetSource());
+}
+
// Gameobject searchers
template<class Check>
@@ -526,7 +575,7 @@ void Trinity::LocalizedPacketDo<Builder>::operator()(Player* p)
i_builder(*data, loc_idx);
- ASSERT(data->GetOpcode() != MSG_NULL_ACTION);
+ ASSERT(data->GetOpcode() != NULL_OPCODE);
i_data_cache[cache_idx] = data;
}
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index 51a1f2215f8..ab7a0e20512 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -24,6 +24,7 @@
#include "GameObject.h"
#include "DynamicObject.h"
#include "Corpse.h"
+#include "AreaTrigger.h"
#include "World.h"
#include "CellImpl.h"
#include "CreatureAI.h"
@@ -258,7 +259,9 @@ template void ObjectGridUnloader::Visit(CreatureMapType &);
template void ObjectGridUnloader::Visit(GameObjectMapType &);
template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
template void ObjectGridUnloader::Visit(CorpseMapType &);
+template void ObjectGridUnloader::Visit(AreaTriggerMapType &);
template void ObjectGridCleaner::Visit(CreatureMapType &);
template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType &);
template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType &);
+template void ObjectGridCleaner::Visit<AreaTrigger>(AreaTriggerMapType &);
diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h
index 2ddc51848a8..1f351c6a0ba 100644
--- a/src/server/game/Grids/ObjectGridLoader.h
+++ b/src/server/game/Grids/ObjectGridLoader.h
@@ -40,6 +40,7 @@ class ObjectGridLoader
void Visit(CreatureMapType &m);
void Visit(CorpseMapType &) const { }
void Visit(DynamicObjectMapType&) const { }
+ void Visit(AreaTriggerMapType &) const { }
void LoadN(void);
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 354f00a9e91..2198086c900 100644
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -262,6 +262,37 @@ void Group::ConvertToRaid()
player->UpdateForQuestWorldObjects();
}
+void Group::ConvertToGroup()
+{
+ if (m_memberSlots.size() > 5)
+ return; // What message error should we send?
+
+ m_groupType = GroupType(GROUPTYPE_NORMAL);
+
+ if (m_subGroupsCounts)
+ {
+ delete[] m_subGroupsCounts;
+ m_subGroupsCounts = NULL;
+ }
+
+ if (!isBGGroup() && !isBFGroup())
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_TYPE);
+
+ stmt->setUInt8(0, uint8(m_groupType));
+ stmt->setUInt32(1, m_dbStoreId);
+
+ CharacterDatabase.Execute(stmt);
+ }
+
+ SendUpdate();
+
+ // update quest related GO states (quest activity dependent from raid membership)
+ for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr)
+ if (Player* player = ObjectAccessor::FindPlayer(citr->guid))
+ player->UpdateForQuestWorldObjects();
+}
+
bool Group::AddInvite(Player* player)
{
if (!player || player->GetGroupInvite())
@@ -433,7 +464,7 @@ bool Group::AddMember(Player* player)
// Broadcast new player group member fields to rest of the group
player->SetFieldNotifyFlag(UF_FLAG_PARTY_MEMBER);
- UpdateData groupData;
+ UpdateData groupData(player->GetMapId());
WorldPacket groupDataPacket;
// Broadcast group members' fields to player
@@ -453,7 +484,7 @@ bool Group::AddMember(Player* player)
if (member->HaveAtClient(player))
{
- UpdateData newData;
+ UpdateData newData(player->GetMapId());
WorldPacket newDataPacket;
player->BuildValuesUpdateBlockForPlayer(&newData, member);
if (newData.HasData())
@@ -777,6 +808,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
data << uint32(r.itemCount); // items in stack
data << uint32(countDown); // the countdown time to choose "need" or "greed"
data << uint8(r.rollVoteMask); // roll type mask
+ data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
{
@@ -807,6 +839,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
if (!canNeed)
voteMask &= ~ROLL_FLAG_TYPE_NEED;
data << uint8(voteMask); // roll type mask
+ data << uint8(r.totalPlayersRolling); // maybe the number of players rolling for it???
p->GetSession()->SendPacket(&data);
}
@@ -820,7 +853,7 @@ void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber,
data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
data << uint32(roll.itemRandomSuffix); // randomSuffix
data << uint32(roll.itemRandomPropId); // Item random property ID
- data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
+ data << uint32(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
@@ -844,7 +877,7 @@ void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumb
data << uint32(roll.itemRandomSuffix); // randomSuffix
data << uint32(roll.itemRandomPropId); // Item random property
data << uint64(targetGuid); // guid of the player who won.
- data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
+ data << uint32(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
@@ -1488,6 +1521,7 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot)
{
data << uint8(sLFGMgr->GetState(m_guid) == lfg::LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done
data << uint32(sLFGMgr->GetDungeon(m_guid));
+ data << uint8(0); // 4.x new
}
data << uint64(m_guid);
@@ -1520,7 +1554,6 @@ void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot)
data << uint8(m_lootThreshold); // loot threshold
data << uint8(m_dungeonDifficulty); // Dungeon Difficulty
data << uint8(m_raidDifficulty); // Raid Difficulty
- data << uint8(0); // 3.3
}
player->GetSession()->SendPacket(&data);
@@ -1543,6 +1576,21 @@ void Group::UpdatePlayerOutOfRange(Player* player)
}
}
+void Group::BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group, uint64 ignore)
+{
+ for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* player = itr->GetSource();
+ if (!player || (ignore != 0 && player->GetGUID() == ignore) || (ignorePlayersInBGRaid && player->GetGroup() != this))
+ continue;
+
+ if (WorldSession* session = player->GetSession())
+ if (session && (group == -1 || itr->getSubGroup() == group))
+ if (session->IsAddonRegistered(prefix))
+ session->SendPacket(packet);
+ }
+}
+
void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group, uint64 ignore)
{
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
@@ -1757,7 +1805,7 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
BattlemasterListEntry const* bgEntry = sBattlemasterListStore.LookupEntry(bgOrTemplate->GetTypeID());
if (!bgEntry)
- return ERR_GROUP_JOIN_BATTLEGROUND_FAIL; // shouldn't happen
+ return ERR_BATTLEGROUND_JOIN_FAILED; // shouldn't happen
// check for min / max count
uint32 memberscount = GetMembersCount();
@@ -1822,7 +1870,7 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const*
if (bgOrTemplate->isArena() && memberscount != MinPlayerCount)
return ERR_ARENA_TEAM_PARTY_SIZE;
- return GroupJoinBattlegroundResult(bgOrTemplate->GetTypeID());
+ return ERR_BATTLEGROUND_NONE;
}
//===================================================
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 6336a1bb30c..d2981cf56bd 100644
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -94,34 +94,38 @@ enum GroupType
enum GroupUpdateFlags
{
GROUP_UPDATE_FLAG_NONE = 0x00000000, // nothing
- GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16, flags
- GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32
- GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32
- GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8
- GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // uint16
- GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // uint16
- GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16
- GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16
- GROUP_UPDATE_FLAG_POSITION = 0x00000100, // uint16, uint16
- GROUP_UPDATE_FLAG_AURAS = 0x00000200, // uint64 mask, for each bit set uint32 spellid + uint8 unk
- GROUP_UPDATE_FLAG_PET_GUID = 0x00000400, // uint64 pet guid
- GROUP_UPDATE_FLAG_PET_NAME = 0x00000800, // pet name, NULL terminated string
- GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00001000, // uint16, model id
- GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00002000, // uint32 pet cur health
- GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00004000, // uint32 pet max health
- GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00008000, // uint8 pet power type
- GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00010000, // uint16 pet cur power
- GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00020000, // uint16 pet max power
- GROUP_UPDATE_FLAG_PET_AURAS = 0x00040000, // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras...
- GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00080000, // uint32 vehicle_seat_id (index from VehicleSeat.dbc)
- GROUP_UPDATE_PET = 0x0007FC00, // all pet flags
- GROUP_UPDATE_FULL = 0x0007FFFF // all known flags
+ GROUP_UPDATE_FLAG_STATUS = 0x00000001, // uint16 (GroupMemberStatusFlag)
+ GROUP_UPDATE_FLAG_CUR_HP = 0x00000002, // uint32 (HP)
+ GROUP_UPDATE_FLAG_MAX_HP = 0x00000004, // uint32 (HP)
+ GROUP_UPDATE_FLAG_POWER_TYPE = 0x00000008, // uint8 (PowerType)
+ GROUP_UPDATE_FLAG_CUR_POWER = 0x00000010, // int16 (power value)
+ GROUP_UPDATE_FLAG_MAX_POWER = 0x00000020, // int16 (power value)
+ GROUP_UPDATE_FLAG_LEVEL = 0x00000040, // uint16 (level value)
+ GROUP_UPDATE_FLAG_ZONE = 0x00000080, // uint16 (zone id)
+ GROUP_UPDATE_FLAG_UNK100 = 0x00000100, // int16 (unk)
+ GROUP_UPDATE_FLAG_POSITION = 0x00000200, // uint16 (x), uint16 (y), uint16 (z)
+ GROUP_UPDATE_FLAG_AURAS = 0x00000400, // uint8 (unk), uint64 (mask), uint32 (count), for each bit set: uint32 (spell id) + uint16 (AuraFlags) (if has flags Scalable -> 3x int32 (bps))
+ GROUP_UPDATE_FLAG_PET_GUID = 0x00000800, // uint64 (pet guid)
+ GROUP_UPDATE_FLAG_PET_NAME = 0x00001000, // cstring (name, NULL terminated string)
+ GROUP_UPDATE_FLAG_PET_MODEL_ID = 0x00002000, // uint16 (model id)
+ GROUP_UPDATE_FLAG_PET_CUR_HP = 0x00004000, // uint32 (HP)
+ GROUP_UPDATE_FLAG_PET_MAX_HP = 0x00008000, // uint32 (HP)
+ GROUP_UPDATE_FLAG_PET_POWER_TYPE = 0x00010000, // uint8 (PowerType)
+ GROUP_UPDATE_FLAG_PET_CUR_POWER = 0x00020000, // uint16 (power value)
+ GROUP_UPDATE_FLAG_PET_MAX_POWER = 0x00040000, // uint16 (power value)
+ GROUP_UPDATE_FLAG_PET_AURAS = 0x00080000, // [see GROUP_UPDATE_FLAG_AURAS]
+ GROUP_UPDATE_FLAG_VEHICLE_SEAT = 0x00100000, // int32 (vehicle seat id)
+ GROUP_UPDATE_FLAG_PHASE = 0x00200000, // int32 (unk), uint32 (phase count), for (count) uint16(phaseId)
+
+ GROUP_UPDATE_PET = GROUP_UPDATE_FLAG_PET_GUID | GROUP_UPDATE_FLAG_PET_NAME | GROUP_UPDATE_FLAG_PET_MODEL_ID |
+ GROUP_UPDATE_FLAG_PET_CUR_HP | GROUP_UPDATE_FLAG_PET_MAX_HP | GROUP_UPDATE_FLAG_PET_POWER_TYPE |
+ GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER | GROUP_UPDATE_FLAG_PET_AURAS, // all pet flags
+ GROUP_UPDATE_FULL = GROUP_UPDATE_FLAG_STATUS | GROUP_UPDATE_FLAG_CUR_HP | GROUP_UPDATE_FLAG_MAX_HP |
+ GROUP_UPDATE_FLAG_POWER_TYPE | GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER |
+ GROUP_UPDATE_FLAG_LEVEL | GROUP_UPDATE_FLAG_ZONE | GROUP_UPDATE_FLAG_POSITION |
+ GROUP_UPDATE_FLAG_AURAS | GROUP_UPDATE_PET | GROUP_UPDATE_FLAG_PHASE // all known flags, except UNK100 and VEHICLE_SEAT
};
-#define GROUP_UPDATE_FLAGS_COUNT 20
- // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
-static const uint8 GroupUpdateLength[GROUP_UPDATE_FLAGS_COUNT] = { 0, 2, 2, 2, 1, 2, 2, 2, 2, 4, 8, 8, 1, 2, 2, 2, 1, 2, 2, 8};
-
class Roll : public LootValidatorRef
{
public:
@@ -240,6 +244,7 @@ class Group
void ConvertToLFG();
void ConvertToRaid();
+ void ConvertToGroup();
void SetBattlegroundGroup(Battleground* bg);
void SetBattlefieldGroup(Battlefield* bf);
@@ -268,6 +273,7 @@ class Group
void UpdatePlayerOutOfRange(Player* player);
// ignore: GUID of player that will be ignored
void BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group = -1, uint64 ignore = 0);
+ void BroadcastAddonMessagePacket(WorldPacket* packet, const std::string& prefix, bool ignorePlayersInBGRaid, int group = -1, uint64 ignore = 0);
void BroadcastReadyCheck(WorldPacket* packet);
void OfflineReadyCheck();
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index f448fbb9f19..a586b389630 100644
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -22,6 +22,7 @@
#include "Config.h"
#include "DatabaseEnv.h"
#include "Guild.h"
+#include "GuildFinderMgr.h"
#include "GuildMgr.h"
#include "Language.h"
#include "Log.h"
@@ -73,7 +74,7 @@ std::string _GetGuildEventString(GuildEvents event)
case GE_BANK_MONEY_SET:
return "Bank money set";
case GE_BANK_TAB_AND_MONEY_UPDATED:
- return "Bank and money updated";
+ return "Bank money changed";
case GE_BANK_TEXT_CHANGED:
return "Bank tab text changed";
default:
@@ -153,9 +154,13 @@ inline void Guild::LogHolder::AddEvent(SQLTransaction& trans, LogEntry* entry)
// Writes information about all events into packet.
inline void Guild::LogHolder::WritePacket(WorldPacket& data) const
{
- data << uint8(m_log.size());
+ ByteBuffer buffer;
+ data.WriteBits(m_log.size(), 23);
for (GuildLog::const_iterator itr = m_log.begin(); itr != m_log.end(); ++itr)
- (*itr)->WritePacket(data);
+ (*itr)->WritePacket(data, buffer);
+
+ data.FlushBits();
+ data.append(buffer);
}
inline uint32 Guild::LogHolder::GetNextGUID()
@@ -189,20 +194,56 @@ void Guild::EventLogEntry::SaveToDB(SQLTransaction& trans) const
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::EventLogEntry::WritePacket(WorldPacket& data) const
+void Guild::EventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const
{
- // Event type
- data << uint8(m_eventType);
- // Player 1
- data << uint64(MAKE_NEW_GUID(m_playerGuid1, 0, HIGHGUID_PLAYER));
- // Player 2 not for left/join guild events
- if (m_eventType != GUILD_EVENT_LOG_JOIN_GUILD && m_eventType != GUILD_EVENT_LOG_LEAVE_GUILD)
- data << uint64(MAKE_NEW_GUID(m_playerGuid2, 0, HIGHGUID_PLAYER));
- // New Rank - only for promote/demote guild events
- if (m_eventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || m_eventType == GUILD_EVENT_LOG_DEMOTE_PLAYER)
- data << uint8(m_newRank);
+ ObjectGuid guid1 = MAKE_NEW_GUID(m_playerGuid1, 0, HIGHGUID_PLAYER);
+ ObjectGuid guid2 = MAKE_NEW_GUID(m_playerGuid2, 0, HIGHGUID_PLAYER);
+
+ data.WriteBit(guid1[2]);
+ data.WriteBit(guid1[4]);
+ data.WriteBit(guid2[7]);
+ data.WriteBit(guid2[6]);
+ data.WriteBit(guid1[3]);
+ data.WriteBit(guid2[3]);
+ data.WriteBit(guid2[5]);
+ data.WriteBit(guid1[7]);
+ data.WriteBit(guid1[5]);
+ data.WriteBit(guid1[0]);
+ data.WriteBit(guid2[4]);
+ data.WriteBit(guid2[2]);
+ data.WriteBit(guid2[0]);
+ data.WriteBit(guid2[1]);
+ data.WriteBit(guid1[1]);
+ data.WriteBit(guid1[6]);
+
+ content.WriteByteSeq(guid2[3]);
+ content.WriteByteSeq(guid2[2]);
+ content.WriteByteSeq(guid2[5]);
+
+ // New Rank
+ content << uint8(m_newRank);
+
+ content.WriteByteSeq(guid2[4]);
+ content.WriteByteSeq(guid1[0]);
+ content.WriteByteSeq(guid1[4]);
+
// Event timestamp
- data << uint32(::time(NULL) - m_timestamp);
+ content << uint32(::time(NULL) - m_timestamp);
+
+ content.WriteByteSeq(guid1[7]);
+ content.WriteByteSeq(guid1[3]);
+ content.WriteByteSeq(guid2[0]);
+ content.WriteByteSeq(guid2[6]);
+ content.WriteByteSeq(guid2[7]);
+ content.WriteByteSeq(guid1[5]);
+
+ // Event type
+ content << uint8(m_eventType);
+
+ content.WriteByteSeq(guid2[1]);
+ content.WriteByteSeq(guid1[2]);
+ content.WriteByteSeq(guid1[6]);
+ content.WriteByteSeq(guid1[1]);
}
// BankEventLogEntry
@@ -230,29 +271,101 @@ void Guild::BankEventLogEntry::SaveToDB(SQLTransaction& trans) const
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::BankEventLogEntry::WritePacket(WorldPacket& data) const
+void Guild::BankEventLogEntry::WritePacket(WorldPacket& data, ByteBuffer& content) const
{
- data << uint8(m_eventType);
- data << uint64(MAKE_NEW_GUID(m_playerGuid, 0, HIGHGUID_PLAYER));
+ ObjectGuid logGuid = MAKE_NEW_GUID(m_playerGuid, 0, HIGHGUID_PLAYER);
- switch (m_eventType)
- {
- case GUILD_BANK_LOG_DEPOSIT_ITEM:
- case GUILD_BANK_LOG_WITHDRAW_ITEM:
- data << uint32(m_itemOrMoney);
- data << uint32(m_itemStackCount);
- break;
- case GUILD_BANK_LOG_MOVE_ITEM:
- case GUILD_BANK_LOG_MOVE_ITEM2:
- data << uint32(m_itemOrMoney);
- data << uint32(m_itemStackCount);
- data << uint8(m_destTabId);
- break;
- default:
- data << uint32(m_itemOrMoney);
- }
+ bool hasItem = m_eventType == GUILD_BANK_LOG_DEPOSIT_ITEM || m_eventType == GUILD_BANK_LOG_WITHDRAW_ITEM ||
+ m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2;
+
+ bool itemMoved = (m_eventType == GUILD_BANK_LOG_MOVE_ITEM || m_eventType == GUILD_BANK_LOG_MOVE_ITEM2);
+
+ bool hasStack = (hasItem && m_itemStackCount > 1) || itemMoved;
- data << uint32(time(NULL) - m_timestamp);
+ data.WriteBit(IsMoneyEvent());
+ data.WriteBit(logGuid[4]);
+ data.WriteBit(logGuid[1]);
+ data.WriteBit(hasItem);
+ data.WriteBit(hasStack);
+ data.WriteBit(logGuid[2]);
+ data.WriteBit(logGuid[5]);
+ data.WriteBit(logGuid[3]);
+ data.WriteBit(logGuid[6]);
+ data.WriteBit(logGuid[0]);
+ data.WriteBit(itemMoved);
+ data.WriteBit(logGuid[7]);
+
+ content.WriteByteSeq(logGuid[6]);
+ content.WriteByteSeq(logGuid[1]);
+ content.WriteByteSeq(logGuid[5]);
+ if (hasStack)
+ content << uint32(m_itemStackCount);
+
+ content << uint8(m_eventType);
+ content.WriteByteSeq(logGuid[2]);
+ content.WriteByteSeq(logGuid[4]);
+ content.WriteByteSeq(logGuid[0]);
+ content.WriteByteSeq(logGuid[7]);
+ content.WriteByteSeq(logGuid[3]);
+ if (hasItem)
+ content << uint32(m_itemOrMoney);
+
+ content << uint32(time(NULL) - m_timestamp);
+
+ if (IsMoneyEvent())
+ content << uint64(m_itemOrMoney);
+
+ if (itemMoved)
+ content << uint8(m_destTabId);
+}
+
+void Guild::NewsLogEntry::SaveToDB(SQLTransaction& trans) const
+{
+ uint8 index = 0;
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GUILD_NEWS);
+ stmt->setUInt32( index, m_guildId);
+ stmt->setUInt32(++index, GetGUID());
+ stmt->setUInt8 (++index, GetType());
+ stmt->setUInt32(++index, GetPlayerGuid());
+ stmt->setUInt32(++index, GetFlags());
+ stmt->setUInt32(++index, GetValue());
+ stmt->setUInt64(++index, GetTimestamp());
+ CharacterDatabase.ExecuteOrAppend(trans, stmt);
+}
+
+void Guild::NewsLogEntry::WritePacket(WorldPacket& data, ByteBuffer& /*content*/) const
+{
+ data.WriteBits(0, 26); // Not yet implemented used for guild achievements
+ ObjectGuid guid = GetPlayerGuid();
+
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guid[5]);
+
+ data << uint32(GetFlags()); // 1 sticky
+ data << uint32(GetValue());
+ data << uint32(0); // always 0
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+
+ data << uint32(GetGUID());
+ data << uint32(GetType());
+ data.AppendPackedTime(GetTimestamp());
}
// RankInfo
@@ -302,20 +415,6 @@ void Guild::RankInfo::CreateMissingTabsIfNeeded(uint8 tabs, SQLTransaction& tran
}
}
-void Guild::RankInfo::WritePacket(WorldPacket& data) const
-{
- data << uint32(m_rights);
- if (m_bankMoneyPerDay == GUILD_WITHDRAW_MONEY_UNLIMITED)
- data << uint32(GUILD_WITHDRAW_MONEY_UNLIMITED);
- else
- data << uint32(m_bankMoneyPerDay);
- for (uint8 i = 0; i < GUILD_BANK_MAX_TABS; ++i)
- {
- data << uint32(m_bankTabRightsAndSlots[i].GetRights());
- data << uint32(m_bankTabRightsAndSlots[i].GetSlots());
- }
-}
-
void Guild::RankInfo::SetName(std::string const& name)
{
if (m_name == name)
@@ -444,64 +543,6 @@ void Guild::BankTab::Delete(SQLTransaction& trans, bool removeItemsFromDB)
}
}
-inline void Guild::BankTab::WritePacket(WorldPacket& data) const
-{
- uint8 count = 0;
-
- size_t pos = data.wpos();
- data << uint8(0);
-
- for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
- if (WriteSlotPacket(data, slotId))
- ++count;
-
- data.put<uint8>(pos, count);
-}
-
-// Writes information about contents of specified slot into packet.
-bool Guild::BankTab::WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignoreEmpty /* = true */) const
-{
- Item* pItem = GetItem(slotId);
- uint32 itemEntry = pItem ? pItem->GetEntry() : 0;
-
- if (!itemEntry && ignoreEmpty)
- return false;
-
- data << uint8(slotId);
- data << uint32(itemEntry);
- if (itemEntry)
- {
- data << uint32(0); // 3.3.0 (0x00018020, 0x00018000)
-
-
- if (uint32 random = pItem->GetItemRandomPropertyId())
- {
- data << uint32(random); // Random item property id
- data << uint32(pItem->GetItemSuffixFactor()); // SuffixFactor
- }
- else
- data << uint32(0);
-
- data << uint32(pItem->GetCount()); // ITEM_FIELD_STACK_COUNT
- data << uint32(0);
- data << uint8(abs(pItem->GetSpellCharges())); // Spell charges
-
- uint8 enchCount = 0;
- size_t enchCountPos = data.wpos();
-
- data << uint8(enchCount); // Number of enchantments
- for (uint32 i = PERM_ENCHANTMENT_SLOT; i < MAX_ENCHANTMENT_SLOT; ++i)
- if (uint32 enchId = pItem->GetEnchantmentId(EnchantmentSlot(i)))
- {
- data << uint8(i);
- data << uint32(enchId);
- ++enchCount;
- }
- data.put<uint8>(enchCountPos, enchCount);
- }
- return true;
-}
-
void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon)
{
if (m_name == name && m_icon == icon)
@@ -567,19 +608,20 @@ bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* item)
void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const
{
- WorldPacket data(MSG_QUERY_GUILD_BANK_TEXT, 1 + m_text.size() + 1);
- data << uint8(m_tabId);
- data << m_text;
+ WorldPacket data(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, 1 + m_text.size() + 1);
+ data.WriteBits(m_text.length(), 14);
+ data << uint32(m_tabId);
+ data.WriteString(m_text);
if (session)
{
- TC_LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [%s]: Tabid: %u, Text: %s"
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [%s]: Tabid: %u, Text: %s"
, session->GetPlayerInfo().c_str(), m_tabId, m_text.c_str());
session->SendPacket(&data);
}
else
{
- TC_LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str());
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_QUERY_TEXT_RESULT [Broadcast]: Tabid: %u, Text: %s", m_tabId, m_text.c_str());
guild->BroadcastPacket(&data);
}
}
@@ -592,15 +634,17 @@ void Guild::Member::SetStats(Player* player)
m_class = player->getClass();
m_zoneId = player->GetZoneId();
m_accountId = player->GetSession()->GetAccountId();
+ m_achievementPoints = player->GetAchievementPoints();
}
-void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId)
+void Guild::Member::SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId, uint32 reputation)
{
m_name = name;
m_level = level;
m_class = _class;
m_zoneId = zoneId;
m_accountId = accountId;
+ m_totalReputation = reputation;
}
void Guild::Member::SetPublicNote(std::string const& publicNote)
@@ -665,12 +709,16 @@ bool Guild::Member::LoadFromDB(Field* fields)
for (uint8 i = 0; i <= GUILD_BANK_MAX_TABS; ++i)
m_bankWithdraw[i] = fields[5 + i].GetUInt32();
- SetStats(fields[12].GetString(),
- fields[13].GetUInt8(), // characters.level
- fields[14].GetUInt8(), // characters.class
- fields[15].GetUInt16(), // characters.zone
- fields[16].GetUInt32()); // characters.account
- m_logoutTime = fields[17].GetUInt32(); // characters.logout_time
+ SetStats(fields[14].GetString(),
+ fields[15].GetUInt8(), // characters.level
+ fields[16].GetUInt8(), // characters.class
+ fields[17].GetUInt16(), // characters.zone
+ fields[18].GetUInt32(), // characters.account
+ 0);
+ m_logoutTime = fields[19].GetUInt32(); // characters.logout_time
+ m_totalActivity = 0;
+ m_weekActivity = 0;
+ m_weekReputation = 0;
if (!CheckStats())
return false;
@@ -701,28 +749,6 @@ bool Guild::Member::CheckStats() const
return true;
}
-void Guild::Member::WritePacket(WorldPacket& data, bool sendOfficerNote) const
-{
- data << uint64(m_guid)
- << uint8(m_flags)
- << m_name
- << uint32(m_rankId)
- << uint8(m_level)
- << uint8(m_class)
- << uint8(0)
- << uint32(m_zoneId);
-
- if (!m_flags)
- data << float(float(::time(NULL) - m_logoutTime) / DAY);
-
- data << m_publicNote;
-
- if (sendOfficerNote)
- data << m_officerNote;
- else
- data << "";
-}
-
// Decreases amount of money/slots left for today.
// If (tabId == GUILD_BANK_MAX_TABS) decrease money amount.
// Otherwise decrease remaining items amount for specified tab.
@@ -741,10 +767,16 @@ void Guild::Member::UpdateBankWithdrawValue(SQLTransaction& trans, uint8 tabId,
CharacterDatabase.ExecuteOrAppend(trans, stmt);
}
-void Guild::Member::ResetValues()
+void Guild::Member::ResetValues(bool weekly /* = false*/)
{
for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId)
m_bankWithdraw[tabId] = 0;
+
+ if (weekly)
+ {
+ m_weekActivity = 0;
+ m_weekReputation = 0;
+ }
}
// Get amount of money/slots left for today.
@@ -851,13 +883,13 @@ bool Guild::PlayerMoveItemData::InitItem()
// Anti-WPE protection. Do not move non-empty bags to bank.
if (m_pItem->IsNotEmptyBag())
{
- m_pPlayer->SendEquipError(EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS, m_pItem);
+ m_pPlayer->SendEquipError(EQUIP_ERR_DESTROY_NONEMPTY_BAG, m_pItem);
m_pItem = NULL;
}
// Bound items cannot be put into bank.
else if (!m_pItem->CanBeTraded())
{
- m_pPlayer->SendEquipError(EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, m_pItem);
+ m_pPlayer->SendEquipError(EQUIP_ERR_CANT_SWAP, m_pItem);
m_pItem = NULL;
}
}
@@ -1082,11 +1114,11 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
uint32 count = pItem->GetCount();
// Soulbound items cannot be moved
if (pItem->IsSoulBound())
- return EQUIP_ERR_CANT_DROP_SOULBOUND;
+ return EQUIP_ERR_DROP_BOUND_ITEM;
// Make sure destination bank tab exists
if (m_container >= m_pGuild->_GetPurchasedTabsSize())
- return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
+ return EQUIP_ERR_WRONG_BAG_TYPE;
// Slot explicitely specified. Check it.
if (m_slotId != NULL_SLOT)
@@ -1097,7 +1129,7 @@ InventoryResult Guild::BankMoveItemData::CanStore(Item* pItem, bool swap)
pItemDest = NULL;
if (!_ReserveSpace(m_slotId, pItem, pItemDest, count))
- return EQUIP_ERR_ITEM_CANT_STACK;
+ return EQUIP_ERR_CANT_STACK;
if (count == 0)
return EQUIP_ERR_OK;
@@ -1127,7 +1159,12 @@ Guild::Guild():
m_createdDate(0),
m_accountsNumber(0),
m_bankMoney(0),
- m_eventLog(NULL)
+ m_eventLog(NULL),
+ m_newsLog(NULL),
+ m_achievementMgr(this),
+ _level(1),
+ _experience(0),
+ _todayExperience(0)
{
memset(&m_bankEventLog, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(LogHolder*));
}
@@ -1140,6 +1177,8 @@ Guild::~Guild()
// Cleanup
delete m_eventLog;
m_eventLog = NULL;
+ delete m_newsLog;
+ m_newsLog = NULL;
for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId)
{
@@ -1172,6 +1211,9 @@ bool Guild::Create(Player* pLeader, std::string const& name)
m_motd = "No message set.";
m_bankMoney = 0;
m_createdDate = ::time(NULL);
+ _level = 1;
+ _experience = 0;
+ _todayExperience = 0;
_CreateLogHolders();
TC_LOG_DEBUG("guild", "GUILD: creating guild [%s] for leader %s (%u)",
@@ -1204,7 +1246,10 @@ bool Guild::Create(Player* pLeader, std::string const& name)
bool ret = AddMember(m_leaderGuid, GR_GUILDMASTER); // Add guildmaster
if (ret)
+ {
+ _BroadcastEvent(GE_FOUNDER, 0);
sScriptMgr->OnGuildCreate(this, pLeader, name);
+ }
return ret;
}
@@ -1257,9 +1302,28 @@ void Guild::Disband()
trans->Append(stmt);
CharacterDatabase.CommitTransaction(trans);
+
+ sGuildFinderMgr->DeleteGuild(m_id);
+
sGuildMgr->RemoveGuild(m_id);
}
+void Guild::SaveToDB()
+{
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_EXPERIENCE);
+ stmt->setUInt32(0, GetLevel());
+ stmt->setUInt64(1, GetExperience());
+ stmt->setUInt64(2, GetTodayExperience());
+ stmt->setUInt32(3, GetId());
+ trans->Append(stmt);
+
+ m_achievementMgr.SaveToDB(trans);
+
+ CharacterDatabase.CommitTransaction(trans);
+}
+
void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value)
{
if (Member* member = GetMember(player->GetGUID()))
@@ -1267,7 +1331,10 @@ void Guild::UpdateMemberData(Player* player, uint8 dataid, uint32 value)
switch (dataid)
{
case GUILD_MEMBER_DATA_ZONEID:
- member->SetZoneID(value);
+ member->SetZoneId(value);
+ break;
+ case GUILD_MEMBER_DATA_ACHIEVEMENT_POINTS:
+ member->SetAchievementPoints(value);
break;
case GUILD_MEMBER_DATA_LEVEL:
member->SetLevel(value);
@@ -1300,23 +1367,113 @@ bool Guild::SetName(std::string const& name)
stmt->setString(0, m_name);
stmt->setUInt32(1, GetId());
CharacterDatabase.Execute(stmt);
+
+ ObjectGuid guid = GetGUID();
+ WorldPacket data(SMSG_GUILD_RENAMED, 24 + 8 + 1);
+ data.WriteBit(guid[5]);
+ data.WriteBits(name.length(), 8);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[2]);
+
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteString(name);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[5]);
+
+ BroadcastPacket(&data);
return true;
}
void Guild::HandleRoster(WorldSession* session)
{
+ ByteBuffer memberData(100);
// Guess size
- WorldPacket data(SMSG_GUILD_ROSTER, (4 + m_motd.length() + 1 + m_info.length() + 1 + 4 + _GetRanksSize() * (4 + 4 + GUILD_BANK_MAX_TABS * (4 + 4)) + m_members.size() * 50));
- data << uint32(m_members.size());
- data << m_motd;
- data << m_info;
-
- data << uint32(_GetRanksSize());
- for (Ranks::const_iterator ritr = m_ranks.begin(); ritr != m_ranks.end(); ++ritr)
- ritr->WritePacket(data);
+ WorldPacket data(SMSG_GUILD_ROSTER, 100);
+ data.WriteBits(m_motd.length(), 11);
+ data.WriteBits(m_members.size(), 18);
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- itr->second->WritePacket(data, _HasRankRight(session->GetPlayer(), GR_RIGHT_VIEWOFFNOTE));
+ {
+ Member* member = itr->second;
+ size_t pubNoteLength = member->GetPublicNote().length();
+ size_t offNoteLength = member->GetOfficerNote().length();
+
+ ObjectGuid guid = member->GetGUID();
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(0); // Has Authenticator
+ data.WriteBit(0); // Can Scroll of Ressurect
+ data.WriteBits(pubNoteLength, 8);
+ data.WriteBits(offNoteLength, 8);
+ data.WriteBit(guid[0]);
+ data.WriteBits(member->GetName().length(), 7);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[7]);
+
+ memberData << uint8(member->GetClass());
+ memberData << uint32(member->GetTotalReputation());
+ memberData.WriteByteSeq(guid[0]);
+ memberData << uint64(member->GetWeekActivity());
+ memberData << uint32(member->GetRankId());
+ memberData << uint32(member->GetAchievementPoints());
+
+ // for (2 professions)
+ memberData << uint32(0) << uint32(0) << uint32(0);
+ memberData << uint32(0) << uint32(0) << uint32(0);
+
+ memberData.WriteByteSeq(guid[2]);
+ memberData << uint8(member->GetFlags());
+ memberData << uint32(member->GetZoneId());
+ memberData << uint64(member->GetTotalActivity());
+ memberData.WriteByteSeq(guid[7]);
+ memberData << uint32(sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP) - member->GetWeekReputation());
+
+ if (pubNoteLength)
+ memberData.WriteString(member->GetPublicNote());
+
+ memberData.WriteByteSeq(guid[3]);
+ memberData << uint8(member->GetLevel());
+ memberData << int32(0); // unk
+ memberData.WriteByteSeq(guid[5]);
+ memberData.WriteByteSeq(guid[4]);
+ memberData << uint8(0); // unk
+ memberData.WriteByteSeq(guid[1]);
+ memberData << float(member->IsOnline() ? 0.0f : float(::time(NULL) - member->GetLogoutTime()) / DAY);
+
+ if (offNoteLength)
+ memberData.WriteString(member->GetOfficerNote());
+
+ memberData.WriteByteSeq(guid[6]);
+ memberData.WriteString(member->GetName());
+ }
+
+ size_t infoLength = m_info.length();
+ data.WriteBits(infoLength, 12);
+
+ data.FlushBits();
+ data.append(memberData);
+
+ if (infoLength)
+ data.WriteString(m_info);
+
+ data.WriteString(m_motd);
+ data << uint32(m_accountsNumber);
+ data << uint32(sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP));
+ data.AppendPackedTime(m_createdDate);
+ data << uint32(0);
TC_LOG_DEBUG("guild", "SMSG_GUILD_ROSTER [%s]", session->GetPlayerInfo().c_str());
session->SendPacket(&data);
@@ -1325,7 +1482,8 @@ void Guild::HandleRoster(WorldSession* session)
void Guild::HandleQuery(WorldSession* session)
{
WorldPacket data(SMSG_GUILD_QUERY_RESPONSE, 8 * 32 + 200); // Guess size
- data << uint32(m_id);
+
+ data << uint64(GetGUID());
data << m_name;
// Rank name
@@ -1337,6 +1495,24 @@ void Guild::HandleQuery(WorldSession* session)
data << uint8(0); // Empty string
}
+ // Rank order of creation
+ for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i)
+ {
+ if (i < _GetRanksSize())
+ data << uint32(i);
+ else
+ data << uint32(0);
+ }
+
+ // Rank order of "importance" (sorting by rights)
+ for (uint8 i = 0; i < GUILD_RANKS_MAX_COUNT; ++i)
+ {
+ if (i < _GetRanksSize())
+ data << uint32(m_ranks[i].GetId());
+ else
+ data << uint32(0);
+ }
+
m_emblemInfo.WritePacket(data);
data << uint32(_GetRanksSize()); // Number of ranks used
@@ -1344,6 +1520,44 @@ void Guild::HandleQuery(WorldSession* session)
TC_LOG_DEBUG("guild", "SMSG_GUILD_QUERY_RESPONSE [%s]", session->GetPlayerInfo().c_str());
}
+void Guild::SendGuildRankInfo(WorldSession* session) const
+{
+ ByteBuffer rankData(100);
+ WorldPacket data(SMSG_GUILD_RANK, 100);
+
+ data.WriteBits(_GetRanksSize(), 18);
+
+ for (uint8 i = 0; i < _GetRanksSize(); i++)
+ {
+ RankInfo const* rankInfo = GetRankInfo(i);
+ if (!rankInfo)
+ continue;
+
+ data.WriteBits(rankInfo->GetName().length(), 7);
+
+ rankData << uint32(rankInfo->GetId());
+
+ for (uint8 j = 0; j < GUILD_BANK_MAX_TABS; ++j)
+ {
+ rankData << uint32(rankInfo->GetBankTabSlotsPerDay(j));
+ rankData << uint32(rankInfo->GetBankTabRights(j));
+ }
+
+ rankData << uint32(rankInfo->GetBankMoneyPerDay());
+ rankData << uint32(rankInfo->GetRights());
+
+ if (rankInfo->GetName().length())
+ rankData.WriteString(rankInfo->GetName());
+
+ rankData << uint32(i);
+ }
+
+ data.FlushBits();
+ data.append(rankData);
+ session->SendPacket(&data);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_RANK [%s]", session->GetPlayerInfo().c_str());
+}
+
void Guild::HandleSetMOTD(WorldSession* session, std::string const& motd)
{
if (m_motd == motd)
@@ -1391,11 +1605,11 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo)
Player* player = session->GetPlayer();
if (!_IsLeader(player))
SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTGUILDMASTER); // "Only guild leaders can create emblems."
- else if (!player->HasEnoughMoney(EMBLEM_PRICE))
+ else if (!player->HasEnoughMoney(uint64(EMBLEM_PRICE)))
SendSaveEmblemResult(session, ERR_GUILDEMBLEM_NOTENOUGHMONEY); // "You can't afford to do that."
else
{
- player->ModifyMoney(-int32(EMBLEM_PRICE));
+ player->ModifyMoney(-int64(EMBLEM_PRICE));
m_emblemInfo = emblemInfo;
m_emblemInfo.SaveToDB(m_id);
@@ -1406,20 +1620,20 @@ void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo)
}
}
-void Guild::HandleSetLeader(WorldSession* session, std::string const& name)
+void Guild::HandleSetNewGuildMaster(WorldSession* session, std::string const& name)
{
Player* player = session->GetPlayer();
- // Only leader can assign new leader
+ // Only the guild master can throne a new guild master
if (!_IsLeader(player))
SendCommandResult(session, GUILD_COMMAND_CHANGE_LEADER, ERR_GUILD_PERMISSIONS);
- // Old leader must be a member of guild
- else if (Member* pOldLeader = GetMember(player->GetGUID()))
+ // Old GM must be a guild member
+ else if (Member* oldGuildMaster = GetMember(player->GetGUID()))
{
- // New leader must be a member of guild
- if (Member* pNewLeader = GetMember(name))
+ // Same for the new one
+ if (Member* newGuildMaster = GetMember(name))
{
- _SetLeaderGUID(pNewLeader);
- pOldLeader->ChangeRank(GR_OFFICER);
+ _SetLeaderGUID(newGuildMaster);
+ oldGuildMaster->ChangeRank(GR_INITIATE);
_BroadcastEvent(GE_LEADER_CHANGED, 0, player->GetName().c_str(), name.c_str());
}
}
@@ -1442,19 +1656,19 @@ void Guild::HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string
_BroadcastEvent(GE_BANK_TAB_UPDATED, 0, aux, name.c_str(), icon.c_str());
}
-void Guild::HandleSetMemberNote(WorldSession* session, std::string const& name, std::string const& note, bool isPublic)
+void Guild::HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic)
{
// Player must have rights to set public/officer note
if (!_HasRankRight(session->GetPlayer(), isPublic ? GR_RIGHT_EPNOTE : GR_RIGHT_EOFFNOTE))
SendCommandResult(session, GUILD_COMMAND_PUBLIC_NOTE, ERR_GUILD_PERMISSIONS);
- else if (Member* member = GetMember(name))
+ else if (Member* member = GetMember(guid))
{
if (isPublic)
member->SetPublicNote(note);
else
member->SetOfficerNote(note);
- HandleRoster(session);
+ HandleRoster(session); // FIXME - We should send SMSG_GUILD_MEMBER_UPDATE_NOTE
}
}
@@ -1476,7 +1690,7 @@ void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string c
char aux[2];
sprintf(aux, "%u", rankId);
- _BroadcastEvent(GE_RANK_UPDATED, 0, aux, name.c_str());
+ _BroadcastEvent(GE_RANK_UPDATED, 0, aux);
}
}
@@ -1496,14 +1710,19 @@ void Guild::HandleBuyBankTab(WorldSession* session, uint8 tabId)
if (tabId != _GetPurchasedTabsSize())
return;
- uint32 tabCost = _GetGuildBankTabPrice(tabId) * GOLD;
- if (!tabCost)
- return;
+ // Do not get money for bank tabs that the GM bought, we had to buy them already.
+ // This is just a speedup check, GetGuildBankTabPrice will return 0.
+ if (tabId < GUILD_BANK_MAX_TABS - 2) // 7th tab is actually the 6th
+ {
+ uint32 tabCost = _GetGuildBankTabPrice(tabId) * GOLD;
+ if (!tabCost)
+ return;
- if (!player->HasEnoughMoney(tabCost)) // Should not happen, this is checked by client
- return;
+ if (!player->HasEnoughMoney(uint64(tabCost))) // Should not happen, this is checked by client
+ return;
- player->ModifyMoney(-int32(tabCost));
+ player->ModifyMoney(-int64(tabCost));
+ }
_CreateNewBankTab();
_BroadcastEvent(GE_BANK_TAB_PURCHASED, 0);
@@ -1529,12 +1748,14 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_GUILD_NOT_ALLIED, name);
return;
}
+
// Invited player cannot be in another guild
- if (pInvitee->GetGuildId())
+ /*if (pInvitee->GetGuildId())
{
SendCommandResult(session, GUILD_COMMAND_INVITE, ERR_ALREADY_IN_GUILD_S, name);
return;
- }
+ }*/
+
// Invited player cannot be invited
if (pInvitee->GetGuildIdInvited())
{
@@ -1555,9 +1776,65 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name)
pInvitee->SetGuildIdInvited(m_id);
_LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUIDLow(), pInvitee->GetGUIDLow());
- WorldPacket data(SMSG_GUILD_INVITE, 8 + 10); // Guess size
- data << player->GetName();
- data << m_name;
+ WorldPacket data(SMSG_GUILD_INVITE, 100);
+ data << uint32(GetLevel());
+ data << uint32(m_emblemInfo.GetBorderStyle());
+ data << uint32(m_emblemInfo.GetBorderColor());
+ data << uint32(m_emblemInfo.GetStyle());
+ data << uint32(m_emblemInfo.GetBackgroundColor());
+ data << uint32(m_emblemInfo.GetColor());
+
+ ObjectGuid oldGuildGuid = MAKE_NEW_GUID(pInvitee->GetGuildId(), 0, pInvitee->GetGuildId() ? uint32(HIGHGUID_GUILD) : 0);
+ ObjectGuid newGuildGuid = GetGUID();
+
+ data.WriteBit(newGuildGuid[3]);
+ data.WriteBit(newGuildGuid[2]);
+ data.WriteBits(pInvitee->GetGuildName().length(), 8);
+ data.WriteBit(newGuildGuid[1]);
+ data.WriteBit(oldGuildGuid[6]);
+ data.WriteBit(oldGuildGuid[4]);
+ data.WriteBit(oldGuildGuid[1]);
+ data.WriteBit(oldGuildGuid[5]);
+ data.WriteBit(oldGuildGuid[7]);
+ data.WriteBit(oldGuildGuid[2]);
+ data.WriteBit(newGuildGuid[7]);
+ data.WriteBit(newGuildGuid[0]);
+ data.WriteBit(newGuildGuid[6]);
+ data.WriteBits(m_name.length(), 8);
+ data.WriteBit(oldGuildGuid[3]);
+ data.WriteBit(oldGuildGuid[0]);
+ data.WriteBit(newGuildGuid[5]);
+ data.WriteBits(player->GetName().size(), 7);
+ data.WriteBit(newGuildGuid[4]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(newGuildGuid[1]);
+ data.WriteByteSeq(oldGuildGuid[3]);
+ data.WriteByteSeq(newGuildGuid[6]);
+ data.WriteByteSeq(oldGuildGuid[2]);
+ data.WriteByteSeq(oldGuildGuid[1]);
+ data.WriteByteSeq(newGuildGuid[0]);
+
+ if (!pInvitee->GetGuildName().empty())
+ data.WriteString(pInvitee->GetGuildName());
+
+ data.WriteByteSeq(newGuildGuid[7]);
+ data.WriteByteSeq(newGuildGuid[2]);
+
+ data.WriteString(player->GetName());
+
+ data.WriteByteSeq(oldGuildGuid[7]);
+ data.WriteByteSeq(oldGuildGuid[6]);
+ data.WriteByteSeq(oldGuildGuid[5]);
+ data.WriteByteSeq(oldGuildGuid[0]);
+ data.WriteByteSeq(newGuildGuid[4]);
+
+ data.WriteString(m_name);
+
+ data.WriteByteSeq(newGuildGuid[5]);
+ data.WriteByteSeq(newGuildGuid[3]);
+ data.WriteByteSeq(oldGuildGuid[4]);
pInvitee->GetSession()->SendPacket(&data);
TC_LOG_DEBUG("guild", "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str());
}
@@ -1583,6 +1860,8 @@ void Guild::HandleLeaveMember(WorldSession* session)
if (m_members.size() > 1)
// Leader cannot leave if he is not the last member
SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_LEADER_LEAVE);
+ else if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_UNDELETABLE_LEVEL))
+ SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL);
else
{
// Guild is disbanded if leader leaves.
@@ -1606,14 +1885,17 @@ void Guild::HandleLeaveMember(WorldSession* session)
delete this;
}
-void Guild::HandleRemoveMember(WorldSession* session, std::string const& name)
+void Guild::HandleRemoveMember(WorldSession* session, uint64 guid)
{
Player* player = session->GetPlayer();
+
// Player must have rights to remove members
if (!_HasRankRight(player, GR_RIGHT_REMOVE))
SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_PERMISSIONS);
- else if (Member* member = GetMember(name))
+ else if (Member* member = GetMember(guid))
{
+ std::string name = member->GetName();
+
// Guild masters cannot be removed
if (member->IsRank(GR_GUILDMASTER))
SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_LEADER_LEAVE);
@@ -1625,17 +1907,17 @@ void Guild::HandleRemoveMember(WorldSession* session, std::string const& name)
SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_RANK_TOO_HIGH_S, name);
else
{
- uint64 guid = member->GetGUID();
// After call to DeleteMember pointer to member becomes invalid
DeleteMember(guid, false, true);
_LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUIDLow(), GUID_LOPART(guid));
_BroadcastEvent(GE_REMOVED, 0, name.c_str(), player->GetName().c_str());
+ SendCommandResult(session, GUILD_COMMAND_REMOVE, ERR_GUILD_COMMAND_SUCCESS, name);
}
}
}
}
-void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& name, bool demote)
+void Guild::HandleUpdateMemberRank(WorldSession* session, uint64 guid, bool demote)
{
Player* player = session->GetPlayer();
GuildCommandType type = demote ? GUILD_COMMAND_DEMOTE : GUILD_COMMAND_PROMOTE;
@@ -1643,8 +1925,9 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& nam
if (!_HasRankRight(player, demote ? GR_RIGHT_DEMOTE : GR_RIGHT_PROMOTE))
SendCommandResult(session, type, ERR_GUILD_PERMISSIONS);
// Promoted player must be a member of guild
- else if (Member* member = GetMember(name))
+ else if (Member* member = GetMember(guid))
{
+ std::string name = member->GetName();
// Player cannot promote himself
if (member->IsSamePlayer(player->GetGUID()))
{
@@ -1687,6 +1970,36 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& nam
}
}
+void Guild::HandleSetMemberRank(WorldSession* session, uint64 targetGuid, uint64 setterGuid, uint32 rank)
+{
+ Player* player = session->GetPlayer();
+ Member* member = GetMember(targetGuid);
+ GuildRankRights rights = GR_RIGHT_PROMOTE;
+ GuildCommandType type = GUILD_COMMAND_PROMOTE;
+
+ if (rank > member->GetRankId())
+ {
+ rights = GR_RIGHT_DEMOTE;
+ type = GUILD_COMMAND_DEMOTE;
+ }
+
+ // Promoted player must be a member of guild
+ if (!_HasRankRight(player, rights))
+ {
+ SendCommandResult(session, type, ERR_GUILD_PERMISSIONS);
+ return;
+ }
+
+ // Player cannot promote himself
+ if (member->IsSamePlayer(player->GetGUID()))
+ {
+ SendCommandResult(session, type, ERR_GUILD_NAME_INVALID);
+ return;
+ }
+
+ SendGuildRanksUpdate(setterGuid, targetGuid, rank);
+}
+
void Guild::HandleAddNewRank(WorldSession* session, std::string const& name)
{
uint8 size = _GetRanksSize();
@@ -1696,16 +2009,7 @@ void Guild::HandleAddNewRank(WorldSession* session, std::string const& name)
// Only leader can add new rank
if (_IsLeader(session->GetPlayer()))
if (_CreateRank(name, GR_RIGHT_GCHATLISTEN | GR_RIGHT_GCHATSPEAK))
- {
- char aux[2];
- sprintf(aux, "%u", size);
- _BroadcastEvent(GE_RANK_UPDATED, 0, aux, name.c_str());
- }
-}
-
-void Guild::HandleRemoveLowestRank(WorldSession* session)
-{
- HandleRemoveRank(session, _GetLowestRankId());
+ _BroadcastEvent(GE_RANK_CREATED, 0);
}
void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId)
@@ -1720,17 +2024,17 @@ void Guild::HandleRemoveRank(WorldSession* session, uint8 rankId)
stmt->setUInt8(1, rankId);
CharacterDatabase.Execute(stmt);
// Delete rank
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_LOWEST_RANK);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_RANK);
stmt->setUInt32(0, m_id);
stmt->setUInt8(1, rankId);
CharacterDatabase.Execute(stmt);
- m_ranks.pop_back();
+ m_ranks.erase(m_ranks.begin() + rankId);
- _BroadcastEvent(GE_RANK_DELETED, 0);
+ _BroadcastEvent(GE_RANK_DELETED, rankId);
}
-void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount)
+void Guild::HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow /*=false*/)
{
Player* player = session->GetPlayer();
@@ -1739,11 +2043,13 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount)
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_ModifyBankMoney(trans, amount, true);
+ if (!cashFlow)
+ {
+ player->ModifyMoney(-int64(amount));
+ player->SaveGoldToDB(trans);
+ }
- player->ModifyMoney(-int32(amount));
- player->SaveGoldToDB(trans);
- _LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUIDLow(), amount);
-
+ _LogBankEvent(trans, cashFlow ? GUILD_BANK_LOG_CASH_FLOW_DEPOSIT : GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUIDLow(), amount);
CharacterDatabase.CommitTransaction(trans);
std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&m_bankMoney), 8, true);
@@ -1752,15 +2058,15 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount)
if (player->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
{
sLog->outCommand(player->GetSession()->GetAccountId(),
- "GM %s (Account: %u) deposit money (Amount: %u) to guild bank (Guild ID %u)",
+ "GM %s (Account: %u) deposit money (Amount: " UI64FMTD ") to guild bank (Guild ID %u)",
player->GetName().c_str(), player->GetSession()->GetAccountId(), amount, m_id);
}
}
-bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair)
+bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair)
{
- //clamp amount to MAX_MONEY_AMOUNT, Players can't hold more than that anyway
- amount = std::min(amount, uint32(MAX_MONEY_AMOUNT));
+ // clamp amount to MAX_MONEY_AMOUNT, Players can't hold more than that anyway
+ amount = std::min(amount, uint64(MAX_MONEY_AMOUNT));
if (m_bankMoney < amount) // Not enough money in bank
return false;
@@ -1771,7 +2077,7 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool
if (!member)
return false;
- if (uint32(_GetMemberRemainingMoney(member)) < amount) // Check if we have enough slot/money today
+ if (uint64(_GetMemberRemainingMoney(member)) < amount) // Check if we have enough slot/money today
return false;
// Call script after validation and before money transfer.
@@ -1811,6 +2117,8 @@ void Guild::HandleMemberLogout(WorldSession* session)
member->ResetFlags();
}
_BroadcastEvent(GE_SIGNED_OFF, player->GetGUID(), player->GetName().c_str());
+
+ SaveToDB();
}
void Guild::HandleDisband(WorldSession* session)
@@ -1824,50 +2132,104 @@ void Guild::HandleDisband(WorldSession* session)
}
}
-// Send data to client
-void Guild::SendInfo(WorldSession* session) const
+void Guild::HandleGuildPartyRequest(WorldSession* session)
{
- WorldPacket data(SMSG_GUILD_INFO, m_name.size() + 4 + 4 + 4);
- data << m_name;
- data.AppendPackedTime(m_createdDate); // 3.x (prev. year + month + day)
- data << uint32(m_members.size()); // Number of members
- data << m_accountsNumber; // Number of accounts
+ Player* player = session->GetPlayer();
+ Group* group = player->GetGroup();
+
+ // Make sure player is a member of the guild and that he is in a group.
+ if (!IsMember(player->GetGUID()) || !group)
+ return;
+
+ WorldPacket data(SMSG_GUILD_PARTY_STATE_RESPONSE, 13);
+ data.WriteBit(player->GetMap()->GetOwnerGuildId(player->GetTeam()) == GetId()); // Is guild group
+ data.FlushBits();
+ data << float(0.f); // Guild XP multiplier
+ data << uint32(0); // Current guild members
+ data << uint32(0); // Needed guild members
session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "SMSG_GUILD_INFO [%s]", session->GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_PARTY_STATE_RESPONSE [%s]", session->GetPlayerInfo().c_str());
}
void Guild::SendEventLog(WorldSession* session) const
{
- WorldPacket data(MSG_GUILD_EVENT_LOG_QUERY, 1 + m_eventLog->GetSize() * (1 + 8 + 4));
+ WorldPacket data(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, 1 + m_eventLog->GetSize() * (1 + 8 + 4));
m_eventLog->WritePacket(data);
session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "MSG_GUILD_EVENT_LOG_QUERY [%s]", session->GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT_LOG_QUERY_RESULT [%s]", session->GetPlayerInfo().c_str());
}
-void Guild::SendBankLog(WorldSession* session, uint8 tabId) const
+void Guild::SendNewsUpdate(WorldSession* session)
{
- // GUILD_BANK_MAX_TABS send by client for money log
- if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS)
+ uint32 size = m_newsLog->GetSize();
+ GuildLog* logs = m_newsLog->GetGuildLog();
+
+ if (!logs)
+ return;
+
+ WorldPacket data(SMSG_GUILD_NEWS_UPDATE, (21 + size * (26 + 8)) / 8 + (8 + 6 * 4) * size);
+ data.WriteBits(size, 21);
+
+ for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
{
- const LogHolder* pLog = m_bankEventLog[tabId];
- WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, pLog->GetSize() * (4 * 4 + 1) + 1 + 1);
- data << uint8(tabId);
- pLog->WritePacket(data);
- session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [%s]", session->GetPlayerInfo().c_str());
+ data.WriteBits(0, 26); // Not yet implemented used for guild achievements
+ ObjectGuid guid = ((NewsLogEntry*)(*itr))->GetPlayerGuid();
+
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[2]);
}
-}
-void Guild::SendBankTabData(WorldSession* session, uint8 tabId) const
-{
- if (tabId < _GetPurchasedTabsSize())
- _SendBankContent(session, tabId);
+ data.FlushBits();
+
+ for (GuildLog::const_iterator itr = logs->begin(); itr != logs->end(); ++itr)
+ {
+ NewsLogEntry* news = (NewsLogEntry*)(*itr);
+ ObjectGuid guid = news->GetPlayerGuid();
+ data.WriteByteSeq(guid[5]);
+
+ data << uint32(news->GetFlags()); // 1 sticky
+ data << uint32(news->GetValue());
+ data << uint32(0);
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[6]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[1]);
+
+ data << uint32(news->GetGUID());
+ data << uint32(news->GetType());
+ data.AppendPackedTime(news->GetTimestamp());
+ }
+
+ session->SendPacket(&data);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_NEWS_UPDATE [%s]", session->GetPlayerInfo().c_str());
}
-void Guild::SendBankTabsInfo(WorldSession* session, bool sendAllSlots /*= false*/) const
+void Guild::SendBankLog(WorldSession* session, uint8 tabId) const
{
- _SendBankList(session, 0, sendAllSlots);
+ // GUILD_BANK_MAX_TABS send by client for money log
+ if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS)
+ {
+ LogHolder const* log = m_bankEventLog[tabId];
+ WorldPacket data(SMSG_GUILD_BANK_LOG_QUERY_RESULT, log->GetSize() * (4 * 4 + 1) + 1 + 1);
+ data.WriteBit(GetLevel() >= 5 && tabId == GUILD_BANK_MAX_TABS); // has Cash Flow perk
+ log->WritePacket(data);
+ data << uint32(tabId);
+ //if (tabId == GUILD_BANK_MAX_TABS && hasCashFlow)
+ // data << uint64(cashFlowContribution);
+ session->SendPacket(&data);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LOG_QUERY_RESULT [%s] TabId: %u", session->GetPlayerInfo().c_str(), tabId);
+ }
}
void Guild::SendBankTabText(WorldSession* session, uint8 tabId) const
@@ -1884,11 +2246,12 @@ void Guild::SendPermissions(WorldSession* session) const
uint8 rankId = member->GetRankId();
- WorldPacket data(MSG_GUILD_PERMISSIONS, 4 * 15 + 1);
+ WorldPacket data(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, 4 * 15 + 1);
data << uint32(rankId);
+ data << uint32(_GetPurchasedTabsSize());
data << uint32(_GetRankRights(rankId));
data << uint32(_GetMemberRemainingMoney(member));
- data << uint8(_GetPurchasedTabsSize());
+ data.WriteBits(GUILD_BANK_MAX_TABS, 23);
for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
{
data << uint32(_GetRankBankTabRights(rankId, tabId));
@@ -1896,7 +2259,7 @@ void Guild::SendPermissions(WorldSession* session) const
}
session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "MSG_GUILD_PERMISSIONS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_PERMISSIONS_QUERY_RESULTS [%s] Rank: %u", session->GetPlayerInfo().c_str(), rankId);
}
void Guild::SendMoneyInfo(WorldSession* session) const
@@ -1906,14 +2269,30 @@ void Guild::SendMoneyInfo(WorldSession* session) const
return;
int32 amount = _GetMemberRemainingMoney(member);
- WorldPacket data(MSG_GUILD_BANK_MONEY_WITHDRAWN, 4);
- data << int32(amount);
+ WorldPacket data(SMSG_GUILD_BANK_MONEY_WITHDRAWN, 8);
+ data << int64(amount);
session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_MONEY_WITHDRAWN [%s] Money: %u", session->GetPlayerInfo().c_str(), amount);
}
void Guild::SendLoginInfo(WorldSession* session)
{
+ Player* player = session->GetPlayer();
+ Member* member = GetMember(player->GetGUID());
+ if (!member)
+ return;
+
+ /*
+ Login sequence:
+ SMSG_GUILD_EVENT - GE_MOTD
+ SMSG_GUILD_RANK
+ SMSG_GUILD_EVENT - GE_SIGNED_ON
+ -- learn perks
+ SMSG_GUILD_REPUTATION_WEEKLY_CAP
+ SMSG_GUILD_ACHIEVEMENT_DATA
+ SMSG_GUILD_MEMBER_DAILY_RESET // bank withdrawal reset
+ */
+
WorldPacket data(SMSG_GUILD_EVENT, 1 + 1 + m_motd.size() + 1);
data << uint8(GE_MOTD);
data << uint8(1);
@@ -1922,18 +2301,34 @@ void Guild::SendLoginInfo(WorldSession* session)
TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [%s] MOTD", session->GetPlayerInfo().c_str());
- SendBankTabsInfo(session);
+ SendGuildRankInfo(session);
+ _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str());
- Player* player = session->GetPlayer();
+ // Send to self separately, player is not in world yet and is not found by _BroadcastEvent
+ data.Initialize(SMSG_GUILD_EVENT, 1 + 1 + player->GetName().size() + 8);
+ data << uint8(GE_SIGNED_ON);
+ data << uint8(1);
+ data << player->GetName();
+ data << uint64(player->GetGUID());
+ session->SendPacket(&data);
- HandleRoster(session);
- _BroadcastEvent(GE_SIGNED_ON, player->GetGUID(), player->GetName().c_str());
+ data.Initialize(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
+ session->SendPacket(&data);
- if (Member* member = GetMember(player->GetGUID()))
- {
- member->SetStats(player);
- member->AddFlag(GUILDMEMBER_STATUS_ONLINE);
- }
+ if (!sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
+ return;
+
+ for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
+ if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
+ if (entry->Level <= GetLevel())
+ player->learnSpell(entry->SpellId, true);
+
+ SendGuildReputationWeeklyCap(session, member->GetWeekReputation());
+
+ m_achievementMgr.SendAllAchievementData(player);
+
+ member->SetStats(player);
+ member->AddFlag(GUILDMEMBER_STATUS_ONLINE);
}
// Loading methods
@@ -1947,8 +2342,11 @@ bool Guild::LoadFromDB(Field* fields)
m_motd = fields[9].GetString();
m_createdDate = time_t(fields[10].GetUInt32());
m_bankMoney = fields[11].GetUInt64();
+ _level = fields[12].GetUInt32();
+ _experience = fields[13].GetUInt64();
+ _todayExperience = fields[14].GetUInt64();
- uint8 purchasedTabs = uint8(fields[12].GetUInt64());
+ uint8 purchasedTabs = uint8(fields[15].GetUInt64());
if (purchasedTabs > GUILD_BANK_MAX_TABS)
purchasedTabs = GUILD_BANK_MAX_TABS;
@@ -2048,6 +2446,21 @@ bool Guild::LoadBankEventLogFromDB(Field* fields)
return true;
}
+void Guild::LoadGuildNewsLogFromDB(Field* fields)
+{
+ if (!m_newsLog->CanInsert())
+ return;
+
+ m_newsLog->LoadEvent(new NewsLogEntry(
+ m_id, // guild id
+ fields[1].GetUInt32(), // guid
+ fields[6].GetUInt32(), // timestamp //64 bits?
+ GuildNews(fields[2].GetUInt8()), // type
+ fields[3].GetUInt32(), // player guid
+ fields[4].GetUInt32(), // Flags
+ fields[5].GetUInt32())); // value
+}
+
void Guild::LoadBankTabFromDB(Field* fields)
{
uint8 tabId = fields[1].GetUInt8();
@@ -2076,7 +2489,7 @@ bool Guild::Validate()
// GUILD RANKS represent a sequence starting from 0 = GUILD_MASTER (ALL PRIVILEGES) to max 9 (lowest privileges).
// The lower rank id is considered higher rank - so promotion does rank-- and demotion does rank++
// Between ranks in sequence cannot be gaps - so 0, 1, 2, 4 is impossible
- // Min ranks count is 5 and max is 10.
+ // Min ranks count is 2 and max is 10.
bool broken_ranks = false;
uint8 ranks = _GetRanksSize();
if (ranks < GUILD_RANKS_MIN_COUNT || ranks > GUILD_RANKS_MAX_COUNT)
@@ -2156,6 +2569,21 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin
}
}
+void Guild::BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string const& msg, std::string const& prefix) const
+{
+ 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);
+ 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()->GetGUIDLow()) &&
+ player->GetSession()->IsAddonRegistered(prefix))
+ player->GetSession()->SendPacket(&data);
+ }
+}
+
void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const
{
for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
@@ -2235,7 +2663,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)
player->SetInGuild(m_id);
player->SetGuildIdInvited(0);
player->SetRank(rankId);
- member->SetStats(player);
+ player->SetGuildLevel(GetLevel());
SendLoginInfo(player->GetSession());
name = player->GetName();
}
@@ -2256,10 +2684,12 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)
fields[1].GetUInt8(),
fields[2].GetUInt8(),
fields[3].GetUInt16(),
- fields[4].GetUInt32());
+ fields[4].GetUInt32(),
+ 0);
ok = member->CheckStats();
}
+
if (!ok)
{
delete member;
@@ -2274,6 +2704,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)
_UpdateAccountsNumber();
_LogEvent(GUILD_EVENT_LOG_JOIN_GUILD, lowguid);
_BroadcastEvent(GE_JOINED, guid, name.c_str());
+ sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(lowguid);
// Call scripts if member was succesfully added (and stored to database)
sScriptMgr->OnGuildAddMember(this, player, rankId);
@@ -2333,6 +2764,12 @@ void Guild::DeleteMember(uint64 guid, bool isDisbanding, bool isKicked, bool can
{
player->SetInGuild(0);
player->SetRank(0);
+ player->SetGuildLevel(0);
+
+ for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
+ if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
+ if (entry->Level <= GetLevel())
+ player->removeSpell(entry->SpellId, false, false);
}
_DeleteMemberFromDB(lowguid);
@@ -2351,6 +2788,12 @@ bool Guild::ChangeMemberRank(uint64 guid, uint8 newRank)
return false;
}
+bool Guild::IsMember(uint64 guid) const
+{
+ Members::const_iterator itr = m_members.find(GUID_LOPART(guid));
+ return itr != m_members.end();
+}
+
// Bank (items move)
void Guild::SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount)
{
@@ -2393,6 +2836,7 @@ void Guild::SetBankTabText(uint8 tabId, std::string const& text)
void Guild::_CreateLogHolders()
{
m_eventLog = new LogHolder(sWorld->getIntConfig(CONFIG_GUILD_EVENT_LOG_COUNT));
+ m_newsLog = new LogHolder(sWorld->getIntConfig(CONFIG_GUILD_NEWS_LOG_COUNT));
for (uint8 tabId = 0; tabId <= GUILD_BANK_MAX_TABS; ++tabId)
m_bankEventLog[tabId] = new LogHolder(sWorld->getIntConfig(CONFIG_GUILD_BANK_EVENT_LOG_COUNT));
}
@@ -2783,20 +3227,6 @@ bool Guild::_DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError
return true;
}
-void Guild::_SendBankContent(WorldSession* session, uint8 tabId) const
-{
- uint64 guid = session->GetPlayer()->GetGUID();
- if (!_MemberHasTabRights(guid, tabId, GUILD_BANK_RIGHT_VIEW_TAB))
- return;
-
- _SendBankList(session, tabId, true);
-}
-
-void Guild::_SendBankMoneyUpdate(WorldSession* session) const
-{
- _SendBankList(session);
-}
-
void Guild::_SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const
{
ASSERT(pSrc->IsBank() || pDest->IsBank());
@@ -2831,7 +3261,68 @@ void Guild::_SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) cons
void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const
{
- _SendBankList(NULL, tabId, false, &slots);
+ if (BankTab const* tab = GetBankTab(tabId))
+ {
+ ByteBuffer tabData;
+ WorldPacket data(SMSG_GUILD_BANK_LIST, 1200);
+ data.WriteBit(0);
+ data.WriteBits(slots.size(), 20); // Item count
+ data.WriteBits(0, 22); // Tab count
+
+ for (SlotIds::const_iterator itr = slots.begin(); itr != slots.end(); ++itr)
+ {
+ data.WriteBit(0);
+
+ Item const* tabItem = tab->GetItem(*itr);
+ uint32 enchantCount = 0;
+ if (tabItem)
+ {
+ for (uint32 enchSlot = 0; enchSlot < MAX_ENCHANTMENT_SLOT; ++enchSlot)
+ {
+ if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(enchSlot)))
+ {
+ tabData << uint32(enchantId);
+ tabData << uint32(enchSlot);
+ ++enchantCount;
+ }
+ }
+ }
+
+ data.WriteBits(enchantCount, 23); // enchantment count
+
+ tabData << uint32(0);
+ tabData << uint32(0);
+ tabData << uint32(0);
+ tabData << uint32(tabItem ? tabItem->GetCount() : 0); // ITEM_FIELD_STACK_COUNT
+ tabData << uint32(*itr);
+ tabData << uint32(0);
+ tabData << uint32(tabItem ? tabItem->GetEntry() : 0);
+ tabData << uint32(tabItem ? tabItem->GetItemRandomPropertyId() : 0);
+ tabData << uint32(tabItem ? abs(tabItem->GetSpellCharges()) : 0); // Spell charges
+ tabData << uint32(tabItem ? tabItem->GetItemSuffixFactor() : 0); // SuffixFactor
+ }
+
+ data.FlushBits();
+
+ data << uint64(m_bankMoney);
+ if (!tabData.empty())
+ data.append(tabData);
+
+ data << uint32(tabId);
+
+ size_t rempos = data.wpos();
+ data << uint32(0); // Item withdraw amount, will be filled later
+
+ for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
+ if (_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
+ if (Player* player = itr->second->FindPlayer())
+ {
+ data.put<uint32>(rempos, uint32(_GetMemberRemainingSlots(itr->second, tabId)));
+ player->GetSession()->SendPacket(&data);
+ }
+
+ TC_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
+ }
}
void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1, const char* param2, const char* param3) const
@@ -2858,69 +3349,293 @@ void Guild::_BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* par
TC_LOG_DEBUG("guild", "SMSG_GUILD_EVENT [Broadcast] Event: %s (%u)", _GetGuildEventString(guildEvent).c_str(), guildEvent);
}
-void Guild::_SendBankList(WorldSession* session /* = NULL*/, uint8 tabId /*= 0*/, bool sendAllSlots /*= false*/, SlotIds *slots /*= NULL*/) const
+void Guild::SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const
{
+ Member const* member = GetMember(session->GetPlayer()->GetGUID());
+ if (!member) // Shouldn't happen, just in case
+ return;
+
+ ByteBuffer tabData;
WorldPacket data(SMSG_GUILD_BANK_LIST, 500);
- data << uint64(m_bankMoney);
- data << uint8(tabId);
- size_t rempos = data.wpos();
- data << uint32(0);
- data << uint8(sendAllSlots);
+ data.WriteBit(0);
+ uint32 itemCount = 0;
+ if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
+ if (BankTab const* tab = GetBankTab(tabId))
+ for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
+ if (tab->GetItem(slotId))
+ ++itemCount;
+
+ data.WriteBits(itemCount, 20);
+ data.WriteBits(withTabInfo ? _GetPurchasedTabsSize() : 0, 22);
+ if (withContent && _MemberHasTabRights(session->GetPlayer()->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
+ {
+ if (BankTab const* tab = GetBankTab(tabId))
+ {
+ for (uint8 slotId = 0; slotId < GUILD_BANK_MAX_SLOTS; ++slotId)
+ {
+ if (Item* tabItem = tab->GetItem(slotId))
+ {
+ data.WriteBit(0);
+
+ uint32 enchants = 0;
+ for (uint32 ench = 0; ench < MAX_ENCHANTMENT_SLOT; ++ench)
+ {
+ if (uint32 enchantId = tabItem->GetEnchantmentId(EnchantmentSlot(ench)))
+ {
+ tabData << uint32(enchantId);
+ tabData << uint32(ench);
+ ++enchants;
+ }
+ }
+
+ data.WriteBits(enchants, 23);
+
+ tabData << uint32(0);
+ tabData << uint32(0);
+ tabData << uint32(0);
+ tabData << uint32(tabItem->GetCount()); // ITEM_FIELD_STACK_COUNT
+ tabData << uint32(slotId);
+ tabData << uint32(0);
+ tabData << uint32(tabItem->GetEntry());
+ tabData << uint32(tabItem->GetItemRandomPropertyId());
+ tabData << uint32(abs(tabItem->GetSpellCharges())); // Spell charges
+ tabData << uint32(tabItem->GetItemSuffixFactor()); // SuffixFactor
+ }
+ }
+ }
+ }
- if (sendAllSlots && !tabId)
+ if (withTabInfo)
{
- data << uint8(_GetPurchasedTabsSize()); // Number of tabs
for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
- m_bankTabs[i]->WriteInfoPacket(data);
+ {
+ data.WriteBits(m_bankTabs[i]->GetIcon().length(), 9);
+ data.WriteBits(m_bankTabs[i]->GetName().length(), 7);
+ }
}
- BankTab const* tab = GetBankTab(tabId);
- if (!tab)
- data << uint8(0);
- else if (sendAllSlots)
- tab->WritePacket(data);
- else if (slots && !slots->empty())
+ data.FlushBits();
+
+ if (withTabInfo)
{
- data << uint8(slots->size());
- for (SlotIds::const_iterator itr = slots->begin(); itr != slots->end(); ++itr)
- tab->WriteSlotPacket(data, *itr, false);
+ for (uint8 i = 0; i < _GetPurchasedTabsSize(); ++i)
+ {
+ data.WriteString(m_bankTabs[i]->GetIcon());
+ data << uint32(i);
+ data.WriteString(m_bankTabs[i]->GetName());
+ }
}
- else
- data << uint8(0);
- if (session)
+ data << uint64(m_bankMoney);
+ if (!tabData.empty())
+ data.append(tabData);
+
+ data << uint32(tabId);
+ data << uint32(_GetMemberRemainingSlots(member, tabId));
+
+ session->SendPacket(&data);
+
+ TC_LOG_DEBUG("guild", "WORLD: Sent (SMSG_GUILD_BANK_LIST)");
+}
+
+void Guild::SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank)
+{
+ ObjectGuid tarGuid = targetGuid;
+ ObjectGuid setGuid = setterGuid;
+
+ Member* member = GetMember(targetGuid);
+ ASSERT(member);
+
+ WorldPacket data(SMSG_GUILD_RANKS_UPDATE, 100);
+ data.WriteBit(setGuid[7]);
+ data.WriteBit(setGuid[2]);
+ data.WriteBit(tarGuid[2]);
+ data.WriteBit(setGuid[1]);
+ data.WriteBit(tarGuid[1]);
+ data.WriteBit(tarGuid[7]);
+ data.WriteBit(tarGuid[0]);
+ data.WriteBit(tarGuid[5]);
+ data.WriteBit(tarGuid[4]);
+ data.WriteBit(rank < member->GetRankId()); // 1 == higher, 0 = lower?
+ data.WriteBit(setGuid[5]);
+ data.WriteBit(setGuid[0]);
+ data.WriteBit(tarGuid[6]);
+ data.WriteBit(setGuid[3]);
+ data.WriteBit(setGuid[6]);
+ data.WriteBit(tarGuid[3]);
+ data.WriteBit(setGuid[4]);
+
+ data.FlushBits();
+
+ data << uint32(rank);
+ data.WriteByteSeq(setGuid[3]);
+ data.WriteByteSeq(tarGuid[7]);
+ data.WriteByteSeq(setGuid[6]);
+ data.WriteByteSeq(setGuid[2]);
+ data.WriteByteSeq(tarGuid[5]);
+ data.WriteByteSeq(tarGuid[0]);
+ data.WriteByteSeq(setGuid[7]);
+ data.WriteByteSeq(setGuid[5]);
+ data.WriteByteSeq(tarGuid[2]);
+ data.WriteByteSeq(tarGuid[1]);
+ data.WriteByteSeq(setGuid[0]);
+ data.WriteByteSeq(setGuid[4]);
+ data.WriteByteSeq(setGuid[1]);
+ data.WriteByteSeq(tarGuid[3]);
+ data.WriteByteSeq(tarGuid[6]);
+ data.WriteByteSeq(tarGuid[4]);
+ BroadcastPacket(&data);
+
+ member->ChangeRank(rank);
+
+ TC_LOG_DEBUG("network", "SMSG_GUILD_RANKS_UPDATE [Broadcast] Target: %u, Issuer: %u, RankId: %u",
+ GUID_LOPART(targetGuid), GUID_LOPART(setterGuid), rank);
+}
+
+void Guild::GiveXP(uint32 xp, Player* source)
+{
+ if (!sWorld->getBoolConfig(CONFIG_GUILD_LEVELING_ENABLED))
+ return;
+
+ /// @todo: Award reputation and count activity for player
+
+ if (GetLevel() >= sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
+ xp = 0; // SMSG_GUILD_XP_GAIN is always sent, even for no gains
+
+ if (GetLevel() < GUILD_EXPERIENCE_UNCAPPED_LEVEL)
+ xp = std::min(xp, sWorld->getIntConfig(CONFIG_GUILD_DAILY_XP_CAP) - uint32(_todayExperience));
+
+ WorldPacket data(SMSG_GUILD_XP_GAIN, 8);
+ data << uint64(xp);
+ source->GetSession()->SendPacket(&data);
+
+ _experience += xp;
+ _todayExperience += xp;
+
+ if (!xp)
+ return;
+
+ uint32 oldLevel = GetLevel();
+
+ // Ding, mon!
+ while (GetExperience() >= sGuildMgr->GetXPForGuildLevel(GetLevel()) && GetLevel() < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
{
- int32 numSlots = 0;
- if (Member const* member = GetMember(session->GetPlayer()->GetGUID()))
- numSlots = _GetMemberRemainingSlots(member, tabId);
- data.put<uint32>(rempos, numSlots);
- session->SendPacket(&data);
- TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [%s]: TabId: %u, FullSlots: %u, slots: %d",
- session->GetPlayerInfo().c_str(), tabId, sendAllSlots, numSlots);
+ _experience -= sGuildMgr->GetXPForGuildLevel(GetLevel());
+ ++_level;
+
+ // Find all guild perks to learn
+ std::vector<uint32> perksToLearn;
+ for (uint32 i = 0; i < sGuildPerkSpellsStore.GetNumRows(); ++i)
+ if (GuildPerkSpellsEntry const* entry = sGuildPerkSpellsStore.LookupEntry(i))
+ if (entry->Level > oldLevel && entry->Level <= GetLevel())
+ perksToLearn.push_back(entry->SpellId);
+
+ // Notify all online players that guild level changed and learn perks
+ for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
+ {
+ if (Player* player = itr->second->FindPlayer())
+ {
+ player->SetGuildLevel(GetLevel());
+ for (size_t i = 0; i < perksToLearn.size(); ++i)
+ player->learnSpell(perksToLearn[i], true);
+ }
+ }
+
+ AddGuildNews(GUILD_NEWS_LEVEL_UP, 0, 0, _level);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_GUILD_LEVEL, GetLevel(), 0, 0, NULL, source);
+
+ ++oldLevel;
}
- else /// @todo - Probably this is just sent to session + those that have sent CMSG_GUILD_BANKER_ACTIVATE
+}
+
+void Guild::SendGuildXP(WorldSession* session /* = NULL */) const
+{
+ //Member const* member = GetMember(session->GetGuidLow());
+
+ WorldPacket data(SMSG_GUILD_XP, 40);
+ data << uint64(/*member ? member->GetTotalActivity() :*/ 0);
+ data << uint64(sGuildMgr->GetXPForGuildLevel(GetLevel()) - GetExperience()); // XP missing for next level
+ data << uint64(GetTodayExperience());
+ data << uint64(/*member ? member->GetWeeklyActivity() :*/ 0);
+ data << uint64(GetExperience());
+ session->SendPacket(&data);
+}
+
+void Guild::SendGuildReputationWeeklyCap(WorldSession* session, uint32 reputation) const
+{
+ uint32 cap = sWorld->getIntConfig(CONFIG_GUILD_WEEKLY_REP_CAP) - reputation;
+ WorldPacket data(SMSG_GUILD_REPUTATION_WEEKLY_CAP, 4);
+ data << uint32(cap);
+ session->SendPacket(&data);
+ TC_LOG_DEBUG("guild", "SMSG_GUILD_REPUTATION_WEEKLY_CAP [%s]: Left: %u",
+ session->GetPlayerInfo().c_str(), cap);
+}
+
+void Guild::ResetTimes(bool weekly)
+{
+ _todayExperience = 0;
+ for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
- for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
+ itr->second->ResetValues(weekly);
+ if (Player* player = itr->second->FindPlayer())
{
- if (!_MemberHasTabRights(itr->second->GetGUID(), tabId, GUILD_BANK_RIGHT_VIEW_TAB))
- continue;
- Player* player = itr->second->FindPlayer();
- if (!player)
- continue;
-
- uint32 numSlots = _GetMemberRemainingSlots(itr->second, tabId);
- data.put<uint32>(rempos, numSlots);
+ //SendGuildXP(player->GetSession());
+ WorldPacket data(SMSG_GUILD_MEMBER_DAILY_RESET, 0); // tells the client to request bank withdrawal limit
player->GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [%s]: TabId: %u, FullSlots: %u, slots: %u"
- , player->GetName().c_str(), tabId, sendAllSlots, numSlots);
}
}
}
-void Guild::ResetTimes()
+void Guild::AddGuildNews(uint8 type, uint64 guid, uint32 flags, uint32 value)
{
- for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
- itr->second->ResetValues();
+ uint32 lowGuid = GUID_LOPART(guid);
+ NewsLogEntry* news = new NewsLogEntry(m_id, m_newsLog->GetNextGUID(), GuildNews(type), lowGuid, flags, value);
- _BroadcastEvent(GE_BANK_TAB_AND_MONEY_UPDATED, 0);
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ m_newsLog->AddEvent(trans, news);
+ CharacterDatabase.CommitTransaction(trans);
+
+ WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
+ data.WriteBits(1, 21); // size, we are only sending 1 news here
+ ByteBuffer buffer;
+ news->WritePacket(data, buffer);
+
+ BroadcastPacket(&data);
+}
+
+bool Guild::HasAchieved(uint32 achievementId) const
+{
+ return m_achievementMgr.HasAchieved(achievementId);
+}
+
+void Guild::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player)
+{
+ m_achievementMgr.UpdateAchievementCriteria(type, miscValue1, miscValue2, miscValue3, unit, player);
+}
+
+void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky)
+{
+ GuildLog* logs = m_newsLog->GetGuildLog();
+ GuildLog::iterator itr = logs->begin();
+ while (itr != logs->end() && (*itr)->GetGUID() != newsId)
+ ++itr;
+
+ if (itr == logs->end())
+ {
+ TC_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] requested unknown newsId %u - Sticky: %u",
+ session->GetPlayerInfo().c_str(), newsId, sticky);
+ return;
+ }
+
+ NewsLogEntry* news = (NewsLogEntry*)(*itr);
+ news->SetSticky(sticky);
+
+ TC_LOG_DEBUG("guild", "HandleNewsSetSticky: [%s] chenged newsId %u sticky to %u",
+ session->GetPlayerInfo().c_str(), newsId, sticky);
+
+ WorldPacket data(SMSG_GUILD_NEWS_UPDATE, 7 + 32);
+ data.WriteBits(1, 21);
+ ByteBuffer buffer;
+ news->WritePacket(data, buffer);
+ session->SendPacket(&data);
}
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index fca483e92c3..2d9d9085917 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -19,31 +19,35 @@
#ifndef TRINITYCORE_GUILD_H
#define TRINITYCORE_GUILD_H
+#include "AchievementMgr.h"
#include "World.h"
#include "Item.h"
#include "WorldPacket.h"
#include "ObjectMgr.h"
#include "Player.h"
+#include "DBCStore.h"
class Item;
enum GuildMisc
{
- GUILD_BANK_MAX_TABS = 6, // send by client for money log also
+ GUILD_BANK_MAX_TABS = 8, // send by client for money log also
GUILD_BANK_MAX_SLOTS = 98,
GUILD_BANK_MONEY_LOGS_TAB = 100, // used for money log in DB
- GUILD_RANKS_MIN_COUNT = 5,
+ GUILD_RANKS_MIN_COUNT = 2,
GUILD_RANKS_MAX_COUNT = 10,
GUILD_RANK_NONE = 0xFF,
GUILD_WITHDRAW_MONEY_UNLIMITED = 0xFFFFFFFF,
GUILD_WITHDRAW_SLOT_UNLIMITED = 0xFFFFFFFF,
GUILD_EVENT_LOG_GUID_UNDEFINED = 0xFFFFFFFF,
+ GUILD_EXPERIENCE_UNCAPPED_LEVEL = 20, ///> Hardcoded in client, starting from this level, guild daily experience gain is unlimited.
TAB_UNDEFINED = 0xFF,
};
enum GuildMemberData
{
GUILD_MEMBER_DATA_ZONEID,
+ GUILD_MEMBER_DATA_ACHIEVEMENT_POINTS,
GUILD_MEMBER_DATA_LEVEL,
};
@@ -79,7 +83,7 @@ enum GuildRankRights
GR_RIGHT_WITHDRAW_REPAIR = 0x00040000, // withdraw for repair
GR_RIGHT_WITHDRAW_GOLD = 0x00080000, // withdraw gold
GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000, // wotlk
- GR_RIGHT_ALL = 0x001DF1FF
+ GR_RIGHT_ALL = 0x00DDFFBF
};
enum GuildCommandType
@@ -128,37 +132,53 @@ enum GuildCommandError
ERR_GUILD_NOT_ENOUGH_MONEY = 26,
ERR_GUILD_BANK_FULL = 28,
ERR_GUILD_ITEM_NOT_FOUND = 29,
+ ERR_GUILD_TOO_MUCH_MONEY = 31,
+ ERR_GUILD_BANK_WRONG_TAB = 32,
+ ERR_RANK_REQUIRES_AUTHENTICATOR = 34,
+ ERR_GUILD_BANK_VOUCHER_FAILED = 35,
+ ERR_GUILD_TRIAL_ACCOUNT = 36,
+ ERR_GUILD_UNDELETABLE_DUE_TO_LEVEL = 37,
+ ERR_GUILD_MOVE_STARTING = 38,
+ ERR_GUILD_REP_TOO_LOW = 39
};
enum GuildEvents
{
- GE_PROMOTION = 0,
- GE_DEMOTION = 1,
- GE_MOTD = 2,
- GE_JOINED = 3,
- GE_LEFT = 4,
- GE_REMOVED = 5,
- GE_LEADER_IS = 6,
- GE_LEADER_CHANGED = 7,
- GE_DISBANDED = 8,
- GE_TABARDCHANGE = 9,
- GE_RANK_UPDATED = 10,
- GE_RANK_DELETED = 11,
- GE_SIGNED_ON = 12,
- GE_SIGNED_OFF = 13,
- GE_GUILDBANKBAGSLOTS_CHANGED = 14, /// TODO: Sent when items are moved in gbank - all players with bank open will send tab query
- GE_BANK_TAB_PURCHASED = 15,
- GE_BANK_TAB_UPDATED = 16,
- GE_BANK_MONEY_SET = 17,
- GE_BANK_TAB_AND_MONEY_UPDATED = 18,
- GE_BANK_TEXT_CHANGED = 19,
+ GE_PROMOTION = 1,
+ GE_DEMOTION = 2,
+ GE_MOTD = 3,
+ GE_JOINED = 4,
+ GE_LEFT = 5,
+ GE_REMOVED = 6,
+ GE_LEADER_IS = 7,
+ GE_LEADER_CHANGED = 8,
+ GE_DISBANDED = 9,
+ GE_TABARDCHANGE = 10,
+ GE_RANK_UPDATED = 11,
+ GE_RANK_CREATED = 12,
+ GE_RANK_DELETED = 13,
+ GE_RANK_ORDER_CHANGED = 14,
+ GE_FOUNDER = 15,
+ GE_SIGNED_ON = 16,
+ GE_SIGNED_OFF = 17,
+ GE_GUILDBANKBAGSLOTS_CHANGED = 18,
+ GE_BANK_TAB_PURCHASED = 19,
+ GE_BANK_TAB_UPDATED = 20,
+ GE_BANK_MONEY_SET = 21,
+ GE_BANK_TAB_AND_MONEY_UPDATED = 22,
+ GE_BANK_TEXT_CHANGED = 23,
+ // 24 - error 795
+ GE_SIGNED_ON_MOBILE = 25,
+ GE_SIGNED_Off_MOBILE = 26,
};
enum PetitionTurns
{
PETITION_TURN_OK = 0,
PETITION_TURN_ALREADY_IN_GUILD = 2,
- PETITION_TURN_NEED_MORE_SIGNATURES = 4
+ PETITION_TURN_NEED_MORE_SIGNATURES = 4,
+ PETITION_TURN_GUILD_PERMISSIONS = 11,
+ PETITION_TURN_GUILD_NAME_INVALID = 12
};
enum PetitionSigns
@@ -167,7 +187,10 @@ enum PetitionSigns
PETITION_SIGN_ALREADY_SIGNED = 1,
PETITION_SIGN_ALREADY_IN_GUILD = 2,
PETITION_SIGN_CANT_SIGN_OWN = 3,
- PETITION_SIGN_NOT_SERVER = 4
+ PETITION_SIGN_NOT_SERVER = 4,
+ PETITION_SIGN_FULL = 5,
+ PETITION_SIGN_ALREADY_SIGNED_OTHER = 6,
+ PETITION_SIGN_RESTRICTED_ACCOUNT = 7
};
enum GuildBankRights
@@ -190,7 +213,8 @@ enum GuildBankEventLogTypes
GUILD_BANK_LOG_REPAIR_MONEY = 6,
GUILD_BANK_LOG_MOVE_ITEM2 = 7,
GUILD_BANK_LOG_UNK1 = 8,
- GUILD_BANK_LOG_BUY_SLOT = 9
+ GUILD_BANK_LOG_BUY_SLOT = 9,
+ GUILD_BANK_LOG_CASH_FLOW_DEPOSIT = 10
};
enum GuildEventLogTypes
@@ -222,6 +246,28 @@ enum GuildMemberFlags
GUILDMEMBER_STATUS_MOBILE = 0x0008, // remote chat from mobile app
};
+enum GuildNews
+{
+ GUILD_NEWS_GUILD_ACHIEVEMENT = 0,
+ GUILD_NEWS_PLAYER_ACHIEVEMENT = 1,
+ GUILD_NEWS_DUNGEON_ENCOUNTER = 2, // @todo Implement
+ GUILD_NEWS_ITEM_LOOTED = 3,
+ GUILD_NEWS_ITEM_CRAFTED = 4,
+ GUILD_NEWS_ITEM_PURCHASED = 5,
+ GUILD_NEWS_LEVEL_UP = 6,
+};
+
+struct GuildReward
+{
+ uint32 Entry;
+ int32 Racemask;
+ uint64 Price;
+ uint32 AchievementId;
+ uint8 Standing;
+};
+
+uint32 const MinNewsItemLevel[MAX_CONTENT] = { 61, 90, 200, 353 };
+
// Emblem info
class EmblemInfo
{
@@ -295,19 +341,27 @@ private:
m_flags(GUILDMEMBER_STATUS_NONE),
m_logoutTime(::time(NULL)),
m_accountId(0),
- m_rankId(rankId)
+ m_rankId(rankId),
+ m_achievementPoints(0),
+ m_totalActivity(0),
+ m_weekActivity(0),
+ m_totalReputation(0),
+ m_weekReputation(0)
{
memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32));
}
void SetStats(Player* player);
- void SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId);
+ void SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId, uint32 reputation);
bool CheckStats() const;
void SetPublicNote(std::string const& publicNote);
void SetOfficerNote(std::string const& officerNote);
- void SetZoneID(uint32 id) { m_zoneId = id; }
+ void SetZoneId(uint32 id) { m_zoneId = id; }
+ void SetAchievementPoints(uint32 val) { m_achievementPoints = val; }
void SetLevel(uint8 var) { m_level = var; }
+ void AddReputation(uint32& reputation);
+ void AddActivity(uint64 activity);
void AddFlag(uint8 var) { m_flags |= var; }
void RemFlag(uint8 var) { m_flags &= ~var; }
@@ -315,7 +369,6 @@ private:
bool LoadFromDB(Field* fields);
void SaveToDB(SQLTransaction& trans) const;
- void WritePacket(WorldPacket& data, bool sendOfficerNote) const;
uint64 GetGUID() const { return m_guid; }
std::string const& GetName() const { return m_name; }
@@ -328,6 +381,12 @@ private:
uint8 GetLevel() const { return m_level; }
uint8 GetFlags() const { return m_flags; }
uint32 GetZoneId() const { return m_zoneId; }
+ uint32 GetAchievementPoints() const { return m_achievementPoints; }
+ uint64 GetTotalActivity() const { return m_totalActivity; }
+ uint64 GetWeekActivity() const { return m_weekActivity; }
+ uint32 GetTotalReputation() const { return m_totalReputation; }
+ uint32 GetWeekReputation() const { return m_weekReputation; }
+
bool IsOnline() { return (m_flags & GUILDMEMBER_STATUS_ONLINE); }
void ChangeRank(uint8 newRank);
@@ -339,7 +398,7 @@ private:
void UpdateBankWithdrawValue(SQLTransaction& trans, uint8 tabId, uint32 amount);
int32 GetBankWithdrawValue(uint8 tabId) const;
- void ResetValues();
+ void ResetValues(bool weekly = false);
inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); }
@@ -360,6 +419,11 @@ private:
std::string m_officerNote;
int32 m_bankWithdraw[GUILD_BANK_MAX_TABS + 1];
+ uint32 m_achievementPoints;
+ uint64 m_totalActivity;
+ uint64 m_weekActivity;
+ uint32 m_totalReputation;
+ uint32 m_weekReputation;
};
// Base class for event entries
@@ -374,7 +438,7 @@ private:
uint64 GetTimestamp() const { return m_timestamp; }
virtual void SaveToDB(SQLTransaction& trans) const = 0;
- virtual void WritePacket(WorldPacket& data) const = 0;
+ virtual void WritePacket(WorldPacket& data, ByteBuffer& content) const = 0;
protected:
uint32 m_guildId;
@@ -395,7 +459,7 @@ private:
~EventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const;
- void WritePacket(WorldPacket& data) const;
+ void WritePacket(WorldPacket& data, ByteBuffer& content) const;
private:
GuildEventLogTypes m_eventType;
@@ -413,31 +477,71 @@ private:
return
eventType == GUILD_BANK_LOG_DEPOSIT_MONEY ||
eventType == GUILD_BANK_LOG_WITHDRAW_MONEY ||
- eventType == GUILD_BANK_LOG_REPAIR_MONEY;
+ eventType == GUILD_BANK_LOG_REPAIR_MONEY ||
+ eventType == GUILD_BANK_LOG_CASH_FLOW_DEPOSIT;
}
- BankEventLogEntry(uint32 guildId, uint32 guid, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
+ bool IsMoneyEvent() const
+ {
+ return IsMoneyEvent(m_eventType);
+ }
+
+ BankEventLogEntry(uint32 guildId, uint32 guid, GuildBankEventLogTypes eventType, uint8 tabId, uint32 playerGuid, uint64 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
LogEntry(guildId, guid), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
- BankEventLogEntry(uint32 guildId, uint32 guid, time_t timestamp, uint8 tabId, GuildBankEventLogTypes eventType, uint32 playerGuid, uint32 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
+ BankEventLogEntry(uint32 guildId, uint32 guid, time_t timestamp, uint8 tabId, GuildBankEventLogTypes eventType, uint32 playerGuid, uint64 itemOrMoney, uint16 itemStackCount, uint8 destTabId) :
LogEntry(guildId, guid, timestamp), m_eventType(eventType), m_bankTabId(tabId), m_playerGuid(playerGuid),
m_itemOrMoney(itemOrMoney), m_itemStackCount(itemStackCount), m_destTabId(destTabId) { }
~BankEventLogEntry() { }
void SaveToDB(SQLTransaction& trans) const;
- void WritePacket(WorldPacket& data) const;
+ void WritePacket(WorldPacket& data, ByteBuffer& content) const;
private:
GuildBankEventLogTypes m_eventType;
uint8 m_bankTabId;
uint32 m_playerGuid;
- uint32 m_itemOrMoney;
+ uint64 m_itemOrMoney;
uint16 m_itemStackCount;
uint8 m_destTabId;
};
+ // News log entry
+ class NewsLogEntry : public LogEntry
+ {
+ public:
+ NewsLogEntry(uint32 guildId, uint32 guid, GuildNews type, uint32 playerGuid, uint32 flags, uint32 value) :
+ LogEntry(guildId, guid), m_type(type), m_playerGuid(playerGuid), m_flags(flags), m_value(value) { }
+
+ NewsLogEntry(uint32 guildId, uint32 guid, time_t timestamp, GuildNews type, uint32 playerGuid, uint32 flags, uint32 value) :
+ LogEntry(guildId, guid, timestamp), m_type(type), m_playerGuid(playerGuid), m_flags(flags), m_value(value) { }
+
+ ~NewsLogEntry() { }
+
+ GuildNews GetType() const { return m_type; }
+ uint64 GetPlayerGuid() const { return m_playerGuid ? MAKE_NEW_GUID(m_playerGuid, 0, HIGHGUID_PLAYER) : 0; }
+ uint32 GetValue() const { return m_value; }
+ uint32 GetFlags() const { return m_flags; }
+ void SetSticky(bool sticky)
+ {
+ if (sticky)
+ m_flags |= 1;
+ else
+ m_flags &= ~1;
+ }
+
+ void SaveToDB(SQLTransaction& trans) const;
+ void WritePacket(WorldPacket& data, ByteBuffer& content) const;
+
+ private:
+ GuildNews m_type;
+ uint32 m_playerGuid;
+ uint32 m_flags;
+ uint32 m_value;
+ };
+
// Class encapsulating work with events collection
typedef std::list<LogEntry*> GuildLog;
@@ -457,6 +561,7 @@ private:
// Writes information about all events to packet
void WritePacket(WorldPacket& data) const;
uint32 GetNextGUID();
+ GuildLog* GetGuildLog() { return &m_log; } // Hack needed for news as WritePacket can't be used
private:
GuildLog m_log;
@@ -476,7 +581,6 @@ private:
void LoadFromDB(Field* fields);
void SaveToDB(SQLTransaction& trans) const;
- void WritePacket(WorldPacket& data) const;
uint8 GetId() const { return m_rankId; }
@@ -505,7 +609,6 @@ private:
private:
uint32 m_guildId;
-
uint8 m_rankId;
std::string m_name;
uint32 m_rights;
@@ -535,10 +638,14 @@ private:
void SetInfo(std::string const& name, std::string const& icon);
void SetText(std::string const& text);
- void SendText(const Guild* guild, WorldSession* session) const;
+ void SendText(Guild const* guild, WorldSession* session) const;
+
+ std::string const& GetName() const { return m_name; }
+ std::string const& GetIcon() const { return m_icon; }
+ std::string const& GetText() const { return m_text; }
inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : NULL; }
- bool SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem);
+ bool SetItem(SQLTransaction& trans, uint8 slotId, Item* item);
private:
uint32 m_guildId;
@@ -651,8 +758,11 @@ public:
bool Create(Player* pLeader, std::string const& name);
void Disband();
+ void SaveToDB();
+
// Getters
uint32 GetId() const { return m_id; }
+ uint64 GetGUID() const { return MAKE_NEW_GUID(m_id, 0, HIGHGUID_GUILD); }
uint64 GetLeaderGUID() const { return m_leaderGuid; }
std::string const& GetName() const { return m_name; }
std::string const& GetMOTD() const { return m_motd; }
@@ -666,40 +776,44 @@ public:
void HandleSetMOTD(WorldSession* session, std::string const& motd);
void HandleSetInfo(WorldSession* session, std::string const& info);
void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo);
- void HandleSetLeader(WorldSession* session, std::string const& name);
+ void HandleSetNewGuildMaster(WorldSession* session, std::string const& name);
void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon);
- void HandleSetMemberNote(WorldSession* session, std::string const& name, std::string const& note, bool officer);
- void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, const GuildBankRightsAndSlotsVec& rightsAndSlots);
+ void HandleSetMemberNote(WorldSession* session, std::string const& note, uint64 guid, bool isPublic);
+ void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots);
void HandleBuyBankTab(WorldSession* session, uint8 tabId);
void HandleInviteMember(WorldSession* session, std::string const& name);
void HandleAcceptMember(WorldSession* session);
void HandleLeaveMember(WorldSession* session);
- void HandleRemoveMember(WorldSession* session, std::string const& name);
- void HandleUpdateMemberRank(WorldSession* session, std::string const& name, bool demote);
+ void HandleRemoveMember(WorldSession* session, uint64 guid);
+ void HandleUpdateMemberRank(WorldSession* session, uint64 guid, bool demote);
+ void HandleSetMemberRank(WorldSession* session, uint64 guid, uint64 setterGuid, uint32 rank);
void HandleAddNewRank(WorldSession* session, std::string const& name);
void HandleRemoveRank(WorldSession* session, uint8 rankId);
- void HandleRemoveLowestRank(WorldSession* session);
- void HandleMemberDepositMoney(WorldSession* session, uint32 amount);
- bool HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool repair = false);
+ void HandleMemberDepositMoney(WorldSession* session, uint64 amount, bool cashFlow = false);
+ bool HandleMemberWithdrawMoney(WorldSession* session, uint64 amount, bool repair = false);
void HandleMemberLogout(WorldSession* session);
void HandleDisband(WorldSession* session);
+ void HandleGuildPartyRequest(WorldSession* session);
+ void HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky);
void UpdateMemberData(Player* player, uint8 dataid, uint32 value);
void OnPlayerStatusChange(Player* player, uint32 flag, bool state);
// Send info to client
- void SendInfo(WorldSession* session) const;
+ void SendGuildRankInfo(WorldSession* session) const;
void SendEventLog(WorldSession* session) const;
void SendBankLog(WorldSession* session, uint8 tabId) const;
- void SendBankTabsInfo(WorldSession* session, bool showTabs = false) const;
- void SendBankTabData(WorldSession* session, uint8 tabId) const;
+ void SendBankList(WorldSession* session, uint8 tabId, bool withContent, bool withTabInfo) const;
+ void SendGuildXP(WorldSession* session = NULL) const;
void SendBankTabText(WorldSession* session, uint8 tabId) const;
void SendPermissions(WorldSession* session) const;
void SendMoneyInfo(WorldSession* session) const;
void SendLoginInfo(WorldSession* session);
+ void SendNewsUpdate(WorldSession* session);
// Load from DB
bool LoadFromDB(Field* fields);
+ void LoadGuildNewsLogFromDB(Field* fields);
void LoadRankFromDB(Field* fields);
bool LoadMemberFromDB(Field* fields);
bool LoadEventLogFromDB(Field* fields);
@@ -711,6 +825,7 @@ public:
// Broadcasts
void BroadcastToGuild(WorldSession* session, bool officerOnly, std::string const& msg, uint32 language = LANG_UNIVERSAL) const;
+ void BroadcastAddonToGuild(WorldSession* session, bool officerOnly, std::string const& msg, std::string const& prefix) const;
void BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const;
void BroadcastPacket(WorldPacket* packet) const;
@@ -730,6 +845,8 @@ public:
bool AddMember(uint64 guid, uint8 rankId = GUILD_RANK_NONE);
void DeleteMember(uint64 guid, bool isDisbanding = false, bool isKicked = false, bool canDeleteGuild = false);
bool ChangeMemberRank(uint64 guid, uint8 newRank);
+ bool IsMember(uint64 guid) const;
+ uint32 GetMembersCount() { return m_members.size(); }
// Bank
void SwapItems(Player* player, uint8 tabId, uint8 slotId, uint8 destTabId, uint8 destSlotId, uint32 splitedAmount);
@@ -738,7 +855,22 @@ public:
// Bank tabs
void SetBankTabText(uint8 tabId, std::string const& text);
- void ResetTimes();
+ AchievementMgr<Guild>& GetAchievementMgr() { return m_achievementMgr; }
+ AchievementMgr<Guild> const& GetAchievementMgr() const { return m_achievementMgr; }
+
+ // Guild leveling
+ uint8 GetLevel() const { return _level; }
+ void GiveXP(uint32 xp, Player* source);
+ uint64 GetExperience() const { return _experience; }
+ uint64 GetTodayExperience() const { return _todayExperience; }
+
+ void AddGuildNews(uint8 type, uint64 guid, uint32 flags, uint32 value);
+
+ EmblemInfo const& GetEmblemInfo() const { return m_emblemInfo; }
+ void ResetTimes(bool weekly);
+
+ bool HasAchieved(uint32 achievementId) const;
+ void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player);
protected:
uint32 m_id;
@@ -759,12 +891,18 @@ protected:
// These are actually ordered lists. The first element is the oldest entry.
LogHolder* m_eventLog;
LogHolder* m_bankEventLog[GUILD_BANK_MAX_TABS + 1];
+ LogHolder* m_newsLog;
+ AchievementMgr<Guild> m_achievementMgr;
+
+ uint8 _level;
+ uint64 _experience;
+ uint64 _todayExperience;
private:
inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); }
inline const RankInfo* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; }
inline RankInfo* GetRankInfo(uint8 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : NULL; }
- inline bool _HasRankRight(Player* player, uint32 right) const
+ inline bool _HasRankRight(Player const* player, uint32 right) const
{
if (player)
if (Member const* member = GetMember(player->GetGUID()))
@@ -842,11 +980,10 @@ private:
void _MoveItems(MoveItemData* pSrc, MoveItemData* pDest, uint32 splitedAmount);
bool _DoItemsMove(MoveItemData* pSrc, MoveItemData* pDest, bool sendError, uint32 splitedAmount = 0);
- void _SendBankContent(WorldSession* session, uint8 tabId) const;
- void _SendBankMoneyUpdate(WorldSession* session) const;
void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const;
void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const;
- void _SendBankList(WorldSession* session = NULL, uint8 tabId = 0, bool sendFullSlots = false, SlotIds *slots = NULL) const;
+ void SendGuildReputationWeeklyCap(WorldSession* session, uint32 reputation) const;
+ void SendGuildRanksUpdate(uint64 setterGuid, uint64 targetGuid, uint32 rank);
void _BroadcastEvent(GuildEvents guildEvent, uint64 guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const;
};
diff --git a/src/server/game/Guilds/GuildFinderMgr.cpp b/src/server/game/Guilds/GuildFinderMgr.cpp
new file mode 100644
index 00000000000..024f4f4bd38
--- /dev/null
+++ b/src/server/game/Guilds/GuildFinderMgr.cpp
@@ -0,0 +1,333 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "GuildFinderMgr.h"
+#include "GuildMgr.h"
+#include "World.h"
+
+GuildFinderMgr::GuildFinderMgr()
+{
+}
+
+GuildFinderMgr::~GuildFinderMgr()
+{
+}
+
+void GuildFinderMgr::LoadFromDB()
+{
+ LoadGuildSettings();
+ LoadMembershipRequests();
+}
+
+void GuildFinderMgr::LoadGuildSettings()
+{
+ TC_LOG_INFO("server.loading", "Loading guild finder guild-related settings...");
+ // 0 1 2 3 4 5 6 7
+ QueryResult result = CharacterDatabase.Query("SELECT gfgs.guildId, gfgs.availability, gfgs.classRoles, gfgs.interests, gfgs.level, gfgs.listed, gfgs.comment, c.race "
+ "FROM guild_finder_guild_settings gfgs "
+ "LEFT JOIN guild_member gm ON gm.guildid=gfgs.guildId "
+ "LEFT JOIN characters c ON c.guid = gm.guid LIMIT 1");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 guild finder guild-related settings. Table `guild_finder_guild_settings` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ uint32 oldMSTime = getMSTime();
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 guildId = fields[0].GetUInt32();
+ uint8 availability = fields[1].GetUInt8();
+ uint8 classRoles = fields[2].GetUInt8();
+ uint8 interests = fields[3].GetUInt8();
+ uint8 level = fields[4].GetUInt8();
+ bool listed = (fields[5].GetUInt8() != 0);
+ std::string comment = fields[6].GetString();
+
+ TeamId guildTeam = TEAM_ALLIANCE;
+ if (ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(fields[7].GetUInt8()))
+ if (raceEntry->TeamID == 1)
+ guildTeam = TEAM_HORDE;
+
+ LFGuildSettings settings(listed, guildTeam, guildId, classRoles, availability, interests, level, comment);
+ _guildSettings[guildId] = settings;
+
+ ++count;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u guild finder guild-related settings in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildFinderMgr::LoadMembershipRequests()
+{
+ TC_LOG_INFO("server.loading", "Loading guild finder membership requests...");
+ // 0 1 2 3 4 5 6
+ QueryResult result = CharacterDatabase.Query("SELECT guildId, playerGuid, availability, classRole, interests, comment, submitTime "
+ "FROM guild_finder_applicant");
+
+ if (!result)
+ {
+ TC_LOG_INFO("server.loading", ">> Loaded 0 guild finder membership requests. Table `guild_finder_applicant` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+ uint32 oldMSTime = getMSTime();
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 guildId = fields[0].GetUInt32();
+ uint32 playerId = fields[1].GetUInt32();
+ uint8 availability = fields[2].GetUInt8();
+ uint8 classRoles = fields[3].GetUInt8();
+ uint8 interests = fields[4].GetUInt8();
+ std::string comment = fields[5].GetString();
+ uint32 submitTime = fields[6].GetUInt32();
+
+ MembershipRequest request(playerId, guildId, availability, classRoles, interests, comment, time_t(submitTime));
+
+ _membershipRequests[guildId].push_back(request);
+
+ ++count;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u guild finder membership requests in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildFinderMgr::AddMembershipRequest(uint32 guildGuid, MembershipRequest const& request)
+{
+ _membershipRequests[guildGuid].push_back(request);
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, request.GetGuildId());
+ stmt->setUInt32(1, request.GetPlayerGUID());
+ stmt->setUInt8(2, request.GetAvailability());
+ stmt->setUInt8(3, request.GetClassRoles());
+ stmt->setUInt8(4, request.GetInterests());
+ stmt->setString(5, request.GetComment());
+ stmt->setUInt32(6, request.GetSubmitTime());
+ trans->Append(stmt);
+ CharacterDatabase.CommitTransaction(trans);
+
+ // Notify the applicant his submittion has been added
+ if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(request.GetPlayerGUID(), 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(guildGuid))
+ SendApplicantListUpdate(*guild);
+}
+
+void GuildFinderMgr::RemoveAllMembershipRequestsFromPlayer(uint32 playerId)
+{
+ for (MembershipRequestStore::iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ std::vector<MembershipRequest>::iterator itr2 = itr->second.begin();
+ for (; itr2 != itr->second.end(); ++itr2)
+ if (itr2->GetPlayerGUID() == playerId)
+ break;
+
+ if (itr2 == itr->second.end())
+ continue;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr2->GetGuildId());
+ stmt->setUInt32(1, itr2->GetPlayerGUID());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+ itr->second.erase(itr2);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(itr->first))
+ SendApplicantListUpdate(*guild);
+ }
+}
+
+void GuildFinderMgr::RemoveMembershipRequest(uint32 playerId, uint32 guildId)
+{
+ std::vector<MembershipRequest>::iterator itr = _membershipRequests[guildId].begin();
+ for (; itr != _membershipRequests[guildId].end(); ++itr)
+ if (itr->GetPlayerGUID() == playerId)
+ break;
+
+ if (itr == _membershipRequests[guildId].end())
+ return;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr->GetGuildId());
+ stmt->setUInt32(1, itr->GetPlayerGUID());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+
+ _membershipRequests[guildId].erase(itr);
+
+ // Notify the applicant his submittion has been removed
+ if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(playerId, 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+
+ // Notify the guild master and officers the list changed
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ SendApplicantListUpdate(*guild);
+}
+
+std::list<MembershipRequest> GuildFinderMgr::GetAllMembershipRequestsForPlayer(uint32 playerGuid)
+{
+ std::list<MembershipRequest> resultSet;
+ for (MembershipRequestStore::const_iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ std::vector<MembershipRequest> const& guildReqs = itr->second;
+ for (std::vector<MembershipRequest>::const_iterator itr2 = guildReqs.begin(); itr2 != guildReqs.end(); ++itr2)
+ {
+ if (itr2->GetPlayerGUID() == playerGuid)
+ {
+ resultSet.push_back(*itr2);
+ break;
+ }
+ }
+ }
+ return resultSet;
+}
+
+uint8 GuildFinderMgr::CountRequestsFromPlayer(uint32 playerId)
+{
+ uint8 result = 0;
+ for (MembershipRequestStore::const_iterator itr = _membershipRequests.begin(); itr != _membershipRequests.end(); ++itr)
+ {
+ for (std::vector<MembershipRequest>::const_iterator itr2 = itr->second.begin(); itr2 != itr->second.end(); ++itr2)
+ {
+ if (itr2->GetPlayerGUID() != playerId)
+ continue;
+ ++result;
+ break;
+ }
+ }
+ return result;
+}
+
+LFGuildStore GuildFinderMgr::GetGuildsMatchingSetting(LFGuildPlayer& settings, TeamId faction)
+{
+ LFGuildStore resultSet;
+ for (LFGuildStore::const_iterator itr = _guildSettings.begin(); itr != _guildSettings.end(); ++itr)
+ {
+ LFGuildSettings const& guildSettings = itr->second;
+
+ if (guildSettings.GetTeam() != faction)
+ continue;
+
+ if (!(guildSettings.GetAvailability() & settings.GetAvailability()))
+ continue;
+
+ if (!(guildSettings.GetClassRoles() & settings.GetClassRoles()))
+ continue;
+
+ if (!(guildSettings.GetInterests() & settings.GetInterests()))
+ continue;
+
+ if (!(guildSettings.GetLevel() & settings.GetLevel()))
+ continue;
+
+ resultSet.insert(std::make_pair(itr->first, guildSettings));
+ }
+
+ return resultSet;
+}
+
+bool GuildFinderMgr::HasRequest(uint32 playerId, uint32 guildId)
+{
+ for (std::vector<MembershipRequest>::const_iterator itr = _membershipRequests[guildId].begin(); itr != _membershipRequests[guildId].end(); ++itr)
+ if (itr->GetPlayerGUID() == playerId)
+ return true;
+ return false;
+}
+
+void GuildFinderMgr::SetGuildSettings(uint32 guildGuid, LFGuildSettings const& settings)
+{
+ _guildSettings[guildGuid] = settings;
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS);
+ stmt->setUInt32(0, settings.GetGUID());
+ stmt->setUInt8(1, settings.GetAvailability());
+ stmt->setUInt8(2, settings.GetClassRoles());
+ stmt->setUInt8(3, settings.GetInterests());
+ stmt->setUInt8(4, settings.GetLevel());
+ stmt->setUInt8(5, settings.IsListed());
+ stmt->setString(6, settings.GetComment());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+}
+
+void GuildFinderMgr::DeleteGuild(uint32 guildId)
+{
+ std::vector<MembershipRequest>::iterator itr = _membershipRequests[guildId].begin();
+ while (itr != _membershipRequests[guildId].end())
+ {
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+
+ uint32 applicant = itr->GetPlayerGUID();
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_APPLICANT);
+ stmt->setUInt32(0, itr->GetGuildId());
+ stmt->setUInt32(1, applicant);
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS);
+ stmt->setUInt32(0, itr->GetGuildId());
+ trans->Append(stmt);
+
+ CharacterDatabase.CommitTransaction(trans);
+
+ // Notify the applicant his submition has been removed
+ if (Player* player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(applicant, 0, HIGHGUID_PLAYER)))
+ SendMembershipRequestListUpdate(*player);
+
+ ++itr;
+ }
+
+ _membershipRequests.erase(guildId);
+ _guildSettings.erase(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->GetGuildById(guildId))
+ SendApplicantListUpdate(*guild);
+}
+
+void GuildFinderMgr::SendApplicantListUpdate(Guild& guild)
+{
+ WorldPacket data(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, 0);
+ if (Player* player = ObjectAccessor::FindPlayer(guild.GetLeaderGUID()))
+ player->SendDirectMessage(&data);
+ guild.BroadcastPacketToRank(&data, GR_OFFICER);
+}
+
+void GuildFinderMgr::SendMembershipRequestListUpdate(Player& player)
+{
+ WorldPacket data(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, 0);
+ player.SendDirectMessage(&data);
+}
diff --git a/src/server/game/Guilds/GuildFinderMgr.h b/src/server/game/Guilds/GuildFinderMgr.h
new file mode 100644
index 00000000000..3bf7840b4ec
--- /dev/null
+++ b/src/server/game/Guilds/GuildFinderMgr.h
@@ -0,0 +1,274 @@
+/*
+ * 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 __TRINITY_GUILDFINDER_H
+#define __TRINITY_GUILDFINDER_H
+
+#include <ace/Singleton.h>
+#include "Common.h"
+#include "World.h"
+#include "GuildMgr.h"
+
+enum GuildFinderOptionsInterest
+{
+ INTEREST_QUESTING = 0x01,
+ INTEREST_DUNGEONS = 0x02,
+ INTEREST_RAIDS = 0x04,
+ INTEREST_PVP = 0x08,
+ INTEREST_ROLE_PLAYING = 0x10,
+ ALL_INTERESTS = INTEREST_QUESTING | INTEREST_DUNGEONS | INTEREST_RAIDS | INTEREST_PVP | INTEREST_ROLE_PLAYING
+};
+
+enum GuildFinderOptionsAvailability
+{
+ AVAILABILITY_WEEKDAYS = 0x1,
+ AVAILABILITY_WEEKENDS = 0x2,
+ AVAILABILITY_ALWAYS = AVAILABILITY_WEEKDAYS | AVAILABILITY_WEEKENDS
+};
+
+enum GuildFinderOptionsRoles
+{
+ GUILDFINDER_ROLE_TANK = 0x1,
+ GUILDFINDER_ROLE_HEALER = 0x2,
+ GUILDFINDER_ROLE_DPS = 0x4,
+ GUILDFINDER_ALL_ROLES = GUILDFINDER_ROLE_TANK | GUILDFINDER_ROLE_HEALER | GUILDFINDER_ROLE_DPS
+};
+
+enum GuildFinderOptionsLevel
+{
+ ANY_FINDER_LEVEL = 0x1,
+ MAX_FINDER_LEVEL = 0x2,
+ ALL_GUILDFINDER_LEVELS = ANY_FINDER_LEVEL | MAX_FINDER_LEVEL
+};
+
+/// Holds all required informations about a membership request
+struct MembershipRequest
+{
+ public:
+ MembershipRequest(MembershipRequest const& settings) : _comment(settings.GetComment())
+ {
+ _availability = settings.GetAvailability();
+ _classRoles = settings.GetClassRoles();
+ _interests = settings.GetInterests();
+ _guildId = settings.GetGuildId();
+ _playerGUID = settings.GetPlayerGUID();
+ _time = settings.GetSubmitTime();
+ }
+
+ MembershipRequest(uint32 playerGUID, uint32 guildId, uint32 availability, uint32 classRoles, uint32 interests, std::string& comment, time_t submitTime) :
+ _comment(comment), _guildId(guildId), _playerGUID(playerGUID), _availability(availability),
+ _classRoles(classRoles), _interests(interests), _time(submitTime) {}
+
+ MembershipRequest() : _guildId(0), _playerGUID(0), _availability(0), _classRoles(0),
+ _interests(0), _time(time(NULL)) {}
+
+ uint32 GetGuildId() const { return _guildId; }
+ uint32 GetPlayerGUID() const { return _playerGUID; }
+ uint8 GetAvailability() const { return _availability; }
+ uint8 GetClassRoles() const { return _classRoles; }
+ uint8 GetInterests() const { return _interests; }
+ uint8 GetClass() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_class; }
+ uint8 GetLevel() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_level; }
+ time_t GetSubmitTime() const { return _time; }
+ time_t GetExpiryTime() const { return time_t(_time + 30 * 24 * 3600); } // Adding 30 days
+ std::string const& GetComment() const { return _comment; }
+ std::string const& GetName() const { return sWorld->GetCharacterNameData(GetPlayerGUID())->m_name; }
+ private:
+ std::string _comment;
+
+ uint32 _guildId;
+ uint32 _playerGUID;
+
+ uint8 _availability;
+ uint8 _classRoles;
+ uint8 _interests;
+
+ time_t _time;
+};
+
+/// Holds all informations about a player's finder settings. _NOT_ stored in database.
+struct LFGuildPlayer
+{
+ public:
+ LFGuildPlayer()
+ {
+ _guid = 0;
+ _roles = 0;
+ _availability = 0;
+ _interests = 0;
+ _level = 0;
+ }
+
+ LFGuildPlayer(uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level)
+ {
+ _guid = guid;
+ _roles = role;
+ _availability = availability;
+ _interests = interests;
+ _level = level;
+ }
+
+ LFGuildPlayer(uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level, std::string& comment) : _comment(comment)
+ {
+ _guid = guid;
+ _roles = role;
+ _availability = availability;
+ _interests = interests;
+ _level = level;
+ }
+
+ LFGuildPlayer(LFGuildPlayer const& settings) : _comment(settings.GetComment())
+ {
+ _guid = settings.GetGUID();
+ _roles = settings.GetClassRoles();
+ _availability = settings.GetAvailability();
+ _interests = settings.GetInterests();
+ _level = settings.GetLevel();
+ }
+
+ uint32 GetGUID() const { return _guid; }
+ uint8 GetClassRoles() const { return _roles; }
+ uint8 GetAvailability() const { return _availability; }
+ uint8 GetInterests() const { return _interests; }
+ uint8 GetLevel() const { return _level; }
+ std::string const& GetComment() const { return _comment; }
+
+ private:
+ std::string _comment;
+ uint32 _guid;
+ uint8 _roles;
+ uint8 _availability;
+ uint8 _interests;
+ uint8 _level;
+};
+
+/// Holds settings for a guild in the finder system. Saved to database.
+struct LFGuildSettings : public LFGuildPlayer
+{
+ public:
+ LFGuildSettings() : LFGuildPlayer(), _listed(false), _team(TEAM_ALLIANCE) {}
+
+ LFGuildSettings(bool listed, TeamId team) : LFGuildPlayer(), _listed(listed), _team(team) {}
+
+ LFGuildSettings(bool listed, TeamId team, uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level) :
+ LFGuildPlayer(guid, role, availability, interests, level), _listed(listed), _team(team) {}
+
+ LFGuildSettings(bool listed, TeamId team, uint32 guid, uint8 role, uint8 availability, uint8 interests, uint8 level, std::string& comment) :
+ LFGuildPlayer(guid, role, availability, interests, level, comment), _listed(listed), _team(team) {}
+
+ LFGuildSettings(LFGuildSettings const& settings) :
+ LFGuildPlayer(settings), _listed(settings.IsListed()), _team(settings.GetTeam()) {}
+
+
+ bool IsListed() const { return _listed; }
+ void SetListed(bool state) { _listed = state; }
+
+ TeamId GetTeam() const { return _team; }
+ private:
+ bool _listed;
+ TeamId _team;
+};
+
+typedef std::map<uint32 /* guildGuid */, LFGuildSettings> LFGuildStore;
+typedef std::map<uint32 /* guildGuid */, std::vector<MembershipRequest> > MembershipRequestStore;
+
+class GuildFinderMgr
+{
+ friend class ACE_Singleton<GuildFinderMgr, ACE_Null_Mutex>;
+
+ private:
+ GuildFinderMgr();
+ ~GuildFinderMgr();
+
+ LFGuildStore _guildSettings;
+
+ MembershipRequestStore _membershipRequests;
+
+ void LoadGuildSettings();
+ void LoadMembershipRequests();
+
+ public:
+ void LoadFromDB();
+
+ /**
+ * @brief Stores guild settings and begins an asynchronous database insert
+ * @param guildGuid The guild's database guid.
+ * @param LFGuildSettings The guild's settings storage.
+ */
+ void SetGuildSettings(uint32 guildGuid, LFGuildSettings const& settings);
+
+ /**
+ * @brief Returns settings for a guild.
+ * @param guildGuid The guild's database guid.
+ */
+ LFGuildSettings GetGuildSettings(uint32 guildGuid) { return _guildSettings[guildGuid]; }
+
+ /**
+ * @brief Files a membership request to a guild
+ * @param guildGuid The guild's database GUID.
+ * @param MembershipRequest An object storing all data related to the request.
+ */
+ void AddMembershipRequest(uint32 guildGuid, MembershipRequest const& request);
+
+ /**
+ * @brief Removes all membership request from a player.
+ * @param playerId The player's database guid whose application shall be deleted.
+ */
+ void RemoveAllMembershipRequestsFromPlayer(uint32 playerId);
+
+ /**
+ * @brief Removes a membership request to a guild.
+ * @param playerId The player's database guid whose application shall be deleted.
+ * @param guildId The guild's database guid
+ */
+ void RemoveMembershipRequest(uint32 playerId, uint32 guildId);
+
+ /// Wipes everything related to a guild. Used when that guild is disbanded
+ void DeleteGuild(uint32 guildId);
+
+ /**
+ * @brief Returns a set of membership requests for a guild
+ * @param guildGuid The guild's database guid.
+ */
+ std::vector<MembershipRequest> GetAllMembershipRequestsForGuild(uint32 guildGuid) { return _membershipRequests[guildGuid]; }
+
+ /**
+ * @brief Returns a list of membership requests for a player.
+ * @param playerGuid The player's database guid.
+ */
+ std::list<MembershipRequest> GetAllMembershipRequestsForPlayer(uint32 playerGuid);
+
+ /**
+ * @brief Returns a store of guilds matching the settings provided, using bitmask operators.
+ * @param settings The player's finder settings
+ * @param teamId The player's faction (TEAM_ALLIANCE or TEAM_HORDE)
+ */
+ LFGuildStore GetGuildsMatchingSetting(LFGuildPlayer& settings, TeamId faction);
+
+ /// Provided a player DB guid and a guild DB guid, determines if a pending request is filed with these keys.
+ bool HasRequest(uint32 playerId, uint32 guildId);
+
+ /// Counts the amount of pending membership requests, given the player's db guid.
+ uint8 CountRequestsFromPlayer(uint32 playerId);
+
+ void SendApplicantListUpdate(Guild& guild);
+ void SendMembershipRequestListUpdate(Player& player);
+};
+
+#define sGuildFinderMgr ACE_Singleton<GuildFinderMgr, ACE_Null_Mutex>::instance()
+
+#endif // __TRINITY_GUILDFINDER_H
diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp
index b9cb7d6dce9..6794369f375 100644
--- a/src/server/game/Guilds/GuildMgr.cpp
+++ b/src/server/game/Guilds/GuildMgr.cpp
@@ -37,6 +37,12 @@ void GuildMgr::RemoveGuild(uint32 guildId)
GuildStore.erase(guildId);
}
+void GuildMgr::SaveGuilds()
+{
+ for (GuildContainer::iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
+ itr->second->SaveToDB();
+}
+
uint32 GuildMgr::GenerateGuildId()
{
if (NextGuildId >= 0xFFFFFFFE)
@@ -57,6 +63,17 @@ Guild* GuildMgr::GetGuildById(uint32 guildId) const
return NULL;
}
+Guild* GuildMgr::GetGuildByGuid(uint64 guid) const
+{
+ // Full guids are only used when receiving/sending data to client
+ // everywhere else guild id is used
+ if (IS_GUILD_GUID(guid))
+ if (uint32 guildId = GUID_LOPART(guid))
+ return GetGuildById(guildId);
+
+ return NULL;
+}
+
Guild* GuildMgr::GetGuildByName(const std::string& guildName) const
{
std::string search = guildName;
@@ -88,6 +105,13 @@ Guild* GuildMgr::GetGuildByLeader(uint64 guid) const
return NULL;
}
+uint32 GuildMgr::GetXPForGuildLevel(uint8 level) const
+{
+ if (level < GuildXPperLevel.size())
+ return GuildXPperLevel[level];
+ return 0;
+}
+
void GuildMgr::LoadGuilds()
{
// 1. Load all guilds
@@ -97,8 +121,8 @@ void GuildMgr::LoadGuilds()
// 0 1 2 3 4 5 6
QueryResult result = CharacterDatabase.Query("SELECT g.guildid, g.name, g.leaderguid, g.EmblemStyle, g.EmblemColor, g.BorderStyle, g.BorderColor, "
- // 7 8 9 10 11 12
- "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, COUNT(gbt.guildid) "
+ // 7 8 9 10 11 12 13 14 15
+ "g.BackgroundColor, g.info, g.motd, g.createdate, g.BankMoney, g.level, g.experience, g.todayExperience, COUNT(gbt.guildid) "
"FROM guild g LEFT JOIN guild_bank_tab gbt ON g.guildid = gbt.guildid GROUP BY g.guildid ORDER BY g.guildid ASC");
if (!result)
@@ -173,13 +197,13 @@ void GuildMgr::LoadGuilds()
CharacterDatabase.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL");
CharacterDatabase.DirectExecute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL");
- // 0 1 2 3 4 5 6 7 8 9 10
- QueryResult result = CharacterDatabase.Query("SELECT guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, "
- // 11 12 13 14 15 16 17
- "w.money, c.name, c.level, c.class, c.zone, c.account, c.logout_time "
+ // 0 1 2 3 4 5 6 7 8 9 10
+ QueryResult result = CharacterDatabase.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, "
+ // 11 12 13 14 15 16 17 18 19
+ "w.tab6, w.tab7, w.money, c.name, c.level, c.class, c.zone, c.account, c.logout_time "
"FROM guild_member gm "
"LEFT JOIN guild_member_withdraw w ON gm.guid = w.guid "
- "LEFT JOIN characters c ON c.guid = gm.guid ORDER BY guildid ASC");
+ "LEFT JOIN characters c ON c.guid = gm.guid ORDER BY gm.guildid ASC");
if (!result)
TC_LOG_INFO("server.loading", ">> Loaded 0 guild members. DB table `guild_member` is empty.");
@@ -304,7 +328,39 @@ void GuildMgr::LoadGuilds()
}
}
- // 7. Load all guild bank tabs
+ // 7. Load all news event logs
+ TC_LOG_INFO("server.loading", "Loading Guild News...");
+ {
+ uint32 oldMSTime = getMSTime();
+
+ CharacterDatabase.DirectPExecute("DELETE FROM guild_newslog WHERE LogGuid > %u", sWorld->getIntConfig(CONFIG_GUILD_NEWS_LOG_COUNT));
+
+ // 0 1 2 3 4 5 6
+ QueryResult result = CharacterDatabase.Query("SELECT guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp FROM guild_newslog ORDER BY TimeStamp DESC, LogGuid DESC");
+
+ if (!result)
+ TC_LOG_INFO("server.loading", ">> Loaded 0 guild event logs. DB table `guild_newslog` is empty.");
+ else
+ {
+ uint32 count = 0;
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 guildId = fields[0].GetUInt32();
+
+ if (Guild* guild = GetGuildById(guildId))
+ guild->LoadGuildNewsLogFromDB(fields);
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u guild new logs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+ }
+ }
+
+
+ // 8. Load all guild bank tabs
TC_LOG_INFO("server.loading", "Loading guild bank tabs...");
{
uint32 oldMSTime = getMSTime();
@@ -338,7 +394,7 @@ void GuildMgr::LoadGuilds()
}
}
- // 8. Fill all guild bank tabs
+ // 9. Fill all guild bank tabs
TC_LOG_INFO("guild", "Filling bank tabs with items...");
{
uint32 oldMSTime = getMSTime();
@@ -374,8 +430,25 @@ void GuildMgr::LoadGuilds()
}
}
- // 9. Validate loaded guild data
- TC_LOG_INFO("guild", "Validating data of loaded guilds...");
+ // 10. Load guild achievements
+ {
+ PreparedQueryResult achievementResult;
+ PreparedQueryResult criteriaResult;
+ for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT);
+ stmt->setUInt32(0, itr->first);
+ achievementResult = CharacterDatabase.Query(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA);
+ stmt->setUInt32(0, itr->first);
+ criteriaResult = CharacterDatabase.Query(stmt);
+
+ itr->second->GetAchievementMgr().LoadFromDB(achievementResult, criteriaResult);
+ }
+ }
+
+ // 11. Validate loaded guild data
+ TC_LOG_INFO("misc", "Validating data of loaded guilds...");
{
uint32 oldMSTime = getMSTime();
@@ -391,11 +464,112 @@ void GuildMgr::LoadGuilds()
}
}
-void GuildMgr::ResetTimes()
+void GuildMgr::LoadGuildXpForLevel()
{
+ uint32 oldMSTime = getMSTime();
+
+ GuildXPperLevel.resize(sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL));
+ for (uint8 level = 0; level < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL); ++level)
+ GuildXPperLevel[level] = 0;
+
+ // 0 1
+ QueryResult result = WorldDatabase.Query("SELECT lvl, xp_for_next_level FROM guild_xp_for_level");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 xp for guild level definitions. DB table `guild_xp_for_level` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+
+ uint32 level = fields[0].GetUInt8();
+ uint32 requiredXP = fields[1].GetUInt64();
+
+ if (level >= sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL))
+ {
+ TC_LOG_INFO("misc", "Unused (> Guild.MaxLevel in worldserver.conf) level %u in `guild_xp_for_level` table, ignoring.", uint32(level));
+ continue;
+ }
+
+ GuildXPperLevel[level] = requiredXP;
+ ++count;
+
+ } while (result->NextRow());
+
+ // fill level gaps
+ for (uint8 level = 1; level < sWorld->getIntConfig(CONFIG_GUILD_MAX_LEVEL); ++level)
+ {
+ if (!GuildXPperLevel[level])
+ {
+ TC_LOG_ERROR("sql.sql", "Level %i does not have XP for guild level data. Using data of level [%i] + 1660000.", level+1, level);
+ GuildXPperLevel[level] = GuildXPperLevel[level - 1] + 1660000;
+ }
+ }
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u xp for guild level definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildMgr::LoadGuildRewards()
+{
+ uint32 oldMSTime = getMSTime();
+
+ // 0 1 2 3 4
+ QueryResult result = WorldDatabase.Query("SELECT entry, standing, racemask, price, achievement FROM guild_rewards");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 guild reward definitions. DB table `guild_rewards` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do
+ {
+ GuildReward reward;
+ Field* fields = result->Fetch();
+ reward.Entry = fields[0].GetUInt32();
+ reward.Standing = fields[1].GetUInt8();
+ reward.Racemask = fields[2].GetInt32();
+ reward.Price = fields[3].GetUInt64();
+ reward.AchievementId = fields[4].GetUInt32();
+
+ if (!sObjectMgr->GetItemTemplate(reward.Entry))
+ {
+ TC_LOG_ERROR("server.loading", "Guild rewards constains not existing item entry %u", reward.Entry);
+ continue;
+ }
+
+ if (reward.AchievementId != 0 && (!sAchievementMgr->GetAchievement(reward.AchievementId)))
+ {
+ TC_LOG_ERROR("server.loading", "Guild rewards constains not existing achievement entry %u", reward.AchievementId);
+ continue;
+ }
+
+ if (reward.Standing >= MAX_REPUTATION_RANK)
+ {
+ TC_LOG_ERROR("server.loading", "Guild rewards contains wrong reputation standing %u, max is %u", uint32(reward.Standing), MAX_REPUTATION_RANK - 1);
+ continue;
+ }
+
+ GuildRewards.push_back(reward);
+ ++count;
+ } while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u guild reward definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
+void GuildMgr::ResetTimes(bool week)
+{
+ CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE));
+ CharacterDatabase.Execute(CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW));
+
for (GuildContainer::const_iterator itr = GuildStore.begin(); itr != GuildStore.end(); ++itr)
if (Guild* guild = itr->second)
- guild->ResetTimes();
-
- CharacterDatabase.DirectExecute("TRUNCATE guild_member_withdraw");
-} \ No newline at end of file
+ guild->ResetTimes(week);
+}
diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h
index 3d07059000b..1a400a50f5c 100644
--- a/src/server/game/Guilds/GuildMgr.h
+++ b/src/server/game/Guilds/GuildMgr.h
@@ -31,21 +31,34 @@ private:
public:
Guild* GetGuildByLeader(uint64 guid) const;
Guild* GetGuildById(uint32 guildId) const;
+ Guild* GetGuildByGuid(uint64 guid) const;
Guild* GetGuildByName(std::string const& guildName) const;
std::string GetGuildNameById(uint32 guildId) const;
+ void LoadGuildXpForLevel();
+ void LoadGuildRewards();
+
void LoadGuilds();
void AddGuild(Guild* guild);
void RemoveGuild(uint32 guildId);
+ void SaveGuilds();
+
+ void ResetReputationCaps();
+
uint32 GenerateGuildId();
void SetNextGuildId(uint32 Id) { NextGuildId = Id; }
- void ResetTimes();
+ uint32 GetXPForGuildLevel(uint8 level) const;
+ std::vector<GuildReward> const& GetGuildRewards() const { return GuildRewards; }
+
+ void ResetTimes(bool week);
protected:
typedef UNORDERED_MAP<uint32, Guild*> GuildContainer;
uint32 NextGuildId;
GuildContainer GuildStore;
+ std::vector<uint64> GuildXPperLevel;
+ std::vector<GuildReward> GuildRewards;
};
#define sGuildMgr ACE_Singleton<GuildMgr, ACE_Null_Mutex>::instance()
diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp
index f3aedeeeb48..2f27abc4814 100644
--- a/src/server/game/Handlers/ArenaTeamHandler.cpp
+++ b/src/server/game/Handlers/ArenaTeamHandler.cpp
@@ -75,6 +75,54 @@ void WorldSession::HandleArenaTeamRosterOpcode(WorldPacket& recvData)
arenaTeam->Roster(this);
}
+void WorldSession::HandleArenaTeamCreateOpcode(WorldPacket & recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_ARENA_TEAM_CREATE");
+
+ uint32 slot, icon, iconcolor, border, bordercolor, background;
+ std::string name;
+
+ recvData >> slot;
+ recvData >> iconcolor;
+ recvData >> bordercolor;
+ recvData >> border;
+ recvData >> background;
+ recvData >> icon;
+ name = recvData.ReadString(recvData.ReadBits(8));
+
+ uint8 type = ArenaTeam::GetTypeBySlot(slot);
+
+ if (_player->GetArenaTeamId(slot))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_INVITE_SS, "", _player->GetName(), ERR_ALREADY_IN_ARENA_TEAM_S);
+ return;
+ }
+
+ if (sObjectMgr->IsReservedName(name) || !ObjectMgr::IsValidCharterName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
+ return;
+ }
+
+ if (sArenaTeamMgr->GetArenaTeamByName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
+ return;
+ }
+
+ ArenaTeam* arenaTeam = new ArenaTeam;
+ if (!arenaTeam->Create(GUID_LOPART(_player->GetGUID()), type, name, background, icon, iconcolor, border, bordercolor))
+ {
+ TC_LOG_ERROR("bg.arena", "Arena team create failed.");
+ delete arenaTeam;
+ return;
+ }
+
+ sArenaTeamMgr->AddArenaTeam(arenaTeam);
+
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_CREATED);
+}
+
void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "CMSG_ARENA_TEAM_INVITE");
@@ -113,6 +161,12 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData)
return;
}
+ if (arenaTeam->GetCaptain() != _player->GetGUID())
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, "", "", ERR_ARENA_TEAM_PERMISSIONS);
+ return;
+ }
+
// OK result but don't send invite
if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
return;
@@ -349,20 +403,25 @@ void WorldSession::HandleArenaTeamLeaderOpcode(WorldPacket& recvData)
void WorldSession::SendArenaTeamCommandResult(uint32 teamAction, const std::string& team, const std::string& player, uint32 errorId)
{
- WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 4+team.length()+1+player.length()+1+4);
+ WorldPacket data(SMSG_ARENA_TEAM_COMMAND_RESULT, 2 + team.length() + player.length() + 4 + 4);
+
+ data.WriteBits(player.length(), 7);
+ data.WriteBits(team.length(), 8);
+ data.FlushBits();
+
+ data.WriteString(player);
data << uint32(teamAction);
- data << team;
- data << player;
data << uint32(errorId);
+ data.WriteString(team);
SendPacket(&data);
}
void WorldSession::SendNotInArenaTeamPacket(uint8 type)
{
- WorldPacket data(SMSG_ARENA_ERROR, 4+1); // 886 - You are not in a %uv%u arena team
- uint32 unk = 0;
- data << uint32(unk); // unk(0)
- if (!unk)
+ WorldPacket data(SMSG_ARENA_ERROR, 4+1);
+ uint32 error = 0;
+ data << uint32(error); // 0 = ERR_ARENA_NO_TEAM_II, 1 = ERR_ARENA_EXPIRED_CAIS, 2 = ERR_LFG_CANT_USE_BATTLEGROUND
+ if (!error)
data << uint8(type); // team type (2=2v2, 3=3v3, 5=5v5), can be used for custom types...
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index d9e4feb7f85..fddbfac0a5e 100644
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -71,14 +71,29 @@ void WorldSession::SendAuctionHello(uint64 guid, Creature* unit)
}
//call this method when player bids, creates, or deletes auction
-void WorldSession::SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError)
+void WorldSession::SendAuctionCommandResult(AuctionEntry* auction, uint32 action, uint32 errorCode, uint32 bidError)
{
- WorldPacket data(SMSG_AUCTION_COMMAND_RESULT, 16);
- data << auctionId;
- data << Action;
- data << ErrorCode;
- if (!ErrorCode && Action)
- data << bidError; //when bid, then send 0, once...
+ WorldPacket data(SMSG_AUCTION_COMMAND_RESULT);
+ data << uint32(auction ? auction->Id : 0);
+ data << uint32(action);
+ data << uint32(errorCode);
+
+ switch (errorCode)
+ {
+ case ERR_AUCTION_OK:
+ if (action == AUCTION_PLACE_BID)
+ data << uint64(auction->bid ? auction->GetAuctionOutBid() : 0);
+ break;
+ case ERR_AUCTION_INVENTORY:
+ data << uint32(bidError);
+ break;
+ case ERR_AUCTION_HIGHER_BID:
+ data << uint64(auction->bidder);
+ data << uint64(auction->bid);
+ data << uint64(auction->bid ? auction->GetAuctionOutBid() : 0);
+ break;
+ }
+
SendPacket(&data);
}
@@ -89,32 +104,41 @@ void WorldSession::SendAuctionBidderNotification(uint32 location, uint32 auction
data << uint32(location);
data << uint32(auctionId);
data << uint64(bidder);
- data << uint32(bidSum);
- data << uint32(diff);
+ data << uint64(bidSum);
+ data << uint64(diff);
data << uint32(itemEntry);
data << uint32(0);
SendPacket(&data);
}
-//this void causes on client to display: "Your auction sold"
+// this void causes on client to display: "Your auction sold"
void WorldSession::SendAuctionOwnerNotification(AuctionEntry* auction)
{
- WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, (8*4));
+ WorldPacket data(SMSG_AUCTION_OWNER_NOTIFICATION, 40);
data << uint32(auction->Id);
- data << uint32(auction->bid);
- data << uint32(0); //unk
- data << uint64(0); //unk (bidder guid?)
+ data << uint64(auction->bid);
+ data << uint64(0); //unk
+ data << uint64(0); //unk
data << uint32(auction->itemEntry);
- data << uint32(0); //unk
- data << float(0); //unk (time?)
+ data << uint32(0); //unk
+ data << float(0); //unk
+ SendPacket(&data);
+}
+
+void WorldSession::SendAuctionRemovedNotification(uint32 auctionId, uint32 itemEntry, int32 randomPropertyId)
+{
+ WorldPacket data(SMSG_AUCTION_REMOVED_NOTIFICATION, (4+4+4));
+ data << uint32(auctionId);
+ data << uint32(itemEntry);
+ data << uint32(randomPropertyId);
SendPacket(&data);
}
//this void creates new auction and adds auction to some auctionhouse
void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
{
- uint64 auctioneer;
- uint32 itemsCount, etime, bid, buyout;
+ uint64 auctioneer, bid, buyout;
+ uint32 itemsCount, etime;
recvData >> auctioneer;
recvData >> itemsCount;
@@ -123,7 +147,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (itemsCount > MAX_AUCTION_ITEMS)
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
recvData.rfinish();
return;
}
@@ -150,7 +174,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT)
{
TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow());
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
return;
}
@@ -194,7 +218,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (!item)
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_ITEM_NOT_FOUND);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_ITEM_NOT_FOUND);
return;
}
@@ -202,7 +226,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) ||
item->GetCount() < count[i])
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
return;
}
@@ -212,7 +236,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (!finalCount)
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
return;
}
@@ -222,7 +246,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (item->GetMaxStackCount() < finalCount)
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
return;
}
}
@@ -233,9 +257,9 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
uint32 deposit = sAuctionMgr->GetAuctionDeposit(auctionHouseEntry, etime, item, finalCount);
- if (!_player->HasEnoughMoney(deposit))
+ if (!_player->HasEnoughMoney((uint64)deposit))
{
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_NOT_ENOUGHT_MONEY);
return;
}
@@ -268,7 +292,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->deposit = deposit;
AH->auctionHouseEntry = auctionHouseEntry;
- TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
+ TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) "
+ "to auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
+ _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(),
+ AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(item);
auctionHouse->AddAuction(AH);
@@ -281,7 +308,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
_player->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
- SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
+ SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
}
@@ -291,7 +318,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
if (!newItem)
{
TC_LOG_ERROR("network", "CMSG_AUCTION_SELL_ITEM: Could not create clone of item %u", item->GetEntry());
- SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR);
delete AH;
return;
}
@@ -315,7 +342,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
AH->deposit = deposit;
AH->auctionHouseEntry = auctionHouseEntry;
- TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
+ TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to "
+ "auctioneer %u with count %u with initial bid " UI64FMTD " with buyout " UI64FMTD " and with time %u (in sec) in auctionhouse %u",
+ _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(),
+ newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId());
sAuctionMgr->AddAItem(newItem);
auctionHouse->AddAuction(AH);
@@ -353,7 +383,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
_player->SaveInventoryAndGoldToDB(trans);
CharacterDatabase.CommitTransaction(trans);
- SendAuctionCommandResult(AH->Id, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
+ SendAuctionCommandResult(AH, AUCTION_SELL_ITEM, ERR_AUCTION_OK);
GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION, 1);
}
@@ -361,19 +391,20 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData)
_player->ModifyMoney(-int32(deposit));
}
-//this function is called when client bids or buys out auction
+// this function is called when client bids or buys out auction
void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_AUCTION_PLACE_BID");
uint64 auctioneer;
uint32 auctionId;
- uint32 price;
+ uint64 price;
recvData >> auctioneer;
- recvData >> auctionId >> price;
+ recvData >> auctionId;
+ recvData >> price;
if (!auctionId || !price)
- return; //check for cheaters
+ return; // check for cheaters
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
@@ -394,18 +425,18 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
if (!auction || auction->owner == player->GetGUIDLow())
{
//you cannot bid your own auction:
- SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN);
+ SendAuctionCommandResult(NULL, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN);
return;
}
// impossible have online own another character (use this for speedup check in case online owner)
- Player* auction_owner = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER));
+ /*Player* auction_owner = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER));
if (!auction_owner && sObjectMgr->GetPlayerAccountIdByGUID(MAKE_NEW_GUID(auction->owner, 0, HIGHGUID_PLAYER)) == player->GetSession()->GetAccountId())
{
//you cannot bid your another character auction:
- SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN);
+ SendAuctionCommandResult(NULL, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN);
return;
- }
+ }*/
// cheating
if (price <= auction->bid || price < auction->startbid)
@@ -415,14 +446,15 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
if ((price < auction->buyout || auction->buyout == 0) &&
price < auction->bid + auction->GetAuctionOutBid())
{
- //auction has already higher bid, client tests it!
+ // client already test it but just in case ...
+ SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_HIGHER_BID);
return;
}
if (!player->HasEnoughMoney(price))
{
- //you don't have enought money!, client tests!
- //SendAuctionCommandResult(auction->auctionId, AUCTION_PLACE_BID, ???);
+ // client already test it but just in case ...
+ SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_NOT_ENOUGHT_MONEY);
return;
}
@@ -433,16 +465,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
if (auction->bidder > 0)
{
if (auction->bidder == player->GetGUIDLow())
- player->ModifyMoney(-int32(price - auction->bid));
+ player->ModifyMoney(-int64(price - auction->bid));
else
{
// mail to last bidder and return money
sAuctionMgr->SendAuctionOutbiddedMail(auction, price, GetPlayer(), trans);
- player->ModifyMoney(-int32(price));
+ player->ModifyMoney(-int64(price));
}
}
else
- player->ModifyMoney(-int32(price));
+ player->ModifyMoney(-int64(price));
auction->bidder = player->GetGUIDLow();
auction->bid = price;
@@ -454,16 +486,16 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
stmt->setUInt32(2, auction->Id);
trans->Append(stmt);
- SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK, 0);
+ SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK);
}
else
{
//buyout:
if (player->GetGUIDLow() == auction->bidder)
- player->ModifyMoney(-int32(auction->buyout - auction->bid));
+ player->ModifyMoney(-int64(auction->buyout - auction->bid));
else
{
- player->ModifyMoney(-int32(auction->buyout));
+ player->ModifyMoney(-int64(auction->buyout));
if (auction->bidder) //buyout for bidded auction ..
sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans);
}
@@ -476,7 +508,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData)
sAuctionMgr->SendAuctionSuccessfulMail(auction, trans);
sAuctionMgr->SendAuctionWonMail(auction, trans);
- SendAuctionCommandResult(auction->Id, AUCTION_PLACE_BID, ERR_AUCTION_OK);
+ SendAuctionCommandResult(auction, AUCTION_PLACE_BID, ERR_AUCTION_OK);
auction->DeleteFromDB(trans);
@@ -497,7 +529,6 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData)
uint32 auctionId;
recvData >> auctioneer;
recvData >> auctionId;
- //TC_LOG_DEBUG("Cancel AUCTION AuctionID: %u", auctionId);
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
@@ -524,11 +555,10 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData)
if (auction->bidder > 0) // If we have a bidder, we have to send him the money he paid
{
uint32 auctionCut = auction->GetAuctionCut();
- if (!player->HasEnoughMoney(auctionCut)) //player doesn't have enough money, maybe message needed
+ if (!player->HasEnoughMoney((uint64)auctionCut)) //player doesn't have enough money, maybe message needed
return;
- //some auctionBidderNotification would be needed, but don't know that parts..
- sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans);
- player->ModifyMoney(-int32(auctionCut));
+ sAuctionMgr->SendAuctionCancelledToBidderMail(auction, trans, pItem);
+ player->ModifyMoney(-int64(auctionCut));
}
// item will deleted or added to received mail list
@@ -538,21 +568,21 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData)
}
else
{
- TC_LOG_ERROR("network", "Auction id: %u has non-existed item (item guid : %u)!!!", auction->Id, auction->itemGUIDLow);
- SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR);
+ TC_LOG_ERROR("network", "Auction id: %u got non existing item (item guid : %u)!", auction->Id, auction->itemGUIDLow);
+ SendAuctionCommandResult(NULL, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR);
return;
}
}
else
{
- SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR);
+ SendAuctionCommandResult(NULL, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR);
//this code isn't possible ... maybe there should be assert
- TC_LOG_ERROR("network", "CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", player->GetGUIDLow(), auctionId);
+ TC_LOG_ERROR("network", "CHEATER: %u tried to cancel auction (id: %u) of another player or auction is NULL", player->GetGUIDLow(), auctionId);
return;
}
//inform player, that auction is removed
- SendAuctionCommandResult(auction->Id, AUCTION_CANCEL, ERR_AUCTION_OK);
+ SendAuctionCommandResult(auction, AUCTION_CANCEL, ERR_AUCTION_OK);
// Now remove the auction
@@ -599,7 +629,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData)
WorldPacket data(SMSG_AUCTION_BIDDER_LIST_RESULT, (4+4+4));
Player* player = GetPlayer();
- data << (uint32) 0; //add 0 as count
+ data << uint32(0); //add 0 as count
uint32 count = 0;
uint32 totalcount = 0;
while (outbiddedCount > 0) //add all data, which client requires
@@ -618,7 +648,7 @@ void WorldSession::HandleAuctionListBidderItems(WorldPacket& recvData)
auctionHouse->BuildListBidderItems(data, player, count, totalcount);
data.put<uint32>(0, count); // add count to placeholder
data << totalcount;
- data << (uint32)300; //unk 2.3.0
+ data << uint32(300); //unk 2.3.0
SendPacket(&data);
}
@@ -647,15 +677,15 @@ void WorldSession::HandleAuctionListOwnerItems(WorldPacket& recvData)
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
WorldPacket data(SMSG_AUCTION_OWNER_LIST_RESULT, (4+4+4));
- data << (uint32) 0; // amount place holder
+ data << uint32(0); // amount place holder
uint32 count = 0;
uint32 totalcount = 0;
auctionHouse->BuildListOwnerItems(data, _player, count, totalcount);
data.put<uint32>(0, count);
- data << (uint32) totalcount;
- data << (uint32) 0;
+ data << uint32(totalcount);
+ data << uint32(0);
SendPacket(&data);
}
@@ -678,15 +708,11 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
recvData >> quality >> usable;
recvData.read_skip<uint8>(); // unk
+ recvData.read_skip<uint8>(); // unk
// this block looks like it uses some lame byte packing or similar...
- uint8 unkCnt;
- recvData >> unkCnt;
- for (uint8 i = 0; i < unkCnt; i++)
- {
- recvData.read_skip<uint8>();
+ for (uint8 i = 0; i < 15; i++)
recvData.read_skip<uint8>();
- }
Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_AUCTIONEER);
if (!creature)
@@ -701,13 +727,13 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
AuctionHouseObject* auctionHouse = sAuctionMgr->GetAuctionsMap(creature->getFaction());
- //TC_LOG_DEBUG("Auctionhouse search (GUID: %u TypeId: %u)",, list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
+ //TC_LOG_DEBUG("misc", "Auctionhouse search (GUID: %u TypeId: %u)",, list from: %u, searchedname: %s, levelmin: %u, levelmax: %u, auctionSlotID: %u, auctionMainCategory: %u, auctionSubCategory: %u, quality: %u, usable: %u",
// GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)), listfrom, searchedname.c_str(), levelmin, levelmax, auctionSlotID, auctionMainCategory, auctionSubCategory, quality, usable);
WorldPacket data(SMSG_AUCTION_LIST_RESULT, (4+4+4));
uint32 count = 0;
uint32 totalcount = 0;
- data << (uint32) 0;
+ data << uint32(0);
// converting string that we try to find to lower case
std::wstring wsearchedname;
@@ -722,8 +748,8 @@ void WorldSession::HandleAuctionListItems(WorldPacket& recvData)
count, totalcount);
data.put<uint32>(0, count);
- data << (uint32) totalcount;
- data << (uint32) 300; // unk 2.3.0 const?
+ data << uint32(totalcount);
+ data << uint32(300); //unk 2.3.0
SendPacket(&data);
}
@@ -741,7 +767,7 @@ void WorldSession::HandleAuctionListPendingSales(WorldPacket& recvData)
{
data << ""; // string
data << ""; // string
- data << uint32(0);
+ data << uint64(0);
data << uint32(0);
data << float(0);
}*/
diff --git a/src/server/game/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp
index 70b0d541e6c..5fafeea9991 100644
--- a/src/server/game/Handlers/AuthHandler.cpp
+++ b/src/server/game/Handlers/AuthHandler.cpp
@@ -19,20 +19,28 @@
#include "WorldSession.h"
#include "WorldPacket.h"
-void WorldSession::SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos)
+void WorldSession::SendAuthResponse(uint8 code, bool queued, uint32 queuePos)
{
- WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1 + (shortForm ? 0 : (4 + 1)));
- packet << uint8(code);
+ WorldPacket packet(SMSG_AUTH_RESPONSE, 1 /*bits*/ + 4 + 1 + 4 + 1 + 4 + 1 + 1 + (queued ? 4 : 0));
+ packet.WriteBit(queued);
+ if (queued)
+ packet.WriteBit(0);
+
+ packet.WriteBit(1); // has account info
+
+ packet.FlushBits();
+
+ // account info
packet << uint32(0); // BillingTimeRemaining
- packet << uint8(0); // BillingPlanFlags
+ packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, 3 - CATA; must be set in database manually for each account
+ packet << uint32(0);
+ packet << uint8(Expansion()); // Unknown, these two show the same
packet << uint32(0); // BillingTimeRested
- packet << uint8(Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account
+ packet << uint8(0); // BillingPlanFlags
- if (!shortForm)
- {
+ packet << uint8(code);
+ if (queued)
packet << uint32(queuePos); // Queue position
- packet << uint8(0); // Realm has a free character migration - bool
- }
SendPacket(&packet);
}
diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index 0dfe396b65a..f0b98f9cf6f 100644
--- a/src/server/game/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
@@ -66,23 +66,41 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData)
void WorldSession::SendBattleGroundList(uint64 guid, BattlegroundTypeId bgTypeId)
{
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId, 0);
+ sBattlegroundMgr->BuildBattlegroundListPacket(&data, guid, _player, bgTypeId);
SendPacket(&data);
}
void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
{
- uint64 guid;
uint32 bgTypeId_;
uint32 instanceId;
- uint8 joinAsGroup;
+ uint8 asGroup;
bool isPremade = false;
Group* grp = NULL;
-
- recvData >> guid; // battlemaster guid
- recvData >> bgTypeId_; // battleground type id (DBC id)
- recvData >> instanceId; // instance id, 0 if First Available selected
- recvData >> joinAsGroup; // join as group
+ ObjectGuid guid;
+
+ recvData >> instanceId; // Instance Id
+ guid[2] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ asGroup = recvData.ReadBit(); // As Group
+ guid[4] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[5]);
+ recvData.ReadByteSeq(guid[1]);
+
+ //extract from guid
+ bgTypeId_ = GUID_LOPART(guid);
if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
{
@@ -95,10 +113,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED);
return;
}
-
BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID: %u TypeId:%u)", GUID_LOPART(guid), GuidHigh2TypeId(GUID_HIPART(guid)));
+ //TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_JOIN Message from (GUID:"UI64FMTD" TypeId:%u)", guid, bgTypeId_);
// can do this, since it's battleground, not arena
BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, 0);
@@ -123,16 +140,15 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
if (!bracketEntry)
return;
- GroupJoinBattlegroundResult err;
+ GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE;
// check queue conditions
- if (!joinAsGroup)
+ if (!asGroup)
{
if (GetPlayer()->isUsingLfg())
{
- // player is using dungeon finder or raid finder
WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_LFG_CANT_USE_BATTLEGROUND);
GetPlayer()->GetSession()->SendPacket(&data);
return;
}
@@ -141,7 +157,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
if (!_player->CanJoinToBattleground(bg))
{
WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
_player->GetSession()->SendPacket(&data);
return;
}
@@ -150,7 +166,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
{
// player is already in random queue
WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_RANDOM_BG);
_player->GetSession()->SendPacket(&data);
return;
}
@@ -159,7 +175,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
{
// player is already in queue, can't start random queue
WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_IN_NON_RANDOM_BG);
_player->GetSession()->SendPacket(&data);
return;
}
@@ -173,33 +189,37 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
if (!_player->HasFreeBattlegroundQueueId())
{
WorldPacket data;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, ERR_BATTLEGROUND_TOO_MANY_QUEUES);
_player->GetSession()->SendPacket(&data);
return;
}
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
-
GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
+
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
- // already checked if queueSlot is valid, now just get it
uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
- WorldPacket data;
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0);
+ // add joined time data
+ _player->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
+
+ WorldPacket data; // send status packet (in queue)
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType);
SendPacket(&data);
+
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",
bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str());
}
else
{
grp = _player->GetGroup();
- // no group found, error
+
if (!grp)
return;
+
if (grp->GetLeaderGUID() != _player->GetGUID())
return;
+
err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, 0, bg->GetMaxPlayersPerTeam(), false, 0);
isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam());
@@ -207,7 +227,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
GroupQueueInfo* ginfo = NULL;
uint32 avgTime = 0;
- if (err > 0)
+ if (!err)
{
TC_LOG_DEBUG("bg.battleground", "Battleground: the following players are joining as group:");
ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0);
@@ -220,11 +240,10 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
if (!member)
continue; // this should never happen
- WorldPacket data;
-
- if (err <= 0)
+ if (err)
{
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
+ WorldPacket data;
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err);
member->GetSession()->SendPacket(&data);
continue;
}
@@ -232,65 +251,107 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData)
// add to queue
uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0);
- member->GetSession()->SendPacket(&data);
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
+ // add joined time data
+ member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
+
+ WorldPacket data; // send status packet (in queue)
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, ginfo->ArenaType);
member->GetSession()->SendPacket(&data);
TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",
bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str());
}
TC_LOG_DEBUG("bg.battleground", "Battleground: group end");
}
+
sBattlegroundMgr->ScheduleQueueUpdate(0, 0, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvData*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd MSG_BATTLEGROUND_PLAYER_POSITIONS Message");
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEGROUND_PLAYER_POSITIONS Message");
Battleground* bg = _player->GetBattleground();
if (!bg) // can't be received if player not in battleground
return;
- uint32 flagCarrierCount = 0;
- Player* allianceFlagCarrier = NULL;
- Player* hordeFlagCarrier = NULL;
+ uint32 acount = 0;
+ uint32 hcount = 0;
+ Player* aplr = NULL;
+ Player* hplr = NULL;
if (uint64 guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE))
{
- allianceFlagCarrier = ObjectAccessor::FindPlayer(guid);
- if (allianceFlagCarrier)
- ++flagCarrierCount;
+ aplr = ObjectAccessor::FindPlayer(guid);
+ if (aplr)
+ ++acount;
}
if (uint64 guid = bg->GetFlagPickerGUID(TEAM_HORDE))
{
- hordeFlagCarrier = ObjectAccessor::FindPlayer(guid);
- if (hordeFlagCarrier)
- ++flagCarrierCount;
+ hplr = ObjectAccessor::FindPlayer(guid);
+ if (hplr)
+ ++hcount;
}
- WorldPacket data(MSG_BATTLEGROUND_PLAYER_POSITIONS, 4 + 4 + 16 * flagCarrierCount);
- // Used to send several player positions (found used in AV)
- data << 0; // CGBattlefieldInfo__m_numPlayerPositions
- /*
- for (CGBattlefieldInfo__m_numPlayerPositions)
- data << guid << posx << posy;
- */
- data << flagCarrierCount;
- if (allianceFlagCarrier)
+ ObjectGuid aguid = aplr ? aplr->GetGUID() : 0;
+ ObjectGuid hguid = hplr ? hplr->GetGUID() : 0;
+
+ WorldPacket data(SMSG_BATTLEFIELD_PLAYER_POSITIONS);
+
+ data.WriteBits(acount, 22);
+ for (uint8 i = 0; i < acount; i++)
+ {
+ data.WriteBit(aguid[3]);
+ data.WriteBit(aguid[5]);
+ data.WriteBit(aguid[1]);
+ data.WriteBit(aguid[6]);
+ data.WriteBit(aguid[7]);
+ data.WriteBit(aguid[0]);
+ data.WriteBit(aguid[2]);
+ data.WriteBit(aguid[4]);
+ }
+
+ data.WriteBits(hcount, 22);
+ for (uint8 i = 0; i < hcount; i++)
+ {
+ data.WriteBit(hguid[6]);
+ data.WriteBit(hguid[5]);
+ data.WriteBit(hguid[4]);
+ data.WriteBit(hguid[7]);
+ data.WriteBit(hguid[2]);
+ data.WriteBit(hguid[1]);
+ data.WriteBit(hguid[0]);
+ data.WriteBit(hguid[3]);
+ }
+
+ data.FlushBits();
+
+ for (uint8 i = 0; i < hcount; i++)
{
- data << uint64(allianceFlagCarrier->GetGUID());
- data << float(allianceFlagCarrier->GetPositionX());
- data << float(allianceFlagCarrier->GetPositionY());
+ data.WriteByteSeq(hguid[2]);
+ data.WriteByteSeq(hguid[1]);
+ data << float(hplr->GetPositionY());
+ data.WriteByteSeq(hguid[5]);
+ data.WriteByteSeq(hguid[4]);
+ data.WriteByteSeq(hguid[7]);
+ data.WriteByteSeq(hguid[0]);
+ data.WriteByteSeq(hguid[6]);
+ data.WriteByteSeq(hguid[3]);
+ data << float(hplr->GetPositionX());
}
- if (hordeFlagCarrier)
+ for (uint8 i = 0; i < acount; i++)
{
- data << uint64(hordeFlagCarrier->GetGUID());
- data << float(hordeFlagCarrier->GetPositionX());
- data << float(hordeFlagCarrier->GetPositionY());
+ data.WriteByteSeq(aguid[6]);
+ data << float(aplr->GetPositionX());
+ data.WriteByteSeq(aguid[5]);
+ data.WriteByteSeq(aguid[3]);
+ data << float(aplr->GetPositionY());
+ data.WriteByteSeq(aguid[1]);
+ data.WriteByteSeq(aguid[7]);
+ data.WriteByteSeq(aguid[0]);
+ data.WriteByteSeq(aguid[2]);
+ data.WriteByteSeq(aguid[4]);
}
SendPacket(&data);
@@ -298,7 +359,7 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa
void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd MSG_PVP_LOG_DATA Message");
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_PVP_LOG_DATA Message");
Battleground* bg = _player->GetBattleground();
if (!bg)
@@ -312,22 +373,16 @@ void WorldSession::HandlePVPLogDataOpcode(WorldPacket & /*recvData*/)
sBattlegroundMgr->BuildPvpLogDataPacket(&data, bg);
SendPacket(&data);
- TC_LOG_DEBUG("network", "WORLD: Sent MSG_PVP_LOG_DATA Message");
+ TC_LOG_DEBUG("network", "WORLD: Sent SMSG_PVP_LOG_DATA Message");
}
-void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData)
+void WorldSession::HandleBattlefieldListOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LIST Message");
uint32 bgTypeId;
recvData >> bgTypeId; // id from DBC
- uint8 fromWhere;
- recvData >> fromWhere; // 0 - battlemaster (lua: ShowBattlefieldList), 1 - UI (lua: RequestBattlegroundInstanceInfo)
-
- uint8 canGainXP;
- recvData >> canGainXP; // players with locked xp have their own bg queue on retail
-
BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId);
if (!bl)
{
@@ -336,60 +391,87 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData)
}
WorldPacket data;
- sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId), fromWhere);
+ sBattlegroundMgr->BuildBattlegroundListPacket(&data, 0, _player, BattlegroundTypeId(bgTypeId));
SendPacket(&data);
}
void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
{
- uint8 type; // arenatype if arena
- uint8 unk2; // unk, can be 0x0 (may be if was invited?) and 0x1
- uint32 bgTypeId_; // type id from dbc
- uint16 unk; // 0x1F90 constant?
- uint8 action; // enter battle 0x1, leave queue 0x0
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_PORT Message");
+
+ uint32 time;
+ uint32 queueSlot;
+ uint32 unk;
+ uint8 action; // enter battle 0x1, leave queue 0x0
+ ObjectGuid guid;
+
+ recvData >> time;
+ recvData >> queueSlot;
+ recvData >> unk;
+
+ guid[0] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[2] = recvData.ReadBit();
+
+ action = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[5]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[4]);
- recvData >> type >> unk2 >> bgTypeId_ >> unk >> action;
- if (!sBattlemasterListStore.LookupEntry(bgTypeId_))
+ if (!_player->InBattlegroundQueue())
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Invalid BgType!",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue!",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action);
return;
}
- if (!_player->InBattlegroundQueue())
+ BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(queueSlot);
+ if (bgQueueTypeId == BATTLEGROUND_QUEUE_NONE)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player not in queue!",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Invalid queueSlot!",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action);
return;
}
- //get GroupQueueInfo from BattlegroundQueue
- BattlegroundTypeId bgTypeId = BattlegroundTypeId(bgTypeId_);
- BattlegroundQueueTypeId bgQueueTypeId = BattlegroundMgr::BGQueueTypeId(bgTypeId, type);
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
+
//we must use temporary variable, because GroupQueueInfo pointer can be deleted in BattlegroundQueue::RemovePlayer() function
GroupQueueInfo ginfo;
if (!bgQueue.GetPlayerGroupInfoData(_player->GetGUID(), &ginfo))
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player not in queue (No player Group Info)!",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player not in queue (No player Group Info)!",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action);
return;
}
// if action == 1, then instanceId is required
if (!ginfo.IsInvitedToBGInstanceGUID && action == 1)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Player is not invited to any bg!",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Player is not invited to any bg!",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action);
return;
}
- Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
+ BattlegroundTypeId bgTypeId = BattlegroundMgr::BGTemplateId(bgQueueTypeId);
+ // BGTemplateId returns BATTLEGROUND_AA when it is arena queue.
+ // Do instance id search as there is no AA bg instances.
+ Battleground* bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId == BATTLEGROUND_AA ? BATTLEGROUND_TYPE_NONE : bgTypeId);
if (!bg)
{
if (action)
{
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u. Cant find BG with id %u!",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action, ginfo.IsInvitedToBGInstanceGUID);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u. Cant find BG with id %u!",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action, ginfo.IsInvitedToBGInstanceGUID);
return;
}
@@ -401,8 +483,11 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
}
}
- TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s ArenaType: %u, Unk: %u, BgType: %u, Action: %u.",
- GetPlayerInfo().c_str(), type, unk2, bgTypeId_, action);
+ TC_LOG_DEBUG("bg.battleground", "CMSG_BATTLEFIELD_PORT %s Slot: %u, Unk: %u, Time: %u, Action: %u.",
+ GetPlayerInfo().c_str(), queueSlot, unk, time, action);
+
+ // get real bg type
+ bgTypeId = bg->GetTypeID();
// expected bracket entry
PvPDifficultyEntry const* bracketEntry = GetBattlegroundBracketByLevel(bg->GetMapId(), _player->getLevel());
@@ -417,7 +502,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
{
//send bg command result to show nice message
WorldPacket data2;
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
+ sBattlegroundMgr->BuildStatusFailedPacket(&data2, bg, _player, 0, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS);
_player->GetSession()->SendPacket(&data2);
action = 0;
TC_LOG_DEBUG("bg.battleground", "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow());
@@ -425,12 +510,12 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
//if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue
if (_player->getLevel() > bg->GetMaxLevel())
{
- TC_LOG_ERROR("network", "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
+ TC_LOG_DEBUG("network", "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!",
_player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID());
action = 0;
}
}
- uint32 queueSlot = _player->GetBattlegroundQueueIndex(bgQueueTypeId);
+
WorldPacket data;
if (action)
{
@@ -453,7 +538,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
_player->CleanupAfterTaxiFlight();
}
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), bg->GetArenaType());
_player->GetSession()->SendPacket(&data);
// remove battleground queue status from BGmgr
@@ -476,9 +561,6 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
}
else // leave queue
{
- if (bg->isArena() && bg->GetStatus() > STATUS_WAIT_QUEUE)
- return;
-
// if player leaves rated arena match before match start, it is counted as he played but he lost
if (ginfo.IsRated && ginfo.IsInvitedToBGInstanceGUID)
{
@@ -490,25 +572,22 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData)
at->SaveToDB();
}
}
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, _player, queueSlot, STATUS_NONE, _player->GetBattlegroundQueueJoinTime(bgTypeId), 0, 0);
+ SendPacket(&data);
+
_player->RemoveBattlegroundQueueId(bgQueueTypeId); // must be called this way, because if you move this call to queue->removeplayer, it causes bugs
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0);
bgQueue.RemovePlayer(_player->GetGUID(), true);
// player left queue, we should update it - do not update Arena Queue
if (!ginfo.ArenaType)
sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
- SendPacket(&data);
+
TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId);
}
}
-void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData)
+void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& /*recvData*/)
{
- TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_LEAVE_BATTLEFIELD Message");
-
- recvData.read_skip<uint8>(); // unk1
- recvData.read_skip<uint8>(); // unk2
- recvData.read_skip<uint32>(); // BattlegroundTypeId
- recvData.read_skip<uint16>(); // unk3
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_LEAVE Message");
// not allow leave battleground in combat
if (_player->IsInCombat())
@@ -522,7 +601,7 @@ void WorldSession::HandleBattlefieldLeaveOpcode(WorldPacket& recvData)
void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
{
// empty opcode
- TC_LOG_DEBUG("network", "WORLD: Battleground status");
+ TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEFIELD_STATUS Message");
WorldPacket data;
// we must update all queues here
@@ -541,13 +620,14 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
//so i must use bg pointer to get that information
if (bg && bg->GetArenaType() == arenaType)
{
- // this line is checked, i only don't know if GetStartTime is changing itself after bg end!
+ // this line is checked, i only don't know if GetElapsedTime() is changing itself after bg end!
// send status in Battleground
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_IN_PROGRESS, bg->GetEndTime(), bg->GetStartTime(), arenaType, _player->GetBGTeam());
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_IN_PROGRESS, _player->GetBattlegroundQueueJoinTime(bgTypeId), bg->GetElapsedTime(), arenaType);
SendPacket(&data);
continue;
}
}
+
//we are sending update to player about queue - he can be invited there!
//get GroupQueueInfo for queue status
BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
@@ -559,9 +639,9 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
bg = sBattlegroundMgr->GetBattleground(ginfo.IsInvitedToBGInstanceGUID, bgTypeId);
if (!bg)
continue;
- uint32 remainingTime = getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime);
+
// send status invited to Battleground
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_JOIN, remainingTime, 0, arenaType, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_JOIN, getMSTimeDiff(getMSTime(), ginfo.RemoveInviteTime), _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType);
SendPacket(&data);
}
else
@@ -577,7 +657,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/)
uint32 avgTime = bgQueue.GetAverageQueueWaitTime(&ginfo, bracketEntry->GetBracketId());
// send status in Battleground Queue
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, i, STATUS_WAIT_QUEUE, avgTime, getMSTimeDiff(ginfo.JoinTime, getMSTime()), arenaType, 0);
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, GetPlayer(), i, STATUS_WAIT_QUEUE, avgTime, _player->GetBattlegroundQueueJoinTime(bgTypeId), arenaType);
SendPacket(&data);
}
}
@@ -587,44 +667,18 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_BATTLEMASTER_JOIN_ARENA");
- uint64 guid; // arena Battlemaster guid
uint8 arenaslot; // 2v2, 3v3 or 5v5
- uint8 asGroup; // asGroup
- uint8 isRated; // isRated
- Group* grp = NULL;
- recvData >> guid >> arenaslot >> asGroup >> isRated;
+ recvData >> arenaslot;
// ignore if we already in BG or BG queue
if (_player->InBattleground())
return;
- Creature* unit = GetPlayer()->GetMap()->GetCreature(guid);
- if (!unit)
- return;
-
- if (!unit->IsBattleMaster()) // it's not battle master
- return;
-
- uint8 arenatype = 0;
uint32 arenaRating = 0;
uint32 matchmakerRating = 0;
- switch (arenaslot)
- {
- case 0:
- arenatype = ARENA_TYPE_2v2;
- break;
- case 1:
- arenatype = ARENA_TYPE_3v3;
- break;
- case 2:
- arenatype = ARENA_TYPE_5v5;
- break;
- default:
- TC_LOG_ERROR("network", "Unknown arena slot %u at HandleBattlemasterJoinArena()", arenaslot);
- return;
- }
+ uint8 arenatype = ArenaTeam::GetTypeBySlot(arenaslot);
//check existance
Battleground* bg = sBattlegroundMgr->GetBattlegroundTemplate(BATTLEGROUND_AA);
@@ -646,108 +700,73 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData)
if (!bracketEntry)
return;
- GroupJoinBattlegroundResult err = ERR_GROUP_JOIN_BATTLEGROUND_FAIL;
+ GroupJoinBattlegroundResult err = ERR_BATTLEGROUND_NONE;
- if (!asGroup)
- {
- // check if already in queue
- if (_player->GetBattlegroundQueueIndex(bgQueueTypeId) < PLAYER_MAX_BATTLEGROUND_QUEUES)
- //player is already in this queue
- return;
- // check if has free queue slots
- if (!_player->HasFreeBattlegroundQueueId())
- return;
- }
- else
+ Group* grp = _player->GetGroup();
+ // no group found, error
+ if (!grp)
+ return;
+ if (grp->GetLeaderGUID() != _player->GetGUID())
+ return;
+
+ uint32 ateamId = _player->GetArenaTeamId(arenaslot);
+ // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
+ ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
+ if (!at)
{
- grp = _player->GetGroup();
- // no group found, error
- if (!grp)
- return;
- if (grp->GetLeaderGUID() != _player->GetGUID())
- return;
- err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, (bool)isRated, arenaslot);
+ _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
+ return;
}
- uint32 ateamId = 0;
+ // get the team rating for queueing
+ arenaRating = at->GetRating();
+ matchmakerRating = at->GetAverageMMR(grp);
+ // the arenateam id must match for everyone in the group
+
+ if (arenaRating <= 0)
+ arenaRating = 1;
+
+ BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
- if (isRated)
+ uint32 avgTime = 0;
+ GroupQueueInfo* ginfo = NULL;
+
+ err = grp->CanJoinBattlegroundQueue(bg, bgQueueTypeId, arenatype, arenatype, true, arenaslot);
+ if (!err)
{
- ateamId = _player->GetArenaTeamId(arenaslot);
- // check real arenateam existence only here (if it was moved to group->CanJoin .. () then we would ahve to get it twice)
- ArenaTeam* at = sArenaTeamMgr->GetArenaTeamById(ateamId);
- if (!at)
- {
- _player->GetSession()->SendNotInArenaTeamPacket(arenatype);
- return;
- }
- // get the team rating for queueing
- arenaRating = at->GetRating();
- matchmakerRating = at->GetAverageMMR(grp);
- // the arenateam id must match for everyone in the group
+ TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype);
- if (arenaRating <= 0)
- arenaRating = 1;
+ ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, true, false, arenaRating, matchmakerRating, ateamId);
+ avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
}
- BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId);
- if (asGroup)
+ for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
{
- uint32 avgTime = 0;
+ Player* member = itr->GetSource();
+ if (!member)
+ continue;
- if (err > 0)
+ if (err)
{
- TC_LOG_DEBUG("bg.battleground", "Battleground: arena join as group start");
- if (isRated)
- {
- TC_LOG_DEBUG("bg.battleground", "Battleground: arena team id %u, leader %s queued with matchmaker rating %u for type %u", _player->GetArenaTeamId(arenaslot), _player->GetName().c_str(), matchmakerRating, arenatype);
- bg->SetRated(true);
- }
- else
- bg->SetRated(false);
-
- GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, grp, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId);
- avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
+ WorldPacket data;
+ sBattlegroundMgr->BuildStatusFailedPacket(&data, bg, _player, 0, err);
+ member->GetSession()->SendPacket(&data);
+ continue;
}
- for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- Player* member = itr->GetSource();
- if (!member)
- continue;
-
- WorldPacket data;
+ // add to queue
+ uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
- if (err <= 0)
- {
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->GetSession()->SendPacket(&data);
- continue;
- }
+ // add joined time data
+ member->AddBattlegroundQueueJoinTime(bgTypeId, ginfo->JoinTime);
- // add to queue
- uint32 queueSlot = member->AddBattlegroundQueueId(bgQueueTypeId);
+ WorldPacket data; // send status packet (in queue)
+ sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, member, queueSlot, STATUS_WAIT_QUEUE, avgTime, ginfo->JoinTime, arenatype);
+ member->GetSession()->SendPacket(&data);
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0);
- member->GetSession()->SendPacket(&data);
- sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err);
- member->GetSession()->SendPacket(&data);
- TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str());
- }
+ TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str());
}
- else
- {
- GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated, false, arenaRating, matchmakerRating, ateamId);
- uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId());
- uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId);
- WorldPacket data;
- // send status packet (in queue)
- sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0);
- SendPacket(&data);
- TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str());
- }
sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId());
}
@@ -767,3 +786,78 @@ void WorldSession::HandleReportPvPAFK(WorldPacket& recvData)
reportedPlayer->ReportedAfkBy(_player);
}
+
+void WorldSession::HandleRequestRatedBgInfo(WorldPacket & recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_RATED_BG_INFO");
+
+ uint8 unk;
+ recvData >> unk;
+
+ TC_LOG_DEBUG("bg.battleground", "WorldSession::HandleRequestRatedBgInfo: unk = %u", unk);
+
+ /// @Todo: perfome research in this case
+ /// The unk fields are related to arenas
+ WorldPacket data(SMSG_RATED_BG_STATS, 72);
+ data << uint32(0); // BgWeeklyWins20vs20
+ data << uint32(0); // BgWeeklyPlayed20vs20
+ data << uint32(0); // BgWeeklyPlayed15vs15
+ data << uint32(0);
+ data << uint32(0); // BgWeeklyWins10vs10
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0); // BgWeeklyWins15vs15
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0);
+ data << uint32(0); // BgWeeklyPlayed10vs10
+ data << uint32(0);
+ data << uint32(0);
+
+ SendPacket(&data);
+}
+
+void WorldSession::HandleRequestPvpOptions(WorldPacket& /*recvData*/)
+{
+ TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_PVP_OPTIONS_ENABLED");
+
+ /// @Todo: perfome research in this case
+ WorldPacket data(SMSG_PVP_OPTIONS_ENABLED, 1);
+ data.WriteBit(1);
+ data.WriteBit(1); // WargamesEnabled
+ data.WriteBit(1);
+ data.WriteBit(1); // RatedBGsEnabled
+ data.WriteBit(1); // RatedArenasEnabled
+
+ data.FlushBits();
+
+ SendPacket(&data);
+}
+
+void WorldSession::HandleRequestPvpReward(WorldPacket& /*recvData*/)
+{
+ TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_PVP_REWARDS");
+
+ _player->SendPvpRewards();
+}
+
+void WorldSession::HandleRequestRatedBgStats(WorldPacket& /*recvData*/)
+{
+ TC_LOG_DEBUG("network", "WORLD: CMSG_REQUEST_RATED_BG_STATS");
+
+ WorldPacket data(SMSG_BATTLEFIELD_RATED_INFO, 29);
+ data << uint32(0); // Reward
+ data << uint8(3); // unk
+ data << uint32(0); // unk
+ data << uint32(0); // unk
+ data << _player->GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, true);
+ data << uint32(0); // unk
+ data << uint32(0); // unk
+ data << _player->GetCurrency(CURRENCY_TYPE_CONQUEST_POINTS, true);
+
+ SendPacket(&data);
+}
diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp
index b0580681f91..632cf83cd8f 100644
--- a/src/server/game/Handlers/BattlefieldHandler.cpp
+++ b/src/server/game/Handlers/BattlefieldHandler.cpp
@@ -21,96 +21,223 @@
#include "Player.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "Object.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
/**
- * @fn void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 acceptTime)
+ * @fn void WorldSession::SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 acceptTime)
*
* @brief This send to player windows for invite player to join the war.
*
- * @param battleId The BattleId of Bf
+ * @param guid The guid of Bf
* @param zoneId The zone where the battle is (4197 for wg)
* @param acceptTime Time in second that the player have for accept
*/
-void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 acceptTime)
+void WorldSession::SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 acceptTime)
{
- WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 12);
- data << uint32(battleId);
- data << uint32(zoneId);
- data << uint32(time(NULL) + acceptTime);
+ ObjectGuid guidBytes = guid;
+
+ WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 16);
+
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[0]);
+
+ data.WriteByteSeq(guidBytes[6]);
+ data << uint32(zoneId); // Zone Id
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[0]);
+ data << uint32(time(NULL) + acceptTime); // Invite lasts until
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[5]);
SendPacket(&data);
}
/**
- * @fn void WorldSession::SendBfInvitePlayerToQueue(uint32 battleId)
+ * @fn void WorldSession::SendBfInvitePlayerToQueue(uint64 guid)
*
* @brief This send invitation to player to join the queue.
*
- * @param battleId The BattleId of Bf
+ * @param guid The guid of Bf
*/
-void WorldSession::SendBfInvitePlayerToQueue(uint32 battleId)
+void WorldSession::SendBfInvitePlayerToQueue(uint64 guid)
{
+ ObjectGuid guidBytes = guid;
+
WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, 5);
- data << uint32(battleId);
- data << uint8(1); // warmup ? used ?
+
+ data.WriteBit(1); // unk
+ data.WriteBit(0); // Has Warmup
+ data.WriteBit(1); // unk
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(1); // unk
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(1); // unk
+ data.WriteBit(0); // unk
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(1); // unk
+ data.WriteBit(guidBytes[7]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[6]);
+ data << uint8(1); // Warmup
+ data.WriteByteSeq(guidBytes[5]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[7]);
SendPacket(&data);
}
/**
- * @fn void WorldSession::SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue, bool full)
+ * @fn void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 zoneId, bool canQueue, bool full)
*
* @brief This send packet for inform player that he join queue.
*
- * @param battleId The BattleId of Bf
+ * @param guid The guid of Bf
* @param zoneId The zone where the battle is (4197 for wg)
* @param canQueue if able to queue
* @param full on log in is full
*/
-void WorldSession::SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue, bool full)
+void WorldSession::SendBfQueueInviteResponse(uint64 guid, uint32 zoneId, bool canQueue, bool full)
{
- WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 11);
- data << uint32(battleId);
+ const bool hasSecondGuid = false;
+ const bool warmup = true;
+ ObjectGuid guidBytes = guid;
+
+ WorldPacket data(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, 16);
+
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(full); // Logging In, VERIFYME
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(!hasSecondGuid);
+ data.WriteBit(guidBytes[4]);
+
+ // if (hasSecondGuid) 7 3 0 4 2 6 1 5
+
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[2]);
+
+ // if (hasSecondGuid) 2 5 3 0 4 6 1 7
+
+ data.FlushBits();
+
+ data << uint8(canQueue); // Accepted
+
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[6]);
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[0]);
+
+ data << uint8(warmup);
+
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[5]);
+
data << uint32(zoneId);
- data << uint8(canQueue ? 1 : 0); // Accepted // 0 you cannot queue wg // 1 you are queued
- data << uint8(full ? 0 : 1); // Logging In // 0 wg full // 1 queue for upcoming
- data << uint8(1); // Warmup
+
SendPacket(&data);
}
/**
- * @fn void WorldSession::SendBfEntered(uint32 battleId)
+ * @fn void WorldSession::SendBfEntered(uint64 guid)
*
* @brief This is call when player accept to join war.
*
- * @param battleId The BattleId of Bf
+ * @param guid The guid of Bf
*/
-void WorldSession::SendBfEntered(uint32 battleId)
+void WorldSession::SendBfEntered(uint64 guid)
{
- WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 7);
- data << uint32(battleId);
- data << uint8(1); // unk
- data << uint8(1); // unk
- data << uint8(_player->isAFK() ? 1 : 0); // Clear AFK
+ uint8 isAFK = _player->isAFK() ? 1 : 0;
+ ObjectGuid guidBytes = guid;
+
+ WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTERED, 11);
+
+ data.WriteBit(0); // unk
+ data.WriteBit(isAFK); // Clear AFK
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[4]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(0); // unk
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[2]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(guidBytes[5]);
+ data.WriteByteSeq(guidBytes[3]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[6]);
+
SendPacket(&data);
}
/**
- * @fn void WorldSession::SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason)
+ * @fn void WorldSession::SendBfLeaveMessage(uint64 guid, BFLeaveReason reason)
*
* @brief This is call when player leave battlefield zone.
*
- * @param battleId The BattleId of Bf
+ * @param guid The guid of Bf
* @param reason Reason why player left battlefield
*/
-void WorldSession::SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason /*= BF_LEAVE_REASON_EXITED*/)
+void WorldSession::SendBfLeaveMessage(uint64 guid, BFLeaveReason reason /*= BF_LEAVE_REASON_EXITED*/)
{
- WorldPacket data(SMSG_BATTLEFIELD_MGR_EJECTED, 7);
- data << uint32(battleId);
- data << uint8(reason); // byte Reason
- data << uint8(2); // byte BattleStatus
- data << uint8(0); // bool Relocated
+ ObjectGuid guidBytes = guid;
+
+ WorldPacket data(SMSG_BATTLEFIELD_MGR_EJECTED, 11);
+
+ data.WriteBit(guidBytes[2]);
+ data.WriteBit(guidBytes[5]);
+ data.WriteBit(guidBytes[1]);
+ data.WriteBit(guidBytes[0]);
+ data.WriteBit(guidBytes[3]);
+ data.WriteBit(guidBytes[6]);
+ data.WriteBit(0); // Relocated
+ data.WriteBit(guidBytes[7]);
+ data.WriteBit(guidBytes[4]);
+
+ data.FlushBits();
+
+ data << uint8(2); // BattleStatus
+ data.WriteByteSeq(guidBytes[1]);
+ data.WriteByteSeq(guidBytes[7]);
+ data.WriteByteSeq(guidBytes[4]);
+ data.WriteByteSeq(guidBytes[2]);
+ data.WriteByteSeq(guidBytes[3]);
+ data << uint8(reason); // Reason
+ data.WriteByteSeq(guidBytes[6]);
+ data.WriteByteSeq(guidBytes[0]);
+ data.WriteByteSeq(guidBytes[5]);
+
SendPacket(&data);
}
@@ -121,14 +248,31 @@ void WorldSession::SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason /*=
*/
void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData)
{
- uint32 battleId;
uint8 accepted;
+ ObjectGuid guid;
+
+ guid[2] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ accepted = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
- recvData >> battleId >> accepted;
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[5]);
- TC_LOG_DEBUG("misc", "HandleBfQueueInviteResponse: BattleID:%u Accepted:%u", battleId, accepted);
+ TC_LOG_ERROR("misc", "HandleQueueInviteResponse: GUID: " UI64FMTD ", accepted: %u", uint64(guid), accepted);
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
if (!bf)
return;
@@ -143,14 +287,31 @@ void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData)
*/
void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData)
{
- uint32 battleId;
uint8 accepted;
+ ObjectGuid guid;
- recvData >> battleId >> accepted;
+ guid[6] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ accepted = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[2] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
- TC_LOG_DEBUG("misc", "HandleBfEntryInviteResponse: battleId: %u, accepted: %u", battleId, accepted);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[5]);
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
+ TC_LOG_ERROR("misc", "HandleBattlefieldInviteResponse: GUID: " UI64FMTD ", accepted: %u", uint64(guid), accepted);
+
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
if (!bf)
return;
@@ -173,13 +334,29 @@ void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData)
*/
void WorldSession::HandleBfExitRequest(WorldPacket& recvData)
{
- uint32 battleId;
+ ObjectGuid guid;
+
+ guid[2] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
- recvData >> battleId;
+ recvData.ReadByteSeq(guid[5]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[6]);
- TC_LOG_DEBUG("misc", "HandleBfExitRequest: battleId: %u ", battleId);
+ TC_LOG_ERROR("misc", "HandleBfExitRequest: GUID: " UI64FMTD, uint64(guid));
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByBattleId(battleId);
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
if (!bf)
return;
diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index 45d4d221d06..89e09484458 100644
--- a/src/server/game/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
@@ -90,6 +90,10 @@ void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/)
data.AppendPackedTime(calendarEvent->GetEventTime());
data << uint32(calendarEvent->GetFlags());
data << int32(calendarEvent->GetDungeonId());
+
+ Guild* guild = sGuildMgr->GetGuildById(calendarEvent->GetGuildId());
+ data << uint64(guild ? guild->GetGUID() : 0);
+
data.appendPackGUID(calendarEvent->GetCreatorGUID());
}
@@ -615,10 +619,11 @@ void WorldSession::HandleCalendarComplain(WorldPacket& recvData)
uint64 guid = _player->GetGUID();
uint64 eventId;
uint64 complainGUID;
+ uint64 inviteId;
- recvData >> eventId >> complainGUID;
+ recvData >> complainGUID >> eventId >> inviteId;
TC_LOG_DEBUG("network", "CMSG_CALENDAR_COMPLAIN [" UI64FMTD "] EventId ["
- UI64FMTD "] guid [" UI64FMTD "]", guid, eventId, complainGUID);
+ UI64FMTD "] guid [" UI64FMTD "] InviteId [" UI64FMTD "]", guid, eventId, complainGUID, inviteId);
// what to do with complains?
}
diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp
index c95eadc7d90..0ab5a8ab811 100644
--- a/src/server/game/Handlers/ChannelHandler.cpp
+++ b/src/server/game/Handlers/ChannelHandler.cpp
@@ -19,14 +19,21 @@
#include "ObjectMgr.h" // for normalizePlayerName
#include "ChannelMgr.h"
#include "Player.h"
+#include "WorldSession.h"
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
{
uint32 channelId;
- uint8 unknown1, unknown2;
+ uint32 channelLength, passLength;
std::string channelName, password;
- recvPacket >> channelId >> unknown1 >> unknown2 >> channelName >> password;
+ 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());
@@ -57,7 +64,9 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
{
uint32 unk;
std::string channelName;
- recvPacket >> unk >> channelName;
+ recvPacket >> unk; // channel id?
+ uint32 length = recvPacket.ReadBits(8);
+ channelName = recvPacket.ReadString(length);
TC_LOG_DEBUG("chat.system", "CMSG_LEAVE_CHANNEL %s Channel: %s, unk1: %u",
GetPlayerInfo().c_str(), channelName.c_str(), unk);
@@ -75,8 +84,8 @@ void WorldSession::HandleLeaveChannel(WorldPacket& recvPacket)
void WorldSession::HandleChannelList(WorldPacket& recvPacket)
{
- std::string channelName;
- recvPacket >> channelName;
+ 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",
@@ -89,8 +98,11 @@ void WorldSession::HandleChannelList(WorldPacket& recvPacket)
void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
{
- std::string channelName, password;
- recvPacket >> channelName >> password;
+ uint32 nameLength = recvPacket.ReadBits(8);
+ uint32 passLength = recvPacket.ReadBits(7);
+
+ std::string channelName = recvPacket.ReadString(nameLength);
+ std::string password = recvPacket.ReadString(passLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_PASSWORD %s Channel: %s, Password: %s",
GetPlayerInfo().c_str(), channelName.c_str(), password.c_str());
@@ -102,8 +114,11 @@ void WorldSession::HandleChannelPassword(WorldPacket& recvPacket)
void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 channelLength = recvPacket.ReadBits(8);
+ uint32 nameLength = recvPacket.ReadBits(7);
+
+ std::string targetName = recvPacket.ReadString(nameLength);
+ std::string channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_SET_OWNER %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -118,8 +133,8 @@ void WorldSession::HandleChannelSetOwner(WorldPacket& recvPacket)
void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
{
- std::string channelName;
- recvPacket >> channelName;
+ uint32 length = recvPacket.ReadBits(8);
+ std::string channelName = recvPacket.ReadString(length);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_OWNER %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
@@ -131,8 +146,11 @@ void WorldSession::HandleChannelOwner(WorldPacket& recvPacket)
void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 channelLength = recvPacket.ReadBits(8);
+ uint32 nameLength = recvPacket.ReadBits(7);
+
+ std::string targetName = recvPacket.ReadString(nameLength);
+ std::string channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_MODERATOR %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -147,8 +165,11 @@ void WorldSession::HandleChannelModerator(WorldPacket& recvPacket)
void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 nameLength = recvPacket.ReadBits(7);
+ uint32 channelLength = recvPacket.ReadBits(8);
+
+ std::string channelName = recvPacket.ReadString(channelLength);
+ std::string targetName = recvPacket.ReadString(nameLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMODERATOR %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -163,8 +184,11 @@ void WorldSession::HandleChannelUnmoderator(WorldPacket& recvPacket)
void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 channelLength = recvPacket.ReadBits(8);
+ uint32 nameLength = recvPacket.ReadBits(7);
+
+ std::string channelName = recvPacket.ReadString(channelLength);
+ std::string targetName = recvPacket.ReadString(nameLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_MUTE %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -179,8 +203,11 @@ void WorldSession::HandleChannelMute(WorldPacket& recvPacket)
void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 nameLength = recvPacket.ReadBits(8);
+ uint32 channelLength = recvPacket.ReadBits(7);
+
+ std::string targetName = recvPacket.ReadString(nameLength);
+ std::string channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNMUTE %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -195,8 +222,11 @@ void WorldSession::HandleChannelUnmute(WorldPacket& recvPacket)
void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 nameLength = recvPacket.ReadBits(7);
+ uint32 channelLength = recvPacket.ReadBits(8);
+
+ std::string targetName = recvPacket.ReadString(nameLength);
+ std::string channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_INVITE %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -211,8 +241,11 @@ void WorldSession::HandleChannelInvite(WorldPacket& recvPacket)
void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 channelLength = recvPacket.ReadBits(8);
+ uint32 nameLength = recvPacket.ReadBits(7);
+
+ std::string channelName = recvPacket.ReadString(channelLength);
+ std::string targetName = recvPacket.ReadString(nameLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_KICK %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -227,8 +260,14 @@ void WorldSession::HandleChannelKick(WorldPacket& recvPacket)
void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
{
+ uint32 channelLength, nameLength;
std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+
+ channelLength = recvPacket.ReadBits(8);
+ nameLength = recvPacket.ReadBits(7);
+
+ targetName = recvPacket.ReadString(nameLength);
+ channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_BAN %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -243,8 +282,11 @@ void WorldSession::HandleChannelBan(WorldPacket& recvPacket)
void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
{
- std::string channelName, targetName;
- recvPacket >> channelName >> targetName;
+ uint32 channelLength = recvPacket.ReadBits(7);
+ uint32 nameLength = recvPacket.ReadBits(8);
+
+ std::string targetName = recvPacket.ReadString(nameLength);
+ std::string channelName = recvPacket.ReadString(channelLength);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_UNBAN %s Channel: %s, Target: %s",
GetPlayerInfo().c_str(), channelName.c_str(), targetName.c_str());
@@ -259,8 +301,8 @@ void WorldSession::HandleChannelUnban(WorldPacket& recvPacket)
void WorldSession::HandleChannelAnnouncements(WorldPacket& recvPacket)
{
- std::string channelName;
- recvPacket >> channelName;
+ uint32 length = recvPacket.ReadBits(8);
+ std::string channelName = recvPacket.ReadString(length);
TC_LOG_DEBUG("chat.system", "CMSG_CHANNEL_ANNOUNCEMENTS %s Channel: %s",
GetPlayerInfo().c_str(), channelName.c_str());
@@ -300,7 +342,7 @@ void WorldSession::HandleGetChannelMemberCount(WorldPacket &recvPacket)
}
}
-void WorldSession::HandleSetChannelWatch(WorldPacket &recvPacket)
+void WorldSession::HandleSetChannelWatch(WorldPacket& recvPacket)
{
std::string channelName;
recvPacket >> channelName;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 4c7d1669233..e81506678ef 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -26,6 +26,7 @@
#include "DatabaseEnv.h"
#include "Group.h"
#include "Guild.h"
+#include "GuildFinderMgr.h"
#include "GuildMgr.h"
#include "Language.h"
#include "LFGMgr.h"
@@ -47,7 +48,6 @@
#include "WorldPacket.h"
#include "WorldSession.h"
-
class LoginQueryHolder : public SQLQueryHolder
{
private:
@@ -116,6 +116,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_INVENTORY, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_VOID_STORAGE);
+ stmt->setUInt32(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_VOID_STORAGE, stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_ACTIONS, stmt);
@@ -168,6 +172,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_EQUIPMENT_SETS, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_CUF_PROFILES);
+ stmt->setUInt32(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CUF_PROFILES, stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_BGDATA);
stmt->setUInt32(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_BG_DATA, stmt);
@@ -204,39 +212,56 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt32(0, m_accountId);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PLAYER_CURRENCY);
+ stmt->setUInt32(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CURRENCY, stmt);
+
return res;
}
void WorldSession::HandleCharEnum(PreparedQueryResult result)
{
- WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
-
- uint8 num = 0;
+ uint32 charCount = 0;
+ ByteBuffer bitBuffer;
+ ByteBuffer dataBuffer;
- data << num;
-
- _legitCharacters.clear();
+ bitBuffer.WriteBits(0, 23);
+ bitBuffer.WriteBit(1);
if (result)
{
+ _legitCharacters.clear();
+
+ charCount = uint32(result->GetRowCount());
+ bitBuffer.reserve(24 * charCount / 8);
+ dataBuffer.reserve(charCount * 381);
+
+ bitBuffer.WriteBits(charCount, 17);
+
do
{
- uint32 guidlow = (*result)[0].GetUInt32();
- TC_LOG_INFO("network", "Loading char guid %u from account %u.", guidlow, GetAccountId());
- if (Player::BuildEnumData(result, &data))
- {
- // Do not allow banned characters to log in
- if (!(*result)[20].GetUInt32())
- _legitCharacters.insert(guidlow);
+ uint32 guidLow = (*result)[0].GetUInt32();
- if (!sWorld->HasCharacterNameData(guidlow)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
- sWorld->AddCharacterNameData(guidlow, (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8());
- ++num;
- }
- }
- while (result->NextRow());
+ TC_LOG_INFO("network", "Loading char guid %u from account %u.", guidLow, GetAccountId());
+
+ Player::BuildEnumData(result, &dataBuffer, &bitBuffer);
+
+ // Do not allow banned characters to log in
+ if (!(*result)[20].GetUInt32())
+ _legitCharacters.insert(guidLow);
+
+ if (!sWorld->HasCharacterNameData(guidLow)) // This can happen if characters are inserted into the database manually. Core hasn't loaded name data yet.
+ sWorld->AddCharacterNameData(guidLow, (*result)[1].GetString(), (*result)[4].GetUInt8(), (*result)[2].GetUInt8(), (*result)[3].GetUInt8(), (*result)[7].GetUInt8());
+ } while (result->NextRow());
+
+ bitBuffer.FlushBits();
}
+ else
+ bitBuffer.WriteBits(0, 17);
- data.put<uint8>(0, num);
+ WorldPacket data(SMSG_CHAR_ENUM, 7 + bitBuffer.size() + dataBuffer.size());
+ data.append(bitBuffer);
+ if (charCount)
+ data.append(dataBuffer);
SendPacket(&data);
}
@@ -752,6 +777,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
sLog->outCharDump(dump.c_str(), accountId, GUID_LOPART(guid), name.c_str());
}
+ sGuildFinderMgr->RemoveAllMembershipRequestsFromPlayer(guid);
sCalendarMgr->RemoveAllPlayerEventsAndInvites(guid);
Player::DeleteFromDB(guid, accountId);
@@ -766,16 +792,33 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
{
if (PlayerLoading() || GetPlayer() != NULL)
{
- TC_LOG_ERROR("network", "Player tryes to login again, AccountId = %d", GetAccountId());
+ TC_LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId());
return;
}
m_playerLoading = true;
- uint64 playerGuid = 0;
+ ObjectGuid playerGuid;
TC_LOG_DEBUG("network", "WORLD: Recvd Player Logon Message");
-
- recvData >> playerGuid;
+ playerGuid[2] = recvData.ReadBit();
+ playerGuid[3] = recvData.ReadBit();
+ playerGuid[0] = recvData.ReadBit();
+ playerGuid[6] = recvData.ReadBit();
+ playerGuid[4] = recvData.ReadBit();
+ playerGuid[5] = recvData.ReadBit();
+ playerGuid[1] = recvData.ReadBit();
+ playerGuid[7] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(playerGuid[2]);
+ recvData.ReadByteSeq(playerGuid[7]);
+ recvData.ReadByteSeq(playerGuid[0]);
+ recvData.ReadByteSeq(playerGuid[3]);
+ recvData.ReadByteSeq(playerGuid[5]);
+ recvData.ReadByteSeq(playerGuid[6]);
+ recvData.ReadByteSeq(playerGuid[1]);
+ recvData.ReadByteSeq(playerGuid[4]);
+
+ TC_LOG_DEBUG("network", "Character (Guid: %u) logging in", GUID_LOPART(playerGuid));
if (!IsLegitCharacterForAccount(GUID_LOPART(playerGuid)))
{
@@ -795,6 +838,17 @@ void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData)
_charLoginCallback = CharacterDatabase.DelayQueryHolder((SQLQueryHolder*)holder);
}
+void WorldSession::HandleLoadScreenOpcode(WorldPacket& recvPacket)
+{
+ TC_LOG_INFO("misc", "WORLD: Recvd CMSG_LOAD_SCREEN");
+ uint32 mapID;
+
+ recvPacket >> mapID;
+ recvPacket.ReadBit();
+
+ // TODO: Do something with this packet
+}
+
void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
{
uint64 playerGuid = holder->GetGuid();
@@ -829,9 +883,34 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
LoadAccountData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_ACCOUNT_DATA), PER_CHARACTER_CACHE_MASK);
SendAccountDataTimes(PER_CHARACTER_CACHE_MASK);
- data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2); // added in 2.2.0
+ bool featureBit4 = true;
+ data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 7); // checked in 4.2.2
data << uint8(2); // unknown value
- data << uint8(0); // enable(1)/disable(0) voice chat interface in client
+ data << uint32(1);
+ data << uint32(1);
+ data << uint32(2);
+ data << uint32(0);
+ data.WriteBit(1);
+ data.WriteBit(1);
+ data.WriteBit(0);
+ data.WriteBit(featureBit4);
+ data.WriteBit(0);
+ data.WriteBit(0);
+ data.FlushBits();
+ if (featureBit4)
+ {
+ data << uint32(1);
+ data << uint32(0);
+ data << uint32(10);
+ data << uint32(60);
+ }
+
+ //if (featureBit5)
+ //{
+ // data << uint32(0);
+ // data << uint32(0);
+ // data << uint32(0);
+ //}
SendPacket(&data);
// Send MOTD
@@ -878,28 +957,30 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
Field* fields = resultGuild->Fetch();
pCurrChar->SetInGuild(fields[0].GetUInt32());
pCurrChar->SetRank(fields[1].GetUInt8());
+ if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId()))
+ pCurrChar->SetGuildLevel(guild->GetLevel());
}
else if (pCurrChar->GetGuildId()) // clear guild related fields in case wrong data about non existed membership
{
pCurrChar->SetInGuild(0);
pCurrChar->SetRank(0);
+ pCurrChar->SetGuildLevel(0);
}
- if (pCurrChar->GetGuildId() != 0)
+ data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4);
+ data << uint64(0);
+ SendPacket(&data);
+
+ data.Initialize(SMSG_HOTFIX_INFO);
+ HotfixData const& hotfix = sObjectMgr->GetHotfixData();
+ data.WriteBits(hotfix.size(), 22);
+ data.FlushBits();
+ for (uint32 i = 0; i < hotfix.size(); ++i)
{
- if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId()))
- guild->SendLoginInfo(this);
- else
- {
- // remove wrong guild data
- TC_LOG_ERROR("network", "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId());
- pCurrChar->SetInGuild(0);
- }
+ data << uint32(hotfix[i].Type);
+ data << uint32(hotfix[i].Timestamp);
+ data << uint32(hotfix[i].Entry);
}
-
- data.Initialize(SMSG_LEARNED_DANCE_MOVES, 4+4);
- data << uint32(0);
- data << uint32(0);
SendPacket(&data);
pCurrChar->SendInitialPacketsBeforeAddToMap();
@@ -924,7 +1005,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
{
- AreaTrigger const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
+ AreaTriggerStruct const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
if (at)
pCurrChar->TeleportTo(at->target_mapId, at->target_X, at->target_Y, at->target_Z, pCurrChar->GetOrientation());
else
@@ -934,18 +1015,26 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
sObjectAccessor->AddObject(pCurrChar);
//TC_LOG_DEBUG("Player %s added to Map.", pCurrChar->GetName().c_str());
+ if (pCurrChar->GetGuildId() != 0)
+ {
+ if (Guild* guild = sGuildMgr->GetGuildById(pCurrChar->GetGuildId()))
+ guild->SendLoginInfo(this);
+ else
+ {
+ // remove wrong guild data
+ TC_LOG_ERROR("misc", "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId());
+ pCurrChar->SetInGuild(0);
+ }
+ }
+
pCurrChar->SendInitialPacketsAfterAddToMap();
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE);
-
stmt->setUInt32(0, pCurrChar->GetGUIDLow());
-
CharacterDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_ONLINE);
-
stmt->setUInt32(0, GetAccountId());
-
LoginDatabase.Execute(stmt);
pCurrChar->SetInGameTime(getMSTime());
@@ -968,11 +1057,13 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
if (pCurrChar->m_deathState != ALIVE)
{
// not blizz like, we must correctly save and load player instead...
- if (pCurrChar->getRace() == RACE_NIGHTELF)
+ if (pCurrChar->getRace() == RACE_NIGHTELF && !pCurrChar->HasAura(20584))
pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)
- pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
- pCurrChar->SetMovement(MOVE_WATER_WALK);
+ if (!pCurrChar->HasAura(8326))
+ pCurrChar->CastSpell(pCurrChar, 8326, true, 0); // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?)
+
+ pCurrChar->SetWaterWalking(true);
}
pCurrChar->ContinueTaxiFlight();
@@ -1000,14 +1091,37 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
if (pCurrChar->HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
{
- pCurrChar->resetTalents(true);
+ pCurrChar->ResetTalents(true);
pCurrChar->SendTalentsInfoData(false); // original talents send already in to SendInitialPacketsBeforeAddToMap, resend reset state
SendNotification(LANG_RESET_TALENTS);
}
if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST))
+ {
pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST);
+ if (pCurrChar->getClass() == CLASS_HUNTER)
+ {
+ static uint32 const HunterCreatePetSpells[MAX_RACES] =
+ {
+ 0, /* None */ 79597, /* Human - Young Wolf */
+ 79598, /* Orc - Young Boar */ 79593, /* Dwarf - Young Bear */
+ 79602, /* Night Elf - Young Cat */ 79600, /* Undead - Young Widow */
+ 79603, /* Tauren - Young Tallstrider */ 0, /* Gnome */
+ 79599, /* Troll - Young Raptor */ 79595, /* Goblin - Young Crab */
+ 79594, /* Blood Elf - Young Dragonhawk */ 79601, /* Draenei - Young Moth */
+ 0, /* Fel Orc */ 0, /* Naga */
+ 0, /* Broken */ 0, /* Skeleton */
+ 0, /* Vrykul */ 0, /* Tuskarr */
+ 0, /* Forest Troll */ 0, /* Taunka */
+ 0, /* Northrend Skeleton */ 0, /* Ice Troll */
+ 79596, /* Worgen - Young Mastiff */
+ };
+
+ pCurrChar->CastSpell(pCurrChar, HunterCreatePetSpells[pCurrChar->getRace()], true);
+ }
+ }
+
// show time before shutdown if shutdown planned.
if (sWorld->IsShuttingDown())
sWorld->ShutdownMsg(true, pCurrChar);
@@ -1067,13 +1181,13 @@ void WorldSession::HandleTutorialFlag(WorldPacket& recvData)
SetTutorialInt(index, flag);
}
-void WorldSession::HandleTutorialClear(WorldPacket & /*recvData*/)
+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::HandleTutorialReset(WorldPacket& /*recvData*/)
{
for (uint8 i = 0; i < MAX_ACCOUNT_TUTORIAL_VALUES; ++i)
SetTutorialInt(i, 0x00000000);
@@ -1220,7 +1334,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1230,7 +1343,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1239,7 +1351,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1253,7 +1364,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1265,7 +1375,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1275,7 +1384,6 @@ void WorldSession::HandleSetPlayerDeclinedNames(WorldPacket& recvData)
{
WorldPacket data(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, 4+8);
data << uint32(1);
- data << uint64(guid);
SendPacket(&data);
return;
}
@@ -1348,8 +1456,8 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData)
// 0 - ok
// 1, 3 - not enough money
- // 2 - you have to seat on barber chair
- if (!_player->HasEnoughMoney(cost))
+ // 2 - you have to sit on barber chair
+ if (!_player->HasEnoughMoney((uint64)cost))
{
WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4);
data << uint32(1); // no money
@@ -1363,7 +1471,7 @@ void WorldSession::HandleAlterAppearance(WorldPacket& recvData)
SendPacket(&data);
}
- _player->ModifyMoney(-int32(cost)); // it isn't free
+ _player->ModifyMoney(-int64(cost)); // it isn't free
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER, cost);
_player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id));
@@ -1388,7 +1496,7 @@ void WorldSession::HandleRemoveGlyph(WorldPacket& recvData)
return;
}
- if (uint32 glyph = _player->GetGlyph(slot))
+ if (uint32 glyph = _player->GetGlyph(_player->GetActiveSpec(), slot))
{
if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph))
{
@@ -1420,7 +1528,6 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
recvData >> gender >> skin >> hairColor >> hairStyle >> facialHair >> face;
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AT_LOGIN);
-
stmt->setUInt32(0, GUID_LOPART(guid));
// TODO: Make async with callback
// TODO 2: Allow opcode at end of callback
@@ -1526,7 +1633,7 @@ void WorldSession::HandleCharCustomize(WorldPacket& recvData)
SendPacket(&data);
}
-void WorldSession::HandleEquipmentSetSave(WorldPacket &recvData)
+void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_SAVE");
@@ -1588,7 +1695,7 @@ void WorldSession::HandleEquipmentSetDelete(WorldPacket &recvData)
_player->DeleteEquipmentSet(setGuid);
}
-void WorldSession::HandleEquipmentSetUse(WorldPacket &recvData)
+void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "CMSG_EQUIPMENT_SET_USE");
@@ -1794,6 +1901,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
case RACE_UNDEAD_PLAYER:
case RACE_TROLL:
case RACE_BLOODELF:
+ case RACE_GOBLIN:
team = TEAM_HORDE;
break;
default:
@@ -1838,6 +1946,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
case RACE_NIGHTELF:
stmt->setUInt16(1, 113);
break;
+ case RACE_WORGEN:
+ stmt->setUInt16(1, 791);
+ break;
case RACE_UNDEAD_PLAYER:
stmt->setUInt16(1, 673);
break;
@@ -1850,6 +1961,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
case RACE_BLOODELF:
stmt->setUInt16(1, 137);
break;
+ case RACE_GOBLIN:
+ stmt->setUInt16(1, 792);
+ break;
}
trans->Append(stmt);
@@ -2190,3 +2304,88 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData)
data << uint8(race);
SendPacket(&data);
}
+
+void WorldSession::HandleRandomizeCharNameOpcode(WorldPacket& recvData)
+{
+ uint8 gender, race;
+
+ recvData >> race;
+ recvData >> gender;
+
+ if (!Player::IsValidRace(race))
+ {
+ TC_LOG_ERROR("misc", "Invalid race (%u) sent by accountId: %u", race, GetAccountId());
+ return;
+ }
+
+ if (!Player::IsValidGender(gender))
+ {
+ TC_LOG_ERROR("misc", "Invalid gender (%u) sent by accountId: %u", gender, GetAccountId());
+ return;
+ }
+
+ std::string const* name = GetRandomCharacterName(race, gender);
+ WorldPacket data(SMSG_RANDOMIZE_CHAR_NAME, 10);
+ data.WriteBit(0); // unk
+ data.WriteBits(name->size(), 7);
+ data.WriteString(*name);
+ SendPacket(&data);
+}
+
+void WorldSession::HandleReorderCharacters(WorldPacket& recvData)
+{
+ uint32 charactersCount = recvData.ReadBits(10);
+
+ std::vector<ObjectGuid> guids(charactersCount);
+ uint8 position;
+
+ for (uint8 i = 0; i < charactersCount; ++i)
+ {
+ guids[i][1] = recvData.ReadBit();
+ guids[i][4] = recvData.ReadBit();
+ guids[i][5] = recvData.ReadBit();
+ guids[i][3] = recvData.ReadBit();
+ guids[i][0] = recvData.ReadBit();
+ guids[i][7] = recvData.ReadBit();
+ guids[i][6] = recvData.ReadBit();
+ guids[i][2] = recvData.ReadBit();
+ }
+
+ SQLTransaction trans = CharacterDatabase.BeginTransaction();
+ for (uint8 i = 0; i < charactersCount; ++i)
+ {
+ recvData.ReadByteSeq(guids[i][6]);
+ recvData.ReadByteSeq(guids[i][5]);
+ recvData.ReadByteSeq(guids[i][1]);
+ recvData.ReadByteSeq(guids[i][4]);
+ recvData.ReadByteSeq(guids[i][0]);
+ recvData.ReadByteSeq(guids[i][3]);
+
+ recvData >> position;
+
+ recvData.ReadByteSeq(guids[i][2]);
+ recvData.ReadByteSeq(guids[i][7]);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_LIST_SLOT);
+ stmt->setUInt8(0, position);
+ stmt->setUInt32(1, GUID_LOPART(guids[i]));
+ trans->Append(stmt);
+ }
+
+ CharacterDatabase.CommitTransaction(trans);
+}
+
+void WorldSession::HandleOpeningCinematic(WorldPacket& /*recvData*/)
+{
+ // Only players that has not yet gained any experience can use this
+ if (_player->GetUInt32Value(PLAYER_XP))
+ return;
+
+ if (ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(_player->getClass()))
+ {
+ if (classEntry->CinematicSequence)
+ _player->SendCinematicStart(classEntry->CinematicSequence);
+ else if (ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(_player->getRace()))
+ _player->SendCinematicStart(raceEntry->CinematicSequence);
+ }
+}
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 17b5974d1ca..7c946542d7c 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -42,11 +42,55 @@
void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
{
- uint32 type;
+ uint32 type = 0;
uint32 lang;
- recvData >> type;
- recvData >> lang;
+ switch (recvData.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();
+ return;
+ }
if (type >= MAX_CHAT_MSG_TYPE)
{
@@ -57,118 +101,125 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
Player* sender = GetPlayer();
- //TC_LOG_DEBUG("CHAT: packet received. type %u, lang %u", type, lang);
+ //TC_LOG_DEBUG("misc", "CHAT: packet received. type %u, lang %u", type, lang);
- // prevent talking at unknown language (cheating)
- LanguageDesc const* langDesc = GetLanguageDescByID(lang);
- if (!langDesc)
+ // no language sent with emote packet.
+ if (type != CHAT_MSG_EMOTE && type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
{
- SendNotification(LANG_UNKNOWN_LANGUAGE);
- recvData.rfinish();
- return;
- }
+ recvData >> lang;
- 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)
+ // prevent talking at unknown language (cheating)
+ LanguageDesc const* langDesc = GetLanguageDescByID(lang);
+ if (!langDesc)
{
- if ((*i)->GetMiscValue() == int32(lang))
- {
- foundAura = true;
- break;
- }
- }
- if (!foundAura)
- {
- SendNotification(LANG_NOT_LEARNED_LANGUAGE);
+ SendNotification(LANG_UNKNOWN_LANGUAGE);
recvData.rfinish();
return;
}
- }
-
- if (lang == LANG_ADDON)
- {
- // LANG_ADDON is only valid for the following message types
- switch (type)
+ if (langDesc->skill_id != 0 && !sender->HasSkill(langDesc->skill_id))
{
- case CHAT_MSG_PARTY:
- case CHAT_MSG_RAID:
- case CHAT_MSG_GUILD:
- case CHAT_MSG_BATTLEGROUND:
- case CHAT_MSG_WHISPER:
- if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
+ // 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))
{
- std::string msg = "";
- recvData >> msg;
+ foundAura = true;
+ break;
+ }
+ }
+ if (!foundAura)
+ {
+ SendNotification(LANG_NOT_LEARNED_LANGUAGE);
+ recvData.rfinish();
+ return;
+ }
+ }
- if (msg.empty())
+ if (lang == LANG_ADDON)
+ {
+ // LANG_ADDON is only valid for the following message types
+ switch (type)
+ {
+ case CHAT_MSG_PARTY:
+ case CHAT_MSG_RAID:
+ case CHAT_MSG_GUILD:
+ case CHAT_MSG_BATTLEGROUND:
+ case CHAT_MSG_WHISPER:
+ if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
+ {
+ std::string msg = "";
+ recvData >> msg;
+
+ if (msg.empty())
+ return;
+
+ sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
+ }
+
+ // Disabled addon channel?
+ if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
return;
+ break;
+ default:
+ TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
+ GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
- sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), lang, msg);
- }
-
- // Disabled addon channel?
- if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
+ recvData.rfinish();
return;
- break;
- default:
- TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination",
- GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
-
- recvData.rfinish();
- return;
+ }
}
- }
- // LANG_ADDON should not be changed nor be affected by flood control
- else
- {
- // send in universal language if player in .gmon mode (ignore spell effects)
- if (sender->IsGameMaster())
- lang = LANG_UNIVERSAL;
+ // LANG_ADDON should not be changed nor be affected by flood control
else
{
- Unit::AuraEffectList const& ModLangAuras = sender->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
- if (!ModLangAuras.empty())
- lang = ModLangAuras.front()->GetMiscValue();
- else if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
+ // send in universal language if player in .gm on mode (ignore spell effects)
+ if (sender->IsGameMaster())
lang = LANG_UNIVERSAL;
else
{
- switch (type)
+ // send in universal language in two side iteration allowed mode
+ if (HasPermission(rbac::RBAC_PERM_TWO_SIDE_INTERACTION_CHAT))
+ lang = LANG_UNIVERSAL;
+ else
{
- 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;
+ 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;
+ 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;
+ }
}
-
- if (type != CHAT_MSG_AFK && type != CHAT_MSG_DND)
- sender->UpdateSpeakTime();
}
+ else
+ lang = LANG_UNIVERSAL;
if (sender->HasAura(1852) && type != CHAT_MSG_WHISPER)
{
@@ -177,6 +228,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}
+ uint32 textLength = 0;
+ uint32 receiverLength = 0;
std::string to, channel, msg;
bool ignoreChecks = false;
switch (type)
@@ -185,27 +238,30 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
case CHAT_MSG_EMOTE:
case CHAT_MSG_YELL:
case CHAT_MSG_PARTY:
- case CHAT_MSG_PARTY_LEADER:
case CHAT_MSG_GUILD:
case CHAT_MSG_OFFICER:
case CHAT_MSG_RAID:
- case CHAT_MSG_RAID_LEADER:
case CHAT_MSG_RAID_WARNING:
case CHAT_MSG_BATTLEGROUND:
- case CHAT_MSG_BATTLEGROUND_LEADER:
- recvData >> msg;
+ textLength = recvData.ReadBits(9);
+ msg = recvData.ReadString(textLength);
break;
case CHAT_MSG_WHISPER:
- recvData >> to;
- recvData >> msg;
+ receiverLength = recvData.ReadBits(10);
+ textLength = recvData.ReadBits(9);
+ to = recvData.ReadString(receiverLength);
+ msg = recvData.ReadString(textLength);
break;
case CHAT_MSG_CHANNEL:
- recvData >> channel;
- recvData >> msg;
+ 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:
- recvData >> msg;
+ textLength = recvData.ReadBits(9);
+ msg = recvData.ReadString(textLength);
ignoreChecks = true;
break;
}
@@ -259,7 +315,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sender->TextEmote(msg);
else if (type == CHAT_MSG_YELL)
sender->Yell(msg, lang);
- } break;
+ break;
+ }
case CHAT_MSG_WHISPER:
{
if (!normalizePlayerName(to))
@@ -299,7 +356,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
sender->AddWhisperWhiteList(receiver->GetGUID());
GetPlayer()->Whisper(msg, lang, receiver->GetGUID());
- } break;
+ break;
+ }
case CHAT_MSG_PARTY:
case CHAT_MSG_PARTY_LEADER:
{
@@ -312,15 +370,16 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}
- if (type == CHAT_MSG_PARTY_LEADER && !group->IsLeader(sender->GetGUID()))
- return;
+ if (group->IsLeader(GetPlayer()->GetGUID()))
+ type = CHAT_MSG_PARTY_LEADER;
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()));
- } break;
+ break;
+ }
case CHAT_MSG_GUILD:
{
if (GetPlayer()->GetGuildId())
@@ -332,7 +391,8 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
guild->BroadcastToGuild(this, false, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
}
}
- } break;
+ break;
+ }
case CHAT_MSG_OFFICER:
{
if (GetPlayer()->GetGuildId())
@@ -344,8 +404,10 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
guild->BroadcastToGuild(this, true, msg, lang == LANG_ADDON ? LANG_ADDON : LANG_UNIVERSAL);
}
}
- } break;
+ 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();
@@ -356,29 +418,16 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
return;
}
- sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
-
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false);
- } break;
- 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() || !group->IsLeader(sender->GetGUID()))
- return;
- }
+ if (group->IsLeader(GetPlayer()->GetGUID()))
+ type = CHAT_MSG_RAID_LEADER;
sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg);
+ ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
- } break;
+ break;
+ }
case CHAT_MSG_RAID_WARNING:
{
Group* group = GetPlayer()->GetGroup();
@@ -391,33 +440,26 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
//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;
+ break;
+ }
case CHAT_MSG_BATTLEGROUND:
- {
- //battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
- Group* group = GetPlayer()->GetGroup();
- if (!group || !group->isBGGroup())
- return;
-
- sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group);
-
- WorldPacket data;
- ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg);
- group->BroadcastPacket(&data, false);
- } break;
case CHAT_MSG_BATTLEGROUND_LEADER:
{
// battleground raid is always in Player->GetGroup(), never in GetOriginalGroup()
Group* group = GetPlayer()->GetGroup();
- if (!group || !group->isBGGroup() || !group->IsLeader(GetPlayer()->GetGUID()))
+ 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, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);;
+ ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg);
group->BroadcastPacket(&data, false);
- } break;
+ break;
+ }
case CHAT_MSG_CHANNEL:
{
if (!HasPermission(rbac::RBAC_PERM_SKIP_CHECK_CHAT_CHANNEL_REQ))
@@ -437,17 +479,18 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
chn->Say(sender->GetGUID(), msg.c_str(), lang);
}
}
- } break;
+ break;
+ }
case CHAT_MSG_AFK:
{
if (!sender->IsInCombat())
{
- if (sender->isAFK()) // Already AFK
+ if (sender ->isAFK()) // Already AFK
{
if (msg.empty())
- sender->ToggleAFK(); // Remove AFK
+ sender->ToggleAFK(); // Remove AFK
else
- sender->autoReplyMsg = msg; // Update message
+ sender->autoReplyMsg = msg; // Update message
}
else // New AFK mode
{
@@ -465,12 +508,12 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
case CHAT_MSG_DND:
{
- if (sender->isDND()) // Already DND
+ if (sender->isDND()) // Already DND
{
if (msg.empty())
- sender->ToggleDND(); // Remove DND
+ sender->ToggleDND(); // Remove DND
else
- sender->autoReplyMsg = msg; // Update message
+ sender->autoReplyMsg = msg; // Update message
}
else // New DND mode
{
@@ -491,6 +534,147 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
}
+void WorldSession::HandleAddonMessagechatOpcode(WorldPacket& recvData)
+{
+ Player* sender = GetPlayer();
+ ChatMsg type;
+
+ switch (recvData.GetOpcode())
+ {
+ case CMSG_MESSAGECHAT_ADDON_BATTLEGROUND:
+ type = CHAT_MSG_BATTLEGROUND;
+ break;
+ case CMSG_MESSAGECHAT_ADDON_GUILD:
+ type = CHAT_MSG_GUILD;
+ break;
+ case CMSG_MESSAGECHAT_ADDON_OFFICER:
+ type = CHAT_MSG_OFFICER;
+ break;
+ case CMSG_MESSAGECHAT_ADDON_PARTY:
+ type = CHAT_MSG_PARTY;
+ break;
+ 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();
+ return;
+ }
+
+ std::string message;
+ std::string prefix;
+ std::string targetName;
+
+ 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;
+ }
+
+ if (prefix.empty() || prefix.length() > 16)
+ return;
+
+ // Logging enabled?
+ if (sWorld->getBoolConfig(CONFIG_CHATLOG_ADDON))
+ {
+ if (message.empty())
+ return;
+
+ // Weird way to log stuff...
+ sScriptMgr->OnPlayerChat(sender, uint32(CHAT_MSG_ADDON), uint32(LANG_ADDON), message);
+ }
+
+ // Disabled addon channel?
+ if (!sWorld->getBoolConfig(CONFIG_ADDON_CHANNEL))
+ 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);
+ break;
+ }
+ case CHAT_MSG_WHISPER:
+ {
+ if (!normalizePlayerName(targetName))
+ break;
+ Player* receiver = sObjectAccessor->FindPlayerByName(targetName);
+ if (!receiver)
+ break;
+
+ sender->WhisperAddon(message, prefix, receiver);
+ break;
+ }
+ // Messages sent to "RAID" while in a party will get delivered to "PARTY"
+ case CHAT_MSG_PARTY:
+ case CHAT_MSG_RAID:
+ {
+
+ Group* group = sender->GetGroup();
+ if (!group || group->isBGGroup())
+ break;
+
+ WorldPacket data;
+ ChatHandler::BuildChatPacket(data, type, LANG_ADDON, sender, NULL, message, 0U, "", DEFAULT_LOCALE, prefix);
+ group->BroadcastAddonMessagePacket(&data, prefix, true, -1, group->GetMemberGroup(sender->GetGUID()));
+ break;
+ }
+ default:
+ {
+ TC_LOG_ERROR("misc", "HandleAddonMessagechatOpcode: unknown addon message type %u", type);
+ break;
+ }
+ }
+}
+
void WorldSession::HandleEmoteOpcode(WorldPacket& recvData)
{
if (!GetPlayer()->IsAlive() || GetPlayer()->HasUnitState(UNIT_STATE_DIED))
@@ -589,7 +773,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
TypeContainerVisitor<Trinity::PlayerDistWorker<Trinity::LocalizedPacketDo<Trinity::EmoteChatBuilder> >, WorldTypeMapContainer> message(emote_worker);
cell.Visit(p, message, *GetPlayer()->GetMap(), *GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
- GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, unit);
+ GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE, text_emote, 0, 0, unit);
//Send scripted event call
if (unit && unit->GetTypeId() == TYPEID_UNIT && ((Creature*)unit)->AI())
@@ -598,14 +782,30 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData)
void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
{
- uint64 iguid;
+ ObjectGuid guid;
uint8 unk;
//TC_LOG_DEBUG("network", "WORLD: Received CMSG_CHAT_IGNORED");
- recvData >> iguid;
recvData >> unk; // probably related to spam reporting
-
- Player* player = ObjectAccessor::FindPlayer(iguid);
+ guid[5] = recvData.ReadBit();
+ guid[2] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[5]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[2]);
+
+ Player* player = ObjectAccessor::FindPlayer(guid);
if (!player || !player->GetSession())
return;
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 6404d3c8e41..8fb3935e74c 100644
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -48,11 +48,12 @@ class Aura;
void WorldSession::SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val /* = 0 */)
{
- WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4);
+ WorldPacket data(SMSG_PARTY_COMMAND_RESULT, 4 + member.size() + 1 + 4 + 4 + 8);
data << uint32(operation);
data << member;
data << uint32(res);
data << uint32(val); // LFD cooldown related (used with ERR_PARTY_LFG_BOOT_COOLDOWN_S and ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S)
+ data << uint64(0); // player who caused error (in some cases).
SendPacket(&data);
}
@@ -61,59 +62,91 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_INVITE");
- std::string membername;
- recvData >> membername;
- recvData.read_skip<uint32>();
+ ObjectGuid crossRealmGuid; // unused
+
+ recvData.read_skip<uint32>(); // Non-zero in cross realm invites
+ recvData.read_skip<uint32>(); // Always 0
+
+ crossRealmGuid[2] = recvData.ReadBit();
+ crossRealmGuid[7] = recvData.ReadBit();
+
+ uint8 realmLen = recvData.ReadBits(9);
+
+ crossRealmGuid[3] = recvData.ReadBit();
+
+ uint8 nameLen = recvData.ReadBits(10);
+
+ crossRealmGuid[5] = recvData.ReadBit();
+ crossRealmGuid[4] = recvData.ReadBit();
+ crossRealmGuid[6] = recvData.ReadBit();
+ crossRealmGuid[0] = recvData.ReadBit();
+ crossRealmGuid[1] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(crossRealmGuid[4]);
+ recvData.ReadByteSeq(crossRealmGuid[7]);
+ recvData.ReadByteSeq(crossRealmGuid[6]);
+
+ std::string memberName, realmName;
+ memberName = recvData.ReadString(nameLen);
+ realmName = recvData.ReadString(realmLen); // unused
+
+ recvData.ReadByteSeq(crossRealmGuid[1]);
+ recvData.ReadByteSeq(crossRealmGuid[0]);
+ recvData.ReadByteSeq(crossRealmGuid[5]);
+ recvData.ReadByteSeq(crossRealmGuid[3]);
+ recvData.ReadByteSeq(crossRealmGuid[2]);
// attempt add selected player
// cheating
- if (!normalizePlayerName(membername))
+ if (!normalizePlayerName(memberName))
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
- Player* player = sObjectAccessor->FindPlayerByName(membername);
+ Player* player = sObjectAccessor->FindPlayerByName(memberName);
// no player
if (!player)
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
// restrict invite to GMs
if (!sWorld->getBoolConfig(CONFIG_ALLOW_GM_GROUP) && !GetPlayer()->IsGameMaster() && player->IsGameMaster())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_BAD_PLAYER_NAME_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_BAD_PLAYER_NAME_S);
return;
}
// can't group with
if (!GetPlayer()->IsGameMaster() && !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP) && GetPlayer()->GetTeam() != player->GetTeam())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_PLAYER_WRONG_FACTION);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PLAYER_WRONG_FACTION);
return;
}
if (GetPlayer()->GetInstanceId() != 0 && player->GetInstanceId() != 0 && GetPlayer()->GetInstanceId() != player->GetInstanceId() && GetPlayer()->GetMapId() == player->GetMapId())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_TARGET_NOT_IN_INSTANCE_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_TARGET_NOT_IN_INSTANCE_S);
return;
}
// just ignore us
if (player->GetInstanceId() != 0 && player->GetDungeonDifficulty() != GetPlayer()->GetDungeonDifficulty())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S);
return;
}
if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_IGNORING_YOU_S);
return;
}
+ ObjectGuid invitedGuid = player->GetGUID();
+
Group* group = GetPlayer()->GetGroup();
if (group && group->isBGGroup())
group = GetPlayer()->GetOriginalGroup();
@@ -124,17 +157,63 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
// player already in another group or invited
if (group2 || player->GetGroupInvite())
{
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_ALREADY_IN_GROUP_S);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_ALREADY_IN_GROUP_S);
if (group2)
{
// tell the player that they were invited but it failed as they were already in a group
- WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
- data << uint8(0); // invited/already in group flag
- data << GetPlayer()->GetName(); // max len 48
- data << uint32(0); // unk
- data << uint8(0); // count
- data << uint32(0); // unk
+ WorldPacket data(SMSG_GROUP_INVITE, 45);
+
+ data.WriteBit(0);
+
+ data.WriteBit(invitedGuid[0]);
+ data.WriteBit(invitedGuid[3]);
+ data.WriteBit(invitedGuid[2]);
+
+ data.WriteBit(0); // Inverse already in group
+
+ data.WriteBit(invitedGuid[6]);
+ data.WriteBit(invitedGuid[5]);
+
+ data.WriteBits(0, 9); // Realm name
+
+ data.WriteBit(invitedGuid[4]);
+
+ data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length
+
+ data.WriteBits(0, 24); // Count 2
+
+ data.WriteBit(0);
+
+ data.WriteBit(invitedGuid[1]);
+ data.WriteBit(invitedGuid[7]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(invitedGuid[1]);
+ data.WriteByteSeq(invitedGuid[4]);
+
+ data << int32(getMSTime());
+ data << int32(0);
+ data << int32(0);
+
+ data.WriteByteSeq(invitedGuid[6]);
+ data.WriteByteSeq(invitedGuid[0]);
+ data.WriteByteSeq(invitedGuid[2]);
+ data.WriteByteSeq(invitedGuid[3]);
+
+ // for count2 { int32(0) }
+
+ data.WriteByteSeq(invitedGuid[5]);
+
+ // data.append(realm name);
+
+ data.WriteByteSeq(invitedGuid[7]);
+
+ data.WriteString(GetPlayer()->GetName()); // inviter name
+
+ data << int32(0);
+
player->GetSession()->SendPacket(&data);
}
@@ -185,90 +264,138 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData)
}
// ok, we do it
- WorldPacket data(SMSG_GROUP_INVITE, 10); // guess size
- data << uint8(1); // invited/already in group flag
- data << GetPlayer()->GetName(); // max len 48
- data << uint32(0); // unk
- data << uint8(0); // count
- data << uint32(0); // unk
+ WorldPacket data(SMSG_GROUP_INVITE, 45);
+
+ data.WriteBit(0);
+
+ data.WriteBit(invitedGuid[0]);
+ data.WriteBit(invitedGuid[3]);
+ data.WriteBit(invitedGuid[2]);
+
+ data.WriteBit(1); // Inverse already in group
+
+ data.WriteBit(invitedGuid[6]);
+ data.WriteBit(invitedGuid[5]);
+
+ data.WriteBits(0, 9); // Realm name
+
+ data.WriteBit(invitedGuid[4]);
+
+ data.WriteBits(GetPlayer()->GetName().size(), 7); // Inviter name length
+
+ data.WriteBits(0, 24); // Count 2
+
+ data.WriteBit(0);
+
+ data.WriteBit(invitedGuid[1]);
+ data.WriteBit(invitedGuid[7]);
+
+ data.FlushBits();
+
+ data.WriteByteSeq(invitedGuid[1]);
+ data.WriteByteSeq(invitedGuid[4]);
+
+ data << int32(getMSTime());
+ data << int32(0);
+ data << int32(0);
+
+ data.WriteByteSeq(invitedGuid[6]);
+ data.WriteByteSeq(invitedGuid[0]);
+ data.WriteByteSeq(invitedGuid[2]);
+ data.WriteByteSeq(invitedGuid[3]);
+
+ // for count2 { int32(0) }
+
+ data.WriteByteSeq(invitedGuid[5]);
+
+ // data.append(realm name);
+
+ data.WriteByteSeq(invitedGuid[7]);
+
+ data.WriteString(GetPlayer()->GetName());
+
+ data << int32(0);
+
player->GetSession()->SendPacket(&data);
- SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK);
+ SendPartyResult(PARTY_OP_INVITE, memberName, ERR_PARTY_RESULT_OK);
}
-void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData)
+void WorldSession::HandleGroupInviteResponseOpcode(WorldPacket& recvData)
{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ACCEPT");
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_INVITE_RESPONSE");
- recvData.read_skip<uint32>();
- Group* group = GetPlayer()->GetGroupInvite();
+ recvData.ReadBit(); // unk always 0
+ bool accept = recvData.ReadBit();
- if (!group)
- return;
+ // Never actually received?
+ /*if (accept)
+ recvData.read_skip<uint32>(); // unk*/
- // Remove player from invitees in any case
- group->RemoveInvite(GetPlayer());
+ Group* group = GetPlayer()->GetGroupInvite();
- if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
- {
- TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
+ if (!group)
return;
- }
- // Group is full
- if (group->IsFull())
+ if (accept)
{
- SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL);
- return;
- }
+ // Remove player from invitees in any case
+ group->RemoveInvite(GetPlayer());
- Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
-
- // Forming a new group, create it
- if (!group->IsCreated())
- {
- // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
- if (!leader)
+ if (group->GetLeaderGUID() == GetPlayer()->GetGUID())
{
- group->RemoveAllInvites();
+ TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow());
return;
}
- // If we're about to create a group there really should be a leader present
- ASSERT(leader);
- group->RemoveInvite(leader);
- group->Create(leader);
- sGroupMgr->AddGroup(group);
- }
+ // Group is full
+ if (group->IsFull())
+ {
+ SendPartyResult(PARTY_OP_INVITE, "", ERR_GROUP_FULL);
+ return;
+ }
- // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
- if (!group->AddMember(GetPlayer()))
- return;
+ Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
- group->BroadcastGroupUpdate();
-}
+ // Forming a new group, create it
+ if (!group->IsCreated())
+ {
+ // This can happen if the leader is zoning. To be removed once delayed actions for zoning are implemented
+ if (!leader)
+ {
+ group->RemoveAllInvites();
+ return;
+ }
-void WorldSession::HandleGroupDeclineOpcode(WorldPacket & /*recvData*/)
-{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_DECLINE");
+ // If we're about to create a group there really should be a leader present
+ ASSERT(leader);
+ group->RemoveInvite(leader);
+ group->Create(leader);
+ sGroupMgr->AddGroup(group);
+ }
- Group* group = GetPlayer()->GetGroupInvite();
- if (!group)
- return;
+ // Everything is fine, do it, PLAYER'S GROUP IS SET IN ADDMEMBER!!!
+ if (!group->AddMember(GetPlayer()))
+ return;
- // Remember leader if online (group pointer will be invalid if group gets disbanded)
- Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
+ group->BroadcastGroupUpdate();
+ }
+ else
+ {
+ // Remember leader if online (group pointer will be invalid if group gets disbanded)
+ Player* leader = ObjectAccessor::FindPlayer(group->GetLeaderGUID());
- // uninvite, group can be deleted
- GetPlayer()->UninviteFromGroup();
+ // uninvite, group can be deleted
+ GetPlayer()->UninviteFromGroup();
- if (!leader || !leader->GetSession())
- return;
+ if (!leader || !leader->GetSession())
+ return;
- // report
- WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length());
- data << GetPlayer()->GetName();
- leader->GetSession()->SendPacket(&data);
+ // report
+ WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().size());
+ data << GetPlayer()->GetName();
+ leader->GetSession()->SendPacket(&data);
+ }
}
void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData)
@@ -386,7 +513,81 @@ void WorldSession::HandleGroupSetLeaderOpcode(WorldPacket& recvData)
group->SendUpdate();
}
-void WorldSession::HandleGroupDisbandOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleGroupSetRolesOpcode(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SET_ROLES");
+
+ uint32 newRole;
+ ObjectGuid guid1; // Assigner GUID
+ ObjectGuid guid2; // Target GUID
+
+ guid1 = GetPlayer()->GetGUID();
+
+ recvData >> newRole;
+
+ guid2[2] = recvData.ReadBit();
+ guid2[6] = recvData.ReadBit();
+ guid2[3] = recvData.ReadBit();
+ guid2[7] = recvData.ReadBit();
+ guid2[5] = recvData.ReadBit();
+ guid2[1] = recvData.ReadBit();
+ guid2[0] = recvData.ReadBit();
+ guid2[4] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid2[6]);
+ recvData.ReadByteSeq(guid2[4]);
+ recvData.ReadByteSeq(guid2[1]);
+ recvData.ReadByteSeq(guid2[3]);
+ recvData.ReadByteSeq(guid2[0]);
+ recvData.ReadByteSeq(guid2[5]);
+ recvData.ReadByteSeq(guid2[2]);
+ recvData.ReadByteSeq(guid2[7]);
+
+ WorldPacket data(SMSG_GROUP_SET_ROLE, 24);
+
+ data.WriteBit(guid1[1]);
+ data.WriteBit(guid2[0]);
+ data.WriteBit(guid2[2]);
+ data.WriteBit(guid2[4]);
+ data.WriteBit(guid2[7]);
+ data.WriteBit(guid2[3]);
+ data.WriteBit(guid1[7]);
+ data.WriteBit(guid2[5]);
+ data.WriteBit(guid1[5]);
+ data.WriteBit(guid1[4]);
+ data.WriteBit(guid1[3]);
+ data.WriteBit(guid2[6]);
+ data.WriteBit(guid1[2]);
+ data.WriteBit(guid1[6]);
+ data.WriteBit(guid2[1]);
+ data.WriteBit(guid1[0]);
+
+ data.WriteByteSeq(guid1[7]);
+ data.WriteByteSeq(guid2[3]);
+ data.WriteByteSeq(guid1[6]);
+ data.WriteByteSeq(guid2[4]);
+ data.WriteByteSeq(guid2[0]);
+ data << uint32(newRole); // New Role
+ data.WriteByteSeq(guid2[6]);
+ data.WriteByteSeq(guid2[2]);
+ data.WriteByteSeq(guid1[0]);
+ data.WriteByteSeq(guid1[4]);
+ data.WriteByteSeq(guid2[1]);
+ data.WriteByteSeq(guid1[3]);
+ data.WriteByteSeq(guid1[5]);
+ data.WriteByteSeq(guid1[2]);
+ data.WriteByteSeq(guid2[5]);
+ data.WriteByteSeq(guid2[7]);
+ data.WriteByteSeq(guid1[1]);
+ data << uint32(0); // Old Role
+
+ if (GetPlayer()->GetGroup())
+ GetPlayer()->GetGroup()->BroadcastPacket(&data, false);
+ else
+ SendPacket(&data);
+}
+
+void WorldSession::HandleGroupDisbandOpcode(WorldPacket& /*recvData*/)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_DISBAND");
@@ -471,7 +672,7 @@ void WorldSession::HandleMinimapPingOpcode(WorldPacket& recvData)
recvData >> x;
recvData >> y;
- //TC_LOG_DEBUG("Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
+ //TC_LOG_DEBUG("misc", "Received opcode MSG_MINIMAP_PING X: %f, Y: %f", x, y);
/** error handling **/
/********************/
@@ -500,7 +701,7 @@ void WorldSession::HandleRandomRollOpcode(WorldPacket& recvData)
// everything's fine, do it
roll = urand(minimum, maximum);
- //TC_LOG_DEBUG("ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
+ //TC_LOG_DEBUG("misc", "ROLL: MIN: %u, MAX: %u, ROLL: %u", minimum, maximum, roll);
WorldPacket data(MSG_RANDOM_ROLL, 4+4+4+8);
data << uint32(minimum);
@@ -521,7 +722,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData)
if (!group)
return;
- uint8 x;
+ uint8 x;
recvData >> x;
/** error handling **/
@@ -529,9 +730,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData)
// everything's fine, do it
if (x == 0xFF) // target icon request
- {
group->SendTargetIconList(this);
- }
else // target icon update
{
if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID()))
@@ -543,7 +742,7 @@ void WorldSession::HandleRaidTargetUpdateOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_RAID_CONVERT");
@@ -554,14 +753,22 @@ void WorldSession::HandleGroupRaidConvertOpcode(WorldPacket & /*recvData*/)
if (_player->InBattleground())
return;
- /** error handling **/
+ // error handling
if (!group->IsLeader(GetPlayer()->GetGUID()) || group->GetMembersCount() < 2)
return;
- /********************/
// everything's fine, do it (is it 0 (PARTY_OP_INVITE) correct code)
SendPartyResult(PARTY_OP_INVITE, "", ERR_PARTY_RESULT_OK);
- group->ConvertToRaid();
+
+ // New 4.x: it is now possible to convert a raid to a group if member count is 5 or less
+
+ bool toRaid;
+ recvData >> toRaid;
+
+ if (toRaid)
+ group->ConvertToRaid();
+ else
+ group->ConvertToGroup();
}
void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData)
@@ -590,10 +797,9 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData)
Player* movedPlayer = sObjectAccessor->FindPlayerByName(name);
uint64 guid;
+
if (movedPlayer)
- {
guid = movedPlayer->GetGUID();
- }
else
{
CharacterDatabase.EscapeString(name);
@@ -603,6 +809,16 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket& recvData)
group->ChangeMembersGroup(guid, groupNr);
}
+void WorldSession::HandleGroupSwapSubGroupOpcode(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_SWAP_SUB_GROUP");
+ std::string unk1;
+ std::string unk2;
+
+ recvData >> unk1;
+ recvData >> unk2;
+}
+
void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_GROUP_ASSISTANT_LEADER");
@@ -693,7 +909,7 @@ void WorldSession::HandleRaidReadyCheckOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleRaidReadyCheckFinishedOpcode(WorldPacket& /*recvData*/)
{
//Group* group = GetPlayer()->GetGroup();
//if (!group)
@@ -712,18 +928,16 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
if (mask == GROUP_UPDATE_FLAG_NONE)
return;
+ std::set<uint32> phases;
+ player->GetPhaseMgr().GetActivePhases(phases);
+
if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also
mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);
if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets
mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);
- uint32 byteCount = 0;
- for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
- if (mask & (1 << i))
- byteCount += GroupUpdateLength[i];
-
- data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
+ data->Initialize(SMSG_PARTY_MEMBER_STATS, 80); // average value
data->append(player->GetPackGUID());
*data << uint32(mask);
@@ -775,23 +989,47 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_ZONE)
*data << uint16(player->GetZoneId());
+ if (mask & GROUP_UPDATE_FLAG_UNK100)
+ *data << uint16(0);
+
if (mask & GROUP_UPDATE_FLAG_POSITION)
{
*data << uint16(player->GetPositionX());
*data << uint16(player->GetPositionY());
+ *data << uint16(player->GetPositionZ());
}
if (mask & GROUP_UPDATE_FLAG_AURAS)
{
+ *data << uint8(0);
uint64 auramask = player->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
+ *data << uint32(MAX_AURAS); // count
for (uint32 i = 0; i < MAX_AURAS; ++i)
{
if (auramask & (uint64(1) << i))
{
AuraApplication const* aurApp = player->GetVisibleAura(i);
- *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
- *data << uint8(1);
+ if (!aurApp)
+ {
+ *data << uint32(0);
+ *data << uint16(0);
+ continue;
+ }
+
+ *data << uint32(aurApp->GetBase()->GetId());
+ *data << uint16(aurApp->GetFlags());
+
+ if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ {
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
+ *data << int32(eff->GetAmount());
+ else
+ *data << int32(0);
+ }
+ }
}
}
}
@@ -800,9 +1038,9 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
if (mask & GROUP_UPDATE_FLAG_PET_GUID)
{
if (pet)
- *data << (uint64) pet->GetGUID();
+ *data << uint64(pet->GetGUID());
else
- *data << (uint64) 0;
+ *data << uint64(0);
}
if (mask & GROUP_UPDATE_FLAG_PET_NAME)
@@ -865,20 +1103,43 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
{
if (pet)
{
+ *data << uint8(0);
uint64 auramask = pet->GetAuraUpdateMaskForRaid();
*data << uint64(auramask);
+ *data << uint32(MAX_AURAS); // count
for (uint32 i = 0; i < MAX_AURAS; ++i)
{
if (auramask & (uint64(1) << i))
{
AuraApplication const* aurApp = pet->GetVisibleAura(i);
- *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
- *data << uint8(aurApp ? aurApp->GetFlags() : 0);
+ if (!aurApp)
+ {
+ *data << uint32(0);
+ *data << uint16(0);
+ continue;
+ }
+
+ *data << uint32(aurApp->GetBase()->GetId());
+ *data << uint16(aurApp->GetFlags());
+
+ if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ {
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
+ *data << int32(eff->GetAmount());
+ else
+ *data << int32(0);
+ }
+ }
}
}
}
else
+ {
+ *data << uint8(0);
*data << uint64(0);
+ }
}
if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
@@ -887,22 +1148,31 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke
*data << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
else
*data << uint32(0);
+
+ }
+
+ if (mask & GROUP_UPDATE_FLAG_PHASE)
+ {
+ *data << uint32(phases.empty() ? 8 : 0);
+ *data << uint32(phases.size());
+ for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
+ *data << uint16(*itr);
}
}
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
-void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
+void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
- uint64 Guid;
- recvData >> Guid;
+ uint64 guid;
+ recvData >> guid;
- Player* player = HashMapHolder<Player>::Find(Guid);
+ Player* player = HashMapHolder<Player>::Find(guid);
if (!player)
{
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
- data.appendPackGUID(Guid);
+ data.appendPackGUID(guid);
data << uint32(GROUP_UPDATE_FLAG_STATUS);
data << uint16(MEMBER_STATUS_OFFLINE);
SendPacket(&data);
@@ -911,6 +1181,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
Pet* pet = player->GetPet();
Powers powerType = player->getPowerType();
+ std::set<uint32> phases;
+ player->GetPhaseMgr().GetActivePhases(phases);
WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
@@ -931,6 +1203,9 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
if (player->GetVehicle())
updateFlags |= GROUP_UPDATE_FLAG_VEHICLE_SEAT;
+ if (!phases.empty())
+ updateFlags |= GROUP_UPDATE_FLAG_PHASE;
+
uint16 playerStatus = MEMBER_STATUS_ONLINE;
if (player->IsPvP())
playerStatus |= MEMBER_STATUS_PVP;
@@ -965,21 +1240,38 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
data << uint16(player->GetZoneId()); // GROUP_UPDATE_FLAG_ZONE
data << uint16(player->GetPositionX()); // GROUP_UPDATE_FLAG_POSITION
data << uint16(player->GetPositionY()); // GROUP_UPDATE_FLAG_POSITION
+ data << uint16(player->GetPositionZ()); // GROUP_UPDATE_FLAG_POSITION
- uint64 auraMask = 0;
+ // GROUP_UPDATE_FLAG_AURAS
+ data << uint8(1);
+ uint64 auramask = 0;
size_t maskPos = data.wpos();
- data << uint64(auraMask); // placeholder
+ data << uint64(auramask); // placeholder
+ data << uint32(MAX_AURAS); // count
+
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
if (AuraApplication const* aurApp = player->GetVisibleAura(i))
{
- auraMask |= uint64(1) << i;
+ auramask |= (uint64(1) << i);
+
data << uint32(aurApp->GetBase()->GetId());
- data << uint8(aurApp->GetFlags());
+ data << uint16(aurApp->GetFlags());
+
+ if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ {
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
+ data << int32(eff->GetAmount());
+ else
+ data << int32(0);
+ }
+ }
}
}
- data.put<uint64>(maskPos, auraMask); // GROUP_UPDATE_FLAG_AURAS
+ data.put<uint64>(maskPos, auramask); // GROUP_UPDATE_FLAG_AURAS
if (updateFlags & GROUP_UPDATE_FLAG_PET_GUID)
data << uint64(pet->GetGUID());
@@ -1002,18 +1294,33 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
if (updateFlags & GROUP_UPDATE_FLAG_PET_MAX_POWER)
data << uint16(pet->GetMaxPower(pet->getPowerType()));
+ // GROUP_UPDATE_FLAG_PET_AURAS
uint64 petAuraMask = 0;
+ data << uint8(1);
maskPos = data.wpos();
data << uint64(petAuraMask); // placeholder
+ data << uint32(MAX_AURAS); // count
if (pet)
{
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
if (AuraApplication const* aurApp = pet->GetVisibleAura(i))
{
- petAuraMask |= uint64(1) << i;
+ petAuraMask |= (uint64(1) << i);
+
data << uint32(aurApp->GetBase()->GetId());
- data << uint8(aurApp->GetFlags());
+ data << uint16(aurApp->GetFlags());
+
+ if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT)
+ {
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect const* eff = aurApp->GetBase()->GetEffect(i))
+ data << int32(eff->GetAmount());
+ else
+ data << int32(0);
+ }
+ }
}
}
}
@@ -1023,31 +1330,34 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket &recvData)
if (updateFlags & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
data << uint32(player->GetVehicle()->GetVehicleInfo()->m_seatID[player->m_movementInfo.transport.seat]);
+ if (updateFlags & GROUP_UPDATE_FLAG_PHASE)
+ {
+ data << uint32(phases.empty() ? 8 : 0);
+ data << uint32(phases.size());
+ for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
+ data << uint16(*itr);
+ }
+
SendPacket(&data);
}
-/*!*/void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleRequestRaidInfoOpcode(WorldPacket& /*recvData*/)
{
// every time the player checks the character screen
_player->SendRaidInfo();
}
-/*void WorldSession::HandleGroupCancelOpcode(WorldPacket& recvData)
-{
- TC_LOG_DEBUG("WORLD: got CMSG_GROUP_CANCEL.");
-}*/
-
void WorldSession::HandleOptOutOfLootOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_OPT_OUT_OF_LOOT");
- uint32 passOnLoot;
+ bool passOnLoot;
recvData >> passOnLoot; // 1 always pass, 0 do not pass
// ignore if player not loaded
if (!GetPlayer()) // needed because STATUS_AUTHED
{
- if (passOnLoot != 0)
+ if (passOnLoot)
TC_LOG_ERROR("network", "CMSG_OPT_OUT_OF_LOOT value<>0 for not-loaded character!");
return;
}
diff --git a/src/server/game/Handlers/GuildFinderHandler.cpp b/src/server/game/Handlers/GuildFinderHandler.cpp
new file mode 100644
index 00000000000..14175b44d9f
--- /dev/null
+++ b/src/server/game/Handlers/GuildFinderHandler.cpp
@@ -0,0 +1,442 @@
+/*
+ * 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 "WorldSession.h"
+#include "WorldPacket.h"
+#include "Object.h"
+#include "SharedDefines.h"
+#include "GuildFinderMgr.h"
+#include "GuildMgr.h"
+
+void WorldSession::HandleGuildFinderAddRecruit(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_ADD_RECRUIT");
+
+ if (sGuildFinderMgr->GetAllMembershipRequestsForPlayer(GetPlayer()->GetGUIDLow()).size() == 10)
+ return;
+
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+
+ recvPacket >> classRoles >> guildInterests >> availability;
+
+ ObjectGuid guid;
+ guid[3] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ uint16 commentLength = recvPacket.ReadBits(11);
+ guid[5] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ uint8 nameLength = recvPacket.ReadBits(7);
+ guid[2] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[5]);
+ std::string comment = recvPacket.ReadString(commentLength);
+ std::string playerName = recvPacket.ReadString(nameLength);
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[3]);
+
+ uint32 guildLowGuid = GUID_LOPART(uint64(guid));
+
+ if (!IS_GUILD_GUID(guid))
+ return;
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & AVAILABILITY_ALWAYS) || availability > AVAILABILITY_ALWAYS)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+
+ MembershipRequest request = MembershipRequest(GetPlayer()->GetGUIDLow(), guildLowGuid, availability, classRoles, guildInterests, comment, time(NULL));
+ sGuildFinderMgr->AddMembershipRequest(guildLowGuid, request);
+}
+
+void WorldSession::HandleGuildFinderBrowse(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_BROWSE");
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+ uint32 playerLevel = 0; // Raw player level (1-85), do they use MAX_FINDER_LEVEL when on level 85 ?
+
+ recvPacket >> classRoles >> availability >> guildInterests >> playerLevel;
+
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & AVAILABILITY_ALWAYS) || availability > AVAILABILITY_ALWAYS)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+ if (playerLevel > sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) || playerLevel < 1)
+ return;
+
+ Player* player = GetPlayer();
+
+ LFGuildPlayer settings(player->GetGUIDLow(), classRoles, availability, guildInterests, ANY_FINDER_LEVEL);
+ LFGuildStore guildList = sGuildFinderMgr->GetGuildsMatchingSetting(settings, player->GetTeamId());
+ uint32 guildCount = guildList.size();
+
+ if (guildCount == 0)
+ {
+ WorldPacket packet(SMSG_LF_GUILD_BROWSE_UPDATED, 0);
+ player->SendDirectMessage(&packet);
+ return;
+ }
+
+ ByteBuffer bufferData(65 * guildCount);
+ WorldPacket data(SMSG_LF_GUILD_BROWSE_UPDATED, 3 + guildCount * 65); // Estimated size
+ data.WriteBits(guildCount, 19);
+
+ for (LFGuildStore::const_iterator itr = guildList.begin(); itr != guildList.end(); ++itr)
+ {
+ LFGuildSettings guildSettings = itr->second;
+ Guild* guild = sGuildMgr->GetGuildById(itr->first);
+
+ ObjectGuid guildGUID = ObjectGuid(guild->GetGUID());
+
+ data.WriteBit(guildGUID[7]);
+ data.WriteBit(guildGUID[5]);
+ data.WriteBits(guild->GetName().size(), 8);
+ data.WriteBit(guildGUID[0]);
+ data.WriteBits(guildSettings.GetComment().size(), 11);
+ data.WriteBit(guildGUID[4]);
+ data.WriteBit(guildGUID[1]);
+ data.WriteBit(guildGUID[2]);
+ data.WriteBit(guildGUID[6]);
+ data.WriteBit(guildGUID[3]);
+
+ bufferData << uint32(guild->GetEmblemInfo().GetColor());
+ bufferData << uint32(guild->GetEmblemInfo().GetBorderStyle()); // Guessed
+ bufferData << uint32(guild->GetEmblemInfo().GetStyle());
+
+ bufferData.WriteString(guildSettings.GetComment());
+
+ bufferData << uint8(0); // Unk
+
+ bufferData.WriteByteSeq(guildGUID[5]);
+
+ bufferData << uint32(guildSettings.GetInterests());
+
+ bufferData.WriteByteSeq(guildGUID[6]);
+ bufferData.WriteByteSeq(guildGUID[4]);
+
+ bufferData << uint32(guild->GetLevel());
+
+ bufferData.WriteString(guild->GetName());
+
+ bufferData << uint32(guild->GetAchievementMgr().GetAchievementPoints());
+
+ bufferData.WriteByteSeq(guildGUID[7]);
+
+ bufferData << uint8(sGuildFinderMgr->HasRequest(player->GetGUIDLow(), guild->GetGUID())); // Request pending
+
+ bufferData.WriteByteSeq(guildGUID[2]);
+ bufferData.WriteByteSeq(guildGUID[0]);
+
+ bufferData << uint32(guildSettings.GetAvailability());
+
+ bufferData.WriteByteSeq(guildGUID[1]);
+
+ bufferData << uint32(guild->GetEmblemInfo().GetBackgroundColor());
+ bufferData << uint32(0); // Unk Int 2 (+ 128) // Always 0 or 1
+ bufferData << uint32(guild->GetEmblemInfo().GetBorderColor());
+ bufferData << uint32(guildSettings.GetClassRoles());
+
+ bufferData.WriteByteSeq(guildGUID[3]);
+ bufferData << uint32(guild->GetMembersCount());
+ }
+
+ data.FlushBits();
+ data.append(bufferData);
+
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderDeclineRecruit(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_DECLINE_RECRUIT");
+
+ ObjectGuid playerGuid;
+
+ playerGuid[1] = recvPacket.ReadBit();
+ playerGuid[4] = recvPacket.ReadBit();
+ playerGuid[5] = recvPacket.ReadBit();
+ playerGuid[2] = recvPacket.ReadBit();
+ playerGuid[6] = recvPacket.ReadBit();
+ playerGuid[7] = recvPacket.ReadBit();
+ playerGuid[0] = recvPacket.ReadBit();
+ playerGuid[3] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(playerGuid[5]);
+ recvPacket.ReadByteSeq(playerGuid[7]);
+ recvPacket.ReadByteSeq(playerGuid[2]);
+ recvPacket.ReadByteSeq(playerGuid[3]);
+ recvPacket.ReadByteSeq(playerGuid[4]);
+ recvPacket.ReadByteSeq(playerGuid[1]);
+ recvPacket.ReadByteSeq(playerGuid[0]);
+ recvPacket.ReadByteSeq(playerGuid[6]);
+
+ if (!IS_PLAYER_GUID(playerGuid))
+ return;
+
+ sGuildFinderMgr->RemoveMembershipRequest(GUID_LOPART(playerGuid), GetPlayer()->GetGuildId());
+}
+
+void WorldSession::HandleGuildFinderGetApplications(WorldPacket& /*recvPacket*/)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_GET_APPLICATIONS"); // Empty opcode
+
+ std::list<MembershipRequest> applicatedGuilds = sGuildFinderMgr->GetAllMembershipRequestsForPlayer(GetPlayer()->GetGUIDLow());
+ uint32 applicationsCount = applicatedGuilds.size();
+ WorldPacket data(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, 7 + 54 * applicationsCount);
+ data.WriteBits(applicationsCount, 20);
+
+ if (applicationsCount > 0)
+ {
+ ByteBuffer bufferData(54 * applicationsCount);
+ for (std::list<MembershipRequest>::const_iterator itr = applicatedGuilds.begin(); itr != applicatedGuilds.end(); ++itr)
+ {
+ Guild* guild = sGuildMgr->GetGuildById(itr->GetGuildId());
+ LFGuildSettings guildSettings = sGuildFinderMgr->GetGuildSettings(itr->GetGuildId());
+ MembershipRequest request = *itr;
+
+ ObjectGuid guildGuid = ObjectGuid(guild->GetGUID());
+
+ data.WriteBit(guildGuid[1]);
+ data.WriteBit(guildGuid[0]);
+ data.WriteBit(guildGuid[5]);
+ data.WriteBits(request.GetComment().size(), 11);
+ data.WriteBit(guildGuid[3]);
+ data.WriteBit(guildGuid[7]);
+ data.WriteBit(guildGuid[4]);
+ data.WriteBit(guildGuid[6]);
+ data.WriteBit(guildGuid[2]);
+ data.WriteBits(guild->GetName().size(), 8);
+
+ bufferData.WriteByteSeq(guildGuid[2]);
+ bufferData.WriteString(request.GetComment());
+ bufferData.WriteByteSeq(guildGuid[5]);
+ bufferData.WriteString(guild->GetName());
+
+ bufferData << uint32(guildSettings.GetAvailability());
+ bufferData << uint32(request.GetExpiryTime() - time(NULL)); // Time left to application expiry (seconds)
+
+ bufferData.WriteByteSeq(guildGuid[0]);
+ bufferData.WriteByteSeq(guildGuid[6]);
+ bufferData.WriteByteSeq(guildGuid[3]);
+ bufferData.WriteByteSeq(guildGuid[7]);
+
+ bufferData << uint32(guildSettings.GetClassRoles());
+
+ bufferData.WriteByteSeq(guildGuid[4]);
+ bufferData.WriteByteSeq(guildGuid[1]);
+
+ bufferData << uint32(time(NULL) - request.GetSubmitTime()); // Time since application (seconds)
+ bufferData << uint32(guildSettings.GetInterests());
+ }
+
+ data.FlushBits();
+ data.append(bufferData);
+ }
+ data << uint32(10 - sGuildFinderMgr->CountRequestsFromPlayer(GetPlayer()->GetGUIDLow())); // Applications count left
+
+ GetPlayer()->SendDirectMessage(&data);
+}
+
+// Lists all recruits for a guild - Misses times
+void WorldSession::HandleGuildFinderGetRecruits(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_GET_RECRUITS");
+
+ uint32 unkTime = 0;
+ recvPacket >> unkTime;
+
+ Player* player = GetPlayer();
+ if (!player->GetGuildId())
+ return;
+
+ std::vector<MembershipRequest> recruitsList = sGuildFinderMgr->GetAllMembershipRequestsForGuild(player->GetGuildId());
+ uint32 recruitCount = recruitsList.size();
+
+ ByteBuffer dataBuffer(53 * recruitCount);
+ WorldPacket data(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, 7 + 26 * recruitCount + 53 * recruitCount);
+ data.WriteBits(recruitCount, 20);
+
+ for (std::vector<MembershipRequest>::const_iterator itr = recruitsList.begin(); itr != recruitsList.end(); ++itr)
+ {
+ MembershipRequest request = *itr;
+ ObjectGuid playerGuid(MAKE_NEW_GUID(request.GetPlayerGUID(), 0, HIGHGUID_PLAYER));
+
+ data.WriteBits(request.GetComment().size(), 11);
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBits(request.GetName().size(), 7);
+ data.WriteBit(playerGuid[5]);
+ data.WriteBit(playerGuid[1]);
+ data.WriteBit(playerGuid[6]);
+
+ dataBuffer.WriteByteSeq(playerGuid[4]);
+
+ dataBuffer << int32(time(NULL) <= request.GetExpiryTime());
+
+ dataBuffer.WriteByteSeq(playerGuid[3]);
+ dataBuffer.WriteByteSeq(playerGuid[0]);
+ dataBuffer.WriteByteSeq(playerGuid[1]);
+
+ dataBuffer << int32(request.GetLevel());
+
+ dataBuffer.WriteByteSeq(playerGuid[6]);
+ dataBuffer.WriteByteSeq(playerGuid[7]);
+ dataBuffer.WriteByteSeq(playerGuid[2]);
+
+ dataBuffer << int32(time(NULL) - request.GetSubmitTime()); // Time in seconds since application submitted.
+ dataBuffer << int32(request.GetAvailability());
+ dataBuffer << int32(request.GetClassRoles());
+ dataBuffer << int32(request.GetInterests());
+ dataBuffer << int32(request.GetExpiryTime() - time(NULL)); // TIme in seconds until application expires.
+
+ dataBuffer.WriteString(request.GetName());
+ dataBuffer.WriteString(request.GetComment());
+
+ dataBuffer << int32(request.GetClass());
+
+ dataBuffer.WriteByteSeq(playerGuid[5]);
+ }
+
+ data.FlushBits();
+ data.append(dataBuffer);
+ data << uint32(time(NULL)); // Unk time
+
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderPostRequest(WorldPacket& /*recvPacket*/)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_POST_REQUEST"); // Empty opcode
+
+ Player* player = GetPlayer();
+
+ if (!player->GetGuildId()) // Player must be in guild
+ return;
+
+ bool isGuildMaster = true;
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ if (guild->GetLeaderGUID() != player->GetGUID())
+ isGuildMaster = false;
+
+ LFGuildSettings settings = sGuildFinderMgr->GetGuildSettings(player->GetGuildId());
+
+ WorldPacket data(SMSG_LF_GUILD_POST_UPDATED, 35);
+ data.WriteBit(isGuildMaster); // Guessed
+
+ if (isGuildMaster)
+ {
+ data.WriteBit(settings.IsListed());
+ data.WriteBits(settings.GetComment().size(), 11);
+ data << uint32(settings.GetLevel());
+ data.WriteString(settings.GetComment());
+ data << uint32(0); // Unk Int32
+ data << uint32(settings.GetAvailability());
+ data << uint32(settings.GetClassRoles());
+ data << uint32(settings.GetInterests());
+ }
+ else
+ data.FlushBits();
+ player->SendDirectMessage(&data);
+}
+
+void WorldSession::HandleGuildFinderRemoveRecruit(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_REMOVE_RECRUIT");
+
+ ObjectGuid guildGuid;
+
+ guildGuid[0] = recvPacket.ReadBit();
+ guildGuid[4] = recvPacket.ReadBit();
+ guildGuid[3] = recvPacket.ReadBit();
+ guildGuid[5] = recvPacket.ReadBit();
+ guildGuid[7] = recvPacket.ReadBit();
+ guildGuid[6] = recvPacket.ReadBit();
+ guildGuid[2] = recvPacket.ReadBit();
+ guildGuid[1] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guildGuid[4]);
+ recvPacket.ReadByteSeq(guildGuid[0]);
+ recvPacket.ReadByteSeq(guildGuid[3]);
+ recvPacket.ReadByteSeq(guildGuid[6]);
+ recvPacket.ReadByteSeq(guildGuid[5]);
+ recvPacket.ReadByteSeq(guildGuid[1]);
+ recvPacket.ReadByteSeq(guildGuid[2]);
+ recvPacket.ReadByteSeq(guildGuid[7]);
+
+ if (!IS_GUILD_GUID(guildGuid))
+ return;
+
+ sGuildFinderMgr->RemoveMembershipRequest(GetPlayer()->GetGUIDLow(), GUID_LOPART(guildGuid));
+}
+
+// Sent any time a guild master sets an option in the interface and when listing / unlisting his guild
+void WorldSession::HandleGuildFinderSetGuildPost(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_LF_GUILD_SET_GUILD_POST");
+
+ uint32 classRoles = 0;
+ uint32 availability = 0;
+ uint32 guildInterests = 0;
+ uint32 level = 0;
+
+ recvPacket >> level >> availability >> guildInterests >> classRoles;
+ // Level sent is zero if untouched, force to any (from interface). Idk why
+ if (!level)
+ level = ANY_FINDER_LEVEL;
+
+ uint16 length = recvPacket.ReadBits(11);
+ bool listed = recvPacket.ReadBit();
+ std::string comment = recvPacket.ReadString(length);
+
+ if (!(classRoles & GUILDFINDER_ALL_ROLES) || classRoles > GUILDFINDER_ALL_ROLES)
+ return;
+ if (!(availability & AVAILABILITY_ALWAYS) || availability > AVAILABILITY_ALWAYS)
+ return;
+ if (!(guildInterests & ALL_INTERESTS) || guildInterests > ALL_INTERESTS)
+ return;
+ if (!(level & ALL_GUILDFINDER_LEVELS) || level > ALL_GUILDFINDER_LEVELS)
+ return;
+
+ Player* player = GetPlayer();
+
+ if (!player->GetGuildId()) // Player must be in guild
+ return;
+
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId())) // Player must be guild master
+ if (guild->GetLeaderGUID() != player->GetGUID())
+ return;
+
+ LFGuildSettings settings(listed, player->GetTeamId(), player->GetGuildId(), classRoles, availability, guildInterests, level, comment);
+ sGuildFinderMgr->SetGuildSettings(player->GetGuildId(), settings);
+}
diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp
index 9df633a4c5e..5821cba77d6 100644
--- a/src/server/game/Handlers/GuildHandler.cpp
+++ b/src/server/game/Handlers/GuildHandler.cpp
@@ -30,29 +30,21 @@
void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket)
{
- uint32 guildId;
- recvPacket >> guildId;
+ uint64 guildGuid, playerGuid;
+ recvPacket >> guildGuid >> playerGuid;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY [%s]: Guild: %u", GetPlayerInfo().c_str(), guildId);
- if (!guildId)
- return;
-
- if (Guild* guild = sGuildMgr->GetGuildById(guildId))
- guild->HandleQuery(this);
-}
-
-void WorldSession::HandleGuildCreateOpcode(WorldPacket& recvPacket)
-{
- std::string name;
- recvPacket >> name;
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY [%s]: Guild: %u Target: %u",
+ GetPlayerInfo().c_str(), GUID_LOPART(guildGuid), GUID_LOPART(playerGuid));
- TC_LOG_ERROR("guild", "CMSG_GUILD_CREATE: Possible hacking-attempt: %s tried to create a guild [Name: %s] using cheats", GetPlayerInfo().c_str(), name.c_str());
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ if (guild->IsMember(playerGuid))
+ guild->HandleQuery(this);
}
void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
{
- std::string invitedName;
- recvPacket >> invitedName;
+ uint32 nameLength = recvPacket.ReadBits(7);
+ std::string invitedName = recvPacket.ReadString(nameLength);
TC_LOG_DEBUG("guild", "CMSG_GUILD_INVITE [%s]: Invited: %s", GetPlayerInfo().c_str(), invitedName.c_str());
if (normalizePlayerName(invitedName))
@@ -62,19 +54,35 @@ void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket)
void WorldSession::HandleGuildRemoveOpcode(WorldPacket& recvPacket)
{
- std::string playerName;
- recvPacket >> playerName;
+ ObjectGuid playerGuid;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str());
+ playerGuid[6] = recvPacket.ReadBit();
+ playerGuid[5] = recvPacket.ReadBit();
+ playerGuid[4] = recvPacket.ReadBit();
+ playerGuid[0] = recvPacket.ReadBit();
+ playerGuid[1] = recvPacket.ReadBit();
+ playerGuid[3] = recvPacket.ReadBit();
+ playerGuid[7] = recvPacket.ReadBit();
+ playerGuid[2] = recvPacket.ReadBit();
- if (normalizePlayerName(playerName))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleRemoveMember(this, playerName);
+ recvPacket.ReadByteSeq(playerGuid[2]);
+ recvPacket.ReadByteSeq(playerGuid[6]);
+ recvPacket.ReadByteSeq(playerGuid[5]);
+ recvPacket.ReadByteSeq(playerGuid[7]);
+ recvPacket.ReadByteSeq(playerGuid[1]);
+ recvPacket.ReadByteSeq(playerGuid[4]);
+ recvPacket.ReadByteSeq(playerGuid[3]);
+ recvPacket.ReadByteSeq(playerGuid[0]);
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_REMOVE [%s]: Target: %u", GetPlayerInfo().c_str(), GUID_LOPART(playerGuid));
+
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleRemoveMember(this, playerGuid);
}
void WorldSession::HandleGuildAcceptOpcode(WorldPacket& /*recvPacket*/)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [%s]", GetPlayer()->GetName().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_ACCEPT [%s]", GetPlayerInfo().c_str());
if (!GetPlayer()->GetGuildId())
if (Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildIdInvited()))
@@ -89,17 +97,10 @@ void WorldSession::HandleGuildDeclineOpcode(WorldPacket& /*recvPacket*/)
GetPlayer()->SetInGuild(0);
}
-void WorldSession::HandleGuildInfoOpcode(WorldPacket& /*recvPacket*/)
-{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_INFO [%s]", GetPlayerInfo().c_str());
-
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendInfo(this);
-}
-
-void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildRosterOpcode(WorldPacket& recvPacket)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_ROSTER [%s]", GetPlayerInfo().c_str());
+ recvPacket.rfinish();
if (Guild* guild = GetPlayer()->GetGuild())
guild->HandleRoster(this);
@@ -109,26 +110,107 @@ void WorldSession::HandleGuildRosterOpcode(WorldPacket& /*recvPacket*/)
void WorldSession::HandleGuildPromoteOpcode(WorldPacket& recvPacket)
{
- std::string playerName;
- recvPacket >> playerName;
+ ObjectGuid targetGuid;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str());
+ targetGuid[7] = recvPacket.ReadBit();
+ targetGuid[2] = recvPacket.ReadBit();
+ targetGuid[5] = recvPacket.ReadBit();
+ targetGuid[6] = recvPacket.ReadBit();
+ targetGuid[1] = recvPacket.ReadBit();
+ targetGuid[0] = recvPacket.ReadBit();
+ targetGuid[3] = recvPacket.ReadBit();
+ targetGuid[4] = recvPacket.ReadBit();
- if (normalizePlayerName(playerName))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleUpdateMemberRank(this, playerName, false);
+ recvPacket.ReadByteSeq(targetGuid[0]);
+ recvPacket.ReadByteSeq(targetGuid[5]);
+ recvPacket.ReadByteSeq(targetGuid[2]);
+ recvPacket.ReadByteSeq(targetGuid[3]);
+ recvPacket.ReadByteSeq(targetGuid[6]);
+ recvPacket.ReadByteSeq(targetGuid[4]);
+ recvPacket.ReadByteSeq(targetGuid[1]);
+ recvPacket.ReadByteSeq(targetGuid[7]);
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_PROMOTE [%s]: Target: %u", GetPlayerInfo().c_str(), GUID_LOPART(targetGuid));
+
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleUpdateMemberRank(this, targetGuid, false);
}
void WorldSession::HandleGuildDemoteOpcode(WorldPacket& recvPacket)
{
- std::string playerName;
- recvPacket >> playerName;
+ ObjectGuid targetGuid;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %s", GetPlayerInfo().c_str(), playerName.c_str());
+ targetGuid[7] = recvPacket.ReadBit();
+ targetGuid[1] = recvPacket.ReadBit();
+ targetGuid[5] = recvPacket.ReadBit();
+ targetGuid[6] = recvPacket.ReadBit();
+ targetGuid[2] = recvPacket.ReadBit();
+ targetGuid[3] = recvPacket.ReadBit();
+ targetGuid[0] = recvPacket.ReadBit();
+ targetGuid[4] = recvPacket.ReadBit();
- if (normalizePlayerName(playerName))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleUpdateMemberRank(this, playerName, true);
+ recvPacket.ReadByteSeq(targetGuid[1]);
+ recvPacket.ReadByteSeq(targetGuid[2]);
+ recvPacket.ReadByteSeq(targetGuid[7]);
+ recvPacket.ReadByteSeq(targetGuid[5]);
+ recvPacket.ReadByteSeq(targetGuid[6]);
+ recvPacket.ReadByteSeq(targetGuid[0]);
+ recvPacket.ReadByteSeq(targetGuid[4]);
+ recvPacket.ReadByteSeq(targetGuid[3]);
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DEMOTE [%s]: Target: %u", GetPlayerInfo().c_str(), GUID_LOPART(targetGuid));
+
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleUpdateMemberRank(this, targetGuid, true);
+}
+
+void WorldSession::HandleGuildAssignRankOpcode(WorldPacket& recvPacket)
+{
+ ObjectGuid targetGuid;
+ ObjectGuid setterGuid;
+
+ uint32 rankId;
+ recvPacket >> rankId;
+
+ targetGuid[1] = recvPacket.ReadBit();
+ targetGuid[7] = recvPacket.ReadBit();
+ setterGuid[4] = recvPacket.ReadBit();
+ setterGuid[2] = recvPacket.ReadBit();
+ targetGuid[4] = recvPacket.ReadBit();
+ targetGuid[5] = recvPacket.ReadBit();
+ targetGuid[6] = recvPacket.ReadBit();
+ setterGuid[1] = recvPacket.ReadBit();
+ setterGuid[7] = recvPacket.ReadBit();
+ targetGuid[2] = recvPacket.ReadBit();
+ targetGuid[3] = recvPacket.ReadBit();
+ targetGuid[0] = recvPacket.ReadBit();
+ setterGuid[6] = recvPacket.ReadBit();
+ setterGuid[3] = recvPacket.ReadBit();
+ setterGuid[0] = recvPacket.ReadBit();
+ setterGuid[5] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(targetGuid[0]);
+ recvPacket.ReadByteSeq(setterGuid[1]);
+ recvPacket.ReadByteSeq(setterGuid[3]);
+ recvPacket.ReadByteSeq(setterGuid[5]);
+ recvPacket.ReadByteSeq(targetGuid[7]);
+ recvPacket.ReadByteSeq(targetGuid[3]);
+ recvPacket.ReadByteSeq(setterGuid[0]);
+ recvPacket.ReadByteSeq(targetGuid[1]);
+ recvPacket.ReadByteSeq(setterGuid[6]);
+ recvPacket.ReadByteSeq(targetGuid[2]);
+ recvPacket.ReadByteSeq(targetGuid[5]);
+ recvPacket.ReadByteSeq(targetGuid[4]);
+ recvPacket.ReadByteSeq(setterGuid[2]);
+ recvPacket.ReadByteSeq(setterGuid[4]);
+ recvPacket.ReadByteSeq(targetGuid[6]);
+ recvPacket.ReadByteSeq(setterGuid[7]);
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_ASSIGN_MEMBER_RANK [%s]: Target: %u Rank: %u, Issuer: %u",
+ GetPlayerInfo().c_str(), GUID_LOPART(targetGuid), rankId, GUID_LOPART(setterGuid));
+
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleSetMemberRank(this, targetGuid, setterGuid, rankId);
}
void WorldSession::HandleGuildLeaveOpcode(WorldPacket& /*recvPacket*/)
@@ -147,100 +229,85 @@ void WorldSession::HandleGuildDisbandOpcode(WorldPacket& /*recvPacket*/)
guild->HandleDisband(this);
}
-void WorldSession::HandleGuildLeaderOpcode(WorldPacket& recvPacket)
-{
- std::string name;
- recvPacket >> name;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_LEADER [%s]: Target: %s", GetPlayerInfo().c_str(), name.c_str());
-
- if (normalizePlayerName(name))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetLeader(this, name);
-}
-
void WorldSession::HandleGuildMOTDOpcode(WorldPacket& recvPacket)
{
- std::string motd;
- recvPacket >> motd;
-
+ uint32 motdLength = recvPacket.ReadBits(11);
+ std::string motd = recvPacket.ReadString(motdLength);
TC_LOG_DEBUG("guild", "CMSG_GUILD_MOTD [%s]: MOTD: %s", GetPlayerInfo().c_str(), motd.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
guild->HandleSetMOTD(this, motd);
}
-void WorldSession::HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildSetNoteOpcode(WorldPacket& recvPacket)
{
- std::string playerName;
- std::string note;
- recvPacket >> playerName >> note;
+ ObjectGuid playerGuid;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_PUBLIC_NOTE [%s]: Target: %s, Note: %s",
- GetPlayerInfo().c_str(), playerName.c_str(), note.c_str());
-
- if (normalizePlayerName(playerName))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetMemberNote(this, playerName, note, true);
-}
+ playerGuid[1] = recvPacket.ReadBit();
+ playerGuid[4] = recvPacket.ReadBit();
+ playerGuid[5] = recvPacket.ReadBit();
+ playerGuid[3] = recvPacket.ReadBit();
+ playerGuid[0] = recvPacket.ReadBit();
+ playerGuid[7] = recvPacket.ReadBit();
+ bool ispublic = recvPacket.ReadBit(); // 0 == Officer, 1 == Public
+ playerGuid[6] = recvPacket.ReadBit();
+ uint32 noteLength = recvPacket.ReadBits(8);
+ playerGuid[2] = recvPacket.ReadBit();
-void WorldSession::HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket)
-{
- std::string playerName;
- std::string note;
- recvPacket >> playerName >> note;
+ recvPacket.ReadByteSeq(playerGuid[4]);
+ recvPacket.ReadByteSeq(playerGuid[5]);
+ recvPacket.ReadByteSeq(playerGuid[0]);
+ recvPacket.ReadByteSeq(playerGuid[3]);
+ recvPacket.ReadByteSeq(playerGuid[1]);
+ recvPacket.ReadByteSeq(playerGuid[6]);
+ recvPacket.ReadByteSeq(playerGuid[7]);
+ std::string note = recvPacket.ReadString(noteLength);
+ recvPacket.ReadByteSeq(playerGuid[2]);
- TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_OFFICER_NOTE [%s]: Target: %s, Note: %s",
- GetPlayerInfo().c_str(), playerName.c_str(), note.c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_NOTE [%s]: Target: %u, Note: %s, Public: %u",
+ GetPlayerInfo().c_str(), GUID_LOPART(playerGuid), note.c_str(), ispublic);
- if (normalizePlayerName(playerName))
- if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleSetMemberNote(this, playerName, note, false);
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleSetMemberNote(this, note, playerGuid, ispublic);
}
-void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
+void WorldSession::HandleGuildQueryRanksOpcode(WorldPacket& recvPacket)
{
- uint32 rankId;
- recvPacket >> rankId;
-
- uint32 rights;
- recvPacket >> rights;
-
- std::string rankName;
- recvPacket >> rankName;
-
- uint32 money;
- recvPacket >> money;
-
- TC_LOG_DEBUG("guild", "CMSG_GUILD_RANK [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), rankName.c_str(), rankId);
+ ObjectGuid guildGuid;
- Guild* guild = GetPlayer()->GetGuild();
- if (!guild)
- {
- recvPacket.rpos(recvPacket.wpos());
- return;
- }
-
- GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS);
-
- for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
- {
- uint32 bankRights;
- uint32 slots;
+ guildGuid[2] = recvPacket.ReadBit();
+ guildGuid[3] = recvPacket.ReadBit();
+ guildGuid[0] = recvPacket.ReadBit();
+ guildGuid[6] = recvPacket.ReadBit();
+ guildGuid[4] = recvPacket.ReadBit();
+ guildGuid[7] = recvPacket.ReadBit();
+ guildGuid[5] = recvPacket.ReadBit();
+ guildGuid[1] = recvPacket.ReadBit();
- recvPacket >> bankRights;
- recvPacket >> slots;
+ recvPacket.ReadByteSeq(guildGuid[3]);
+ recvPacket.ReadByteSeq(guildGuid[4]);
+ recvPacket.ReadByteSeq(guildGuid[5]);
+ recvPacket.ReadByteSeq(guildGuid[7]);
+ recvPacket.ReadByteSeq(guildGuid[1]);
+ recvPacket.ReadByteSeq(guildGuid[0]);
+ recvPacket.ReadByteSeq(guildGuid[6]);
+ recvPacket.ReadByteSeq(guildGuid[2]);
- rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, bankRights, slots);
- }
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY_RANKS [%s]: Guild: %u",
+ GetPlayerInfo().c_str(), GUID_LOPART(guildGuid));
- guild->HandleSetRankInfo(this, rankId, rankName, rights, money, rightsAndSlots);
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ if (guild->IsMember(_player->GetGUID()))
+ guild->SendGuildRankInfo(this);
}
void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
{
- std::string rankName;
- recvPacket >> rankName;
+ uint32 rankId;
+ recvPacket >> rankId;
+
+ uint32 length = recvPacket.ReadBits(7);
+ std::string rankName = recvPacket.ReadString(length);
TC_LOG_DEBUG("guild", "CMSG_GUILD_ADD_RANK [%s]: Rank: %s", GetPlayerInfo().c_str(), rankName.c_str());
@@ -248,18 +315,21 @@ void WorldSession::HandleGuildAddRankOpcode(WorldPacket& recvPacket)
guild->HandleAddNewRank(this, rankName);
}
-void WorldSession::HandleGuildDelRankOpcode(WorldPacket& /*recvPacket*/)
+void WorldSession::HandleGuildDelRankOpcode(WorldPacket& recvPacket)
{
- TC_LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [%s]", GetPlayerInfo().c_str());
+ uint32 rankId;
+ recvPacket >> rankId;
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_DEL_RANK [%s]: Rank: %u", GetPlayerInfo().c_str(), rankId);
if (Guild* guild = GetPlayer()->GetGuild())
- guild->HandleRemoveLowestRank(this);
+ guild->HandleRemoveRank(this, rankId);
}
void WorldSession::HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket)
{
- std::string info;
- recvPacket >> info;
+ uint32 length = recvPacket.ReadBits(12);
+ std::string info = recvPacket.ReadString(length);
TC_LOG_DEBUG("guild", "CMSG_GUILD_INFO_TEXT [%s]: %s", GetPlayerInfo().c_str(), info.c_str());
@@ -304,32 +374,36 @@ void WorldSession::HandleGuildEventLogQueryOpcode(WorldPacket& /* recvPacket */)
guild->SendEventLog(this);
}
-void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket & /* recvData */)
+void WorldSession::HandleGuildBankMoneyWithdrawn(WorldPacket& /* recvPacket */)
{
- TC_LOG_DEBUG("guild", "MSG_GUILD_BANK_MONEY_WITHDRAWN [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_MONEY_WITHDRAWN [%s]", GetPlayerInfo().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
guild->SendMoneyInfo(this);
}
-void WorldSession::HandleGuildPermissions(WorldPacket& /* recvData */)
+void WorldSession::HandleGuildPermissions(WorldPacket& /* recvPacket */)
{
- TC_LOG_DEBUG("guild", "MSG_GUILD_PERMISSIONS [%s]", GetPlayerInfo().c_str());
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_PERMISSIONS [%s]", GetPlayerInfo().c_str());
if (Guild* guild = GetPlayer()->GetGuild())
guild->SendPermissions(this);
}
// Called when clicking on Guild bank gameobject
-void WorldSession::HandleGuildBankerActivate(WorldPacket& recvData)
+void WorldSession::HandleGuildBankerActivate(WorldPacket& recvPacket)
{
uint64 guid;
bool sendAllSlots;
- recvData >> guid >> sendAllSlots;
+ recvPacket >> guid >> sendAllSlots;
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANKER_ACTIVATE [%s]: Go: [" UI64FMTD "] AllSlots: %u"
, GetPlayerInfo().c_str(), guid, sendAllSlots);
+ GameObject const* const go = GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK);
+ if (!go)
+ return;
+
Guild* const guild = GetPlayer()->GetGuild();
if (!guild)
{
@@ -337,33 +411,33 @@ void WorldSession::HandleGuildBankerActivate(WorldPacket& recvData)
return;
}
- guild->SendBankTabsInfo(this, sendAllSlots);
+ guild->SendBankList(this, 0, true, true);
}
// Called when opening guild bank tab only (first one)
-void WorldSession::HandleGuildBankQueryTab(WorldPacket& recvData)
+void WorldSession::HandleGuildBankQueryTab(WorldPacket& recvPacket)
{
uint64 guid;
uint8 tabId;
- bool full;
+ bool sendAllSlots;
- recvData >> guid >> tabId >> full;
+ recvPacket >> guid >> tabId >> sendAllSlots;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [%s]: Go: [" UI64FMTD "], TabId: %u, ShowTabs: %u"
- , GetPlayerInfo().c_str(), guid, tabId, full);
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_QUERY_TAB [%s]: Go: [" UI64FMTD "], TabId: %u, AllSlots: %u"
+ , GetPlayerInfo().c_str(), guid, tabId, sendAllSlots);
if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
- guild->SendBankTabData(this, tabId);
+ guild->SendBankList(this, tabId, true, false);
}
-void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvData)
+void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvPacket)
{
uint64 guid;
- uint32 money;
- recvData >> guid >> money;
+ uint64 money;
+ recvPacket >> guid >> money;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [%s]: Go: [" UI64FMTD "], money: %u",
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_DEPOSIT_MONEY [%s]: Go: [" UI64FMTD "], money: " UI64FMTD,
GetPlayerInfo().c_str(), guid, money);
if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
@@ -372,13 +446,13 @@ void WorldSession::HandleGuildBankDepositMoney(WorldPacket& recvData)
guild->HandleMemberDepositMoney(this, money);
}
-void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvData)
+void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvPacket)
{
uint64 guid;
- uint32 money;
- recvData >> guid >> money;
+ uint64 money;
+ recvPacket >> guid >> money;
- TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [%s]: Go: [" UI64FMTD "], money: %u",
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_WITHDRAW_MONEY [%s]: Go: [" UI64FMTD "], money: " UI64FMTD,
GetPlayerInfo().c_str(), guid, money);
if (money && GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
@@ -386,28 +460,28 @@ void WorldSession::HandleGuildBankWithdrawMoney(WorldPacket& recvData)
guild->HandleMemberWithdrawMoney(this, money);
}
-void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData)
+void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvPacket)
{
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_SWAP_ITEMS [%s]", GetPlayerInfo().c_str());
uint64 GoGuid;
- recvData >> GoGuid;
+ recvPacket >> GoGuid;
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
{
- recvData.rfinish(); // Prevent additional spam at rejected packet
+ recvPacket.rfinish(); // Prevent additional spam at rejected packet
return;
}
Guild* guild = GetPlayer()->GetGuild();
if (!guild)
{
- recvData.rfinish(); // Prevent additional spam at rejected packet
+ recvPacket.rfinish(); // Prevent additional spam at rejected packet
return;
}
uint8 bankToBank;
- recvData >> bankToBank;
+ recvPacket >> bankToBank;
uint8 tabId;
uint8 slotId;
@@ -417,18 +491,19 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData)
if (bankToBank)
{
uint8 destTabId;
- recvData >> destTabId;
+ recvPacket >> destTabId;
uint8 destSlotId;
- recvData >> destSlotId;
- recvData.read_skip<uint32>(); // Always 0
+ recvPacket >> destSlotId;
- recvData >> tabId;
- recvData >> slotId;
- recvData >> itemEntry;
- recvData.read_skip<uint8>(); // Always 0
+ uint32 destItemEntry;
+ recvPacket >> destItemEntry;
- recvData >> splitedAmount;
+ recvPacket >> tabId;
+ recvPacket >> slotId;
+ recvPacket >> itemEntry;
+ recvPacket.read_skip<uint8>(); // Always 0
+ recvPacket >> splitedAmount;
guild->SwapItems(GetPlayer(), tabId, slotId, destTabId, destSlotId, splitedAmount);
}
@@ -438,71 +513,70 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData)
uint8 playerSlotId = NULL_SLOT;
uint8 toChar = 1;
- recvData >> tabId;
- recvData >> slotId;
- recvData >> itemEntry;
+ recvPacket >> tabId;
+ recvPacket >> slotId;
+ recvPacket >> itemEntry;
uint8 autoStore;
- recvData >> autoStore;
+ recvPacket >> autoStore;
if (autoStore)
{
- recvData.read_skip<uint32>(); // autoStoreCount
- recvData.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char)
- recvData.read_skip<uint32>(); // Always 0
+ recvPacket.read_skip<uint32>(); // autoStoreCount
+ recvPacket.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in Bank -> Char)
+ recvPacket.read_skip<uint32>(); // Always 0
}
else
{
- recvData >> playerBag;
- recvData >> playerSlotId;
- recvData >> toChar;
- recvData >> splitedAmount;
+ recvPacket >> playerBag;
+ recvPacket >> playerSlotId;
+ recvPacket >> toChar;
+ recvPacket >> splitedAmount;
}
// Player <-> Bank
// Allow to work with inventory only
if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT))
- GetPlayer()->SendEquipError(EQUIP_ERR_NONE, NULL);
+ GetPlayer()->SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, NULL);
else
guild->SwapItemsWithInventory(GetPlayer(), toChar, tabId, slotId, playerBag, playerSlotId, splitedAmount);
}
}
-void WorldSession::HandleGuildBankBuyTab(WorldPacket& recvData)
+void WorldSession::HandleGuildBankBuyTab(WorldPacket& recvPacket)
{
uint64 guid;
- uint8 tabId;
+ recvPacket >> guid;
- recvData >> guid >> tabId;
+ uint8 tabId;
+ recvPacket >> tabId;
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_BUY_TAB [%s]: Go: [" UI64FMTD "], TabId: %u", GetPlayerInfo().c_str(), guid, tabId);
-
- if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
+ if (!guid || GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
guild->HandleBuyBankTab(this, tabId);
}
-void WorldSession::HandleGuildBankUpdateTab(WorldPacket& recvData)
+void WorldSession::HandleGuildBankUpdateTab(WorldPacket& recvPacket)
{
uint64 guid;
uint8 tabId;
std::string name, icon;
- recvData >> guid >> tabId >> name >> icon;
+ recvPacket >> guid >> tabId >> name >> icon;
TC_LOG_DEBUG("guild", "CMSG_GUILD_BANK_UPDATE_TAB [%s]: Go: [" UI64FMTD "], TabId: %u, Name: %s, Icon: %s"
, GetPlayerInfo().c_str(), guid, tabId, name.c_str(), icon.c_str());
-
if (!name.empty() && !icon.empty())
if (GetPlayer()->GetGameObjectIfCanInteractWith(guid, GAMEOBJECT_TYPE_GUILD_BANK))
if (Guild* guild = GetPlayer()->GetGuild())
guild->HandleSetBankTabInfo(this, tabId, name, icon);
}
-void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvData)
+void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvPacket)
{
- uint8 tabId;
- recvData >> tabId;
+ uint32 tabId;
+ recvPacket >> tabId;
TC_LOG_DEBUG("guild", "MSG_GUILD_BANK_LOG_QUERY [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId);
@@ -510,10 +584,10 @@ void WorldSession::HandleGuildBankLogQuery(WorldPacket& recvData)
guild->SendBankLog(this, tabId);
}
-void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvData)
+void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvPacket)
{
uint8 tabId;
- recvData >> tabId;
+ recvPacket >> tabId;
TC_LOG_DEBUG("guild", "MSG_QUERY_GUILD_BANK_TEXT [%s]: TabId: %u", GetPlayerInfo().c_str(), tabId);
@@ -521,14 +595,231 @@ void WorldSession::HandleQueryGuildBankTabText(WorldPacket &recvData)
guild->SendBankTabText(this, tabId);
}
-void WorldSession::HandleSetGuildBankTabText(WorldPacket &recvData)
+void WorldSession::HandleSetGuildBankTabText(WorldPacket& recvPacket)
{
- uint8 tabId;
- std::string text;
- recvData >> tabId >> text;
+ uint32 tabId;
+ recvPacket >> tabId;
+
+ uint32 textLen = recvPacket.ReadBits(14);
+ std::string text = recvPacket.ReadString(textLen);
TC_LOG_DEBUG("guild", "CMSG_SET_GUILD_BANK_TEXT [%s]: TabId: %u, Text: %s", GetPlayerInfo().c_str(), tabId, text.c_str());
if (Guild* guild = GetPlayer()->GetGuild())
guild->SetBankTabText(tabId, text);
}
+
+void WorldSession::HandleGuildQueryXPOpcode(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUERY_GUILD_XP");
+
+ ObjectGuid guildGuid;
+
+ guildGuid[2] = recvPacket.ReadBit();
+ guildGuid[1] = recvPacket.ReadBit();
+ guildGuid[0] = recvPacket.ReadBit();
+ guildGuid[5] = recvPacket.ReadBit();
+ guildGuid[4] = recvPacket.ReadBit();
+ guildGuid[7] = recvPacket.ReadBit();
+ guildGuid[6] = recvPacket.ReadBit();
+ guildGuid[3] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guildGuid[7]);
+ recvPacket.ReadByteSeq(guildGuid[2]);
+ recvPacket.ReadByteSeq(guildGuid[3]);
+ recvPacket.ReadByteSeq(guildGuid[6]);
+ recvPacket.ReadByteSeq(guildGuid[1]);
+ recvPacket.ReadByteSeq(guildGuid[5]);
+ recvPacket.ReadByteSeq(guildGuid[0]);
+ recvPacket.ReadByteSeq(guildGuid[4]);
+
+ TC_LOG_DEBUG("guild", "CMSG_QUERY_GUILD_XP [%s]: Guild: %u", GetPlayerInfo().c_str(), GUID_LOPART(guildGuid));
+
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ if (guild->IsMember(_player->GetGUID()))
+ guild->SendGuildXP(this);
+}
+
+void WorldSession::HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket)
+{
+ Guild* guild = GetPlayer()->GetGuild();
+ if (!guild)
+ {
+ recvPacket.rfinish();
+ return;
+ }
+
+ uint32 oldRankId;
+ uint32 newRankId;
+ uint32 oldRights;
+ uint32 newRights;
+ uint32 moneyPerDay;
+
+ recvPacket >> oldRankId;
+ recvPacket >> oldRights;
+ recvPacket >> newRights;
+
+ GuildBankRightsAndSlotsVec rightsAndSlots(GUILD_BANK_MAX_TABS);
+ for (uint8 tabId = 0; tabId < GUILD_BANK_MAX_TABS; ++tabId)
+ {
+ uint32 bankRights;
+ uint32 slots;
+
+ recvPacket >> bankRights;
+ recvPacket >> slots;
+
+ rightsAndSlots[tabId] = GuildBankRightsAndSlots(tabId, uint8(bankRights), slots);
+ }
+
+ recvPacket >> moneyPerDay;
+ recvPacket >> newRankId;
+ uint32 nameLength = recvPacket.ReadBits(7);
+ std::string rankName = recvPacket.ReadString(nameLength);
+
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_SET_RANK_PERMISSIONS [%s]: Rank: %s (%u)", GetPlayerInfo().c_str(), rankName.c_str(), newRankId);
+
+ guild->HandleSetRankInfo(this, newRankId, rankName, newRights, moneyPerDay, rightsAndSlots);
+}
+
+void WorldSession::HandleGuildRequestPartyState(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_GUILD_REQUEST_PARTY_STATE");
+
+ ObjectGuid guildGuid;
+
+ guildGuid[0] = recvPacket.ReadBit();
+ guildGuid[6] = recvPacket.ReadBit();
+ guildGuid[7] = recvPacket.ReadBit();
+ guildGuid[3] = recvPacket.ReadBit();
+ guildGuid[5] = recvPacket.ReadBit();
+ guildGuid[1] = recvPacket.ReadBit();
+ guildGuid[2] = recvPacket.ReadBit();
+ guildGuid[4] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guildGuid[6]);
+ recvPacket.ReadByteSeq(guildGuid[3]);
+ recvPacket.ReadByteSeq(guildGuid[2]);
+ recvPacket.ReadByteSeq(guildGuid[1]);
+ recvPacket.ReadByteSeq(guildGuid[5]);
+ recvPacket.ReadByteSeq(guildGuid[0]);
+ recvPacket.ReadByteSeq(guildGuid[7]);
+ recvPacket.ReadByteSeq(guildGuid[4]);
+
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(guildGuid))
+ guild->HandleGuildPartyRequest(this);
+}
+
+void WorldSession::HandleGuildRequestMaxDailyXP(WorldPacket& recvPacket)
+{
+ ObjectGuid guid;
+ guid[0] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ guid[2] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[5]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[0]);
+
+ if (Guild* guild = sGuildMgr->GetGuildByGuid(guid))
+ {
+ if (guild->IsMember(_player->GetGUID()))
+ {
+ WorldPacket data(SMSG_GUILD_MAX_DAILY_XP, 8);
+ data << uint64(sWorld->getIntConfig(CONFIG_GUILD_DAILY_XP_CAP));
+ SendPacket(&data);
+ }
+ }
+}
+
+void WorldSession::HandleAutoDeclineGuildInvites(WorldPacket& recvPacket)
+{
+ uint8 enable;
+ recvPacket >> enable;
+
+ GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_AUTO_DECLINE_GUILD, enable);
+}
+
+void WorldSession::HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket)
+{
+ recvPacket.read_skip<uint32>(); // Unk
+
+ if (sGuildMgr->GetGuildById(_player->GetGuildId()))
+ {
+ std::vector<GuildReward> const& rewards = sGuildMgr->GetGuildRewards();
+
+ WorldPacket data(SMSG_GUILD_REWARDS_LIST, 3 + rewards.size() * (4 + 4 + 4 + 8 + 4 + 4));
+ data.WriteBits(rewards.size(), 21);
+ data.FlushBits();
+
+ for (uint32 i = 0; i < rewards.size(); i++)
+ {
+ data << uint32(rewards[i].Standing);
+ data << int32(rewards[i].Racemask);
+ data << uint32(rewards[i].Entry);
+ data << uint64(rewards[i].Price);
+ data << uint32(0); // Unused
+ data << uint32(rewards[i].AchievementId);
+ }
+ data << uint32(time(NULL));
+ SendPacket(&data);
+ }
+}
+
+void WorldSession::HandleGuildQueryNewsOpcode(WorldPacket& recvPacket)
+{
+ recvPacket.read_skip<uint32>();
+ TC_LOG_DEBUG("guild", "CMSG_GUILD_QUERY_NEWS [%s]", GetPlayerInfo().c_str());
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->SendNewsUpdate(this);
+}
+
+void WorldSession::HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket)
+{
+ uint32 newsId;
+ bool sticky;
+ ObjectGuid guid;
+
+ recvPacket >> newsId;
+
+ guid[2] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ sticky = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[5]);
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[4]);
+
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleNewsSetSticky(this, newsId, sticky);
+}
+
+void WorldSession::HandleGuildSetGuildMaster(WorldPacket& recvPacket)
+{
+ uint8 nameLength = recvPacket.ReadBits(7);
+ // This is related to guild master inactivity.
+ /*bool isDethrone = */recvPacket.ReadBit();
+ std::string playerName = recvPacket.ReadString(nameLength);
+ if (Guild* guild = GetPlayer()->GetGuild())
+ guild->HandleSetNewGuildMaster(this, playerName);
+}
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 3571410fd5c..323d5f5e489 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -27,6 +27,8 @@
#include "UpdateData.h"
#include "ObjectAccessor.h"
#include "SpellInfo.h"
+#include "DB2Stores.h"
+#include <vector>
void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData)
{
@@ -54,7 +56,7 @@ void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData)
if (!_player->IsValidPos(dstbag, dstslot, false)) // can be autostore pos
{
- _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, NULL, NULL);
return;
}
@@ -81,7 +83,7 @@ void WorldSession::HandleSwapInvItemOpcode(WorldPacket& recvData)
if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, true))
{
- _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, NULL, NULL);
return;
}
@@ -133,7 +135,7 @@ void WorldSession::HandleSwapItem(WorldPacket& recvData)
if (!_player->IsValidPos(dstbag, dstslot, true))
{
- _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, NULL, NULL);
return;
}
@@ -236,7 +238,7 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket& recvData)
void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
{
- //TC_LOG_DEBUG("network", "WORLD: CMSG_DESTROYITEM");
+ //TC_LOG_DEBUG("network", "WORLD: CMSG_DESTROY_ITEM");
uint8 bag, slot, count, data1, data2, data3;
recvData >> bag >> slot >> count >> data1 >> data2 >> data3;
@@ -264,7 +266,7 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
if (pItem->GetTemplate()->Flags & ITEM_PROTO_FLAG_INDESTRUCTIBLE)
{
- _player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, NULL, NULL);
+ _player->SendEquipError(EQUIP_ERR_DROP_BOUND_ITEM, NULL, NULL);
return;
}
@@ -277,174 +279,11 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData)
_player->DestroyItem(bag, slot, true);
}
-// Only _static_ data send in this packet !!!
-void WorldSession::HandleItemQuerySingleOpcode(WorldPacket& recvData)
-{
- //TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE");
- uint32 item;
- recvData >> item;
-
- TC_LOG_INFO("network", "STORAGE: Item Query = %u", item);
-
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item);
- if (pProto)
- {
- std::string Name = pProto->Name1;
- std::string Description = pProto->Description;
-
- int loc_idx = GetSessionDbLocaleIndex();
- if (loc_idx >= 0)
- {
- if (ItemLocale const* il = sObjectMgr->GetItemLocale(pProto->ItemId))
- {
- ObjectMgr::GetLocaleString(il->Name, loc_idx, Name);
- ObjectMgr::GetLocaleString(il->Description, loc_idx, Description);
- }
- }
- // guess size
- WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 600);
- data << pProto->ItemId;
- data << pProto->Class;
- data << pProto->SubClass;
- data << pProto->SoundOverrideSubclass;
- data << Name;
- data << uint8(0x00); //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...
- data << uint8(0x00); //pProto->Name3; // blizz not send name there, just uint8(0x00);
- data << uint8(0x00); //pProto->Name4; // blizz not send name there, just uint8(0x00);
- data << pProto->DisplayInfoID;
- data << pProto->Quality;
- data << pProto->Flags;
- data << pProto->Flags2;
- data << pProto->BuyPrice;
- data << pProto->SellPrice;
- data << pProto->InventoryType;
- data << pProto->AllowableClass;
- data << pProto->AllowableRace;
- data << pProto->ItemLevel;
- data << pProto->RequiredLevel;
- data << pProto->RequiredSkill;
- data << pProto->RequiredSkillRank;
- data << pProto->RequiredSpell;
- data << pProto->RequiredHonorRank;
- data << pProto->RequiredCityRank;
- data << pProto->RequiredReputationFaction;
- data << pProto->RequiredReputationRank;
- data << int32(pProto->MaxCount);
- data << int32(pProto->Stackable);
- data << pProto->ContainerSlots;
- data << pProto->StatsCount; // item stats count
- for (uint32 i = 0; i < pProto->StatsCount; ++i)
- {
- data << pProto->ItemStat[i].ItemStatType;
- data << pProto->ItemStat[i].ItemStatValue;
- }
- data << pProto->ScalingStatDistribution; // scaling stats distribution
- data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column
- for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i)
- {
- data << pProto->Damage[i].DamageMin;
- data << pProto->Damage[i].DamageMax;
- data << pProto->Damage[i].DamageType;
- }
-
- // resistances (7)
- data << pProto->Armor;
- data << pProto->HolyRes;
- data << pProto->FireRes;
- data << pProto->NatureRes;
- data << pProto->FrostRes;
- data << pProto->ShadowRes;
- data << pProto->ArcaneRes;
-
- data << pProto->Delay;
- data << pProto->AmmoType;
- data << pProto->RangedModRange;
-
- for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
- {
- // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown
- // use `item_template` or if not set then only use spell cooldowns
- SpellInfo const* spell = sSpellMgr->GetSpellInfo(pProto->Spells[s].SpellId);
- if (spell)
- {
- bool db_data = pProto->Spells[s].SpellCooldown >= 0 || pProto->Spells[s].SpellCategoryCooldown >= 0;
-
- data << pProto->Spells[s].SpellId;
- data << pProto->Spells[s].SpellTrigger;
- data << uint32(-abs(pProto->Spells[s].SpellCharges));
-
- if (db_data)
- {
- data << uint32(pProto->Spells[s].SpellCooldown);
- data << uint32(pProto->Spells[s].SpellCategory);
- data << uint32(pProto->Spells[s].SpellCategoryCooldown);
- }
- else
- {
- data << uint32(spell->RecoveryTime);
- data << uint32(spell->GetCategory());
- data << uint32(spell->CategoryRecoveryTime);
- }
- }
- else
- {
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(-1);
- data << uint32(0);
- data << uint32(-1);
- }
- }
- data << pProto->Bonding;
- data << Description;
- data << pProto->PageText;
- data << pProto->LanguageID;
- data << pProto->PageMaterial;
- data << pProto->StartQuest;
- data << pProto->LockID;
- data << int32(pProto->Material);
- data << pProto->Sheath;
- data << pProto->RandomProperty;
- data << pProto->RandomSuffix;
- data << pProto->Block;
- data << pProto->ItemSet;
- data << pProto->MaxDurability;
- data << pProto->Area;
- data << pProto->Map; // Added in 1.12.x & 2.0.1 client branch
- data << pProto->BagFamily;
- data << pProto->TotemCategory;
- for (int s = 0; s < MAX_ITEM_PROTO_SOCKETS; ++s)
- {
- data << pProto->Socket[s].Color;
- data << pProto->Socket[s].Content;
- }
- data << pProto->socketBonus;
- data << pProto->GemProperties;
- data << pProto->RequiredDisenchantSkill;
- data << pProto->ArmorDamageModifier;
- data << pProto->Duration; // added in 2.4.2.8209, duration (seconds)
- data << pProto->ItemLimitCategory; // WotLK, ItemLimitCategory
- data << pProto->HolidayId; // Holiday.dbc?
- SendPacket(&data);
- }
- else
- {
- TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_QUERY_SINGLE - NO item INFO! (ENTRY: %u)", item);
- WorldPacket data(SMSG_ITEM_QUERY_SINGLE_RESPONSE, 4);
- data << uint32(item | 0x80000000);
- SendPacket(&data);
- }
-}
-
void WorldSession::HandleReadItem(WorldPacket& recvData)
{
- //TC_LOG_DEBUG("network", "WORLD: CMSG_READ_ITEM");
-
uint8 bag, slot;
recvData >> bag >> slot;
- //TC_LOG_INFO("network", "STORAGE: Read bag = %u, slot = %u", bag, slot);
Item* pItem = _player->GetItemByPos(bag, slot);
if (pItem && pItem->GetTemplate()->PageText)
@@ -454,7 +293,7 @@ void WorldSession::HandleReadItem(WorldPacket& recvData)
InventoryResult msg = _player->CanUseItem(pItem);
if (msg == EQUIP_ERR_OK)
{
- data.Initialize (SMSG_READ_ITEM_OK, 8);
+ data.Initialize(SMSG_READ_ITEM_OK, 8);
TC_LOG_INFO("network", "STORAGE: Item page sent");
}
else
@@ -470,19 +309,6 @@ void WorldSession::HandleReadItem(WorldPacket& recvData)
_player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
}
-void WorldSession::HandlePageQuerySkippedOpcode(WorldPacket& recvData)
-{
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_PAGE_TEXT_QUERY");
-
- uint32 itemid;
- uint64 guid;
-
- recvData >> itemid >> guid;
-
- TC_LOG_INFO("network", "Packet Info: itemid: %u guidlow: %u guidentry: %u guidhigh: %u",
- itemid, GUID_LOPART(guid), GUID_ENPART(guid), GUID_HIPART(guid));
-}
-
void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_SELL_ITEM");
@@ -498,7 +324,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
if (!creature)
{
TC_LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid)));
- _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, itemguid);
return;
}
@@ -512,21 +338,21 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
// prevent sell not owner item
if (_player->GetGUID() != pItem->GetOwnerGUID())
{
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
// prevent sell non empty bag by drag-and-drop at vendor's item list
if (pItem->IsNotEmptyBag())
{
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
// prevent sell currently looted item
if (_player->GetLootGUID() == pItem->GetGUID())
{
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
@@ -544,7 +370,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
// prevent sell more items that exist in stack (possible only not from client)
if (count > pItem->GetCount())
{
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
}
@@ -560,7 +386,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
if (!pNewItem)
{
TC_LOG_ERROR("network", "WORLD: HandleSellItemOpcode - could not create clone of item %u; count = %u", pItem->GetEntry(), count);
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
@@ -587,11 +413,11 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData)
_player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS, money);
}
else
- _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_SELL_ITEM, creature, itemguid);
return;
}
}
- _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, creature, itemguid, 0);
+ _player->SendSellError(SELL_ERR_CANT_FIND_ITEM, creature, itemguid);
return;
}
@@ -607,7 +433,7 @@ void WorldSession::HandleBuybackItem(WorldPacket& recvData)
if (!creature)
{
TC_LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorguid)));
- _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
+ _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0);
return;
}
@@ -619,7 +445,7 @@ void WorldSession::HandleBuybackItem(WorldPacket& recvData)
if (pItem)
{
uint32 price = _player->GetUInt32Value(PLAYER_FIELD_BUYBACK_PRICE_1 + slot - BUYBACK_SLOT_START);
- if (!_player->HasEnoughMoney(price))
+ if (!_player->HasEnoughMoney(uint64(price)))
{
_player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, pItem->GetEntry(), 0);
return;
@@ -659,24 +485,15 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recvData)
return; // cheating
uint8 bag = NULL_BAG; // init for case invalid bagGUID
-
+ Item* bagItem = NULL;
// find bag slot by bag guid
if (bagguid == _player->GetGUID())
bag = INVENTORY_SLOT_BAG_0;
else
- {
- for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
- {
- if (Bag* pBag = _player->GetBagByPos(i))
- {
- if (bagguid == pBag->GetGUID())
- {
- bag = i;
- break;
- }
- }
- }
- }
+ bagItem = _player->GetItemByGuid(bagguid);
+
+ if (bagItem && bagItem->IsBag())
+ bag = bagItem->GetSlot();
// bag not found, cheating?
if (bag == NULL_BAG)
@@ -688,11 +505,12 @@ void WorldSession::HandleBuyItemInSlotOpcode(WorldPacket& recvData)
void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUY_ITEM");
- uint64 vendorguid;
+ uint64 vendorguid, bagGuid;
uint32 item, slot, count;
- uint8 unk1;
+ uint8 itemType; // 1 = item, 2 = currency
+ uint8 bagSlot;
- recvData >> vendorguid >> item >> slot >> count >> unk1;
+ recvData >> vendorguid >> itemType >> item >> slot >> count >> bagGuid >> bagSlot;
// client expects count starting at 1, and we send vendorslot+1 to client already
if (slot > 0)
@@ -700,7 +518,22 @@ void WorldSession::HandleBuyItemOpcode(WorldPacket& recvData)
else
return; // cheating
- GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
+ if (itemType == ITEM_VENDOR_TYPE_ITEM)
+ {
+ Item* bagItem = _player->GetItemByGuid(bagGuid);
+
+ uint8 bag = NULL_BAG;
+ if (bagItem && bagItem->IsBag())
+ bag = bagItem->GetSlot();
+ else if (bagGuid == GetPlayer()->GetGUID()) // The client sends the player guid when trying to store an item in the default backpack
+ bag = INVENTORY_SLOT_BAG_0;
+
+ GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagSlot);
+ }
+ else if (itemType == ITEM_VENDOR_TYPE_CURRENCY)
+ GetPlayer()->BuyCurrencyFromVendorSlot(vendorguid, slot, item, count);
+ else
+ TC_LOG_DEBUG("network", "WORLD: received wrong itemType (%u) in HandleBuyItemOpcode", itemType);
}
void WorldSession::HandleListInventoryOpcode(WorldPacket& recvData)
@@ -725,7 +558,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
if (!vendor)
{
TC_LOG_DEBUG("network", "WORLD: SendListInventory - Unit (GUID: %u) not found or you can not interact with him.", uint32(GUID_LOPART(vendorGuid)));
- _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0, 0);
+ _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, 0);
return;
}
@@ -737,79 +570,155 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
if (vendor->HasUnitState(UNIT_STATE_MOVING))
vendor->StopMoving();
- VendorItemData const* items = vendor->GetVendorItems();
- if (!items)
- {
- WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + 1);
- data << uint64(vendorGuid);
- data << uint8(0); // count == 0, next will be error code
- data << uint8(0); // "Vendor has no inventory"
- SendPacket(&data);
- return;
- }
+ VendorItemData const* vendorItems = vendor->GetVendorItems();
+ uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
- uint8 itemCount = items->GetItemCount();
- uint8 count = 0;
-
- WorldPacket data(SMSG_LIST_INVENTORY, 8 + 1 + itemCount * 8 * 4);
- data << uint64(vendorGuid);
+ //if (rawItemCount > 300),
+ // rawItemCount = 300; // client cap but uint8 max value is 255
- size_t countPos = data.wpos();
- data << uint8(count);
+ ByteBuffer itemsData(32 * rawItemCount);
+ std::vector<bool> enablers;
+ enablers.reserve(2 * rawItemCount);
- float discountMod = _player->GetReputationPriceDiscount(vendor);
-
- for (uint8 slot = 0; slot < itemCount; ++slot)
+ const float discountMod = _player->GetReputationPriceDiscount(vendor);
+ uint8 count = 0;
+ for (uint32 slot = 0; slot < rawItemCount; ++slot)
{
- if (VendorItem const* item = items->GetItem(slot))
+ VendorItem const* vendorItem = vendorItems->GetItem(slot);
+ if (!vendorItem)
+ continue;
+
+ if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM)
{
- if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(item->item))
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(vendorItem->item);
+ if (!itemTemplate)
+ continue;
+
+ uint32 leftInStock = !vendorItem->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(vendorItem);
+ if (!_player->IsGameMaster()) // ignore conditions if GM on
{
- if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP && !_player->IsGameMaster())
+ // Respect allowed class
+ if (!(itemTemplate->AllowableClass & _player->getClassMask()) && itemTemplate->Bonding == BIND_WHEN_PICKED_UP)
continue;
- // Only display items in vendor lists for the team the
- // player is on. If GM on, display all items.
- if (!_player->IsGameMaster() && ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) || (itemTemplate->Flags2 == ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE)))
+
+ // Only display items in vendor lists for the team the player is on
+ if ((itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_HORDE_ONLY && _player->GetTeam() == ALLIANCE) ||
+ (itemTemplate->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY && _player->GetTeam() == HORDE))
continue;
// Items sold out are not displayed in list
- uint32 leftInStock = !item->maxcount ? 0xFFFFFFFF : vendor->GetVendorItemCurrentCount(item);
- if (!_player->IsGameMaster() && !leftInStock)
+ if (leftInStock == 0)
continue;
+ }
- ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), item->item);
- if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
- {
- TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), item->item);
- continue;
- }
+ ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), vendorItem->item);
+ if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
+ {
+ TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), vendorItem->item);
+ continue;
+ }
+
+ int32 price = vendorItem->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
- // reputation discount
- int32 price = item->IsGoldRequired(itemTemplate) ? uint32(floor(itemTemplate->BuyPrice * discountMod)) : 0;
+ if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES))
+ price -= CalculatePct(price, priceMod);
- data << uint32(slot + 1); // client expects counting to start at 1
- data << uint32(item->item);
- data << uint32(itemTemplate->DisplayInfoID);
- data << int32(leftInStock);
- data << uint32(price);
- data << uint32(itemTemplate->MaxDurability);
- data << uint32(itemTemplate->BuyCount);
- data << uint32(item->ExtendedCost);
+ itemsData << uint32(slot + 1); // client expects counting to start at 1
+ itemsData << uint32(itemTemplate->MaxDurability);
- if (++count >= MAX_VENDOR_ITEMS)
- break;
+ 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;
}
- }
+ else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY)
+ {
+ CurrencyTypesEntry const* currencyTemplate = sCurrencyTypesStore.LookupEntry(vendorItem->item);
+ if (!currencyTemplate)
+ continue;
- if (count == 0)
- {
- data << uint8(0);
- SendPacket(&data);
- return;
+ 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;
+ }
+ // else error
}
- data.put<uint8>(countPos, count);
+ 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]);
+
+ 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());
+
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[7]);
+
SendPacket(&data);
}
@@ -827,7 +736,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData)
if (!_player->IsValidPos(dstbag, NULL_SLOT, false)) // can be autostore pos
{
- _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL);
+ _player->SendEquipError(EQUIP_ERR_WRONG_SLOT, NULL, NULL);
return;
}
@@ -856,7 +765,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData)
if (dest.size() == 1 && dest[0].pos == src)
{
// just remove grey item state
- _player->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
+ _player->SendEquipError(EQUIP_ERR_INTERNAL_BAG_ERROR, pItem, NULL);
return;
}
@@ -901,7 +810,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
uint32 price = slotEntry->price;
- if (!_player->HasEnoughMoney(price))
+ if (!_player->HasEnoughMoney(uint64(price)))
{
data << uint32(ERR_BANKSLOT_INSUFFICIENT_FUNDS);
SendPacket(&data);
@@ -909,7 +818,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& recvPacket)
}
_player->SetBankBagSlotCount(slot);
- _player->ModifyMoney(-int32(price));
+ _player->ModifyMoney(-int64(price));
data << uint32(ERR_BANKSLOT_OK);
SendPacket(&data);
@@ -939,7 +848,7 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket)
if (dest.size() == 1 && dest[0].pos == pItem->GetPos())
{
- _player->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_SWAP, pItem, NULL);
return;
}
@@ -989,36 +898,9 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket)
}
}
-void WorldSession::HandleSetAmmoOpcode(WorldPacket& recvData)
-{
- if (!_player->IsAlive())
- {
- _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL);
- return;
- }
-
- TC_LOG_DEBUG("network", "WORLD: CMSG_SET_AMMO");
- uint32 item;
-
- recvData >> item;
-
- if (item)
- {
- if (!_player->GetItemCount(item))
- {
- _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL);
- return;
- }
-
- _player->SetAmmo(item);
- }
- else
- _player->RemoveAmmo();
-}
-
void WorldSession::SendEnchantmentLog(uint64 target, uint64 caster, uint32 itemId, uint32 enchantId)
{
- WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4)); // last check 2.0.10
+ WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4));
data.appendPackGUID(target);
data.appendPackGUID(caster);
data << uint32(itemId);
@@ -1037,30 +919,6 @@ void WorldSession::SendItemEnchantTimeUpdate(uint64 Playerguid, uint64 Itemguid,
SendPacket(&data);
}
-void WorldSession::HandleItemNameQueryOpcode(WorldPacket& recvData)
-{
- uint32 itemid;
- recvData >> itemid;
- recvData.read_skip<uint64>(); // guid
-
- TC_LOG_DEBUG("network", "WORLD: CMSG_ITEM_NAME_QUERY %u", itemid);
- ItemSetNameEntry const* pName = sObjectMgr->GetItemSetNameEntry(itemid);
- if (pName)
- {
- std::string Name = pName->name;
- int loc_idx = GetSessionDbLocaleIndex();
- if (loc_idx >= 0)
- if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid))
- ObjectMgr::GetLocaleString(isnl->Name, loc_idx, Name);
-
- WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+Name.size()+1+4));
- data << uint32(itemid);
- data << Name;
- data << uint32(pName->InventoryType);
- SendPacket(&data);
- }
-}
-
void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "Received opcode CMSG_WRAP_ITEM");
@@ -1095,44 +953,44 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData)
if (item == gift) // not possable with pacjket from real client
{
- _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_WRAPPED, item, NULL);
return;
}
if (item->IsEquipped())
{
- _player->SendEquipError(EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_EQUIPPED, item, NULL);
return;
}
if (item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED);
{
- _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_WRAPPED, item, NULL);
return;
}
if (item->IsBag())
{
- _player->SendEquipError(EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_BAGS, item, NULL);
return;
}
if (item->IsSoulBound())
{
- _player->SendEquipError(EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_BOUND, item, NULL);
return;
}
if (item->GetMaxStackCount() != 1)
{
- _player->SendEquipError(EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_STACKABLE, item, NULL);
return;
}
// maybe not correct check (it is better than nothing)
- if (item->GetTemplate()->MaxCount>0)
+ if (item->GetTemplate()->MaxCount > 0)
{
- _player->SendEquipError(EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, NULL);
+ _player->SendEquipError(EQUIP_ERR_CANT_WRAP_UNIQUE, item, NULL);
return;
}
@@ -1236,6 +1094,14 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
// tried to put meta gem in normal socket
if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
return;
+
+ // tried to put normal gem in cogwheel socket
+ if (itemProto->Socket[i].Color == SOCKET_COLOR_COGWHEEL && GemProps[i]->color != SOCKET_COLOR_COGWHEEL)
+ return;
+
+ // tried to put cogwheel gem in normal socket
+ if (itemProto->Socket[i].Color != SOCKET_COLOR_COGWHEEL && GemProps[i]->color == SOCKET_COLOR_COGWHEEL)
+ return;
}
uint32 GemEnchants[MAX_GEM_SOCKETS];
@@ -1344,7 +1210,10 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
{
itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0, _player->GetGUID());
if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
- _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
+ {
+ uint32 gemCount = 1;
+ _player->DestroyItemCount(guidItem, gemCount, true);
+ }
}
}
@@ -1372,15 +1241,15 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_CANCEL_TEMP_ENCHANTMENT");
- uint32 eslot;
+ uint32 slot;
- recvData >> eslot;
+ recvData >> slot;
// apply only to equipped item
- if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, eslot))
+ if (!Player::IsEquipmentPos(INVENTORY_SLOT_BAG_0, slot))
return;
- Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, eslot);
+ Item* item = GetPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item)
return;
@@ -1437,7 +1306,7 @@ void WorldSession::HandleItemTextQuery(WorldPacket& recvData )
TC_LOG_DEBUG("network", "CMSG_ITEM_TEXT_QUERY item guid: %u", GUID_LOPART(itemGuid));
- WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, (4+10)); // guess size
+ WorldPacket data(SMSG_ITEM_TEXT_QUERY_RESPONSE, 14); // guess size
if (Item* item = _player->GetItemByGuid(itemGuid))
{
@@ -1452,3 +1321,266 @@ void WorldSession::HandleItemTextQuery(WorldPacket& recvData )
SendPacket(&data);
}
+
+void WorldSession::HandleTransmogrifyItems(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_TRANSMOGRIFY_ITEMS");
+ Player* player = GetPlayer();
+
+ // Read data
+ uint32 count = recvData.ReadBits(22);
+
+ if (count >= EQUIPMENT_SLOT_END)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) sent a wrong count (%u) when transmogrifying items.", player->GetGUIDLow(), player->GetName().c_str(), count);
+ recvData.rfinish();
+ return;
+ }
+
+ std::vector<ObjectGuid> itemGuids(count, ObjectGuid(0));
+ std::vector<uint32> newEntries(count, 0);
+ std::vector<uint32> slots(count, 0);
+
+ for (uint8 i = 0; i < count; ++i)
+ {
+ itemGuids[i][0] = recvData.ReadBit();
+ itemGuids[i][5] = recvData.ReadBit();
+ itemGuids[i][6] = recvData.ReadBit();
+ itemGuids[i][2] = recvData.ReadBit();
+ itemGuids[i][3] = recvData.ReadBit();
+ itemGuids[i][7] = recvData.ReadBit();
+ itemGuids[i][4] = recvData.ReadBit();
+ itemGuids[i][1] = recvData.ReadBit();
+ }
+
+ ObjectGuid npcGuid;
+ npcGuid[7] = recvData.ReadBit();
+ npcGuid[3] = recvData.ReadBit();
+ npcGuid[5] = recvData.ReadBit();
+ npcGuid[6] = recvData.ReadBit();
+ npcGuid[1] = recvData.ReadBit();
+ npcGuid[4] = recvData.ReadBit();
+ npcGuid[0] = recvData.ReadBit();
+ npcGuid[2] = recvData.ReadBit();
+
+ recvData.FlushBits();
+
+ for (uint32 i = 0; i < count; ++i)
+ {
+ recvData >> newEntries[i];
+
+ recvData.ReadByteSeq(itemGuids[i][1]);
+ recvData.ReadByteSeq(itemGuids[i][5]);
+ recvData.ReadByteSeq(itemGuids[i][0]);
+ recvData.ReadByteSeq(itemGuids[i][4]);
+ recvData.ReadByteSeq(itemGuids[i][6]);
+ recvData.ReadByteSeq(itemGuids[i][7]);
+ recvData.ReadByteSeq(itemGuids[i][3]);
+ recvData.ReadByteSeq(itemGuids[i][2]);
+
+ recvData >> slots[i];
+ }
+
+ recvData.ReadByteSeq(npcGuid[7]);
+ recvData.ReadByteSeq(npcGuid[2]);
+ recvData.ReadByteSeq(npcGuid[5]);
+ recvData.ReadByteSeq(npcGuid[4]);
+ recvData.ReadByteSeq(npcGuid[3]);
+ recvData.ReadByteSeq(npcGuid[1]);
+ recvData.ReadByteSeq(npcGuid[6]);
+ recvData.ReadByteSeq(npcGuid[0]);
+
+ // Validate
+
+ if (!player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_TRANSMOGRIFIER))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
+ return;
+ }
+
+ int32 cost = 0;
+ for (uint8 i = 0; i < count; ++i)
+ {
+ // slot of the transmogrified item
+ if (slots[i] >= EQUIPMENT_SLOT_END)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify an item (lowguid: %u) with a wrong slot (%u) when transmogrifying items.", player->GetGUIDLow(), player->GetName().c_str(), GUID_LOPART(itemGuids[i]), slots[i]);
+ return;
+ }
+
+ // entry of the transmogrifier item, if it's not 0
+ if (newEntries[i])
+ {
+ ItemTemplate const* proto = sObjectMgr->GetItemTemplate(newEntries[i]);
+ if (!proto)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify to an invalid item (entry: %u).", player->GetGUIDLow(), player->GetName().c_str(), newEntries[i]);
+ return;
+ }
+ }
+
+ Item* itemTransmogrifier = NULL;
+ // guid of the transmogrifier item, if it's not 0
+ if (itemGuids[i])
+ {
+ itemTransmogrifier = player->GetItemByGuid(itemGuids[i]);
+ if (!itemTransmogrifier)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify with an invalid item (lowguid: %u).", player->GetGUIDLow(), player->GetName().c_str(), GUID_LOPART(itemGuids[i]));
+ return;
+ }
+ }
+
+ // transmogrified item
+ Item* itemTransmogrified = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slots[i]);
+ if (!itemTransmogrified)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) tried to transmogrify an invalid item in a valid slot (slot: %u).", player->GetGUIDLow(), player->GetName().c_str(), slots[i]);
+ return;
+ }
+
+ // uint16 tempDest;
+ //// has to be able to equip item transmogrified item
+ //if (!player->CanEquipItem(slots[i], tempDest, itemTransmogrified, true, true))
+ //{
+ // TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) can't equip the item to be transmogrified (slot: %u, entry: %u).", player->GetGUIDLow(), player->GetName().c_str(), slots[i], itemTransmogrified->GetEntry());
+ // return;
+ //}
+ //
+ //// has to be able to equip item transmogrifier item
+ //if (!player->CanEquipItem(slots[i], tempDest, itemTransmogrifier, true, true))
+ //{
+ // TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) can't equip the transmogrifier item (slot: %u, entry: %u).", player->GetGUIDLow(), player->GetName().c_str(), slots[i], itemTransmogrifier->GetEntry());
+ // return;
+ //}
+
+ if (!newEntries[i]) // reset look
+ {
+ itemTransmogrified->ClearEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT);
+ player->SetVisibleItemSlot(slots[i], itemTransmogrified);
+ }
+ else
+ {
+ if (!Item::CanTransmogrifyItemWithItem(itemTransmogrified, itemTransmogrifier))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleTransmogrifyItems - Player (GUID: %u, name: %s) failed CanTransmogrifyItemWithItem (%u with %u).", player->GetGUIDLow(), player->GetName().c_str(), itemTransmogrified->GetEntry(), itemTransmogrifier->GetEntry());
+ return;
+ }
+
+ // All okay, proceed
+ itemTransmogrified->SetEnchantment(TRANSMOGRIFY_ENCHANTMENT_SLOT, newEntries[i], 0, 0);
+ player->SetVisibleItemSlot(slots[i], itemTransmogrified);
+
+ itemTransmogrified->UpdatePlayedTime(player);
+
+ itemTransmogrified->SetOwnerGUID(player->GetGUID());
+ itemTransmogrified->SetNotRefundable(player);
+ itemTransmogrified->ClearSoulboundTradeable(player);
+
+ if (itemTransmogrifier->GetTemplate()->Bonding == BIND_WHEN_EQUIPED || itemTransmogrifier->GetTemplate()->Bonding == BIND_WHEN_USE)
+ itemTransmogrifier->SetBinding(true);
+
+ itemTransmogrifier->SetOwnerGUID(player->GetGUID());
+ itemTransmogrifier->SetNotRefundable(player);
+ itemTransmogrifier->ClearSoulboundTradeable(player);
+
+ cost += itemTransmogrified->GetSpecialPrice();
+ }
+ }
+
+ // trusting the client, if it got here it has to have enough money
+ // ... unless client was modified
+ if (cost) // 0 cost if reverting look
+ player->ModifyMoney(-cost);
+}
+
+void WorldSession::SendReforgeResult(bool success)
+{
+ WorldPacket data(SMSG_REFORGE_RESULT, 1);
+ data.WriteBit(success);
+ data.FlushBits();
+ SendPacket(&data);
+}
+
+void WorldSession::HandleReforgeItemOpcode(WorldPacket& recvData)
+{
+ uint32 slot, reforgeEntry;
+ ObjectGuid guid;
+ uint32 bag;
+ Player* player = GetPlayer();
+
+ recvData >> reforgeEntry >> slot >> bag;
+
+ guid[2] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[5]);
+
+ if (!player->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_REFORGER))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleReforgeItemOpcode - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(guid));
+ SendReforgeResult(false);
+ return;
+ }
+
+ Item* item = player->GetItemByPos(bag, slot);
+
+ if (!item)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleReforgeItemOpcode - Player (Guid: %u Name: %s) tried to reforge an invalid/non-existant item.", player->GetGUIDLow(), player->GetName().c_str());
+ SendReforgeResult(false);
+ return;
+ }
+
+ if (!reforgeEntry)
+ {
+ // Reset the item
+ if (item->IsEquipped())
+ player->ApplyReforgeEnchantment(item, false);
+ item->ClearEnchantment(REFORGE_ENCHANTMENT_SLOT);
+ SendReforgeResult(true);
+ return;
+ }
+
+ ItemReforgeEntry const* stats = sItemReforgeStore.LookupEntry(reforgeEntry);
+ if (!stats)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleReforgeItemOpcode - Player (Guid: %u Name: %s) tried to reforge an item with invalid reforge entry (%u).", player->GetGUIDLow(), player->GetName().c_str(), reforgeEntry);
+ SendReforgeResult(false);
+ return;
+ }
+
+ if (!item->GetReforgableStat(ItemModType(stats->SourceStat)) || item->GetReforgableStat(ItemModType(stats->FinalStat))) // Cheating, you cant reforge to a stat that the item already has, nor reforge from a stat that the item does not have
+ {
+ SendReforgeResult(false);
+ return;
+ }
+
+ if (!player->HasEnoughMoney(uint64(item->GetSpecialPrice()))) // cheating
+ {
+ SendReforgeResult(false);
+ return;
+ }
+
+ player->ModifyMoney(-int64(item->GetSpecialPrice()));
+
+ item->SetEnchantment(REFORGE_ENCHANTMENT_SLOT, reforgeEntry, 0, 0);
+
+ SendReforgeResult(true);
+
+ if (item->IsEquipped())
+ player->ApplyReforgeEnchantment(item, true);
+}
diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index a984c033872..5f941027571 100644
--- a/src/server/game/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -30,6 +30,8 @@ void BuildPlayerLockDungeonBlock(WorldPacket& data, lfg::LfgLockMap const& lock)
{
data << uint32(it->first); // Dungeon entry (id + type)
data << uint32(it->second); // Lock status
+ data << uint32(0); // Required itemLevel
+ data << uint32(0); // Current itemLevel
}
}
@@ -43,6 +45,40 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, lfg::LfgLockPartyMap const& l
}
}
+void BuildQuestReward(WorldPacket& data, Quest const* quest, Player* player)
+{
+ uint8 rewCount = quest->GetRewItemsCount() + quest->GetRewCurrencyCount();
+
+ data << uint32(quest->GetRewOrReqMoney());
+ data << uint32(quest->XPValue(player));
+ data << uint8(rewCount);
+ if (rewCount)
+ {
+ for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ {
+ if (uint32 currencyId = quest->RewardCurrencyId[i])
+ {
+ data << uint32(currencyId);
+ data << uint32(0);
+ data << uint32(quest->RewardCurrencyCount[i]);
+ data << uint8(1); // Is currency
+ }
+ }
+
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ {
+ if (uint32 itemId = quest->RewardItemId[i])
+ {
+ ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
+ data << uint32(itemId);
+ data << uint32(item ? item->DisplayInfoID : 0);
+ data << uint32(quest->RewardItemIdCount[i]);
+ data << uint8(0); // Is currency
+ }
+ }
+ }
+}
+
void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData)
{
if (!sLFGMgr->isOptionEnabled(lfg::LFG_OPTION_ENABLE_DUNGEON_FINDER | lfg::LFG_OPTION_ENABLE_RAID_BROWSER) ||
@@ -53,12 +89,15 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData)
return;
}
- uint8 numDungeons;
uint32 roles;
recvData >> roles;
- recvData.read_skip<uint16>(); // uint8 (always 0) - uint8 (always 0)
- recvData >> numDungeons;
+ for (int32 i = 0; i < 3; ++i)
+ recvData.read_skip<uint32>();
+
+ uint32 commentLen = recvData.ReadBits(9);
+ uint32 numDungeons = recvData.ReadBits(24);
+
if (!numDungeons)
{
TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s no dungeons selected", GetPlayerInfo().c_str());
@@ -66,48 +105,113 @@ void WorldSession::HandleLfgJoinOpcode(WorldPacket& recvData)
return;
}
+ std::string comment = recvData.ReadString(commentLen);
+
lfg::LfgDungeonSet newDungeons;
- for (int8 i = 0; i < numDungeons; ++i)
+ for (uint32 i = 0; i < numDungeons; ++i)
{
uint32 dungeon;
recvData >> dungeon;
newDungeons.insert((dungeon & 0x00FFFFFF)); // remove the type from the dungeon entry
}
- recvData.read_skip<uint32>(); // for 0..uint8 (always 3) { uint8 (always 0) }
-
- std::string comment;
- recvData >> comment;
TC_LOG_DEBUG("lfg", "CMSG_LFG_JOIN %s roles: %u, Dungeons: %u, Comment: %s",
GetPlayerInfo().c_str(), roles, uint8(newDungeons.size()), comment.c_str());
sLFGMgr->JoinLfg(GetPlayer(), uint8(roles), newDungeons, comment);
}
-void WorldSession::HandleLfgLeaveOpcode(WorldPacket& /*recvData*/)
+void WorldSession::HandleLfgLeaveOpcode(WorldPacket& recvData)
{
+ ObjectGuid leaveGuid;
Group* group = GetPlayer()->GetGroup();
uint64 guid = GetPlayer()->GetGUID();
uint64 gguid = group ? group->GetGUID() : guid;
- TC_LOG_DEBUG("lfg", "CMSG_LFG_LEAVE %s in group: %u",
- GetPlayerInfo().c_str(), group ? 1 : 0);
+ recvData.read_skip<uint32>(); // Always 8
+ recvData.read_skip<uint32>(); // Join date
+ recvData.read_skip<uint32>(); // Always 3
+ recvData.read_skip<uint32>(); // Queue Id
+
+ leaveGuid[4] = recvData.ReadBit();
+ leaveGuid[5] = recvData.ReadBit();
+ leaveGuid[0] = recvData.ReadBit();
+ leaveGuid[6] = recvData.ReadBit();
+ leaveGuid[2] = recvData.ReadBit();
+ leaveGuid[7] = recvData.ReadBit();
+ leaveGuid[1] = recvData.ReadBit();
+ leaveGuid[3] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(leaveGuid[7]);
+ recvData.ReadByteSeq(leaveGuid[4]);
+ recvData.ReadByteSeq(leaveGuid[3]);
+ recvData.ReadByteSeq(leaveGuid[2]);
+ recvData.ReadByteSeq(leaveGuid[6]);
+ recvData.ReadByteSeq(leaveGuid[0]);
+ recvData.ReadByteSeq(leaveGuid[1]);
+ recvData.ReadByteSeq(leaveGuid[5]);
+
+ TC_LOG_DEBUG("lfg", "CMSG_LFG_LEAVE %s in group: %u sent guid " UI64FMTD ".",
+ GetPlayerInfo().c_str(), group ? 1 : 0, uint64(leaveGuid));
// Check cheating - only leader can leave the queue
- if (!group || group->GetLeaderGUID() == GetPlayer()->GetGUID())
+ if (!group || group->GetLeaderGUID() == guid)
sLFGMgr->LeaveLfg(gguid);
}
void WorldSession::HandleLfgProposalResultOpcode(WorldPacket& recvData)
{
- uint32 lfgGroupID; // Internal lfgGroupID
- bool accept; // Accept to join?
- recvData >> lfgGroupID;
- recvData >> accept;
+ uint32 proposalID; // Proposal ID
+ bool accept;
+
+ ObjectGuid guid1;
+ ObjectGuid guid2;
+
+ recvData >> proposalID;
+ recvData.read_skip<uint32>();
+ recvData.read_skip<uint32>();
+ recvData.read_skip<uint32>();
+
+ guid2[4] = recvData.ReadBit();
+ guid2[5] = recvData.ReadBit();
+ guid2[0] = recvData.ReadBit();
+ guid2[6] = recvData.ReadBit();
+ guid2[2] = recvData.ReadBit();
+ guid2[7] = recvData.ReadBit();
+ guid2[1] = recvData.ReadBit();
+ guid2[3] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid2[7]);
+ recvData.ReadByteSeq(guid2[4]);
+ recvData.ReadByteSeq(guid2[3]);
+ recvData.ReadByteSeq(guid2[2]);
+ recvData.ReadByteSeq(guid2[6]);
+ recvData.ReadByteSeq(guid2[0]);
+ recvData.ReadByteSeq(guid2[1]);
+ recvData.ReadByteSeq(guid2[5]);
+
+ guid1[7] = recvData.ReadBit();
+ accept = recvData.ReadBit();
+ guid1[1] = recvData.ReadBit();
+ guid1[3] = recvData.ReadBit();
+ guid1[0] = recvData.ReadBit();
+ guid1[5] = recvData.ReadBit();
+ guid1[4] = recvData.ReadBit();
+ guid1[6] = recvData.ReadBit();
+ guid1[2] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid1[7]);
+ recvData.ReadByteSeq(guid1[1]);
+ recvData.ReadByteSeq(guid1[5]);
+ recvData.ReadByteSeq(guid1[6]);
+ recvData.ReadByteSeq(guid1[3]);
+ recvData.ReadByteSeq(guid1[4]);
+ recvData.ReadByteSeq(guid1[0]);
+ recvData.ReadByteSeq(guid1[2]);
TC_LOG_DEBUG("lfg", "CMSG_LFG_PROPOSAL_RESULT %s proposal: %u accept: %u",
- GetPlayerInfo().c_str(), lfgGroupID, accept ? 1 : 0);
- sLFGMgr->UpdateProposal(lfgGroupID, GetPlayer()->GetGUID(), accept);
+ GetPlayerInfo().c_str(), proposalID, accept ? 1 : 0);
+ sLFGMgr->UpdateProposal(proposalID, GetPlayer()->GetGUID(), accept);
}
void WorldSession::HandleLfgSetRolesOpcode(WorldPacket& recvData)
@@ -160,11 +264,20 @@ void WorldSession::HandleLfgTeleportOpcode(WorldPacket& recvData)
sLFGMgr->TeleportPlayer(GetPlayer(), out, true);
}
-void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*/)
+void WorldSession::HandleLfgGetLockInfoOpcode(WorldPacket& recvData)
+{
+ bool forPlayer = recvData.ReadBit();
+ TC_LOG_DEBUG("lfg", "CMSG_LFG_LOCK_INFO_REQUEST %s for %s", GetPlayerInfo().c_str(), (forPlayer ? "player" : "party"));
+
+ if (forPlayer)
+ SendLfgPlayerLockInfo();
+ else
+ SendLfgPartyLockInfo();
+}
+
+void WorldSession::SendLfgPlayerLockInfo()
{
uint64 guid = GetPlayer()->GetGUID();
- TC_LOG_DEBUG("lfg", "CMSG_LFG_PLAYER_LOCK_INFO_REQUEST %s",
- GetPlayerInfo().c_str());
// Get Random dungeons that can be done at a certain level and expansion
uint8 level = GetPlayer()->getLevel();
@@ -197,45 +310,46 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData*
}
}
- if (quest)
+ data << uint8(done);
+ data << uint32(0); // currencyQuantity
+ data << uint32(0); // some sort of overall cap/weekly cap
+ data << uint32(0); // currencyID
+ data << uint32(0); // tier1Quantity
+ data << uint32(0); // tier1Limit
+ data << uint32(0); // overallQuantity
+ data << uint32(0); // overallLimit
+ data << uint32(0); // periodPurseQuantity
+ data << uint32(0); // periodPurseLimit
+ data << uint32(0); // purseQuantity
+ data << uint32(0); // purseLimit
+ data << uint32(0); // some sort of reward for completion
+ data << uint32(0); // completedEncounters
+ data << uint8(0); // Call to Arms eligible
+
+ for (uint32 i = 0; i < 3; ++i)
{
- data << uint8(done);
- data << uint32(quest->GetRewOrReqMoney());
- data << uint32(quest->XPValue(GetPlayer()));
- data << uint32(0);
- data << uint32(0);
- data << uint8(quest->GetRewItemsCount());
- if (quest->GetRewItemsCount())
- {
- for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
- if (uint32 itemId = quest->RewardItemId[i])
- {
- ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
- data << uint32(itemId);
- data << uint32(item ? item->DisplayInfoID : 0);
- data << uint32(quest->RewardItemIdCount[i]);
- }
- }
+ data << uint32(0); // Call to Arms Role
+ //if (role)
+ // BuildQuestReward(data, ctaRoleQuest, GetPlayer());
}
+
+ if (quest)
+ BuildQuestReward(data, quest, GetPlayer());
else
{
- data << uint8(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint32(0);
- data << uint8(0);
+ data << uint32(0); // Money
+ data << uint32(0); // XP
+ data << uint8(0); // Reward count
}
}
+
BuildPlayerLockDungeonBlock(data, lock);
SendPacket(&data);
}
-void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData*/)
+void WorldSession::SendLfgPartyLockInfo()
{
uint64 guid = GetPlayer()->GetGUID();
- TC_LOG_DEBUG("lfg", "CMSG_LFG_PARTY_LOCK_INFO_REQUEST %s", GetPlayerInfo().c_str());
-
Group* group = GetPlayer()->GetGroup();
if (!group)
return;
@@ -257,7 +371,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData*
uint32 size = 0;
for (lfg::LfgLockPartyMap::const_iterator it = lockMap.begin(); it != lockMap.end(); ++it)
- size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
+ size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4);
TC_LOG_DEBUG("lfg", "SMSG_LFG_PARTY_INFO %s", GetPlayerInfo().c_str());
WorldPacket data(SMSG_LFG_PARTY_INFO, 1 + size);
@@ -287,71 +401,45 @@ void WorldSession::HandleLfgGetStatus(WorldPacket& /*recvData*/)
{
TC_LOG_DEBUG("lfg", "CMSG_LFG_GET_STATUS %s", GetPlayerInfo().c_str());
+ if (!GetPlayer()->isUsingLfg())
+ return;
+
uint64 guid = GetPlayer()->GetGUID();
lfg::LfgUpdateData updateData = sLFGMgr->GetLfgStatus(guid);
if (GetPlayer()->GetGroup())
{
- SendLfgUpdateParty(updateData);
+ SendLfgUpdateStatus(updateData, true);
updateData.dungeons.clear();
- SendLfgUpdatePlayer(updateData);
+ SendLfgUpdateStatus(updateData, false);
}
else
{
- SendLfgUpdatePlayer(updateData);
+ SendLfgUpdateStatus(updateData, false);
updateData.dungeons.clear();
- SendLfgUpdateParty(updateData);
+ SendLfgUpdateStatus(updateData, true);
}
}
-void WorldSession::SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData)
-{
- bool queued = false;
- uint8 size = uint8(updateData.dungeons.size());
-
- switch (updateData.updateType)
- {
- case lfg::LFG_UPDATETYPE_JOIN_QUEUE:
- case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE:
- queued = true;
- break;
- case lfg::LFG_UPDATETYPE_UPDATE_STATUS:
- queued = updateData.state == lfg::LFG_STATE_QUEUED;
- break;
- default:
- break;
- }
-
- TC_LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PLAYER %s updatetype: %u",
- GetPlayerInfo().c_str(), updateData.updateType);
- WorldPacket data(SMSG_LFG_UPDATE_PLAYER, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
- data << uint8(updateData.updateType); // Lfg Update type
- data << uint8(size > 0); // Extra info
- if (size)
- {
- data << uint8(queued); // Join the queue
- data << uint8(0); // unk - Always 0
- data << uint8(0); // unk - Always 0
-
- data << uint8(size);
- for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
- data << uint32(*it);
- data << updateData.comment;
- }
- SendPacket(&data);
-}
-
-void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData)
+void WorldSession::SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, bool party)
{
bool join = false;
bool queued = false;
uint8 size = uint8(updateData.dungeons.size());
+ ObjectGuid guid = _player->GetGUID();
+ time_t joinTime = sLFGMgr->GetQueueJoinTime(_player->GetGUID());
+ uint32 queueId = sLFGMgr->GetQueueId(_player->GetGUID());
switch (updateData.updateType)
{
+ case lfg::LFG_UPDATETYPE_JOIN_QUEUE_INITIAL: // Joined queue outside the dungeon
+ join = true;
+ break;
+ case lfg::LFG_UPDATETYPE_JOIN_QUEUE:
case lfg::LFG_UPDATETYPE_ADDED_TO_QUEUE: // Rolecheck Success
+ join = true;
queued = true;
- // no break on purpose
+ break;
case lfg::LFG_UPDATETYPE_PROPOSAL_BEGIN:
join = true;
break;
@@ -363,25 +451,44 @@ void WorldSession::SendLfgUpdateParty(const lfg::LfgUpdateData& updateData)
break;
}
- TC_LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_PARTY %s updatetype: %u",
- GetPlayerInfo().c_str(), updateData.updateType);
- WorldPacket data(SMSG_LFG_UPDATE_PARTY, 1 + 1 + (size > 0 ? 1 : 0) * (1 + 1 + 1 + 1 + 1 + size * 4 + updateData.comment.length()));
+ TC_LOG_DEBUG("lfg", "SMSG_LFG_UPDATE_STATUS %s updatetype: %u, party %s",
+ GetPlayerInfo().c_str(), updateData.updateType, party ? "true" : "false");
+
+ WorldPacket data(SMSG_LFG_UPDATE_STATUS, 1 + 8 + 3 + 2 + 1 + updateData.comment.length() + 4 + 4 + 1 + 1 + 1 + 4 + size);
+ data.WriteBit(guid[1]);
+ data.WriteBit(party);
+ data.WriteBits(size, 24);
+ data.WriteBit(guid[6]);
+ data.WriteBit(size > 0); // Extra info
+ data.WriteBits(updateData.comment.length(), 9);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(join); // LFG Join
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(queued); // Join the queue
+
data << uint8(updateData.updateType); // Lfg Update type
- data << uint8(size > 0); // Extra info
- if (size)
- {
- data << uint8(join); // LFG Join
- data << uint8(queued); // Join the queue
+ data.WriteString(updateData.comment);
+ data << uint32(queueId); // Queue Id
+ data << uint32(joinTime); // Join date
+ data.WriteByteSeq(guid[6]);
+ for (uint8 i = 0; i < 3; ++i)
data << uint8(0); // unk - Always 0
- data << uint8(0); // unk - Always 0
- for (uint8 i = 0; i < 3; ++i)
- data << uint8(0); // unk - Always 0
- data << uint8(size);
- for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
- data << uint32(*it);
- data << updateData.comment;
- }
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[0]);
+ data << uint32(3);
+ data.WriteByteSeq(guid[7]);
+ for (lfg::LfgDungeonSet::const_iterator it = updateData.dungeons.begin(); it != updateData.dungeons.end(); ++it)
+ data << uint32(*it);
+
SendPacket(&data);
}
@@ -421,10 +528,10 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
// Leader info MUST be sent 1st :S
uint64 guid = roleCheck.leader;
uint8 roles = roleCheck.roles.find(guid)->second;
+ Player* player = ObjectAccessor::FindPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
- Player* player = ObjectAccessor::FindPlayer(guid);
data << uint8(player ? player->getLevel() : 0); // Level
for (lfg::LfgRolesMap::const_iterator it = roleCheck.roles.begin(); it != roleCheck.roles.end(); ++it)
@@ -434,10 +541,10 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
guid = it->first;
roles = it->second;
+ player = ObjectAccessor::FindPlayer(guid);
data << uint64(guid); // Guid
data << uint8(roles > 0); // Ready
data << uint32(roles); // Roles
- player = ObjectAccessor::FindPlayer(guid);
data << uint8(player ? player->getLevel() : 0);// Level
}
}
@@ -447,17 +554,73 @@ void WorldSession::SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& roleCheck)
void WorldSession::SendLfgJoinResult(lfg::LfgJoinResultData const& joinData)
{
uint32 size = 0;
+ ObjectGuid guid = GetPlayer()->GetGUID();
+ uint32 queueId = sLFGMgr->GetQueueId(_player->GetGUID());
for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
- size += 8 + 4 + uint32(it->second.size()) * (4 + 4);
+ size += 8 + 4 + uint32(it->second.size()) * (4 + 4 + 4 + 4);
TC_LOG_DEBUG("lfg", "SMSG_LFG_JOIN_RESULT %s checkResult: %u checkValue: %u",
GetPlayerInfo().c_str(), joinData.result, joinData.state);
WorldPacket data(SMSG_LFG_JOIN_RESULT, 4 + 4 + size);
- data << uint32(joinData.result); // Check Result
- data << uint32(joinData.state); // Check Value
- if (!joinData.lockmap.empty())
- BuildPartyLockDungeonBlock(data, joinData.lockmap);
+ data << uint32(3);
+ data << uint8(joinData.result); // Check Result
+ data << uint32(queueId); // Queue Id
+ data << uint8(joinData.state); // Check Value
+ data << uint32(time(NULL)); // Join date
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[0]);
+ data.WriteBits(joinData.lockmap.size(), 24);
+ for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
+ {
+ ObjectGuid playerGuid = it->first;
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[5]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[6]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[1]);
+ data.WriteBits(it->second.size(), 22);
+ }
+
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[6]);
+ for (lfg::LfgLockPartyMap::const_iterator it = joinData.lockmap.begin(); it != joinData.lockmap.end(); ++it)
+ {
+ ObjectGuid playerGuid = it->first;
+ for (lfg::LfgLockMap::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
+ {
+ data << uint32(itr->second); // Lock status
+ data << uint32(0); // Current itemLevel
+ data << uint32(0); // Required itemLevel
+ data << uint32(itr->first); // Dungeon entry (id + type)
+ }
+
+ data.WriteByteSeq(playerGuid[2]);
+ data.WriteByteSeq(playerGuid[5]);
+ data.WriteByteSeq(playerGuid[1]);
+ data.WriteByteSeq(playerGuid[0]);
+ data.WriteByteSeq(playerGuid[4]);
+ data.WriteByteSeq(playerGuid[3]);
+ data.WriteByteSeq(playerGuid[6]);
+ data.WriteByteSeq(playerGuid[7]);
+ }
+
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[0]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[6]);
+
SendPacket(&data);
}
@@ -470,17 +633,39 @@ void WorldSession::SendLfgQueueStatus(lfg::LfgQueueStatusData const& queueData)
queueData.waitTimeTank, queueData.waitTimeHealer, queueData.waitTimeDps,
queueData.queuedTime, queueData.tanks, queueData.healers, queueData.dps);
- WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 +4 + 1 + 1 + 1 + 4);
- data << uint32(queueData.dungeonId); // Dungeon
- data << int32(queueData.waitTimeAvg); // Average Wait time
- data << int32(queueData.waitTime); // Wait Time
- data << int32(queueData.waitTimeTank); // Wait Tanks
- data << int32(queueData.waitTimeHealer); // Wait Healers
- data << int32(queueData.waitTimeDps); // Wait Dps
+ ObjectGuid guid = _player->GetGUID();
+ WorldPacket data(SMSG_LFG_QUEUE_STATUS, 4 + 4 + 4 + 4 + 4 + 4 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 8);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[7]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[4]);
+
+ data.WriteByteSeq(guid[0]);
data << uint8(queueData.tanks); // Tanks needed
+ data << int32(queueData.waitTimeTank); // Wait Tanks
data << uint8(queueData.healers); // Healers needed
+ data << int32(queueData.waitTimeHealer); // Wait Healers
data << uint8(queueData.dps); // Dps needed
+ data << int32(queueData.waitTimeDps); // Wait Dps
+ data.WriteByteSeq(guid[4]);
+ data.WriteByteSeq(guid[6]);
+ data << int32(queueData.waitTime); // Wait Time
+ data << uint32(queueData.joinTime); // Join time
+ data << uint32(queueData.dungeonId); // Dungeon
data << uint32(queueData.queuedTime); // Player wait time in queue
+ data.WriteByteSeq(guid[5]);
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[3]);
+ data << uint32(queueData.queueId); // Queue Id
+ data.WriteByteSeq(guid[1]);
+ data.WriteByteSeq(guid[2]);
+ data << int32(queueData.waitTimeAvg); // Average Wait time
+ data << uint32(3);
+
SendPacket(&data);
}
@@ -492,29 +677,12 @@ void WorldSession::SendLfgPlayerReward(lfg::LfgPlayerRewardData const& rewardDat
TC_LOG_DEBUG("lfg", "SMSG_LFG_PLAYER_REWARD %s rdungeonEntry: %u, sdungeonEntry: %u, done: %u",
GetPlayerInfo().c_str(), rewardData.rdungeonEntry, rewardData.sdungeonEntry, rewardData.done);
- uint8 itemNum = rewardData.quest->GetRewItemsCount();
+ uint8 itemNum = rewardData.quest->GetRewItemsCount() + rewardData.quest->GetRewCurrencyCount();
WorldPacket data(SMSG_LFG_PLAYER_REWARD, 4 + 4 + 1 + 4 + 4 + 4 + 4 + 4 + 1 + itemNum * (4 + 4 + 4));
- data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
- data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
- data << uint8(rewardData.done);
- data << uint32(1);
- data << uint32(rewardData.quest->GetRewOrReqMoney());
- data << uint32(rewardData.quest->XPValue(GetPlayer()));
- data << uint32(0);
- data << uint32(0);
- data << uint8(itemNum);
- if (itemNum)
- {
- for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
- if (uint32 itemId = rewardData.quest->RewardItemId[i])
- {
- ItemTemplate const* item = sObjectMgr->GetItemTemplate(itemId);
- data << uint32(itemId);
- data << uint32(item ? item->DisplayInfoID : 0);
- data << uint32(rewardData.quest->RewardItemIdCount[i]);
- }
- }
+ data << uint32(rewardData.rdungeonEntry); // Random Dungeon Finished
+ data << uint32(rewardData.sdungeonEntry); // Dungeon Finished
+ BuildQuestReward(data, rewardData.quest, GetPlayer());
SendPacket(&data);
}
@@ -540,16 +708,17 @@ void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot)
GetPlayerInfo().c_str(), uint8(boot.inProgress), uint8(playerVote != lfg::LFG_ANSWER_PENDING),
uint8(playerVote == lfg::LFG_ANSWER_AGREE), GUID_LOPART(boot.victim), votesNum, agreeNum,
secsleft, lfg::LFG_GROUP_KICK_VOTES_NEEDED, boot.reason.c_str());
- WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
- data << uint8(boot.inProgress); // Vote in progress
- data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
- data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
- data << uint64(boot.victim); // Victim GUID
- data << uint32(votesNum); // Total Votes
- data << uint32(agreeNum); // Agree Count
- data << uint32(secsleft); // Time Left
- data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
- data << boot.reason.c_str(); // Kick reason
+ WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + boot.reason.length());
+ data << uint8(boot.inProgress); // Vote in progress
+ data << uint8(agreeNum >= lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Did succeed
+ data << uint8(playerVote != lfg::LFG_ANSWER_PENDING); // Did Vote
+ data << uint8(playerVote == lfg::LFG_ANSWER_AGREE); // Agree
+ data << uint64(boot.victim); // Victim GUID
+ data << uint32(votesNum); // Total Votes
+ data << uint32(agreeNum); // Agree Count
+ data << uint32(secsleft); // Time Left
+ data << uint32(lfg::LFG_GROUP_KICK_VOTES_NEEDED); // Needed Votes
+ data << boot.reason.c_str(); // Kick reason
SendPacket(&data);
}
@@ -559,6 +728,8 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal)
uint64 gguid = proposal.players.find(guid)->second.group;
bool silent = !proposal.isNew && gguid == proposal.group;
uint32 dungeonEntry = proposal.dungeonId;
+ uint32 queueId = sLFGMgr->GetQueueId(_player->GetGUID());
+ time_t joinTime = sLFGMgr->GetQueueJoinTime(_player->GetGUID());
TC_LOG_DEBUG("lfg", "SMSG_LFG_PROPOSAL_UPDATE %s state: %u",
GetPlayerInfo().c_str(), proposal.state);
@@ -574,31 +745,81 @@ void WorldSession::SendLfgUpdateProposal(lfg::LfgProposal const& proposal)
dungeonEntry = sLFGMgr->GetLFGDungeonEntry(dungeonEntry);
WorldPacket data(SMSG_LFG_PROPOSAL_UPDATE, 4 + 1 + 4 + 4 + 1 + 1 + proposal.players.size() * (4 + 1 + 1 + 1 + 1 +1));
+ data << uint32(joinTime);
+ data << uint32(proposal.encounters); // Encounters done
+ data << uint32(queueId); // Queue Id
+ data << uint32(3); // Always 3
data << uint32(dungeonEntry); // Dungeon
- data << uint8(proposal.state); // Proposal state
- data << uint32(proposal.id); // Proposal ID
- data << uint32(proposal.encounters); // encounters done
- data << uint8(silent); // Show proposal window
- data << uint8(proposal.players.size()); // Group size
+ data << uint32(proposal.id); // Proposal Id
+ data << uint8(proposal.state); // State
+
+ ObjectGuid guid1 = guid;
+ ObjectGuid guid2 = gguid;
+
+ data.WriteBit(guid2[4]);
+ data.WriteBit(guid1[3]);
+ data.WriteBit(guid1[7]);
+ data.WriteBit(guid1[0]);
+ data.WriteBit(guid2[1]);
+ data.WriteBit(silent);
+ data.WriteBit(guid1[4]);
+ data.WriteBit(guid1[5]);
+ data.WriteBit(guid2[3]);
+ data.WriteBits(proposal.players.size(), 23);
+ data.WriteBit(guid2[7]);
for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
{
lfg::LfgProposalPlayer const& player = it->second;
- data << uint32(player.role); // Role
- data << uint8(it->first == guid); // Self player
- if (!player.group) // Player not it a group
+
+ if (!player.group)
{
- data << uint8(0); // Not in dungeon
- data << uint8(0); // Not same group
+ data.WriteBit(0);
+ data.WriteBit(0);
}
else
{
- data << uint8(player.group == proposal.group); // In dungeon (silent)
- data << uint8(player.group == gguid); // Same Group than player
+ data.WriteBit(player.group == proposal.group); // Is group in dungeon
+ data.WriteBit(player.group == gguid); // Same group as the player
}
- data << uint8(player.accept != lfg::LFG_ANSWER_PENDING);// Answered
- data << uint8(player.accept == lfg::LFG_ANSWER_AGREE); // Accepted
+
+ data.WriteBit(player.accept == lfg::LFG_ANSWER_AGREE);
+ data.WriteBit(player.accept != lfg::LFG_ANSWER_PENDING);
+ data.WriteBit(it->first == guid);
}
+
+ data.WriteBit(guid2[5]);
+ data.WriteBit(guid1[6]);
+ data.WriteBit(guid2[2]);
+ data.WriteBit(guid2[6]);
+ data.WriteBit(guid1[2]);
+ data.WriteBit(guid1[1]);
+ data.WriteBit(guid2[0]);
+
+ data.WriteByteSeq(guid1[5]);
+ data.WriteByteSeq(guid2[3]);
+ data.WriteByteSeq(guid2[6]);
+ data.WriteByteSeq(guid1[6]);
+ data.WriteByteSeq(guid1[0]);
+ data.WriteByteSeq(guid2[5]);
+ data.WriteByteSeq(guid1[1]);
+
+ for (lfg::LfgProposalPlayerContainer::const_iterator it = proposal.players.begin(); it != proposal.players.end(); ++it)
+ {
+ lfg::LfgProposalPlayer const& player = it->second;
+ data << uint32(player.role);
+ }
+
+ data.WriteByteSeq(guid2[7]);
+ data.WriteByteSeq(guid1[4]);
+ data.WriteByteSeq(guid2[0]);
+ data.WriteByteSeq(guid2[1]);
+ data.WriteByteSeq(guid1[2]);
+ data.WriteByteSeq(guid1[7]);
+ data.WriteByteSeq(guid2[2]);
+ data.WriteByteSeq(guid1[3]);
+ data.WriteByteSeq(guid2[4]);
+
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index f3a1803dfca..72d3fd5a746 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -22,6 +22,7 @@
#include "Creature.h"
#include "GameObject.h"
#include "Group.h"
+#include "GuildMgr.h"
#include "LootMgr.h"
#include "ObjectAccessor.h"
#include "Object.h"
@@ -186,6 +187,10 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
(*i)->ModifyMoney(goldPerPlayer);
(*i)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, goldPerPlayer);
+ if (Guild* guild = sGuildMgr->GetGuildById((*i)->GetGuildId()))
+ if (uint32 guildGold = CalculatePct(goldPerPlayer, (*i)->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT)))
+ guild->HandleMemberDepositMoney(this, guildGold, true);
+
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(goldPerPlayer);
data << uint8(playersNear.size() <= 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..."
@@ -197,6 +202,10 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
player->ModifyMoney(loot->gold);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY, loot->gold);
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ if (uint32 guildGold = CalculatePct(loot->gold, player->GetTotalAuraModifier(SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT)))
+ guild->HandleMemberDepositMoney(this, guildGold, true);
+
WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1);
data << uint32(loot->gold);
data << uint8(1); // "You loot..."
@@ -460,7 +469,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
ItemPosCountVec dest;
InventoryResult msg = target->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item.itemid, item.count);
if (item.follow_loot_rules && !item.AllowedForPlayer(target))
- msg = EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+ msg = EQUIP_ERR_CANT_EQUIP_EVER;
if (msg != EQUIP_ERR_OK)
{
target->SendEquipError(msg, NULL, NULL, item.itemid);
@@ -476,7 +485,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData)
Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters);
target->SendNewItem(newitem, uint32(item.count), false, false, true);
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);
- target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, loot->loot_type, item.count);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE, item.itemid, item.count, loot->loot_type);
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM, item.itemid, item.count);
// mark as looted
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 10ef7810d1d..e65643e7ffe 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -28,6 +28,7 @@
#include "DBCStores.h"
#include "Item.h"
#include "AccountMgr.h"
+#include "GuildMgr.h"
bool WorldSession::CanOpenMailBox(uint64 guid)
{
@@ -57,15 +58,20 @@ bool WorldSession::CanOpenMailBox(uint64 guid)
void WorldSession::HandleSendMail(WorldPacket& recvData)
{
- uint64 mailbox, unk3;
+ ObjectGuid mailbox;
+ uint64 money, COD;
std::string receiverName, subject, body;
- uint32 unk1, unk2, money, COD;
- uint8 unk4;
- uint8 items_count;
- recvData >> mailbox >> receiverName >> subject >> body
- >> unk1 // stationery?
- >> unk2 // 0x00000000
- >> items_count; // attached items count
+ uint32 bodyLength, subjectLength, receiverLength;
+ uint32 unk1, unk2;
+
+ recvData >> unk1;
+ recvData >> unk2; // Stationery?
+
+ recvData >> COD >> money; // money and cod
+ bodyLength = recvData.ReadBits(12);
+ subjectLength = recvData.ReadBits(9);
+
+ uint8 items_count = recvData.ReadBits(5); // attached items count
if (items_count > MAX_MAIL_ITEMS) // client limit
{
@@ -74,17 +80,60 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
return;
}
- uint64 itemGUIDs[MAX_MAIL_ITEMS];
+ mailbox[0] = recvData.ReadBit();
+
+ ObjectGuid itemGUIDs[MAX_MAIL_ITEMS];
for (uint8 i = 0; i < items_count; ++i)
{
- recvData.read_skip<uint8>(); // item slot in mail, not used
- recvData >> itemGUIDs[i];
+ itemGUIDs[i][2] = recvData.ReadBit();
+ itemGUIDs[i][6] = recvData.ReadBit();
+ itemGUIDs[i][3] = recvData.ReadBit();
+ itemGUIDs[i][7] = recvData.ReadBit();
+ itemGUIDs[i][1] = recvData.ReadBit();
+ itemGUIDs[i][0] = recvData.ReadBit();
+ itemGUIDs[i][4] = recvData.ReadBit();
+ itemGUIDs[i][5] = recvData.ReadBit();
}
- recvData >> money >> COD; // money and cod
- recvData >> unk3; // const 0
- recvData >> unk4; // const 0
+ mailbox[3] = recvData.ReadBit();
+ mailbox[4] = recvData.ReadBit();
+ receiverLength = recvData.ReadBits(7);
+ mailbox[2] = recvData.ReadBit();
+ mailbox[6] = recvData.ReadBit();
+ mailbox[1] = recvData.ReadBit();
+ mailbox[7] = recvData.ReadBit();
+ mailbox[5] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(mailbox[4]);
+
+ for (uint8 i = 0; i < items_count; ++i)
+ {
+ recvData.ReadByteSeq(itemGUIDs[i][6]);
+ recvData.ReadByteSeq(itemGUIDs[i][1]);
+ recvData.ReadByteSeq(itemGUIDs[i][7]);
+ recvData.ReadByteSeq(itemGUIDs[i][2]);
+ recvData.read_skip<uint8>(); // item slot in mail, not used
+ recvData.ReadByteSeq(itemGUIDs[i][3]);
+ recvData.ReadByteSeq(itemGUIDs[i][0]);
+ recvData.ReadByteSeq(itemGUIDs[i][4]);
+ recvData.ReadByteSeq(itemGUIDs[i][5]);
+ }
+
+ recvData.ReadByteSeq(mailbox[7]);
+ recvData.ReadByteSeq(mailbox[3]);
+ recvData.ReadByteSeq(mailbox[6]);
+ recvData.ReadByteSeq(mailbox[5]);
+
+ subject = recvData.ReadString(subjectLength);
+ receiverName = recvData.ReadString(receiverLength);
+
+ recvData.ReadByteSeq(mailbox[2]);
+ recvData.ReadByteSeq(mailbox[0]);
+
+ body = recvData.ReadString(bodyLength);
+
+ recvData.ReadByteSeq(mailbox[1]);
// packet read complete, now do check
@@ -109,7 +158,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (!receiverGuid)
{
TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: not existed!) with subject %s "
- "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
+ "and body %s includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u",
player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(),
items_count, money, COD, unk1, unk2);
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND);
@@ -117,7 +166,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
}
TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: %u) with subject %s and body %s "
- "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u",
+ "includes %u items, " UI64FMTD " copper and " UI64FMTD " COD copper with unk1 = %u, unk2 = %u",
player->GetGUIDLow(), receiverName.c_str(), GUID_LOPART(receiverGuid), subject.c_str(),
body.c_str(), items_count, money, COD, unk1, unk2);
@@ -129,7 +178,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
uint32 cost = items_count ? 30 * items_count : 30; // price hardcoded in client
- uint32 reqmoney = cost + money;
+ uint64 reqmoney = cost + money;
if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster())
{
@@ -239,7 +288,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId)
{
- player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS);
+ player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT);
return;
}
@@ -257,7 +306,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (item->IsNotEmptyBag())
{
- player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS);
+ player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_DESTROY_NONEMPTY_BAG);
return;
}
@@ -266,7 +315,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
player->SendMailResult(0, MAIL_SEND, MAIL_OK);
- player->ModifyMoney(-int32(reqmoney));
+ player->ModifyMoney(-int64(reqmoney));
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL, cost);
bool needItemDelay = false;
@@ -307,7 +356,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
if (log && money > 0)
{
- sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: %u to player: %s (GUID: %u) (Account: %u)",
+ sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: " UI64FMTD " to player: %s (GUID: %u) (Account: %u)",
GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), money, receiverName.c_str(), GUID_LOPART(receiverGuid), receiverAccountId);
}
}
@@ -315,6 +364,11 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
// If theres is an item, there is a one hour delivery delay if sent to another account's character.
uint32 deliver_delay = needItemDelay ? sWorld->getIntConfig(CONFIG_MAIL_DELIVERY_DELAY) : 0;
+ // Mail sent between guild members arrives instantly if they have the guild perk "Guild Mail"
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ if (guild->GetLevel() >= 17 && guild->IsMember(receiverGuid))
+ deliver_delay = 0;
+
// will delete item or place to receiver mail list
draft
.AddMoney(money)
@@ -395,8 +449,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket& recvData)
player->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR);
return;
}
- //we can return mail now
- //so firstly delete the old one
+ //we can return mail now, so firstly delete the old one
SQLTransaction trans = CharacterDatabase.BeginTransaction();
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_MAIL_BY_ID);
@@ -420,14 +473,8 @@ void WorldSession::HandleMailReturnToSender(WorldPacket& recvData)
{
for (MailItemInfoVec::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
{
- Item* item = player->GetMItem(itr2->item_guid);
- if (item)
+ if (Item* const item = player->GetMItem(itr2->item_guid))
draft.AddItem(item);
- else
- {
- //WTF?
- }
-
player->RemoveMItem(itr2->item_guid);
}
}
@@ -463,7 +510,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
}
// prevent cheating with skip client money check
- if (!player->HasEnoughMoney(m->COD))
+ if (!player->HasEnoughMoney(uint64(m->COD)))
{
player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_NOT_ENOUGH_MONEY);
return;
@@ -502,7 +549,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
if (!sObjectMgr->GetPlayerNameByGUID(sender_guid, sender_name))
sender_name = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN);
}
- sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: %u to player: %s (Account: %u)",
+ sLog->outCommand(GetAccountId(), "GM %s (Account: %u) receiver mail item: %s (Entry: %u Count: %u) and send COD money: " UI64FMTD " to player: %s (Account: %u)",
GetPlayerName().c_str(), GetAccountId(), it->GetTemplate()->Name1.c_str(), it->GetEntry(), it->GetCount(), m->COD, sender_name.c_str(), sender_accId);
}
else if (!receiver)
@@ -540,9 +587,12 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData)
void WorldSession::HandleMailTakeMoney(WorldPacket& recvData)
{
uint64 mailbox;
+ uint64 money;
uint32 mailId;
+
recvData >> mailbox;
recvData >> mailId;
+ recvData >> money;
if (!CanOpenMailBox(mailbox))
return;
@@ -550,7 +600,8 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData)
Player* player = _player;
Mail* m = player->GetMail(mailId);
- if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL))
+ if ((!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) ||
+ (money > 0 && m->money != money))
{
player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_ERR_INTERNAL_ERROR);
return;
@@ -596,7 +647,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
uint32 mailsCount = 0; // real send to client mails amount
uint32 realCount = 0; // real mails amount
- WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size
+ WorldPacket data(SMSG_MAIL_LIST_RESULT, 200); // guess size
data << uint32(0); // real mail's count
data << uint8(0); // mail's count
time_t cur_time = time(NULL);
@@ -637,14 +688,14 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
case MAIL_GAMEOBJECT:
case MAIL_AUCTION:
case MAIL_CALENDAR:
- data << uint32((*itr)->sender); // creature/gameobject entry, auction id, calendar event id?
+ data << uint32((*itr)->sender); // creature/gameobject entry, auction id, calendar event id?
break;
}
- data << uint32((*itr)->COD); // COD
- data << uint32(0); // package (Package.dbc)
+ data << uint64((*itr)->COD); // COD
+ data << uint32(0); // Package.dbc ID ?
data << uint32((*itr)->stationery); // stationery (Stationery.dbc)
- data << uint32((*itr)->money); // Gold
+ data << uint64((*itr)->money); // Gold
data << uint32((*itr)->checked); // flags
data << float(float((*itr)->expire_time-time(NULL))/DAY); // Time
data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc)
@@ -667,6 +718,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData)
data << uint32((item ? item->GetEnchantmentDuration((EnchantmentSlot)j) : 0));
data << uint32((item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0));
}
+
// can be negative
data << int32((item ? item->GetItemRandomPropertyId() : 0));
// unk
@@ -733,7 +785,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData)
return;
}
- bodyItem->SetText(mailTemplateEntry->content[GetSessionDbcLocale()]);
+ bodyItem->SetText(mailTemplateEntry->content);
}
else
bodyItem->SetText(m->body);
@@ -762,7 +814,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData)
}
/// @todo Fix me! ... this void has probably bad condition, but good data are sent
-void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/)
+void WorldSession::HandleQueryNextMailTime(WorldPacket& /*recvData*/)
{
WorldPacket data(MSG_QUERY_NEXT_MAIL_TIME, 8);
@@ -814,3 +866,10 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/)
SendPacket(&data);
}
+
+void WorldSession::SendShowMailBox(uint64 guid)
+{
+ WorldPacket data(SMSG_SHOW_MAILBOX, 8);
+ data << guid;
+ SendPacket(&data);
+}
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index fcec4f38852..8c9cc9c1338 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -55,6 +55,7 @@
#include "BattlegroundMgr.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
+#include "DB2Stores.h"
void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData)
{
@@ -381,7 +382,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
uint32 reason = 0;
if (GetPlayer()->IsInCombat() && !canLogoutInCombat)
reason = 1;
- else if (GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR))
+ else if (GetPlayer()->IsFalling())
reason = 3; // is jumping or falling
else if (GetPlayer()->duel || GetPlayer()->HasAura(9454)) // is dueling or frozen by GM via freeze command
reason = 2; // FIXME - Need the correct value
@@ -397,7 +398,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
return;
}
- //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
+ // instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf
if (instantLogout)
{
LogoutPlayer(true);
@@ -408,11 +409,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/)
if (GetPlayer()->CanFreeMove())
{
GetPlayer()->SetStandState(UNIT_STAND_STATE_SIT);
-
- WorldPacket data(SMSG_FORCE_MOVE_ROOT, (8+4)); // guess size
- data.append(GetPlayer()->GetPackGUID());
- data << (uint32)2;
- SendPacket(&data);
+ GetPlayer()->SetRooted(true);
GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
@@ -441,10 +438,7 @@ void WorldSession::HandleLogoutCancelOpcode(WorldPacket& /*recvData*/)
if (GetPlayer()->CanFreeMove())
{
//!we can move again
- data.Initialize(SMSG_FORCE_MOVE_UNROOT, 8); // guess size
- data.append(GetPlayer()->GetPackGUID());
- data << uint32(0);
- SendPacket(&data);
+ GetPlayer()->SetRooted(false);
//! Stand Up
GetPlayer()->SetStandState(UNIT_STAND_STATE_STAND);
@@ -501,6 +495,13 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket& recvData)
//GetPlayer()->SendInitWorldStates(true, newZone);
}
+void WorldSession::HandleReturnToGraveyard(WorldPacket& /*recvPacket*/)
+{
+ if (GetPlayer()->IsAlive() || !GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST))
+ return;
+ GetPlayer()->RepopAtGraveyard();
+}
+
void WorldSession::HandleSetSelectionOpcode(WorldPacket& recvData)
{
uint64 guid;
@@ -520,9 +521,8 @@ void WorldSession::HandleStandStateChangeOpcode(WorldPacket& recvData)
void WorldSession::HandleContactListOpcode(WorldPacket& recvData)
{
- uint32 unk;
- recvData >> unk;
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_CONTACT_LIST - Unk: %d", unk);
+ recvData.read_skip<uint32>(); // always 1
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_CONTACT_LIST");
_player->GetSocial()->SendSocialList(_player);
}
@@ -707,9 +707,11 @@ void WorldSession::HandleBugOpcode(WorldPacket& recvData)
uint32 suggestion, contentlen, typelen;
std::string content, type;
- recvData >> suggestion >> contentlen >> content;
+ recvData >> suggestion >> contentlen;
+ content = recvData.ReadString(contentlen);
- recvData >> typelen >> type;
+ recvData >> typelen;
+ type = recvData.ReadString(typelen);
if (suggestion == 0)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_BUG [Bug Report]");
@@ -778,11 +780,11 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData)
if (status == 0)
{
- GetPlayer()->clearResurrectRequestData(); // reject
+ GetPlayer()->ClearResurrectRequestData(); // reject
return;
}
- if (!GetPlayer()->isRessurectRequestedBy(guid))
+ if (!GetPlayer()->IsRessurectRequestedBy(guid))
return;
GetPlayer()->ResurectUsingRequestData();
@@ -916,7 +918,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData)
if (pvp->HandleAreaTrigger(_player, triggerId))
return;
- AreaTrigger const* at = sObjectMgr->GetAreaTrigger(triggerId);
+ AreaTriggerStruct const* at = sObjectMgr->GetAreaTrigger(triggerId);
if (!at)
return;
@@ -1028,6 +1030,13 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recvData)
SendPacket(&data);
}
+int32 WorldSession::HandleEnableNagleAlgorithm()
+{
+ // Instructs the server we wish to receive few amounts of large packets (SMSG_MULTIPLE_PACKETS?)
+ // instead of large amount of small packets
+ return 0;
+}
+
void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recvData)
{
uint8 button;
@@ -1053,12 +1062,32 @@ void WorldSession::HandleNextCinematicCamera(WorldPacket& /*recvData*/)
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket& recvData)
{
- /* WorldSession::Update(getMSTime());*/
TC_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_TIME_SKIPPED");
- uint64 guid;
- recvData.readPackGUID(guid);
- recvData.read_skip<uint32>();
+ ObjectGuid guid;
+ uint32 time;
+ recvData >> time;
+
+ guid[5] = recvData.ReadBit();
+ guid[1] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[2] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[3]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[5]);
+
+ //TODO!
+
/*
uint64 guid;
uint32 time_skipped;
@@ -1174,10 +1203,9 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
return;
}
- uint32 talent_points = 0x47;
- uint32 guid_size = player->GetPackGUID().wpos();
- WorldPacket data(SMSG_INSPECT_TALENT, guid_size+4+talent_points);
- data.append(player->GetPackGUID());
+ uint32 talent_points = 41;
+ WorldPacket data(SMSG_INSPECT_TALENT, 8 + 4 + 1 + 1 + talent_points + 8 + 4 + 8 + 4);
+ data << player->GetGUID();
if (sWorld->getBoolConfig(CONFIG_TALENTS_INSPECTING) || _player->IsGameMaster())
player->BuildPlayerTalentsInfoData(&data);
@@ -1189,29 +1217,66 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recvData)
}
player->BuildEnchantmentsInfoData(&data);
+ if (Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()))
+ {
+ data << uint64(guild->GetGUID());
+ data << uint32(guild->GetLevel());
+ data << uint64(0/*guild->GetXP()*/);
+ data << uint32(guild->GetMembersCount());
+ }
SendPacket(&data);
}
void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recvData)
{
- uint64 guid;
- recvData >> guid;
-
+ ObjectGuid guid;
+ guid[1] = recvData.ReadBit();
+ guid[5] = recvData.ReadBit();
+ guid[7] = recvData.ReadBit();
+ guid[3] = recvData.ReadBit();
+ guid[2] = recvData.ReadBit();
+ guid[4] = recvData.ReadBit();
+ guid[0] = recvData.ReadBit();
+ guid[6] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(guid[4]);
+ recvData.ReadByteSeq(guid[7]);
+ recvData.ReadByteSeq(guid[0]);
+ recvData.ReadByteSeq(guid[5]);
+ recvData.ReadByteSeq(guid[1]);
+ recvData.ReadByteSeq(guid[6]);
+ recvData.ReadByteSeq(guid[2]);
+ recvData.ReadByteSeq(guid[3]);
Player* player = ObjectAccessor::FindPlayer(guid);
if (!player)
{
- TC_LOG_DEBUG("network", "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);
+ TC_LOG_DEBUG("network", "CMSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, (uint64)guid);
return;
}
- WorldPacket data(MSG_INSPECT_HONOR_STATS, 8+1+4*4);
- data << uint64(player->GetGUID());
- data << uint8(player->GetHonorPoints());
- data << uint32(player->GetUInt32Value(PLAYER_FIELD_KILLS));
- data << uint32(player->GetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION));
- data << uint32(player->GetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION));
+ ObjectGuid playerGuid = player->GetGUID();
+ WorldPacket data(SMSG_INSPECT_HONOR_STATS, 8+1+4+4);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[6]);
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[5]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[1]);
+ data << uint8(0); // rank
+ data << uint16(player->GetUInt16Value(PLAYER_FIELD_KILLS, 1)); // yesterday kills
+ data << uint16(player->GetUInt16Value(PLAYER_FIELD_KILLS, 0)); // today kills
+ data.WriteByteSeq(playerGuid[2]);
+ data.WriteByteSeq(playerGuid[0]);
+ data.WriteByteSeq(playerGuid[6]);
+ data.WriteByteSeq(playerGuid[3]);
+ data.WriteByteSeq(playerGuid[4]);
+ data.WriteByteSeq(playerGuid[1]);
+ data.WriteByteSeq(playerGuid[5]);
data << uint32(player->GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS));
+ data.WriteByteSeq(playerGuid[7]);
SendPacket(&data);
}
@@ -1343,8 +1408,9 @@ void WorldSession::HandleComplainOpcode(WorldPacket& recvData)
// if it's mail spam - ALL mails from this spammer automatically removed by client
// Complaint Received message
- WorldPacket data(SMSG_COMPLAIN_RESULT, 1);
- data << uint8(0);
+ WorldPacket data(SMSG_COMPLAIN_RESULT, 2);
+ data << uint8(0); // value 1 resets CGChat::m_complaintsSystemStatus in client. (unused?)
+ data << uint8(0); // value 0xC generates a "CalendarError" in client.
SendPacket(&data);
TC_LOG_DEBUG("network", "REPORT SPAM: type %u, guid %u, unk1 %u, unk2 %u, unk3 %u, unk4 %u, message %s", spam_type, GUID_LOPART(spammer_guid), unk1, unk2, unk3, unk4, description.c_str());
@@ -1420,8 +1486,8 @@ void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
uint32 counter, clientTicks;
recvData >> counter >> clientTicks;
- if (counter != _player->m_timeSyncCounter - 1)
- TC_LOG_DEBUG("network", "Wrong time sync counter from player %s (cheater?)", _player->GetName().c_str());
+ if (counter != _player->m_timeSyncQueue.front())
+ TC_LOG_ERROR("network", "Wrong time sync counter from player %s (cheater?)", _player->GetName().c_str());
TC_LOG_DEBUG("network", "Time sync received: counter %u, client ticks %u, time since last sync %u", counter, clientTicks, clientTicks - _player->m_timeSyncClient);
@@ -1431,6 +1497,7 @@ void WorldSession::HandleTimeSyncResp(WorldPacket& recvData)
TC_LOG_DEBUG("network", "Our ticks: %u, diff %u, latency %u", ourTicks, ourTicks - clientTicks, GetLatency());
_player->m_timeSyncClient = clientTicks;
+ _player->m_timeSyncQueue.pop();
}
void WorldSession::HandleResetInstancesOpcode(WorldPacket& /*recvData*/)
@@ -1594,7 +1661,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode(WorldPacket& recvData)
MovementInfo movementInfo;
movementInfo.guid = guid;
- ReadMovementInfo(recvData, &movementInfo);
+ _player->ReadMovementInfo(recvData, &movementInfo);
recvData.read_skip<float>(); // unk2
@@ -1634,6 +1701,15 @@ void WorldSession::HandleQueryInspectAchievements(WorldPacket& recvData)
player->SendRespondInspectAchievements(_player);
}
+void WorldSession::HandleGuildAchievementProgressQuery(WorldPacket& recvData)
+{
+ uint32 achievementId;
+ recvData >> achievementId;
+
+ if (Guild* guild = sGuildMgr->GetGuildById(_player->GetGuildId()))
+ guild->GetAchievementMgr().SendAchievementInfo(_player, achievementId);
+}
+
void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recvData*/)
{
// empty opcode
@@ -1652,12 +1728,54 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/)
SendAccountDataTimes(GLOBAL_CACHE_MASK);
}
-void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
+void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps)
{
- WorldPacket data(SMSG_SET_PHASE_SHIFT, 4);
- data << uint32(PhaseShift);
+ ObjectGuid guid = _player->GetGUID();
+
+ WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2);
+ data.WriteBit(guid[2]);
+ data.WriteBit(guid[3]);
+ data.WriteBit(guid[1]);
+ data.WriteBit(guid[6]);
+ data.WriteBit(guid[4]);
+ data.WriteBit(guid[5]);
+ data.WriteBit(guid[0]);
+ data.WriteBit(guid[7]);
+
+ data.WriteByteSeq(guid[7]);
+ data.WriteByteSeq(guid[4]);
+
+ data << uint32(0);
+ //for (uint8 i = 0; i < worldMapAreaCount; ++i)
+ // data << uint16(0); // WorldMapArea.dbc id (controls map display)
+
+ data.WriteByteSeq(guid[1]);
+
+ data << uint32(phaseIds.size() ? 0 : 8); // flags (not phasemask)
+
+ data.WriteByteSeq(guid[2]);
+ data.WriteByteSeq(guid[6]);
+
+ data << uint32(0); // Inactive terrain swaps
+ //for (uint8 i = 0; i < inactiveSwapsCount; ++i)
+ // data << uint16(0);
+
+ data << uint32(phaseIds.size()) * 2; // Phase.dbc ids
+ for (std::set<uint32>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr)
+ data << uint16(*itr);
+
+ data.WriteByteSeq(guid[3]);
+ data.WriteByteSeq(guid[0]);
+
+ data << uint32(terrainswaps.size()) * 2; // Active terrain swaps
+ for (std::set<uint32>::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr)
+ data << uint16(*itr);
+
+ data.WriteByteSeq(guid[5]);
+
SendPacket(&data);
}
+
// Battlefield and Battleground
void WorldSession::HandleAreaSpiritHealerQueryOpcode(WorldPacket& recvData)
{
@@ -1745,6 +1863,74 @@ 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");
@@ -1784,7 +1970,179 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket)
{
uint32 opcode;
recvPacket >> opcode;
- recvPacket.SetOpcode(opcode);
+ recvPacket.SetOpcode(MSG_MOVE_STOP); // always set to MSG_MOVE_STOP in client SetOpcode
HandleMovementOpcodes(recvPacket);
}
}
+
+void WorldSession::HandleViolenceLevel(WorldPacket& recvPacket)
+{
+ uint8 violenceLevel;
+ recvPacket >> violenceLevel;
+
+ // do something?
+}
+
+void WorldSession::HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket)
+{
+ ObjectGuid guid;
+ guid[6] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+ guid[2] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[5]);
+
+ WorldObject* obj = ObjectAccessor::GetWorldObject(*GetPlayer(), guid);
+ TC_LOG_ERROR("network", "Object update failed for object " UI64FMTD " (%s) for player %s (%u)", uint64(guid), obj ? obj->GetName().c_str() : "object-not-found", GetPlayerName().c_str(), GetGuidLow());
+
+ // If create object failed for current player then client will be stuck on loading screen
+ if (_player->GetGUID() == guid)
+ {
+ LogoutPlayer(true);
+ return;
+ }
+
+ // Pretend we've never seen this object
+ _player->m_clientGUIDs.erase(guid);
+}
+
+void WorldSession::HandleSaveCUFProfiles(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: CMSG_SAVE_CUF_PROFILES");
+
+ uint8 count = (uint8)recvPacket.ReadBits(20);
+
+ if (count > MAX_CUF_PROFILES)
+ {
+ TC_LOG_ERROR("entities.player", "HandleSaveCUFProfiles - %s tried to save more than %i CUF profiles. Hacking attempt?", GetPlayerName().c_str(), MAX_CUF_PROFILES);
+ recvPacket.rfinish();
+ return;
+ }
+
+ CUFProfile* profiles[MAX_CUF_PROFILES];
+ uint8 strlens[MAX_CUF_PROFILES];
+
+ for (uint8 i = 0; i < count; ++i)
+ {
+ profiles[i] = new CUFProfile;
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_2 , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_10_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_UNK_157 , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_HEAL_PREDICTION , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_SPEC_1 , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVP , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_POWER_BAR , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_15_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_40_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_PETS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_5_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS, recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_2_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_UNK_156 , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_NON_BOSS_DEBUFFS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_MAIN_TANK_AND_ASSIST , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_AGGRO_HIGHLIGHT , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_3_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_BORDER , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_USE_CLASS_COLORS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_UNK_145 , recvPacket.ReadBit());
+ strlens[i] = (uint8)recvPacket.ReadBits(8);
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_PVE , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_DISPLAY_HORIZONTAL_GROUPS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_AUTO_ACTIVATE_25_PLAYERS , recvPacket.ReadBit());
+ profiles[i]->BoolOptions.set(CUF_KEEP_GROUPS_TOGETHER , recvPacket.ReadBit());
+ }
+
+ for (uint8 i = 0; i < count; ++i)
+ {
+ recvPacket >> profiles[i]->Unk146;
+ profiles[i]->ProfileName = recvPacket.ReadString(strlens[i]);
+ recvPacket >> profiles[i]->Unk152;
+ recvPacket >> profiles[i]->FrameHeight;
+ recvPacket >> profiles[i]->FrameWidth;
+ recvPacket >> profiles[i]->Unk150;
+ recvPacket >> profiles[i]->HealthText;
+ recvPacket >> profiles[i]->Unk147;
+ recvPacket >> profiles[i]->SortBy;
+ recvPacket >> profiles[i]->Unk154;
+ recvPacket >> profiles[i]->Unk148;
+
+ GetPlayer()->SaveCUFProfile(i, profiles[i]);
+ }
+
+ for (uint8 i = count; i < MAX_CUF_PROFILES; ++i)
+ GetPlayer()->SaveCUFProfile(i, NULL);
+}
+
+void WorldSession::SendLoadCUFProfiles()
+{
+ Player* player = GetPlayer();
+
+ uint8 count = player->GetCUFProfilesCount();
+
+ ByteBuffer byteBuffer(25 * count);
+ WorldPacket data(SMSG_LOAD_CUF_PROFILES, 5 * count + 25 * count);
+
+ data.WriteBits(count, 20);
+ for (uint8 i = 0; i < MAX_CUF_PROFILES; ++i)
+ {
+ CUFProfile* profile = player->GetCUFProfile(i);
+ if (!profile)
+ continue;
+
+ data.WriteBit(profile->BoolOptions[CUF_UNK_157]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_10_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_5_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_25_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HEAL_PREDICTION]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVE]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_HORIZONTAL_GROUPS]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_40_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_3_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_AGGRO_HIGHLIGHT]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_BORDER]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_2_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_NON_BOSS_DEBUFFS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_MAIN_TANK_AND_ASSIST]);
+ data.WriteBit(profile->BoolOptions[CUF_UNK_156]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_2]);
+ data.WriteBit(profile->BoolOptions[CUF_USE_CLASS_COLORS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_POWER_BAR]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_SPEC_1]);
+ data.WriteBits(profile->ProfileName.size(), 8);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_ONLY_DISPELLABLE_DEBUFFS]);
+ data.WriteBit(profile->BoolOptions[CUF_KEEP_GROUPS_TOGETHER]);
+ data.WriteBit(profile->BoolOptions[CUF_UNK_145]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_15_PLAYERS]);
+ data.WriteBit(profile->BoolOptions[CUF_DISPLAY_PETS]);
+ data.WriteBit(profile->BoolOptions[CUF_AUTO_ACTIVATE_PVP]);
+
+ byteBuffer << uint16(profile->Unk154);
+ byteBuffer << uint16(profile->FrameHeight);
+ byteBuffer << uint16(profile->Unk152);
+ byteBuffer << uint8(profile->Unk147);
+ byteBuffer << uint16(profile->Unk150);
+ byteBuffer << uint8(profile->Unk146);
+ byteBuffer << uint8(profile->HealthText);
+ byteBuffer << uint8(profile->SortBy);
+ byteBuffer << uint16(profile->FrameWidth);
+ byteBuffer << uint8(profile->Unk148);
+ byteBuffer.WriteString(profile->ProfileName);
+ }
+
+ data.FlushBits();
+ data.append(byteBuffer);
+ SendPacket(&data);
+}
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 0c2eae849b8..fa137d98272 100644
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -30,6 +30,7 @@
#include "WaypointMovementGenerator.h"
#include "InstanceSaveMgr.h"
#include "ObjectMgr.h"
+#include "MovementStructures.h"
#define MOVEMENT_PACKET_TIME_DELAY 0
@@ -194,16 +195,33 @@ void WorldSession::HandleMoveWorldportAckOpcode()
GetPlayer()->ProcessDelayedOperations();
}
-void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData)
+void WorldSession::HandleMoveTeleportAck(WorldPacket& recvPacket)
{
TC_LOG_DEBUG("network", "MSG_MOVE_TELEPORT_ACK");
- uint64 guid;
-
- recvData.readPackGUID(guid);
+ ObjectGuid guid;
uint32 flags, time;
- recvData >> flags >> time;
- TC_LOG_DEBUG("network", "Guid " UI64FMTD, guid);
+ 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", "Guid " UI64FMTD, uint64(guid));
TC_LOG_DEBUG("network", "Flags %u, time %u", flags, time/IN_MILLISECONDS);
Player* plMover = _player->m_mover->ToPlayer();
@@ -245,9 +263,9 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recvData)
GetPlayer()->ProcessDelayedOperations();
}
-void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
+void WorldSession::HandleMovementOpcodes(WorldPacket& recvPacket)
{
- uint16 opcode = recvData.GetOpcode();
+ uint16 opcode = recvPacket.GetOpcode();
Unit* mover = _player->m_mover;
@@ -258,46 +276,41 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
if (plrMover && plrMover->IsBeingTeleported())
{
- recvData.rfinish(); // prevent warnings spam
+ recvPacket.rfinish(); // prevent warnings spam
return;
}
/* extract packet */
- uint64 guid;
-
- recvData.readPackGUID(guid);
-
MovementInfo movementInfo;
- movementInfo.guid = guid;
- ReadMovementInfo(recvData, &movementInfo);
-
- recvData.rfinish(); // prevent warnings spam
+ GetPlayer()->ReadMovementInfo(recvPacket, &movementInfo);
// prevent tampered movement data
- if (guid != mover->GetGUID())
+ if (movementInfo.guid != mover->GetGUID())
+ {
+ TC_LOG_ERROR("network", "HandleMovementOpcodes: guid error");
return;
-
+ }
if (!movementInfo.pos.IsPositionValid())
{
- recvData.rfinish(); // prevent warnings spam
+ TC_LOG_ERROR("network", "HandleMovementOpcodes: Invalid Position");
return;
}
/* handle special cases */
- if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)
+ if (movementInfo.transport.guid)
{
// transports size limited
// (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
if (movementInfo.transport.pos.GetPositionX() > 50 || movementInfo.transport.pos.GetPositionY() > 50 || movementInfo.transport.pos.GetPositionZ() > 50)
{
- recvData.rfinish(); // prevent warnings spam
+ recvPacket.rfinish(); // prevent warnings spam
return;
}
if (!Trinity::IsValidMapCoord(movementInfo.pos.GetPositionX() + movementInfo.transport.pos.GetPositionX(), movementInfo.pos.GetPositionY() + movementInfo.transport.pos.GetPositionY(),
movementInfo.pos.GetPositionZ() + movementInfo.transport.pos.GetPositionZ(), movementInfo.pos.GetOrientation() + movementInfo.transport.pos.GetOrientation()))
{
- recvData.rfinish(); // prevent warnings spam
+ recvPacket.rfinish(); // prevent warnings spam
return;
}
@@ -326,7 +339,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
if (!foundNewTransport)
{
plrMover->m_transport = NULL;
- movementInfo.transport.Reset();
+ movementInfo.ResetTransport();
}
}
}
@@ -335,14 +348,14 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
{
GameObject* go = mover->GetMap()->GetGameObject(movementInfo.transport.guid);
if (!go || go->GetGoType() != GAMEOBJECT_TYPE_TRANSPORT)
- movementInfo.flags &= ~MOVEMENTFLAG_ONTRANSPORT;
+ movementInfo.transport.guid = 0;
}
}
else if (plrMover && plrMover->GetTransport()) // if we were on a transport, leave
{
plrMover->m_transport->RemovePassenger(plrMover);
plrMover->m_transport = NULL;
- movementInfo.transport.Reset();
+ movementInfo.ResetTransport();
}
// fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
@@ -361,15 +374,13 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
m_clientTimeDelay = mstime - movementInfo.time;
/* process position-change */
- WorldPacket data(opcode, recvData.size());
movementInfo.time = movementInfo.time + m_clientTimeDelay + MOVEMENT_PACKET_TIME_DELAY;
movementInfo.guid = mover->GetGUID();
- WriteMovementInfo(&data, &movementInfo);
- mover->SendMessageToSet(&data, _player);
-
mover->m_movementInfo = movementInfo;
+ /*----------------------*/
+ /* process position-change */
// this is almost never true (not sure why it is sometimes, but it is), normally use mover->IsVehicle()
if (mover->GetVehicle())
{
@@ -379,6 +390,10 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
mover->UpdatePosition(movementInfo.pos);
+ WorldPacket data(SMSG_PLAYER_MOVE, recvPacket.size());
+ mover->WriteMovementInfo(data);
+ mover->SendMessageToSet(&data, _player);
+
if (plrMover) // nothing is charmed, or player charmed
{
if (plrMover->IsSitState() && (movementInfo.flags & (MOVEMENTFLAG_MASK_MOVING | MOVEMENTFLAG_MASK_TURNING)))
@@ -386,7 +401,9 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
plrMover->UpdateFallInformationIfNeed(movementInfo, opcode);
- if (movementInfo.pos.GetPositionZ() < -500.0f)
+ AreaTableEntry const* zone = GetAreaEntryByAreaID(plrMover->GetAreaId());
+ float depth = zone ? zone->MaxDepth : -500.0f;
+ if (movementInfo.pos.GetPositionZ() < depth)
{
if (!(plrMover->GetBattleground() && plrMover->GetBattleground()->HandlePlayerUnderMap(_player)))
{
@@ -410,62 +427,62 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData)
void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData)
{
uint32 opcode = recvData.GetOpcode();
- TC_LOG_DEBUG("network", "WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);
/* extract packet */
- uint64 guid;
- uint32 unk1;
- float newspeed;
-
- recvData.readPackGUID(guid);
+ MovementInfo movementInfo;
+ static MovementStatusElements const speedElement = MSEExtraFloat;
+ Movement::ExtraMovementStatusElement extras(&speedElement);
+ GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extras);
// now can skip not our packet
- if (_player->GetGUID() != guid)
+ if (_player->GetGUID() != movementInfo.guid)
{
recvData.rfinish(); // prevent warnings spam
return;
}
- // continue parse packet
-
- recvData >> unk1; // counter or moveEvent
-
- MovementInfo movementInfo;
- movementInfo.guid = guid;
- ReadMovementInfo(recvData, &movementInfo);
-
- recvData >> newspeed;
+ float newspeed = extras.Data.floatData;
/*----------------*/
// client ACK send one packet for mounted/run case and need skip all except last from its
// in other cases anti-cheat check can be fail in false case
UnitMoveType move_type;
- UnitMoveType force_move_type;
- static char const* move_type_name[MAX_MOVE_TYPE] = { "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };
+ static char const* const move_type_name[MAX_MOVE_TYPE] =
+ {
+ "Walk",
+ "Run",
+ "RunBack",
+ "Swim",
+ "SwimBack",
+ "TurnRate",
+ "Flight",
+ "FlightBack",
+ "PitchRate"
+ };
switch (opcode)
{
- case CMSG_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; force_move_type = MOVE_WALK; break;
- case CMSG_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; force_move_type = MOVE_RUN; break;
- case CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; force_move_type = MOVE_RUN_BACK; break;
- case CMSG_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; force_move_type = MOVE_SWIM; break;
- case CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; force_move_type = MOVE_SWIM_BACK; break;
- case CMSG_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; force_move_type = MOVE_TURN_RATE; break;
- case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; force_move_type = MOVE_FLIGHT; break;
- case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; force_move_type = MOVE_FLIGHT_BACK; break;
- case CMSG_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; force_move_type = MOVE_PITCH_RATE; break;
+ case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK: move_type = MOVE_WALK; break;
+ case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: move_type = MOVE_RUN; break;
+ case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK: move_type = MOVE_RUN_BACK; break;
+ case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK: move_type = MOVE_SWIM; break;
+ case CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK: move_type = MOVE_SWIM_BACK; break;
+ case CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK: move_type = MOVE_TURN_RATE; break;
+ case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT; break;
+ case CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK: move_type = MOVE_FLIGHT_BACK; break;
+ case CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK: move_type = MOVE_PITCH_RATE; break;
default:
TC_LOG_ERROR("network", "WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);
return;
}
// skip all forced speed changes except last and unexpected
- // in run/mounted case used one ACK and it must be skipped.m_forced_speed_changes[MOVE_RUN} store both.
- if (_player->m_forced_speed_changes[force_move_type] > 0)
+ // in run/mounted case used one ACK and it must be skipped. m_forced_speed_changes[MOVE_RUN] store both.
+ if (_player->m_forced_speed_changes[move_type] > 0)
{
- --_player->m_forced_speed_changes[force_move_type];
- if (_player->m_forced_speed_changes[force_move_type] > 0)
+ --_player->m_forced_speed_changes[move_type];
+ if (_player->m_forced_speed_changes[move_type] > 0)
return;
}
@@ -486,17 +503,34 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recvData)
}
}
-void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recvData)
+void WorldSession::HandleSetActiveMoverOpcode(WorldPacket& recvPacket)
{
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SET_ACTIVE_MOVER");
- uint64 guid;
- recvData >> guid;
+ ObjectGuid guid;
+
+ guid[7] = recvPacket.ReadBit();
+ guid[2] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[0] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[0]);
+ recvPacket.ReadByteSeq(guid[5]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[7]);
if (GetPlayer()->IsInWorld())
{
if (_player->m_mover->GetGUID() != guid)
- TC_LOG_ERROR("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, guid, GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
+ TC_LOG_ERROR("network", "HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, uint64(guid), GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
}
}
@@ -504,14 +538,8 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recvData)
{
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER");
- uint64 old_mover_guid;
- recvData.readPackGUID(old_mover_guid);
-
MovementInfo mi;
- ReadMovementInfo(recvData, &mi);
-
- mi.guid = old_mover_guid;
-
+ GetPlayer()->ReadMovementInfo(recvData, &mi);
_player->m_movementInfo = mi;
}
@@ -527,29 +555,16 @@ void WorldSession::HandleMoveKnockBackAck(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "CMSG_MOVE_KNOCK_BACK_ACK");
- uint64 guid;
- recvData.readPackGUID(guid);
+ MovementInfo movementInfo;
+ GetPlayer()->ReadMovementInfo(recvData, &movementInfo);
- if (_player->m_mover->GetGUID() != guid)
+ if (_player->m_mover->GetGUID() != movementInfo.guid)
return;
- recvData.read_skip<uint32>(); // unk
-
- MovementInfo movementInfo;
- ReadMovementInfo(recvData, &movementInfo);
-
_player->m_movementInfo = movementInfo;
- WorldPacket data(MSG_MOVE_KNOCK_BACK, 66);
- data.appendPackGUID(guid);
- _player->BuildMovementPacket(&data);
-
- // knockback specific info
- data << movementInfo.jump.sinAngle;
- data << movementInfo.jump.cosAngle;
- data << movementInfo.jump.xyspeed;
- data << movementInfo.jump.zspeed;
-
+ WorldPacket data(SMSG_MOVE_UPDATE_KNOCK_BACK, 66);
+ _player->WriteMovementInfo(data);
_player->SendMessageToSet(&data, false);
}
@@ -563,7 +578,7 @@ void WorldSession::HandleMoveHoverAck(WorldPacket& recvData)
recvData.read_skip<uint32>(); // unk
MovementInfo movementInfo;
- ReadMovementInfo(recvData, &movementInfo);
+ GetPlayer()->ReadMovementInfo(recvData, &movementInfo);
recvData.read_skip<uint32>(); // unk2
}
@@ -578,7 +593,7 @@ void WorldSession::HandleMoveWaterWalkAck(WorldPacket& recvData)
recvData.read_skip<uint32>(); // unk
MovementInfo movementInfo;
- ReadMovementInfo(recvData, &movementInfo);
+ GetPlayer()->ReadMovementInfo(recvData, &movementInfo);
recvData.read_skip<uint32>(); // unk2
}
@@ -588,10 +603,20 @@ void WorldSession::HandleSummonResponseOpcode(WorldPacket& recvData)
if (!_player->IsAlive() || _player->IsInCombat())
return;
- uint64 summoner_guid;
+ uint64 summonerGuid;
bool agree;
- recvData >> summoner_guid;
+ recvData >> summonerGuid;
recvData >> agree;
_player->SummonIfPossible(agree);
}
+
+void WorldSession::HandleSetCollisionHeightAck(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "CMSG_MOVE_SET_COLLISION_HEIGHT_ACK");
+
+ static MovementStatusElements const heightElement = MSEExtraFloat;
+ Movement::ExtraMovementStatusElement extra(&heightElement);
+ MovementInfo movementInfo;
+ GetPlayer()->ReadMovementInfo(recvPacket, &movementInfo, &extra);
+}
diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index 4d78064423c..48079c9c630 100644
--- a/src/server/game/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
@@ -41,11 +41,12 @@
enum StableResultCode
{
STABLE_ERR_MONEY = 0x01, // "you don't have enough money"
- STABLE_ERR_STABLE = 0x06, // currently used in most fail cases
+ STABLE_ERR_INVALID_SLOT = 0x03, // "That slot is locked"
STABLE_SUCCESS_STABLE = 0x08, // stable success
STABLE_SUCCESS_UNSTABLE = 0x09, // unstable/swap success
STABLE_SUCCESS_BUY_SLOT = 0x0A, // buy slot success
- STABLE_ERR_EXOTIC = 0x0C // "you are unable to control exotic creatures"
+ STABLE_ERR_EXOTIC = 0x0B, // "you are unable to control exotic creatures"
+ STABLE_ERR_STABLE = 0x0C, // "Internal pet error"
};
void WorldSession::HandleTabardVendorActivateOpcode(WorldPacket& recvData)
@@ -103,13 +104,6 @@ void WorldSession::SendShowBank(uint64 guid)
SendPacket(&data);
}
-void WorldSession::SendShowMailBox(uint64 guid)
-{
- WorldPacket data(SMSG_SHOW_MAILBOX, 8);
- data << guid;
- SendPacket(&data);
-}
-
void WorldSession::HandleTrainerListOpcode(WorldPacket& recvData)
{
uint64 guid;
@@ -158,6 +152,7 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
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());
@@ -195,9 +190,6 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint8(state == TRAINER_SPELL_GREEN_DISABLED ? TRAINER_SPELL_GREEN : state);
data << uint32(floor(tSpell->spellCost * fDiscountMod));
- 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
data << uint8(tSpell->reqLevel);
data << uint32(tSpell->reqSkill);
data << uint32(tSpell->reqSkillValue);
@@ -212,7 +204,7 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint32(prevSpellId);
++maxReq;
}
- if (maxReq == 3)
+ if (maxReq == 2)
break;
SpellsRequiringSpellMapBounds spellsRequired = sSpellMgr->GetSpellsRequiredForSpellBounds(tSpell->learnedSpell[i]);
for (SpellsRequiringSpellMap::const_iterator itr2 = spellsRequired.first; itr2 != spellsRequired.second && maxReq < 3; ++itr2)
@@ -220,15 +212,19 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
data << uint32(itr2->second);
++maxReq;
}
- if (maxReq == 3)
+ if (maxReq == 2)
break;
}
- while (maxReq < 3)
+ while (maxReq < 2)
{
data << uint32(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;
}
@@ -241,9 +237,10 @@ void WorldSession::SendTrainerList(uint64 guid, const std::string& strTitle)
void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
{
uint64 guid;
- uint32 spellId = 0;
+ uint32 spellId;
+ uint32 trainerId;
- recvData >> guid >> spellId;
+ recvData >> guid >> trainerId >> spellId;
TC_LOG_DEBUG("network", "WORLD: Received CMSG_TRAINER_BUY_SPELL NpcGUID=%u, learn spell id is: %u", uint32(GUID_LOPART(guid)), spellId);
Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_TRAINER);
@@ -260,28 +257,40 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
// check present spell in trainer spell list
TrainerSpellData const* trainer_spells = unit->GetTrainerSpells();
if (!trainer_spells)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// not found, cheat?
TrainerSpell const* trainer_spell = trainer_spells->Find(spellId);
if (!trainer_spell)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// can't be learn, cheat? Or double learn with lags...
if (_player->GetTrainerSpellState(trainer_spell) != TRAINER_SPELL_GREEN)
+ {
+ SendTrainerBuyFailed(guid, spellId, 0);
return;
+ }
// apply reputation discount
uint32 nSpellCost = uint32(floor(trainer_spell->spellCost * _player->GetReputationPriceDiscount(unit)));
// check money requirement
- if (!_player->HasEnoughMoney(nSpellCost))
+ if (!_player->HasEnoughMoney(uint64(nSpellCost)))
+ {
+ SendTrainerBuyFailed(guid, spellId, 1);
return;
+ }
- _player->ModifyMoney(-int32(nSpellCost));
+ _player->ModifyMoney(-int64(nSpellCost));
- unit->SendPlaySpellVisual(179); // 53 SpellCastDirected
- unit->SendPlaySpellImpact(_player->GetGUID(), 362); // 113 EmoteSalute
+ unit->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected
+ _player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute
// learn explicitly or cast explicitly
if (trainer_spell->IsCastable())
@@ -291,7 +300,16 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(guid);
- data << uint32(spellId); // should be same as in packet from client
+ data << uint32(spellId);
+ SendPacket(&data);
+}
+
+void WorldSession::SendTrainerBuyFailed(uint64 guid, uint32 spellId, uint32 reason)
+{
+ WorldPacket data(SMSG_TRAINER_BUY_FAILED, 16);
+ data << uint64(guid);
+ data << uint32(spellId); // should be same as in packet from client
+ data << uint32(reason); // 1 == "Not enough money for trainer service." 0 == "Trainer service %d unavailable."
SendPacket(&data);
}
@@ -319,9 +337,7 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket& recvData)
// GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
if (unit->IsArmorer() || unit->IsCivilian() || unit->IsQuestGiver() || unit->IsServiceProvider() || unit->IsGuard())
- {
unit->StopMoving();
- }
// If spiritguide, no need for gossip menu, just put player into resurrect queue
if (unit->IsSpiritGuide())
@@ -473,7 +489,7 @@ void WorldSession::SendBindPoint(Creature* npc)
// send spell for homebinding (3286)
npc->CastSpell(_player, bindspell, true);
- WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, (8+4));
+ WorldPacket data(SMSG_TRAINER_BUY_SUCCEEDED, 12);
data << uint64(npc->GetGUID());
data << uint32(bindspell);
SendPacket(&data);
@@ -537,6 +553,7 @@ void WorldSession::SendStablePetCallback(PreparedQueryResult result, uint64 guid
// not let move dead pet in slot
if (pet && pet->IsAlive() && pet->getPetType() == HUNTER_PET)
{
+ data << uint32(0); // 4.x unknown, some kind of order?
data << uint32(pet->GetCharmInfo()->GetPetNumber());
data << uint32(pet->GetEntry());
data << uint32(pet->getLevel());
@@ -639,14 +656,13 @@ void WorldSession::HandleStablePetCallback(PreparedQueryResult result)
while (result->NextRow());
}
- WorldPacket data(SMSG_STABLE_RESULT, 1);
if (freeSlot > 0 && freeSlot <= GetPlayer()->m_stableSlots)
{
_player->RemovePet(_player->GetPet(), PetSaveMode(freeSlot));
SendStableResult(STABLE_SUCCESS_STABLE);
}
else
- SendStableResult(STABLE_ERR_STABLE);
+ SendStableResult(STABLE_ERR_INVALID_SLOT);
}
void WorldSession::HandleUnstablePet(WorldPacket& recvData)
@@ -749,7 +765,7 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recvData)
if (GetPlayer()->m_stableSlots < MAX_PET_STABLES)
{
- StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
+ /*StableSlotPricesEntry const* SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);
if (_player->HasEnoughMoney(SlotPrice->Price))
{
++GetPlayer()->m_stableSlots;
@@ -757,7 +773,7 @@ void WorldSession::HandleBuyStableSlot(WorldPacket& recvData)
SendStableResult(STABLE_SUCCESS_BUY_SLOT);
}
else
- SendStableResult(STABLE_ERR_MONEY);
+ SendStableResult(STABLE_ERR_MONEY);*/
}
else
SendStableResult(STABLE_ERR_STABLE);
@@ -828,13 +844,15 @@ void WorldSession::HandleStableSwapPetCallback(PreparedQueryResult result, uint3
}
CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(petEntry);
- if (!creatureInfo || !creatureInfo->IsTameable(_player->CanTameExoticPets()))
+ if (!creatureInfo || !creatureInfo->IsTameable(true))
{
- // if problem in exotic pet
- if (creatureInfo && creatureInfo->IsTameable(true))
- SendStableResult(STABLE_ERR_EXOTIC);
- else
- SendStableResult(STABLE_ERR_STABLE);
+ SendStableResult(STABLE_ERR_STABLE);
+ return;
+ }
+
+ if (!creatureInfo->IsTameable(_player->CanTameExoticPets()))
+ {
+ SendStableResult(STABLE_ERR_EXOTIC);
return;
}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 550cb74cffa..78fbd318a11 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -61,9 +61,14 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
uint64 guid1;
uint32 data;
uint64 guid2;
+ float x, y, z;
recvData >> guid1; //pet guid
recvData >> data;
recvData >> guid2; //tag guid
+ // Position
+ recvData >> x;
+ recvData >> y;
+ recvData >> z;
uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data);
uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1
@@ -98,7 +103,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
return;
if (GetPlayer()->m_Controlled.size() == 1)
- HandlePetActionHelper(pet, guid1, spellid, flag, guid2);
+ HandlePetActionHelper(pet, guid1, spellid, flag, guid2, x, y, z);
else
{
//If a pet is dismissed, m_Controlled will change
@@ -107,7 +112,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData)
if ((*itr)->GetEntry() == pet->GetEntry() && (*itr)->IsAlive())
controlled.push_back(*itr);
for (std::vector<Unit*>::iterator itr = controlled.begin(); itr != controlled.end(); ++itr)
- HandlePetActionHelper(*itr, guid1, spellid, flag, guid2);
+ HandlePetActionHelper(*itr, guid1, spellid, flag, guid2, x, y, z);
}
}
@@ -139,7 +144,7 @@ void WorldSession::HandlePetStopAttack(WorldPacket &recvData)
pet->AttackStop();
}
-void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid, uint16 flag, uint64 guid2)
+void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid, uint16 flag, uint64 guid2, float x, float y, float z)
{
CharmInfo* charmInfo = pet->GetCharmInfo();
if (!charmInfo)
@@ -261,6 +266,18 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid
}
}
break;
+ case COMMAND_MOVE_TO:
+ pet->StopMoving();
+ pet->GetMotionMaster()->Clear(false);
+ pet->GetMotionMaster()->MovePoint(0, x, y, z);
+ charmInfo->SetCommandState(COMMAND_MOVE_TO);
+
+ charmInfo->SetIsCommandAttack(false);
+ charmInfo->SetIsAtStay(true);
+ charmInfo->SetIsFollowing(false);
+ charmInfo->SetIsReturning(false);
+ charmInfo->SaveStayPosition();
+ break;
default:
TC_LOG_ERROR("network", "WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
}
@@ -681,15 +698,7 @@ void WorldSession::HandlePetAbandon(WorldPacket& recvData)
if (pet)
{
if (pet->IsPet())
- {
- if (pet->GetGUID() == _player->GetPetGUID())
- {
- uint32 feelty = pet->GetPower(POWER_HAPPINESS);
- pet->SetPower(POWER_HAPPINESS, feelty > 50000 ? (feelty-50000) : 0);
- }
-
_player->RemovePet((Pet*)pet, PET_SAVE_AS_DELETED);
- }
else if (pet->GetGUID() == _player->GetCharmGUID())
_player->StopCastingCharm();
}
@@ -834,14 +843,11 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec
WorldPacket data(SMSG_PET_NAME_INVALID, 4 + name.size() + 1 + 1);
data << uint32(error);
data << name;
+ data << uint8(declinedName ? 1 : 0);
if (declinedName)
- {
- data << uint8(1);
for (uint32 i = 0; i < MAX_DECLINED_NAME_CASES; ++i)
data << declinedName->name[i];
- }
- else
- data << uint8(0);
+
SendPacket(&data);
}
diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index d02b8986e08..8eb699a978f 100644
--- a/src/server/game/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
@@ -182,7 +182,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData)
return;
}
- if (!_player->HasEnoughMoney(cost))
+ if (!_player->HasEnoughMoney(uint64(cost)))
{ //player hasn't got enough money
_player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, charterid, 0);
return;
@@ -382,7 +382,7 @@ void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
void WorldSession::HandlePetitionRenameOpcode(WorldPacket& recvData)
{
- TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME"); // ok
+ TC_LOG_DEBUG("network", "Received opcode MSG_PETITION_RENAME");
uint64 petitionGuid;
uint32 type;
@@ -550,14 +550,10 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
data << uint64(petitionGuid);
data << uint64(_player->GetGUID());
- data << (uint32)PETITION_SIGN_ALREADY_SIGNED;
+ data << uint32(PETITION_SIGN_ALREADY_SIGNED);
// close at signer side
SendPacket(&data);
-
- // update for owner if online
- if (Player* owner = ObjectAccessor::FindPlayer(ownerGuid))
- owner->GetSession()->SendPacket(&data);
return;
}
@@ -779,7 +775,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData)
if (_player->GetGuildId())
{
data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
- data << (uint32)PETITION_TURN_ALREADY_IN_GUILD;
+ data << uint32(PETITION_TURN_ALREADY_IN_GUILD);
_player->GetSession()->SendPacket(&data);
return;
}
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index e30260d34e2..c3ac98aa76a 100644
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -118,10 +118,14 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData)
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);
data << uint32(entry); // creature entry
data << Name;
- data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty
+
+ for (int i = 0; i < 7; i++)
+ data << uint8(0); // name2, ..., name8
+
data << SubName;
data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0
data << uint32(ci->type_flags); // flags
+ data << uint32(ci->type_flags2); // unknown meaning
data << uint32(ci->type); // CreatureType.dbc
data << uint32(ci->family); // CreatureFamily.dbc
data << uint32(ci->rank); // Creature Rank (elite, boss, etc)
@@ -137,6 +141,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData)
for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
data << uint32(ci->questItems[i]); // itemId[6], quest drop
data << uint32(ci->movementId); // CreatureMovementInfo.dbc
+ data << uint32(ci->expansionUnknown); // unknown meaning
SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE");
}
@@ -192,7 +197,8 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
data.append(info->raw.data, MAX_GAMEOBJECT_DATA);
data << float(info->size); // go size
for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i)
- data << uint32(info->questItems[i]); // itemId[6], quest drop
+ data << uint32(info->questItems[i]); // itemId[6], quest drop
+ data << int32(info->unkInt32); // 4.x, unknown
SendPacket(&data);
TC_LOG_DEBUG("network", "WORLD: Sent SMSG_GAMEOBJECT_QUERY_RESPONSE");
}
@@ -207,7 +213,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData)
}
}
-void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleCorpseQueryOpcode(WorldPacket& /*recvData*/)
{
TC_LOG_DEBUG("network", "WORLD: Received MSG_CORPSE_QUERY");
@@ -385,8 +391,8 @@ void WorldSession::HandleCorpseMapPositionQuery(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Recv CMSG_CORPSE_MAP_POSITION_QUERY");
- uint32 unk;
- recvData >> unk;
+ uint32 transportGuidLow;
+ recvData >> transportGuidLow;
WorldPacket data(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, 4+4+4+4);
data << float(0);
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index e8d43b55fd8..7e7c8326a65 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -74,7 +74,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData)
}
//inform client about status of quest
- _player->PlayerTalkClass->SendQuestGiverStatus(uint8(questStatus), guid);
+ _player->PlayerTalkClass->SendQuestGiverStatus(questStatus, guid);
}
void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket& recvData)
@@ -314,34 +314,48 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u", uint32(GUID_LOPART(guid)), questId, reward);
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
- if (!object || !object->hasInvolvedQuest(questId))
+ Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
+ if (!quest)
return;
- // some kind of WPE protection
- if (!_player->CanInteractWithQuestGiver(object))
- return;
+ Object* object = _player;
- if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
+ if (!quest->HasFlag(QUEST_FLAGS_AUTO_SUBMIT))
{
- if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
- (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
- {
- TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
- _player->GetName().c_str(), _player->GetGUIDLow(), questId);
+ object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+ if (!object || !object->hasInvolvedQuest(questId))
return;
- }
- if (_player->CanRewardQuest(quest, reward, true))
- {
- _player->RewardQuest(quest, reward, object);
- switch (object->GetTypeId())
+ // some kind of WPE protection
+ if (!_player->CanInteractWithQuestGiver(object))
+ return;
+ }
+
+ if ((!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) ||
+ (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete()))
+ {
+ TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)",
+ _player->GetName().c_str(), _player->GetGUIDLow(), questId);
+ return;
+ }
+
+ if (_player->CanRewardQuest(quest, reward, true))
+ {
+ _player->RewardQuest(quest, reward, object);
+
+ switch (object->GetTypeId())
+ {
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
{
- case TYPEID_UNIT:
- if (!(sScriptMgr->OnQuestReward(_player, (object->ToCreature()), quest, reward)))
+ //For AutoSubmition was added plr case there as it almost same exclute AI script cases.
+ Creature* creatureQGiver = object->ToCreature();
+ if (!creatureQGiver || !(sScriptMgr->OnQuestReward(_player, creatureQGiver, quest, reward)))
+ {
+ // Send next quest
+ if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- // Send next quest
- if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
_player->AddQuestAndCheckCompletion(nextQuest, object);
@@ -349,14 +363,21 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- (object->ToCreature())->AI()->sQuestReward(_player, quest, reward);
+ _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- break;
- case TYPEID_GAMEOBJECT:
- if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
+
+ if (creatureQGiver)
+ creatureQGiver->AI()->sQuestReward(_player, quest, reward);
+ }
+ break;
+ }
+ case TYPEID_GAMEOBJECT:
+ if (!sScriptMgr->OnQuestReward(_player, ((GameObject*)object), quest, reward))
+ {
+ // Send next quest
+ if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- // Send next quest
- if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
_player->AddQuestAndCheckCompletion(nextQuest, object);
@@ -364,16 +385,18 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData)
_player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
+ _player->PlayerTalkClass->SendQuestGiverQuestDetails(nextQuest, guid, true);
}
- break;
- default:
- break;
- }
+
+ object->ToGameObject()->AI()->QuestReward(_player, quest, reward);
+ }
+ break;
+ default:
+ break;
}
- else
- _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
}
+ else
+ _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
}
void WorldSession::HandleQuestgiverRequestRewardOpcode(WorldPacket& recvData)
@@ -466,7 +489,7 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
uint32 questId;
recvData >> questId;
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT quest = %u", questId);
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_CONFIRM_ACCEPT questId = %u", questId);
if (const Quest* quest = sObjectMgr->GetQuestTemplate(questId))
{
@@ -491,28 +514,31 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData)
void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData)
{
uint32 questId;
- uint64 guid;
+ uint64 playerGuid;
+ bool autoCompleteMode; // 0 - standart complete quest mode with npc, 1 - auto-complete mode
+ recvData >> playerGuid >> questId >> autoCompleteMode;
- recvData >> guid >> questId;
-
- TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, quest = %u", uint32(GUID_LOPART(guid)), questId);
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_COMPLETE_QUEST npc = %u, questId = %u", uint32(GUID_LOPART(playerGuid)), questId);
Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
if (!quest)
return;
- Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
+ Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, playerGuid, TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT);
if (!object || !object->hasInvolvedQuest(questId))
return;
- // some kind of WPE protection
- if (!_player->CanInteractWithQuestGiver(object))
- return;
+ if (autoCompleteMode == 0)
+ {
+ // some kind of WPE protection
+ if (!_player->CanInteractWithQuestGiver(object))
+ return;
+ }
if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE)
{
TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to complete quest [entry: %u] without being in possession of the quest!",
- _player->GetName().c_str(), _player->GetGUIDLow(), questId);
+ _player->GetName().c_str(), _player->GetGUIDLow(), questId);
return;
}
@@ -522,16 +548,16 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData)
if (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE)
{
if (quest->IsRepeatable())
- _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanCompleteRepeatableQuest(quest), false);
+ _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanCompleteRepeatableQuest(quest), false);
else
- _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
+ _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false);
}
else
{
if (quest->GetReqItemsCount()) // some items required
- _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, guid, _player->CanRewardQuest(quest, false), false);
+ _player->PlayerTalkClass->SendQuestGiverRequestItems(quest, playerGuid, _player->CanRewardQuest(quest, false), false);
else // no items required
- _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, guid, true);
+ _player->PlayerTalkClass->SendQuestGiverOfferReward(quest, playerGuid, true);
}
if (Creature* creature = object->ToCreature())
@@ -742,7 +768,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
uint32 count = 0;
- WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4);
+ WorldPacket data(SMSG_QUESTGIVER_STATUS_MULTIPLE, 4 + 8 + 4);
data << uint32(count); // placeholder
for (Player::ClientGUIDs::const_iterator itr = _player->m_clientGUIDs.begin(); itr != _player->m_clientGUIDs.end(); ++itr)
@@ -763,7 +789,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
questStatus = getDialogStatus(_player, questgiver);
data << uint64(questgiver->GetGUID());
- data << uint8(questStatus);
+ data << uint32(questStatus);
++count;
}
else if (IS_GAMEOBJECT_GUID(*itr))
@@ -777,7 +803,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
questStatus = getDialogStatus(_player, questgiver);
data << uint64(questgiver->GetGUID());
- data << uint8(questStatus);
+ data << uint32(questStatus);
++count;
}
}
@@ -786,7 +812,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
SendPacket(&data);
}
-void WorldSession::HandleQueryQuestsCompleted(WorldPacket & /*recvData*/)
+void WorldSession::HandleQueryQuestsCompleted(WorldPacket& /*recvData*/)
{
size_t rew_count = _player->GetRewardedQuestCount();
diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp
index 3b348b6e214..2efc9df5d94 100644
--- a/src/server/game/Handlers/ReferAFriendHandler.cpp
+++ b/src/server/game/Handlers/ReferAFriendHandler.cpp
@@ -48,7 +48,8 @@ void WorldSession::HandleGrantLevel(WorldPacket& recvData)
else if (target->GetGroup() != _player->GetGroup())
error = ERR_REFER_A_FRIEND_NOT_IN_GROUP;
- if (error) {
+ if (error)
+ {
WorldPacket data(SMSG_REFER_A_FRIEND_FAILURE, 24);
data << uint32(error);
if (error == ERR_REFER_A_FRIEND_NOT_IN_GROUP)
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index fe893314b87..2108b654d6b 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -29,18 +29,34 @@
void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData)
{
- uint32 talent_id, requested_rank;
- recvData >> talent_id >> requested_rank;
+ uint32 talentId, requestedRank;
+ recvData >> talentId >> requestedRank;
- _player->LearnTalent(talent_id, requested_rank);
- _player->SendTalentsInfoData(false);
+ if (_player->LearnTalent(talentId, requestedRank))
+ _player->SendTalentsInfoData(false);
}
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
{
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;
@@ -49,7 +65,11 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
{
recvPacket >> talentId >> talentRank;
- _player->LearnTalent(talentId, talentRank);
+ if (!_player->LearnTalent(talentId, talentRank))
+ {
+ recvPacket.rfinish();
+ break;
+ }
}
_player->SendTalentsInfoData(false);
@@ -75,7 +95,7 @@ void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData)
if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH);
- if (!(_player->resetTalents()))
+ if (!_player->ResetTalents())
{
WorldPacket data(MSG_TALENT_WIPE_CONFIRM, 8+4); //you have not any talent
data << uint64(0);
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index ba30803e8c2..04e64634d88 100644
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -21,6 +21,7 @@
#include "WorldPacket.h"
#include "WorldSession.h"
#include "ObjectMgr.h"
+#include "GuildMgr.h"
#include "SpellMgr.h"
#include "Log.h"
#include "Opcodes.h"
@@ -50,9 +51,27 @@ void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlag
uint8 hasMovementData;
recvPacket >> hasMovementData;
if (hasMovementData)
- {
- recvPacket.SetOpcode(recvPacket.read<uint32>());
HandleMovementOpcodes(recvPacket);
+ }
+ else if (castFlags & 0x8) // Archaeology
+ {
+ uint32 count, entry, usedCount;
+ uint8 type;
+ recvPacket >> count;
+ for (uint32 i = 0; i < count; ++i)
+ {
+ recvPacket >> type;
+ switch (type)
+ {
+ case 2: // Keystones
+ recvPacket >> entry; // Item id
+ recvPacket >> usedCount; // Item count
+ break;
+ case 1: // Fragments
+ recvPacket >> entry; // Currency id
+ recvPacket >> usedCount; // Currency count
+ break;
+ }
}
}
}
@@ -200,7 +219,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
// Verify that the bag is an actual bag or wrapped item that can be used "normally"
if (!(proto->Flags & ITEM_PROTO_FLAG_OPENABLE) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
{
- pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
+ pUser->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!",
pUser->GetName().c_str(), pUser->GetGUIDLow(), item->GetGUIDLow(), proto->ItemId);
return;
@@ -310,9 +329,13 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
- uint32 spellId;
+ uint32 spellId, glyphIndex;
uint8 castCount, castFlags;
- recvPacket >> castCount >> spellId >> 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());
@@ -359,6 +382,27 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
return;
}
+ Unit::AuraEffectList swaps = mover->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
+ Unit::AuraEffectList const& swaps2 = mover->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
+ if (!swaps2.empty())
+ swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
+
+ if (!swaps.empty())
+ {
+ for (Unit::AuraEffectList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
+ {
+ if ((*itr)->IsAffectingSpell(spellInfo))
+ {
+ if (SpellInfo const* newInfo = sSpellMgr->GetSpellInfo((*itr)->GetAmount()))
+ {
+ spellInfo = newInfo;
+ spellId = newInfo->Id;
+ }
+ break;
+ }
+ }
+ }
+
// Client is resending autoshot cast opcode when other spell is cast during shoot rotation
// Skip it to prevent "interrupt" message
if (spellInfo->IsAutoRepeatRangedSpell() && caster->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)
@@ -392,6 +436,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE, 0, false);
spell->m_cast_count = castCount; // set count of casts
+ spell->m_glyphIndex = glyphIndex;
spell->prepare(&targets);
}
@@ -506,8 +551,9 @@ void WorldSession::HandleTotemDestroyed(WorldPacket& recvPacket)
return;
uint8 slotId;
-
+ uint64 guid;
recvPacket >> slotId;
+ recvPacket >> guid;
++slotId;
if (slotId >= MAX_TOTEM_SLOT)
@@ -517,12 +563,11 @@ void WorldSession::HandleTotemDestroyed(WorldPacket& recvPacket)
return;
Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]);
-
- if (totem && totem->IsTotem())
+ if (totem && totem->IsTotem() && totem->GetGUID() == guid)
totem->ToTotem()->UnSummon();
}
-void WorldSession::HandleSelfResOpcode(WorldPacket & /*recvData*/)
+void WorldSession::HandleSelfResOpcode(WorldPacket& /*recvData*/)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_SELF_RES"); // empty opcode
@@ -562,6 +607,7 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData)
TC_LOG_DEBUG("network", "WORLD: CMSG_GET_MIRRORIMAGE_DATA");
uint64 guid;
recvData >> guid;
+ recvData.read_skip<uint32>(); // DisplayId ?
// Get unit for which data is needed by client
Unit* unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL);
@@ -586,12 +632,17 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData)
if (creator->GetTypeId() == TYPEID_PLAYER)
{
Player* player = creator->ToPlayer();
+ Guild* guild = NULL;
+
+ if (uint32 guildId = player->GetGuildId())
+ guild = sGuildMgr->GetGuildById(guildId);
+
data << uint8(player->GetByteValue(PLAYER_BYTES, 0)); // skin
data << uint8(player->GetByteValue(PLAYER_BYTES, 1)); // face
data << uint8(player->GetByteValue(PLAYER_BYTES, 2)); // hair
data << uint8(player->GetByteValue(PLAYER_BYTES, 3)); // haircolor
data << uint8(player->GetByteValue(PLAYER_BYTES_2, 0)); // facialhair
- data << uint32(player->GetGuildId()); // unk
+ data << uint64(guild ? guild->GetGUID() : 0);
static EquipmentSlots const itemSlots[] =
{
@@ -680,3 +731,28 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
data << float(z);
caster->SendMessageToSet(&data, true);
}
+
+void WorldSession::HandleRequestCategoryCooldowns(WorldPacket& /*recvPacket*/)
+{
+ std::map<uint32, int32> categoryMods;
+ Unit::AuraEffectList const& categoryCooldownAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN);
+ for (Unit::AuraEffectList::const_iterator itr = categoryCooldownAuras.begin(); itr != categoryCooldownAuras.end(); ++itr)
+ {
+ std::map<uint32, int32>::iterator cItr = categoryMods.find((*itr)->GetMiscValue());
+ if (cItr == categoryMods.end())
+ categoryMods[(*itr)->GetMiscValue()] = (*itr)->GetAmount();
+ else
+ cItr->second += (*itr)->GetAmount();
+ }
+
+ WorldPacket data(SMSG_SPELL_CATEGORY_COOLDOWN, 11);
+ data.WriteBits(categoryMods.size(), 23);
+ data.FlushBits();
+ for (std::map<uint32, int32>::const_iterator itr = categoryMods.begin(); itr != categoryMods.end(); ++itr)
+ {
+ data << uint32(itr->first);
+ data << int32(-itr->second);
+ }
+
+ SendPacket(&data);
+}
diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 34899fc23df..aaa9188b6f4 100644
--- a/src/server/game/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -94,12 +94,12 @@ void WorldSession::SendTaxiMenu(Creature* unit)
{
// find current node
uint32 curloc = sObjectMgr->GetNearestTaxiNode(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetMapId(), GetPlayer()->GetTeam());
-
- if (curloc == 0)
+ if (!curloc)
return;
bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater();
- if (unit->GetEntry() == 29480) GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
+ if (unit->GetEntry() == 29480)
+ GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
TC_LOG_DEBUG("network", "WORLD: CMSG_TAXINODE_STATUS_QUERY %u ", curloc);
@@ -207,13 +207,10 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Received CMSG_MOVE_SPLINE_DONE");
- uint64 guid; // used only for proper packet read
- recvData.readPackGUID(guid);
+ recvData.read_skip<uint32>(); // unk
MovementInfo movementInfo; // used only for proper packet read
- ReadMovementInfo(recvData, &movementInfo);
-
- recvData.read_skip<uint32>(); // unk
+ _player->ReadMovementInfo(recvData, &movementInfo);
// in taxi flight packet received in 2 case:
// 1) end taxi path in far (multi-node) flight
diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index 688d7e58b6c..4ea4d835ae9 100644
--- a/src/server/game/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
@@ -44,7 +44,7 @@ void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData)
GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID());
if (ticket && ticket->IsCompleted())
- sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());;
+ sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID());
// Player must not have ticket
if (!ticket || ticket->IsClosed())
@@ -188,7 +188,7 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData)
recvData >> mainSurvey;
// sub_survey1, r1, comment1, sub_survey2, r2, comment2, sub_survey3, r3, comment3, sub_survey4, r4, comment4, sub_survey5, r5, comment5, sub_survey6, r6, comment6, sub_survey7, r7, comment7, sub_survey8, r8, comment8, sub_survey9, r9, comment9, sub_survey10, r10, comment10,
- for (uint8 i = 0; i < 10; i++)
+ for (uint8 i = 0; i < 15; i++)
{
uint32 subSurveyId; // ref to i'th GMSurveySurveys.dbc field (all fields in that dbc point to fields in GMSurveyQuestions.dbc)
recvData >> subSurveyId;
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 28a511ad9d3..726685044f3 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -34,34 +34,38 @@ void WorldSession::SendTradeStatus(TradeStatus status)
{
WorldPacket data;
+ data.Initialize(SMSG_TRADE_STATUS, 1+4+4);
+ data.WriteBit(0); // unk bit, usually 0
+ data.WriteBits(status, 5);
+
switch (status)
{
case TRADE_STATUS_BEGIN_TRADE:
- data.Initialize(SMSG_TRADE_STATUS, 4+8);
- data << uint32(status);
- data << uint64(0);
+ data.WriteBits(0, 8); // zero guid
+ data.FlushBits();
break;
case TRADE_STATUS_OPEN_WINDOW:
- data.Initialize(SMSG_TRADE_STATUS, 4+4);
- data << uint32(status);
- data << uint32(0); // added in 2.4.0
+ data.FlushBits();
+ data << uint32(0); // unk
break;
case TRADE_STATUS_CLOSE_WINDOW:
- data.Initialize(SMSG_TRADE_STATUS, 4+4+1+4);
- data << uint32(status);
- data << uint32(0);
- data << uint8(0);
- data << uint32(0);
+ data.WriteBit(0); // unk
+ data.FlushBits();
+ data << uint32(0); // unk
+ data << uint32(0); // unk
break;
case TRADE_STATUS_ONLY_CONJURED:
case TRADE_STATUS_NOT_ELIGIBLE:
- data.Initialize(SMSG_TRADE_STATUS, 4+1);
- data << uint32(status);
- data << uint8(0);
+ data.FlushBits();
+ data << uint8(0); // unk
break;
+ case TRADE_STATUS_CURRENCY: // Not implemented
+ case TRADE_STATUS_CURRENCY_NOT_TRADABLE: // Not implemented
+ data.FlushBits();
+ data << uint32(0); // unk
+ data << uint32(0); // unk
default:
- data.Initialize(SMSG_TRADE_STATUS, 4);
- data << uint32(status);
+ data.FlushBits();
break;
}
@@ -71,60 +75,117 @@ void WorldSession::SendTradeStatus(TradeStatus status)
void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/)
{
TC_LOG_DEBUG("network", "WORLD: Ignore Trade %u", _player->GetGUIDLow());
- // recvPacket.print_storage();
}
void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/)
{
TC_LOG_DEBUG("network", "WORLD: Busy Trade %u", _player->GetGUIDLow());
- // recvPacket.print_storage();
}
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
{
TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();
- WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4));
- data << uint8(trader_data); // 1 means traders data, 0 means own
- data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
+ ByteBuffer itemData(7*2 + 7*4 + 3*4 + 3*4 + 1);
+
+ uint8 count = 0;
+ for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
+ if (view_trade->GetItem(TradeSlots(i)))
+ ++count;
+
+ WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70);
+ data << uint32(0); // this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
+ data << uint32(0); // unk 2
+ data << uint64(view_trade->GetMoney()); // trader gold
+ data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases
+ data << uint32(0); // unk 5
+ data << uint8(trader_data); // 1 means traders data, 0 means own
data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases
- data << uint32(view_trade->GetMoney()); // trader gold
- data << uint32(view_trade->GetSpell()); // spell cast on lowest slot item
+ data.WriteBits(count, 22);
for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
{
- data << uint8(i); // trade slot number, if not specified, then end of packet
+ Item* item = view_trade->GetItem(TradeSlots(i));
+ if (!item)
+ continue;
- if (Item* item = view_trade->GetItem(TradeSlots(i)))
- {
- data << uint32(item->GetTemplate()->ItemId); // entry
- data << uint32(item->GetTemplate()->DisplayInfoID);// display id
- data << uint32(item->GetCount()); // stack count
- // wrapped: hide stats but show giftcreator name
- data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED) ? 1 : 0);
- data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR));
- // perm. enchantment and gems
- data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
- for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
- data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
- // creator
- data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR));
- data << uint32(item->GetSpellCharges()); // charges
- data << uint32(item->GetItemSuffixFactor()); // SuffixFactor
- data << uint32(item->GetItemRandomPropertyId());// random properties id
- data << uint32(item->GetTemplate()->LockID); // lock id
- // max durability
- data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
- // durability
- data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
- }
- else
+ ObjectGuid giftCreatorGuid = item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR);
+ ObjectGuid creatorGuid = item->GetUInt64Value(ITEM_FIELD_CREATOR);
+
+ data.WriteBit(giftCreatorGuid[7]);
+ data.WriteBit(giftCreatorGuid[1]);
+ bool notWrapped = data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED));
+ data.WriteBit(giftCreatorGuid[3]);
+
+ if (notWrapped)
{
- for (uint8 j = 0; j < 18; ++j)
- data << uint32(0);
+ data.WriteBit(creatorGuid[7]);
+ data.WriteBit(creatorGuid[1]);
+ data.WriteBit(creatorGuid[4]);
+ data.WriteBit(creatorGuid[6]);
+ data.WriteBit(creatorGuid[2]);
+ data.WriteBit(creatorGuid[3]);
+ data.WriteBit(creatorGuid[5]);
+ data.WriteBit(item->GetTemplate()->LockID != 0);
+ data.WriteBit(creatorGuid[0]);
+
+ itemData.WriteByteSeq(creatorGuid[1]);
+
+ itemData << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
+ for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS /*3*/; ++enchant_slot)
+ itemData << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
+ itemData << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
+
+ itemData.WriteByteSeq(creatorGuid[6]);
+ itemData.WriteByteSeq(creatorGuid[2]);
+ itemData.WriteByteSeq(creatorGuid[7]);
+ itemData.WriteByteSeq(creatorGuid[4]);
+
+ itemData << uint32(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));
+ itemData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
+ itemData << uint32(item->GetItemRandomPropertyId());
+
+ itemData.WriteByteSeq(creatorGuid[3]);
+
+ itemData << uint32(0); // unk7
+
+ itemData.WriteByteSeq(creatorGuid[0]);
+
+ itemData << uint32(item->GetSpellCharges());
+ itemData << uint32(item->GetItemSuffixFactor());
+
+ itemData.WriteByteSeq(creatorGuid[5]);
}
+
+ data.WriteBit(giftCreatorGuid[6]);
+ data.WriteBit(giftCreatorGuid[4]);
+ data.WriteBit(giftCreatorGuid[2]);
+ data.WriteBit(giftCreatorGuid[0]);
+ data.WriteBit(giftCreatorGuid[5]);
+
+ itemData.WriteByteSeq(giftCreatorGuid[6]);
+ itemData.WriteByteSeq(giftCreatorGuid[1]);
+ itemData.WriteByteSeq(giftCreatorGuid[7]);
+ itemData.WriteByteSeq(giftCreatorGuid[4]);
+
+ itemData << uint32(item->GetTemplate()->ItemId);
+
+ itemData.WriteByteSeq(giftCreatorGuid[0]);
+
+ itemData << uint32(item->GetCount());
+
+ itemData.WriteByteSeq(giftCreatorGuid[5]);
+
+ itemData << uint8(i);
+
+ itemData.WriteByteSeq(giftCreatorGuid[2]);
+ itemData.WriteByteSeq(giftCreatorGuid[3]);
}
+
+ data.FlushBits();
+ data.append(itemData);
+
SendPacket(&data);
}
@@ -292,14 +353,14 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
return;
}
- if (_player->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
+ if (_player->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - his_trade->GetMoney())
{
_player->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
my_trade->SetAccepted(false, true);
return;
}
- if (trader->GetMoney() >= uint32(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
+ if (trader->GetMoney() >= uint64(MAX_MONEY_AMOUNT) - my_trade->GetMoney())
{
trader->SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL);
his_trade->SetAccepted(false, true);
@@ -477,7 +538,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
{
if (my_trade->GetMoney() > 0)
{
- sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
+ sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)",
_player->GetName().c_str(), _player->GetSession()->GetAccountId(),
my_trade->GetMoney(),
trader->GetName().c_str(), trader->GetSession()->GetAccountId());
@@ -485,7 +546,7 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
if (his_trade->GetMoney() > 0)
{
- sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)",
+ sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) give money (Amount: " UI64FMTD ") to player: %s (Account: %u)",
trader->GetName().c_str(), trader->GetSession()->GetAccountId(),
his_trade->GetMoney(),
_player->GetName().c_str(), _player->GetSession()->GetAccountId());
@@ -493,9 +554,9 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/)
}
// update money
- _player->ModifyMoney(-int32(my_trade->GetMoney()));
+ _player->ModifyMoney(-int64(my_trade->GetMoney()));
_player->ModifyMoney(his_trade->GetMoney());
- trader->ModifyMoney(-int32(his_trade->GetMoney()));
+ trader->ModifyMoney(-int64(his_trade->GetMoney()));
trader->ModifyMoney(my_trade->GetMoney());
if (my_spell)
@@ -555,15 +616,32 @@ void WorldSession::SendCancelTrade()
void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/)
{
- // sended also after LOGOUT COMPLETE
+ // sent also after LOGOUT COMPLETE
if (_player) // needed because STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT
_player->TradeCancel(true);
}
void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
{
- uint64 ID;
- recvPacket >> ID;
+ ObjectGuid guid;
+
+ guid[0] = recvPacket.ReadBit();
+ guid[3] = recvPacket.ReadBit();
+ guid[5] = recvPacket.ReadBit();
+ guid[1] = recvPacket.ReadBit();
+ guid[4] = recvPacket.ReadBit();
+ guid[6] = recvPacket.ReadBit();
+ guid[7] = recvPacket.ReadBit();
+ guid[2] = recvPacket.ReadBit();
+
+ recvPacket.ReadByteSeq(guid[7]);
+ recvPacket.ReadByteSeq(guid[4]);
+ recvPacket.ReadByteSeq(guid[3]);
+ recvPacket.ReadByteSeq(guid[5]);
+ recvPacket.ReadByteSeq(guid[1]);
+ recvPacket.ReadByteSeq(guid[2]);
+ recvPacket.ReadByteSeq(guid[6]);
+ recvPacket.ReadByteSeq(guid[0]);
if (GetPlayer()->m_trade)
return;
@@ -598,7 +676,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
return;
}
- Player* pOther = ObjectAccessor::FindPlayer(ID);
+ Player* pOther = ObjectAccessor::FindPlayer(guid);
if (!pOther)
{
@@ -664,15 +742,36 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket)
_player->m_trade = new TradeData(_player, pOther);
pOther->m_trade = new TradeData(pOther, _player);
- WorldPacket data(SMSG_TRADE_STATUS, 12);
- data << uint32(TRADE_STATUS_BEGIN_TRADE);
- data << uint64(_player->GetGUID());
+ WorldPacket data(SMSG_TRADE_STATUS, 2+7);
+ data.WriteBit(0); // unk bit, usually 0
+ data.WriteBits(TRADE_STATUS_BEGIN_TRADE, 5);
+
+ ObjectGuid playerGuid = _player->GetGUID();
+ // WTB StartBitStream...
+ data.WriteBit(playerGuid[2]);
+ data.WriteBit(playerGuid[4]);
+ data.WriteBit(playerGuid[6]);
+ data.WriteBit(playerGuid[0]);
+ data.WriteBit(playerGuid[1]);
+ data.WriteBit(playerGuid[3]);
+ data.WriteBit(playerGuid[7]);
+ data.WriteBit(playerGuid[5]);
+
+ data.WriteByteSeq(playerGuid[4]);
+ data.WriteByteSeq(playerGuid[1]);
+ data.WriteByteSeq(playerGuid[2]);
+ data.WriteByteSeq(playerGuid[3]);
+ data.WriteByteSeq(playerGuid[0]);
+ data.WriteByteSeq(playerGuid[7]);
+ data.WriteByteSeq(playerGuid[6]);
+ data.WriteByteSeq(playerGuid[5]);
+
pOther->GetSession()->SendPacket(&data);
}
void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket)
{
- uint32 gold;
+ uint64 gold;
recvPacket >> gold;
TradeData* my_trade = _player->GetTradeData();
@@ -690,9 +789,9 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket)
uint8 bag;
uint8 slot;
+ recvPacket >> slot;
recvPacket >> tradeSlot;
recvPacket >> bag;
- recvPacket >> slot;
TradeData* my_trade = _player->GetTradeData();
if (!my_trade)
diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp
index 3973b23eab4..bd50b77961e 100644
--- a/src/server/game/Handlers/VehicleHandler.cpp
+++ b/src/server/game/Handlers/VehicleHandler.cpp
@@ -22,6 +22,7 @@
#include "Player.h"
#include "Log.h"
#include "ObjectAccessor.h"
+#include "MovementStructures.h"
void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData)
{
@@ -35,20 +36,15 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData)
return;
}
- uint64 guid;
-
- recvData.readPackGUID(guid);
-
MovementInfo mi;
- mi.guid = guid;
- ReadMovementInfo(recvData, &mi);
+ _player->ReadMovementInfo(recvData, &mi);
_player->m_movementInfo = mi;
_player->ExitVehicle();
}
-void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recvData)
+void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE");
@@ -78,20 +74,36 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recvData)
break;
case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE:
{
- uint64 guid; // current vehicle guid
- recvData.readPackGUID(guid);
-
+ static MovementStatusElements const accessoryGuid[] =
+ {
+ MSEExtraInt8,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ };
+
+ Movement::ExtraMovementStatusElement extra(accessoryGuid);
MovementInfo movementInfo;
- ReadMovementInfo(recvData, &movementInfo);
+ GetPlayer()->ReadMovementInfo(recvData, &movementInfo, &extra);
vehicle_base->m_movementInfo = movementInfo;
- uint64 accessory; // accessory guid
- recvData.readPackGUID(accessory);
-
- int8 seatId;
- recvData >> seatId;
+ uint64 accessory = extra.Data.guid;
+ int8 seatId = extra.Data.byteData;
- if (vehicle_base->GetGUID() != guid)
+ if (vehicle_base->GetGUID() != movementInfo.guid)
return;
if (!accessory)
@@ -125,7 +137,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recvData)
}
}
-void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data)
+void WorldSession::HandleEnterPlayerVehicle(WorldPacket& data)
{
// Read guid
uint64 guid;
@@ -144,7 +156,7 @@ void WorldSession::HandleEnterPlayerVehicle(WorldPacket &data)
}
}
-void WorldSession::HandleEjectPassenger(WorldPacket &data)
+void WorldSession::HandleEjectPassenger(WorldPacket& data)
{
Vehicle* vehicle = _player->GetVehicleKit();
if (!vehicle)
diff --git a/src/server/game/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp
index af2d8e20757..fd5d3adad84 100644
--- a/src/server/game/Handlers/VoiceChatHandler.cpp
+++ b/src/server/game/Handlers/VoiceChatHandler.cpp
@@ -30,10 +30,12 @@ void WorldSession::HandleVoiceSessionEnableOpcode(WorldPacket& recvData)
recvData.read_skip<uint8>();
}
-void WorldSession::HandleChannelVoiceOnOpcode(WorldPacket& /*recvData*/)
+void WorldSession::HandleChannelVoiceOnOpcode(WorldPacket& recvData)
{
TC_LOG_DEBUG("network", "WORLD: CMSG_CHANNEL_VOICE_ON");
// Enable Voice button in channel context menu
+ recvData.ReadString(recvData.ReadBits(8));
+ //channel->EnableVoice(recvData.GetOpcode() == CMSG_CHANNEL_VOICE_ON);
}
void WorldSession::HandleSetActiveVoiceChannel(WorldPacket& recvData)
diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp
new file mode 100644
index 00000000000..cf117762801
--- /dev/null
+++ b/src/server/game/Handlers/VoidStorageHandler.cpp
@@ -0,0 +1,619 @@
+/*
+ * 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 "Common.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "Log.h"
+#include "Opcodes.h"
+#include "Player.h"
+#include <list>
+#include <vector>
+#include <utility>
+
+void WorldSession::SendVoidStorageTransferResult(VoidTransferError result)
+{
+ WorldPacket data(SMSG_VOID_TRANSFER_RESULT, 4);
+ data << uint32(result);
+ SendPacket(&data);
+}
+
+void WorldSession::HandleVoidStorageUnlock(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_UNLOCK");
+ Player* player = GetPlayer();
+
+ ObjectGuid npcGuid;
+ npcGuid[4] = recvData.ReadBit();
+ npcGuid[5] = recvData.ReadBit();
+ npcGuid[3] = recvData.ReadBit();
+ npcGuid[0] = recvData.ReadBit();
+ npcGuid[2] = recvData.ReadBit();
+ npcGuid[1] = recvData.ReadBit();
+ npcGuid[7] = recvData.ReadBit();
+ npcGuid[6] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(npcGuid[7]);
+ recvData.ReadByteSeq(npcGuid[1]);
+ recvData.ReadByteSeq(npcGuid[2]);
+ recvData.ReadByteSeq(npcGuid[3]);
+ recvData.ReadByteSeq(npcGuid[5]);
+ recvData.ReadByteSeq(npcGuid[0]);
+ recvData.ReadByteSeq(npcGuid[6]);
+ recvData.ReadByteSeq(npcGuid[4]);
+
+ Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER);
+ if (!unit)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
+ return;
+ }
+
+ if (player->IsVoidStorageUnlocked())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageUnlock - Player (GUID: %u, name: %s) tried to unlock void storage a 2nd time.", player->GetGUIDLow(), player->GetName().c_str());
+ return;
+ }
+
+ player->ModifyMoney(-int64(VOID_STORAGE_UNLOCK));
+ player->UnlockVoidStorage();
+}
+
+void WorldSession::HandleVoidStorageQuery(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_QUERY");
+ Player* player = GetPlayer();
+
+ ObjectGuid npcGuid;
+ npcGuid[4] = recvData.ReadBit();
+ npcGuid[0] = recvData.ReadBit();
+ npcGuid[5] = recvData.ReadBit();
+ npcGuid[7] = recvData.ReadBit();
+ npcGuid[6] = recvData.ReadBit();
+ npcGuid[3] = recvData.ReadBit();
+ npcGuid[1] = recvData.ReadBit();
+ npcGuid[2] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(npcGuid[5]);
+ recvData.ReadByteSeq(npcGuid[6]);
+ recvData.ReadByteSeq(npcGuid[3]);
+ recvData.ReadByteSeq(npcGuid[7]);
+ recvData.ReadByteSeq(npcGuid[1]);
+ recvData.ReadByteSeq(npcGuid[0]);
+ recvData.ReadByteSeq(npcGuid[4]);
+ recvData.ReadByteSeq(npcGuid[2]);
+
+ Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER);
+ if (!unit)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
+ return;
+ }
+
+ if (!player->IsVoidStorageUnlocked())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageQuery - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
+ return;
+ }
+
+ uint8 count = 0;
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ if (player->GetVoidStorageItem(i))
+ ++count;
+
+ WorldPacket data(SMSG_VOID_STORAGE_CONTENTS, 2 * count + (14 + 4 + 4 + 4 + 4) * count);
+
+ data.WriteBits(count, 8);
+
+ ByteBuffer itemData((14 + 4 + 4 + 4 + 4) * count);
+
+ for (uint8 i = 0; i < VOID_STORAGE_MAX_SLOT; ++i)
+ {
+ VoidStorageItem* item = player->GetVoidStorageItem(i);
+ if (!item)
+ continue;
+
+ ObjectGuid itemId = item->ItemId;
+ ObjectGuid creatorGuid = item->CreatorGuid;
+
+ data.WriteBit(creatorGuid[3]);
+ data.WriteBit(itemId[5]);
+ data.WriteBit(creatorGuid[6]);
+ data.WriteBit(creatorGuid[1]);
+ data.WriteBit(itemId[1]);
+ data.WriteBit(itemId[3]);
+ data.WriteBit(itemId[6]);
+ data.WriteBit(creatorGuid[5]);
+ data.WriteBit(creatorGuid[2]);
+ data.WriteBit(itemId[2]);
+ data.WriteBit(creatorGuid[4]);
+ data.WriteBit(itemId[0]);
+ data.WriteBit(itemId[4]);
+ data.WriteBit(itemId[7]);
+ data.WriteBit(creatorGuid[0]);
+ data.WriteBit(creatorGuid[7]);
+
+ itemData.WriteByteSeq(creatorGuid[3]);
+
+ itemData << uint32(item->ItemSuffixFactor);
+
+ itemData.WriteByteSeq(creatorGuid[4]);
+
+ itemData << uint32(i);
+
+ itemData.WriteByteSeq(itemId[0]);
+ itemData.WriteByteSeq(itemId[6]);
+ itemData.WriteByteSeq(creatorGuid[0]);
+ itemData.WriteByteSeq(creatorGuid[1]);
+
+ itemData << uint32(item->ItemRandomPropertyId);
+
+ itemData.WriteByteSeq(itemId[4]);
+ itemData.WriteByteSeq(itemId[5]);
+ itemData.WriteByteSeq(itemId[2]);
+ itemData.WriteByteSeq(creatorGuid[2]);
+ itemData.WriteByteSeq(creatorGuid[6]);
+ itemData.WriteByteSeq(itemId[1]);
+ itemData.WriteByteSeq(itemId[3]);
+ itemData.WriteByteSeq(creatorGuid[5]);
+ itemData.WriteByteSeq(creatorGuid[7]);
+
+ itemData << uint32(item->ItemEntry);
+
+ itemData.WriteByteSeq(itemId[7]);
+ }
+
+ data.FlushBits();
+ data.append(itemData);
+
+ SendPacket(&data);
+}
+
+void WorldSession::HandleVoidStorageTransfer(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_STORAGE_TRANSFER");
+ Player* player = GetPlayer();
+
+ // Read everything
+
+ ObjectGuid npcGuid;
+ npcGuid[1] = recvData.ReadBit();
+
+ uint32 countDeposit = recvData.ReadBits(26);
+
+ if (countDeposit > 9)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countDeposit);
+ return;
+ }
+
+ std::vector<ObjectGuid> itemGuids(countDeposit);
+ for (uint32 i = 0; i < countDeposit; ++i)
+ {
+ itemGuids[i][4] = recvData.ReadBit();
+ itemGuids[i][6] = recvData.ReadBit();
+ itemGuids[i][7] = recvData.ReadBit();
+ itemGuids[i][0] = recvData.ReadBit();
+ itemGuids[i][1] = recvData.ReadBit();
+ itemGuids[i][5] = recvData.ReadBit();
+ itemGuids[i][3] = recvData.ReadBit();
+ itemGuids[i][2] = recvData.ReadBit();
+ }
+
+ npcGuid[2] = recvData.ReadBit();
+ npcGuid[0] = recvData.ReadBit();
+ npcGuid[3] = recvData.ReadBit();
+ npcGuid[5] = recvData.ReadBit();
+ npcGuid[6] = recvData.ReadBit();
+ npcGuid[4] = recvData.ReadBit();
+
+ uint32 countWithdraw = recvData.ReadBits(26);
+
+ if (countWithdraw > 9)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to withdraw more than 9 items (%u).", player->GetGUIDLow(), player->GetName().c_str(), countWithdraw);
+ return;
+ }
+
+ std::vector<ObjectGuid> itemIds(countWithdraw);
+ for (uint32 i = 0; i < countWithdraw; ++i)
+ {
+ itemIds[i][4] = recvData.ReadBit();
+ itemIds[i][7] = recvData.ReadBit();
+ itemIds[i][1] = recvData.ReadBit();
+ itemIds[i][0] = recvData.ReadBit();
+ itemIds[i][2] = recvData.ReadBit();
+ itemIds[i][3] = recvData.ReadBit();
+ itemIds[i][5] = recvData.ReadBit();
+ itemIds[i][6] = recvData.ReadBit();
+ }
+
+ npcGuid[7] = recvData.ReadBit();
+
+ for (uint32 i = 0; i < countDeposit; ++i)
+ {
+ recvData.ReadByteSeq(itemGuids[i][6]);
+ recvData.ReadByteSeq(itemGuids[i][1]);
+ recvData.ReadByteSeq(itemGuids[i][0]);
+ recvData.ReadByteSeq(itemGuids[i][2]);
+ recvData.ReadByteSeq(itemGuids[i][4]);
+ recvData.ReadByteSeq(itemGuids[i][5]);
+ recvData.ReadByteSeq(itemGuids[i][3]);
+ recvData.ReadByteSeq(itemGuids[i][7]);
+ }
+
+ recvData.ReadByteSeq(npcGuid[5]);
+ recvData.ReadByteSeq(npcGuid[6]);
+
+ for (uint32 i = 0; i < countWithdraw; ++i)
+ {
+ recvData.ReadByteSeq(itemIds[i][3]);
+ recvData.ReadByteSeq(itemIds[i][0]);
+ recvData.ReadByteSeq(itemIds[i][1]);
+ recvData.ReadByteSeq(itemIds[i][6]);
+ recvData.ReadByteSeq(itemIds[i][2]);
+ recvData.ReadByteSeq(itemIds[i][7]);
+ recvData.ReadByteSeq(itemIds[i][5]);
+ recvData.ReadByteSeq(itemIds[i][4]);
+ }
+
+ recvData.ReadByteSeq(npcGuid[1]);
+ recvData.ReadByteSeq(npcGuid[4]);
+ recvData.ReadByteSeq(npcGuid[7]);
+ recvData.ReadByteSeq(npcGuid[3]);
+ recvData.ReadByteSeq(npcGuid[2]);
+ recvData.ReadByteSeq(npcGuid[0]);
+
+ Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER);
+ if (!unit)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
+ return;
+ }
+
+ if (!player->IsVoidStorageUnlocked())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
+ return;
+ }
+
+ if (itemGuids.size() > player->GetNumOfVoidStorageFreeSlots())
+ {
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_FULL);
+ return;
+ }
+
+ uint32 freeBagSlots = 0;
+ if (itemIds.size() != 0)
+ {
+ // make this a Player function
+ for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
+ if (Bag* bag = player->GetBagByPos(i))
+ freeBagSlots += bag->GetFreeSlots();
+ for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
+ if (!player->GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ ++freeBagSlots;
+ }
+
+ if (itemIds.size() > freeBagSlots)
+ {
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL);
+ return;
+ }
+
+ if (!player->HasEnoughMoney(uint64(itemGuids.size() * VOID_STORAGE_STORE_ITEM)))
+ {
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY);
+ return;
+ }
+
+ std::pair<VoidStorageItem, uint8> depositItems[VOID_STORAGE_MAX_DEPOSIT];
+ uint8 depositCount = 0;
+ for (std::vector<ObjectGuid>::iterator itr = itemGuids.begin(); itr != itemGuids.end(); ++itr)
+ {
+ Item* item = player->GetItemByGuid(*itr);
+ if (!item)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) wants to deposit an invalid item (item guid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
+ continue;
+ }
+
+ VoidStorageItem itemVS(sObjectMgr->GenerateVoidStorageItemId(), item->GetEntry(), item->GetUInt64Value(ITEM_FIELD_CREATOR), item->GetItemRandomPropertyId(), item->GetItemSuffixFactor());
+
+ uint8 slot = player->AddVoidStorageItem(itemVS);
+
+ depositItems[depositCount++] = std::make_pair(itemVS, slot);
+
+ player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
+ }
+
+ int64 cost = depositCount * VOID_STORAGE_STORE_ITEM;
+
+ player->ModifyMoney(-cost);
+
+ VoidStorageItem withdrawItems[VOID_STORAGE_MAX_WITHDRAW];
+ uint8 withdrawCount = 0;
+ for (std::vector<ObjectGuid>::iterator itr = itemIds.begin(); itr != itemIds.end(); ++itr)
+ {
+ uint8 slot;
+ VoidStorageItem* itemVS = player->GetVoidStorageItem(*itr, slot);
+ if (!itemVS)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) tried to withdraw an invalid item (id: " UI64FMTD ")", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
+ continue;
+ }
+
+ ItemPosCountVec dest;
+ InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemVS->ItemEntry, 1);
+ if (msg != EQUIP_ERR_OK)
+ {
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INVENTORY_FULL);
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidStorageTransfer - Player (GUID: %u, name: %s) couldn't withdraw item id " UI64FMTD " because inventory was full.", player->GetGUIDLow(), player->GetName().c_str(), uint64(*itr));
+ return;
+ }
+
+ Item* item = player->StoreNewItem(dest, itemVS->ItemEntry, true, itemVS->ItemRandomPropertyId);
+ item->SetUInt64Value(ITEM_FIELD_CREATOR, uint64(itemVS->CreatorGuid));
+ item->SetBinding(true);
+ player->SendNewItem(item, 1, false, false, false);
+
+ withdrawItems[withdrawCount++] = *itemVS;
+
+ player->DeleteVoidStorageItem(slot);
+ }
+
+ WorldPacket data(SMSG_VOID_STORAGE_TRANSFER_CHANGES, ((5 + 5 + (7 + 7) * depositCount +
+ 7 * withdrawCount) / 8) + 7 * withdrawCount + (7 + 7 + 4 * 4) * depositCount);
+
+ data.WriteBits(depositCount, 5);
+ data.WriteBits(withdrawCount, 5);
+
+ for (uint8 i = 0; i < depositCount; ++i)
+ {
+ ObjectGuid itemId = depositItems[i].first.ItemId;
+ ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid;
+ data.WriteBit(creatorGuid[7]);
+ data.WriteBit(itemId[7]);
+ data.WriteBit(itemId[4]);
+ data.WriteBit(creatorGuid[6]);
+ data.WriteBit(creatorGuid[5]);
+ data.WriteBit(itemId[3]);
+ data.WriteBit(itemId[5]);
+ data.WriteBit(creatorGuid[4]);
+ data.WriteBit(creatorGuid[2]);
+ data.WriteBit(creatorGuid[0]);
+ data.WriteBit(creatorGuid[3]);
+ data.WriteBit(creatorGuid[1]);
+ data.WriteBit(itemId[2]);
+ data.WriteBit(itemId[0]);
+ data.WriteBit(itemId[1]);
+ data.WriteBit(itemId[6]);
+ }
+
+ for (uint8 i = 0; i < withdrawCount; ++i)
+ {
+ ObjectGuid itemId = withdrawItems[i].ItemId;
+ data.WriteBit(itemId[1]);
+ data.WriteBit(itemId[7]);
+ data.WriteBit(itemId[3]);
+ data.WriteBit(itemId[5]);
+ data.WriteBit(itemId[6]);
+ data.WriteBit(itemId[2]);
+ data.WriteBit(itemId[4]);
+ data.WriteBit(itemId[0]);
+ }
+
+ data.FlushBits();
+
+ for (uint8 i = 0; i < withdrawCount; ++i)
+ {
+ ObjectGuid itemId = withdrawItems[i].ItemId;
+ data.WriteByteSeq(itemId[3]);
+ data.WriteByteSeq(itemId[1]);
+ data.WriteByteSeq(itemId[0]);
+ data.WriteByteSeq(itemId[2]);
+ data.WriteByteSeq(itemId[7]);
+ data.WriteByteSeq(itemId[5]);
+ data.WriteByteSeq(itemId[6]);
+ data.WriteByteSeq(itemId[4]);
+ }
+
+ for (uint8 i = 0; i < depositCount; ++i)
+ {
+ ObjectGuid itemId = depositItems[i].first.ItemId;
+ ObjectGuid creatorGuid = depositItems[i].first.CreatorGuid;
+
+ data << uint32(depositItems[i].first.ItemSuffixFactor);
+
+ data.WriteByteSeq(itemId[6]);
+ data.WriteByteSeq(itemId[4]);
+ data.WriteByteSeq(creatorGuid[4]);
+ data.WriteByteSeq(itemId[2]);
+ data.WriteByteSeq(creatorGuid[1]);
+ data.WriteByteSeq(creatorGuid[3]);
+ data.WriteByteSeq(itemId[3]);
+ data.WriteByteSeq(creatorGuid[0]);
+ data.WriteByteSeq(itemId[0]);
+ data.WriteByteSeq(creatorGuid[6]);
+ data.WriteByteSeq(itemId[5]);
+ data.WriteByteSeq(creatorGuid[5]);
+ data.WriteByteSeq(creatorGuid[7]);
+
+ data << uint32(depositItems[i].first.ItemEntry);
+
+ data.WriteByteSeq(itemId[1]);
+
+ data << uint32(depositItems[i].second); // slot
+
+ data.WriteByteSeq(creatorGuid[2]);
+ data.WriteByteSeq(itemId[7]);
+
+ data << uint32(depositItems[i].first.ItemRandomPropertyId);
+ }
+
+ SendPacket(&data);
+
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_NO_ERROR);
+}
+
+void WorldSession::HandleVoidSwapItem(WorldPacket& recvData)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_VOID_SWAP_ITEM");
+
+ Player* player = GetPlayer();
+ uint32 newSlot;
+ ObjectGuid npcGuid;
+ ObjectGuid itemId;
+
+ recvData >> newSlot;
+
+ npcGuid[2] = recvData.ReadBit();
+ npcGuid[4] = recvData.ReadBit();
+ npcGuid[0] = recvData.ReadBit();
+ itemId[2] = recvData.ReadBit();
+ itemId[6] = recvData.ReadBit();
+ itemId[5] = recvData.ReadBit();
+ npcGuid[1] = recvData.ReadBit();
+ npcGuid[7] = recvData.ReadBit();
+ itemId[3] = recvData.ReadBit();
+ itemId[7] = recvData.ReadBit();
+ itemId[0] = recvData.ReadBit();
+ npcGuid[6] = recvData.ReadBit();
+ npcGuid[5] = recvData.ReadBit();
+ npcGuid[3] = recvData.ReadBit();
+ itemId[1] = recvData.ReadBit();
+ itemId[4] = recvData.ReadBit();
+
+ recvData.ReadByteSeq(npcGuid[1]);
+ recvData.ReadByteSeq(itemId[3]);
+ recvData.ReadByteSeq(itemId[2]);
+ recvData.ReadByteSeq(itemId[4]);
+ recvData.ReadByteSeq(npcGuid[3]);
+ recvData.ReadByteSeq(npcGuid[0]);
+ recvData.ReadByteSeq(itemId[6]);
+ recvData.ReadByteSeq(itemId[1]);
+ recvData.ReadByteSeq(npcGuid[5]);
+ recvData.ReadByteSeq(itemId[5]);
+ recvData.ReadByteSeq(npcGuid[6]);
+ recvData.ReadByteSeq(itemId[0]);
+ recvData.ReadByteSeq(npcGuid[2]);
+ recvData.ReadByteSeq(npcGuid[7]);
+ recvData.ReadByteSeq(npcGuid[4]);
+ recvData.ReadByteSeq(itemId[7]);
+
+ Creature* unit = player->GetNPCIfCanInteractWith(npcGuid, UNIT_NPC_FLAG_VAULTKEEPER);
+ if (!unit)
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Unit (GUID: %u) not found or player can't interact with it.", GUID_LOPART(npcGuid));
+ return;
+ }
+
+ if (!player->IsVoidStorageUnlocked())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) queried void storage without unlocking it.", player->GetGUIDLow(), player->GetName().c_str());
+ return;
+ }
+
+ uint8 oldSlot;
+ if (!player->GetVoidStorageItem(itemId, oldSlot))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleVoidSwapItem - Player (GUID: %u, name: %s) requested swapping an invalid item (slot: %u, itemid: " UI64FMTD ").", player->GetGUIDLow(), player->GetName().c_str(), newSlot, uint64(itemId));
+ return;
+ }
+
+ bool usedSrcSlot = player->GetVoidStorageItem(oldSlot) != NULL; // should be always true
+ bool usedDestSlot = player->GetVoidStorageItem(newSlot) != NULL;
+ ObjectGuid itemIdDest;
+ if (usedDestSlot)
+ itemIdDest = player->GetVoidStorageItem(newSlot)->ItemId;
+
+ if (!player->SwapVoidStorageItem(oldSlot, newSlot))
+ {
+ SendVoidStorageTransferResult(VOID_TRANSFER_ERROR_INTERNAL_ERROR_1);
+ return;
+ }
+
+ WorldPacket data(SMSG_VOID_ITEM_SWAP_RESPONSE, 1 + (usedSrcSlot + usedDestSlot) * (1 + 7 + 4));
+
+ data.WriteBit(!usedDestSlot);
+ data.WriteBit(!usedSrcSlot);
+
+ if (usedSrcSlot)
+ {
+ data.WriteBit(itemId[5]);
+ data.WriteBit(itemId[2]);
+ data.WriteBit(itemId[1]);
+ data.WriteBit(itemId[4]);
+ data.WriteBit(itemId[0]);
+ data.WriteBit(itemId[6]);
+ data.WriteBit(itemId[7]);
+ data.WriteBit(itemId[3]);
+ }
+
+ data.WriteBit(!usedDestSlot); // unk
+
+ if (usedDestSlot)
+ {
+ data.WriteBit(itemIdDest[7]);
+ data.WriteBit(itemIdDest[3]);
+ data.WriteBit(itemIdDest[4]);
+ data.WriteBit(itemIdDest[0]);
+ data.WriteBit(itemIdDest[5]);
+ data.WriteBit(itemIdDest[1]);
+ data.WriteBit(itemIdDest[2]);
+ data.WriteBit(itemIdDest[6]);
+ }
+
+ data.WriteBit(!usedSrcSlot); // unk
+
+ data.FlushBits();
+
+ if (usedDestSlot)
+ {
+ data.WriteByteSeq(itemIdDest[4]);
+ data.WriteByteSeq(itemIdDest[6]);
+ data.WriteByteSeq(itemIdDest[5]);
+ data.WriteByteSeq(itemIdDest[2]);
+ data.WriteByteSeq(itemIdDest[3]);
+ data.WriteByteSeq(itemIdDest[1]);
+ data.WriteByteSeq(itemIdDest[7]);
+ data.WriteByteSeq(itemIdDest[0]);
+ }
+
+ if (usedSrcSlot)
+ {
+ data.WriteByteSeq(itemId[6]);
+ data.WriteByteSeq(itemId[3]);
+ data.WriteByteSeq(itemId[5]);
+ data.WriteByteSeq(itemId[0]);
+ data.WriteByteSeq(itemId[1]);
+ data.WriteByteSeq(itemId[2]);
+ data.WriteByteSeq(itemId[4]);
+ data.WriteByteSeq(itemId[7]);
+ }
+
+ if (usedDestSlot)
+ data << uint32(oldSlot);
+
+ if (usedSrcSlot)
+ data << uint32(newSlot);
+
+ SendPacket(&data);
+}
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index c46d9002604..e37e6847bdd 100644
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -164,11 +164,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId)
void InstanceSaveManager::UnloadInstanceSave(uint32 InstanceId)
{
if (InstanceSave* save = GetInstanceSave(InstanceId))
- {
save->UnloadIfEmpty();
- if (save->m_toDelete)
- delete save;
- }
}
InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset)
diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h
index 1d753ebaa48..7a89e6488f0 100644
--- a/src/server/game/Instances/InstanceSaveMgr.h
+++ b/src/server/game/Instances/InstanceSaveMgr.h
@@ -115,16 +115,16 @@ class InstanceSave
but that would depend on a lot of things that can easily change in future */
Difficulty GetDifficulty() const { return m_difficulty; }
- typedef std::list<Player*> PlayerListType;
- typedef std::list<Group*> GroupListType;
- private:
- bool UnloadIfEmpty();
/* used to flag the InstanceSave as to be deleted, so the caller can delete it */
void SetToDelete(bool toDelete)
{
m_toDelete = toDelete;
}
+ typedef std::list<Player*> PlayerListType;
+ typedef std::list<Group*> GroupListType;
+ private:
+ bool UnloadIfEmpty();
/* the only reason the instSave-object links are kept is because
the object-instSave links need to be broken at reset time */
/// @todo: Check if maybe it's enough to just store the number of players/groups
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index d21ebca9a91..1b6399fb6fd 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -331,7 +331,7 @@ void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type,
if (!PlayerList.isEmpty())
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
if (Player* player = i->GetSource())
- player->UpdateAchievementCriteria(type, miscValue1, miscValue2, unit);
+ player->UpdateAchievementCriteria(type, miscValue1, miscValue2, 0, unit);
}
// Start timed achievement for all players in instance
@@ -411,6 +411,7 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8
case ENCOUNTER_FRAME_ADD_TIMER:
case ENCOUNTER_FRAME_ENABLE_OBJECTIVE:
case ENCOUNTER_FRAME_DISABLE_OBJECTIVE:
+ case ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT:
data << uint8(param1);
break;
case ENCOUNTER_FRAME_UPDATE_OBJECTIVE:
@@ -418,6 +419,8 @@ void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8
data << uint8(param2);
break;
case ENCOUNTER_FRAME_UNK7:
+ case ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT:
+ case ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT:
default:
break;
}
@@ -442,7 +445,7 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
if (encounter->lastEncounterDungeon)
{
dungeonId = encounter->lastEncounterDungeon;
- TC_LOG_DEBUG("lfg", "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u", instance->GetMapName(), instance->GetInstanceId(), encounter->dbcEntry->encounterName[0], dungeonId);
+ TC_LOG_DEBUG("lfg", "UpdateEncounterState: Instance %s (instanceId %u) completed encounter %s. Credit Dungeon: %u", instance->GetMapName(), instance->GetInstanceId(), encounter->dbcEntry->encounterName, dungeonId);
break;
}
}
@@ -463,3 +466,14 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
}
}
}
+
+void InstanceScript::UpdatePhasing()
+{
+ PhaseUpdateData phaseUdateData;
+ phaseUdateData.AddConditionType(CONDITION_INSTANCE_INFO);
+
+ Map::PlayerList const& players = instance->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (Player* player = itr->GetSource())
+ player->GetPhaseMgr().NotifyConditionChanged(phaseUdateData);
+}
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index 3050443edc0..de332afe627 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -40,14 +40,17 @@ typedef std::set<Creature*> MinionSet;
enum EncounterFrameType
{
- ENCOUNTER_FRAME_ENGAGE = 0,
- ENCOUNTER_FRAME_DISENGAGE = 1,
- ENCOUNTER_FRAME_UPDATE_PRIORITY = 2,
- ENCOUNTER_FRAME_ADD_TIMER = 3,
- ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 4,
- ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 5,
- ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 6,
- ENCOUNTER_FRAME_UNK7 = 7 // Seems to have something to do with sorting the encounter units
+ ENCOUNTER_FRAME_SET_COMBAT_RES_LIMIT = 0,
+ ENCOUNTER_FRAME_RESET_COMBAT_RES_LIMIT = 1,
+ ENCOUNTER_FRAME_ENGAGE = 2,
+ ENCOUNTER_FRAME_DISENGAGE = 3,
+ ENCOUNTER_FRAME_UPDATE_PRIORITY = 4,
+ ENCOUNTER_FRAME_ADD_TIMER = 5,
+ ENCOUNTER_FRAME_ENABLE_OBJECTIVE = 6,
+ ENCOUNTER_FRAME_UPDATE_OBJECTIVE = 7,
+ ENCOUNTER_FRAME_DISABLE_OBJECTIVE = 8,
+ ENCOUNTER_FRAME_UNK7 = 9, // Seems to have something to do with sorting the encounter units
+ ENCOUNTER_FRAME_ADD_COMBAT_RES_LIMIT = 10
};
enum EncounterState
@@ -214,6 +217,9 @@ class InstanceScript : public ZoneScript
virtual void FillInitialWorldStates(WorldPacket& /*data*/) { }
+ // ReCheck PhaseTemplate related conditions
+ void UpdatePhasing();
+
protected:
void SetBossNumber(uint32 number) { bosses.resize(number); }
void LoadDoorData(DoorData const* data);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index bb7f679b7cd..899637a7615 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -864,17 +864,21 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint32(0); // gold
b << uint8(0); // item count
+ b << uint8(0); // currency count
return b;
}
Loot &l = lv.loot;
uint8 itemsShown = 0;
+ uint8 currenciesShown = 0;
b << uint32(l.gold); //gold
size_t count_pos = b.wpos(); // pos of item count byte
b << uint8(0); // item count placeholder
+ size_t currency_count_pos = b.wpos(); // pos of currency count byte
+ b << uint8(0); // currency count placeholder
switch (lv.permission)
{
@@ -1052,8 +1056,9 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
}
- //update number of items shown
+ //update number of items and currencies shown
b.put<uint8>(count_pos, itemsShown);
+ b.put<uint8>(currency_count_pos, currenciesShown);
return b;
}
@@ -1535,16 +1540,17 @@ void LoadLootTemplates_Disenchant()
LootIdSet lootIdSet, lootIdSetUsed;
uint32 count = LootTemplates_Disenchant.LoadAndCollectLootIds(lootIdSet);
- ItemTemplateContainer const* its = sObjectMgr->GetItemTemplateStore();
- for (ItemTemplateContainer::const_iterator itr = its->begin(); itr != its->end(); ++itr)
+ for (uint32 i = 0; i < sItemDisenchantLootStore.GetNumRows(); ++i)
{
- if (uint32 lootid = itr->second.DisenchantID)
- {
- if (lootIdSet.find(lootid) == lootIdSet.end())
- LootTemplates_Disenchant.ReportNotExistedId(lootid);
- else
- lootIdSetUsed.insert(lootid);
- }
+ ItemDisenchantLootEntry const* disenchant = sItemDisenchantLootStore.LookupEntry(i);
+ if (!disenchant)
+ continue;
+
+ uint32 lootid = disenchant->Id;
+ if (lootIdSet.find(lootid) == lootIdSet.end())
+ LootTemplates_Disenchant.ReportNotExistedId(lootid);
+ else
+ lootIdSetUsed.insert(lootid);
}
for (LootIdSet::const_iterator itr = lootIdSetUsed.begin(); itr != lootIdSetUsed.end(); ++itr)
diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h
index e3fc42f3f9e..abae99330c0 100644
--- a/src/server/game/Mails/Mail.h
+++ b/src/server/game/Mails/Mail.h
@@ -126,13 +126,13 @@ class MailDraft
public: // Accessors
uint16 GetMailTemplateId() const { return m_mailTemplateId; }
std::string const& GetSubject() const { return m_subject; }
- uint32 GetMoney() const { return m_money; }
- uint32 GetCOD() const { return m_COD; }
+ uint64 GetMoney() const { return m_money; }
+ uint64 GetCOD() const { return m_COD; }
std::string const& GetBody() const { return m_body; }
public: // modifiers
MailDraft& AddItem(Item* item);
- MailDraft& AddMoney(uint32 money) { m_money = money; return *this; }
+ MailDraft& AddMoney(uint64 money) { m_money = money; return *this; }
MailDraft& AddCOD(uint32 COD) { m_COD = COD; return *this; }
public: // finishers
@@ -150,8 +150,8 @@ class MailDraft
MailItemMap m_items; // Keep the items in a map to avoid duplicate guids (which can happen), store only low part of guid
- uint32 m_money;
- uint32 m_COD;
+ uint64 m_money;
+ uint64 m_COD;
};
struct MailItemInfo
@@ -167,7 +167,7 @@ struct Mail
uint8 messageType;
uint8 stationery;
uint16 mailTemplateId;
- uint32 sender;
+ uint32 sender; // TODO: change to uint64 and store full guids
uint32 receiver;
std::string subject;
std::string body;
@@ -175,8 +175,8 @@ struct Mail
std::vector<uint32> removedItems;
time_t expire_time;
time_t deliver_time;
- uint32 money;
- uint32 COD;
+ uint64 money;
+ uint64 COD;
uint32 checked;
MailState state;
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 21e282cfcf4..79e63cf2035 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -560,7 +560,7 @@ bool Map::AddToMap(Transport* obj)
{
if (itr->GetSource()->GetTransport() != obj)
{
- UpdateData data;
+ UpdateData data(GetId());
obj->BuildCreateUpdateBlockForPlayer(&data, itr->GetSource());
WorldPacket packet;
data.BuildPacket(&packet);
@@ -820,13 +820,13 @@ void Map::RemoveFromMap(Transport* obj, bool remove)
Map::PlayerList const& players = GetPlayers();
if (!players.isEmpty())
{
- UpdateData data;
+ UpdateData data(GetId());
obj->BuildOutOfRangeUpdateBlock(&data);
WorldPacket packet;
data.BuildPacket(&packet);
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- if (itr->GetSource()->GetTransport() != obj)
- itr->GetSource()->SendDirectMessage(&packet);
+ if (itr->GetSource()->GetTransport() != obj)
+ itr->GetSource()->SendDirectMessage(&packet);
}
if (_transportsUpdateIter != _transports.end())
@@ -2305,7 +2305,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const
char const* Map::GetMapName() const
{
- return i_mapEntry ? i_mapEntry->name[sWorld->GetDefaultDbcLocale()] : "UNNAMEDMAP\x0";
+ return i_mapEntry ? i_mapEntry->name : "UNNAMEDMAP\x0";
}
void Map::UpdateObjectVisibility(WorldObject* obj, Cell cell, CellCoord cellpair)
@@ -2334,7 +2334,7 @@ void Map::SendInitSelf(Player* player)
{
TC_LOG_INFO("maps", "Creating player data for himself %u", player->GetGUIDLow());
- UpdateData data;
+ UpdateData data(player->GetMapId());
// attach to player data current transport data
if (Transport* transport = player->GetTransport())
@@ -2365,7 +2365,7 @@ void Map::SendInitSelf(Player* player)
void Map::SendInitTransports(Player* player)
{
// Hack to send out transports
- UpdateData transData;
+ UpdateData transData(player->GetMapId());
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
if (*i != player->GetTransport())
(*i)->BuildCreateUpdateBlockForPlayer(&transData, player);
@@ -2378,7 +2378,7 @@ void Map::SendInitTransports(Player* player)
void Map::SendRemoveTransports(Player* player)
{
// Hack to send out transports
- UpdateData transData;
+ UpdateData transData(player->GetMapId());
for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i)
if (*i != player->GetTransport())
(*i)->BuildOutOfRangeUpdateBlock(&transData);
@@ -2489,6 +2489,9 @@ void Map::RemoveAllObjectsInRemoveList()
case TYPEID_DYNAMICOBJECT:
RemoveFromMap((DynamicObject*)obj, true);
break;
+ case TYPEID_AREATRIGGER:
+ RemoveFromMap((AreaTrigger*)obj, true);
+ break;
case TYPEID_GAMEOBJECT:
RemoveFromMap((GameObject*)obj, true);
break;
@@ -2630,11 +2633,13 @@ template bool Map::AddToMap(Corpse*);
template bool Map::AddToMap(Creature*);
template bool Map::AddToMap(GameObject*);
template bool Map::AddToMap(DynamicObject*);
+template bool Map::AddToMap(AreaTrigger*);
template void Map::RemoveFromMap(Corpse*, bool);
template void Map::RemoveFromMap(Creature*, bool);
template void Map::RemoveFromMap(GameObject*, bool);
template void Map::RemoveFromMap(DynamicObject*, bool);
+template void Map::RemoveFromMap(AreaTrigger*, bool);
/* ******* Dungeon Instance Maps ******* */
@@ -2805,10 +2810,11 @@ bool InstanceMap::AddPlayerToMap(Player* player)
// players also become permanently bound when they enter
if (groupBind->perm)
{
- WorldPacket data(SMSG_INSTANCE_LOCK_WARNING_QUERY, 9);
+ WorldPacket data(SMSG_INSTANCE_LOCK_WARNING_QUERY, 10);
data << uint32(60000);
data << uint32(i_data ? i_data->GetCompletedEncounterMask() : 0);
data << uint8(0);
+ data << uint8(0); // events it throws: 1 : INSTANCE_LOCK_WARNING 0 : INSTANCE_LOCK_STOP / INSTANCE_LOCK_START
player->GetSession()->SendPacket(&data);
player->SetPendingBind(mapSave->GetInstanceId(), 60000);
}
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 8e7886dc5d2..01e8760f85f 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -455,6 +455,7 @@ class Map : public GridRefManager<NGridType>
bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);}
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
+ virtual uint32 GetOwnerGuildId(uint32 /*team*/ = TEAM_OTHER) const { return 0; }
/*
RESPAWN TIMES
*/
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index 2e10fdc374b..8ecb9979706 100644
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -151,7 +151,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck)
if (player->IsGameMaster())
return true;
- char const* mapName = entry->name[player->GetSession()->GetSessionDbcLocale()];
+ char const* mapName = entry->name;
Group* group = player->GetGroup();
if (entry->IsRaid())
diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp
new file mode 100644
index 00000000000..f3b31fdf6d5
--- /dev/null
+++ b/src/server/game/Maps/PhaseMgr.cpp
@@ -0,0 +1,403 @@
+/*
+ * 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 "PhaseMgr.h"
+#include "Chat.h"
+#include "Group.h"
+#include "Language.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+
+//////////////////////////////////////////////////////////////////
+// Updating
+
+PhaseMgr::PhaseMgr(Player* _player) : player(_player), phaseData(_player), _UpdateFlags(0)
+{
+ _PhaseDefinitionStore = sObjectMgr->GetPhaseDefinitionStore();
+ _SpellPhaseStore = sObjectMgr->GetSpellPhaseStore();
+}
+
+void PhaseMgr::Update()
+{
+ if (IsUpdateInProgress())
+ return;
+
+ if (_UpdateFlags & PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED)
+ {
+ phaseData.SendPhaseshiftToPlayer();
+ player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PHASE);
+ }
+
+ if (_UpdateFlags & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED)
+ phaseData.SendPhaseMaskToPlayer();
+
+ _UpdateFlags = 0;
+}
+
+void PhaseMgr::RemoveUpdateFlag(PhaseUpdateFlag updateFlag)
+{
+ _UpdateFlags &= ~updateFlag;
+
+ if (updateFlag == PHASE_UPDATE_FLAG_ZONE_UPDATE)
+ {
+ // Update zone changes
+ if (phaseData.HasActiveDefinitions())
+ {
+ phaseData.ResetDefinitions();
+ _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
+ }
+
+ if (_PhaseDefinitionStore->find(player->GetZoneId()) != _PhaseDefinitionStore->end())
+ Recalculate();
+ }
+
+ Update();
+}
+
+/////////////////////////////////////////////////////////////////
+// Notifier
+
+void PhaseMgr::NotifyConditionChanged(PhaseUpdateData const& updateData)
+{
+ if (NeedsPhaseUpdateWithData(updateData))
+ {
+ Recalculate();
+ Update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////
+// Phasing Definitions
+
+void PhaseMgr::Recalculate()
+{
+ if (phaseData.HasActiveDefinitions())
+ {
+ phaseData.ResetDefinitions();
+ _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
+ }
+
+ PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
+ if (itr != _PhaseDefinitionStore->end())
+ for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
+ if (CheckDefinition(&(*phase)))
+ {
+ phaseData.AddPhaseDefinition(&(*phase));
+
+ if (phase->phasemask)
+ _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
+
+ if (phase->phaseId || phase->terrainswapmap)
+ _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
+
+ if (phase->IsLastDefinition())
+ break;
+ }
+}
+
+inline bool PhaseMgr::CheckDefinition(PhaseDefinition const* phaseDefinition)
+{
+ ConditionList const* conditions = sConditionMgr->GetConditionsForPhaseDefinition(phaseDefinition->zoneId, phaseDefinition->entry);
+ if (!conditions)
+ return true;
+
+ ConditionSourceInfo srcInfo(player);
+ return sConditionMgr->IsObjectMeetToConditions(srcInfo, *conditions);
+}
+
+bool PhaseMgr::NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const
+{
+ PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
+ if (itr != _PhaseDefinitionStore->end())
+ {
+ for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
+ {
+ ConditionList const* conditionList = sConditionMgr->GetConditionsForPhaseDefinition(phase->zoneId, phase->entry);
+ if (!conditionList)
+ continue;
+
+ for (ConditionList::const_iterator condition = conditionList->begin(); condition != conditionList->end(); ++condition)
+ if (updateData.IsConditionRelated(*condition))
+ return true;
+ }
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////
+// Auras
+
+void PhaseMgr::RegisterPhasingAuraEffect(AuraEffect const* auraEffect)
+{
+ PhaseInfo phaseInfo;
+
+ if (auraEffect->GetMiscValue())
+ {
+ _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
+ phaseInfo.phasemask = auraEffect->GetMiscValue();
+ }
+ else
+ {
+ SpellPhaseStore::const_iterator itr = _SpellPhaseStore->find(auraEffect->GetId());
+ if (itr != _SpellPhaseStore->end())
+ {
+ if (itr->second.phasemask)
+ {
+ _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
+ phaseInfo.phasemask = itr->second.phasemask;
+ }
+
+ if (itr->second.terrainswapmap)
+ phaseInfo.terrainswapmap = itr->second.terrainswapmap;
+ }
+ }
+
+ phaseInfo.phaseId = auraEffect->GetMiscValueB();
+
+ if (phaseInfo.NeedsClientSideUpdate())
+ _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
+
+ phaseData.AddAuraInfo(auraEffect->GetId(), phaseInfo);
+
+ Update();
+}
+
+void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect)
+{
+ _UpdateFlags |= phaseData.RemoveAuraInfo(auraEffect->GetId());
+
+ Update();
+}
+
+//////////////////////////////////////////////////////////////////
+// Commands
+
+void PhaseMgr::SendDebugReportToPlayer(Player* const debugger)
+{
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName().c_str(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags);
+
+ PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
+ if (itr == _PhaseDefinitionStore->end())
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId());
+ else
+ {
+ for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
+ {
+ if (CheckDefinition(&(*phase)))
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask);
+ else
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId);
+
+ if (phase->IsLastDefinition())
+ {
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId);
+ break;
+ }
+ }
+ }
+
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask);
+
+ ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask());
+}
+
+void PhaseMgr::SetCustomPhase(uint32 phaseMask)
+{
+ phaseData._CustomPhasemask = phaseMask;
+
+ _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
+
+ Update();
+}
+
+//////////////////////////////////////////////////////////////////
+// Phase Data
+
+uint32 PhaseData::GetCurrentPhasemask() const
+{
+ if (player->IsGameMaster())
+ return uint32(PHASEMASK_ANYWHERE);
+
+ if (_CustomPhasemask)
+ return _CustomPhasemask;
+
+ return GetPhaseMaskForSpawn();
+}
+
+inline uint32 PhaseData::GetPhaseMaskForSpawn() const
+{
+ uint32 const phase = (_PhasemaskThroughDefinitions | _PhasemaskThroughAuras);
+ return (phase ? phase : PHASEMASK_NORMAL);
+}
+
+void PhaseData::SendPhaseMaskToPlayer()
+{
+ // Server side update
+ uint32 const phasemask = GetCurrentPhasemask();
+ if (player->GetPhaseMask() == phasemask)
+ return;
+
+ player->SetPhaseMask(phasemask, false);
+
+ if (player->IsVisible())
+ player->UpdateObjectVisibility();
+}
+
+void PhaseData::SendPhaseshiftToPlayer()
+{
+ // Client side update
+ std::set<uint32> phaseIds;
+ std::set<uint32> terrainswaps;
+
+ for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr)
+ {
+ if (itr->second.terrainswapmap)
+ terrainswaps.insert(itr->second.terrainswapmap);
+
+ if (itr->second.phaseId)
+ phaseIds.insert(itr->second.phaseId);
+ }
+
+ // Phase Definitions
+ for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr)
+ {
+ if ((*itr)->phaseId)
+ phaseIds.insert((*itr)->phaseId);
+
+ if ((*itr)->terrainswapmap)
+ terrainswaps.insert((*itr)->terrainswapmap);
+ }
+
+ player->GetSession()->SendSetPhaseShift(phaseIds, terrainswaps);
+}
+
+void PhaseData::GetActivePhases(std::set<uint32>& phases) const
+{
+ for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr)
+ if (itr->second.phaseId)
+ phases.insert(itr->second.phaseId);
+
+ // Phase Definitions
+ for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr)
+ if ((*itr)->phaseId)
+ phases.insert((*itr)->phaseId);
+}
+
+void PhaseData::AddPhaseDefinition(PhaseDefinition const* phaseDefinition)
+{
+ if (phaseDefinition->IsOverwritingExistingPhases())
+ {
+ activePhaseDefinitions.clear();
+ _PhasemaskThroughDefinitions = phaseDefinition->phasemask;
+ }
+ else
+ {
+ if (phaseDefinition->IsNegatingPhasemask())
+ _PhasemaskThroughDefinitions &= ~phaseDefinition->phasemask;
+ else
+ _PhasemaskThroughDefinitions |= phaseDefinition->phasemask;
+ }
+
+ activePhaseDefinitions.push_back(phaseDefinition);
+}
+
+void PhaseData::AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo)
+{
+ if (phaseInfo.phasemask)
+ _PhasemaskThroughAuras |= phaseInfo.phasemask;
+
+ spellPhaseInfo[spellId] = phaseInfo;
+}
+
+uint32 PhaseData::RemoveAuraInfo(uint32 spellId)
+{
+ PhaseInfoContainer::const_iterator rAura = spellPhaseInfo.find(spellId);
+ if (rAura != spellPhaseInfo.end())
+ {
+ uint32 updateflag = 0;
+
+ if (rAura->second.NeedsClientSideUpdate())
+ updateflag |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
+
+ if (rAura->second.NeedsServerSideUpdate())
+ {
+ _PhasemaskThroughAuras = 0;
+
+ updateflag |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
+
+ spellPhaseInfo.erase(rAura);
+
+ for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr)
+ _PhasemaskThroughAuras |= itr->second.phasemask;
+ }
+
+ return updateflag;
+ }
+
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////
+// Phase Update Data
+
+void PhaseUpdateData::AddQuestUpdate(uint32 questId)
+{
+ AddConditionType(CONDITION_QUESTREWARDED);
+ AddConditionType(CONDITION_QUESTTAKEN);
+ AddConditionType(CONDITION_QUEST_COMPLETE);
+ AddConditionType(CONDITION_QUEST_NONE);
+
+ _questId = questId;
+}
+
+bool PhaseUpdateData::IsConditionRelated(Condition const* condition) const
+{
+ switch (condition->ConditionType)
+ {
+ case CONDITION_QUESTREWARDED:
+ case CONDITION_QUESTTAKEN:
+ case CONDITION_QUEST_COMPLETE:
+ case CONDITION_QUEST_NONE:
+ return condition->ConditionValue1 == _questId && ((1 << condition->ConditionType) & _conditionTypeFlags);
+ default:
+ return (1 << condition->ConditionType) & _conditionTypeFlags;
+ }
+}
+
+bool PhaseMgr::IsConditionTypeSupported(ConditionTypes conditionType)
+{
+ switch (conditionType)
+ {
+ case CONDITION_QUESTREWARDED:
+ case CONDITION_QUESTTAKEN:
+ case CONDITION_QUEST_COMPLETE:
+ case CONDITION_QUEST_NONE:
+ case CONDITION_TEAM:
+ case CONDITION_CLASS:
+ case CONDITION_RACE:
+ case CONDITION_INSTANCE_INFO:
+ case CONDITION_LEVEL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void PhaseMgr::GetActivePhases(std::set<uint32>& phases) const
+{
+ phaseData.GetActivePhases(phases);
+}
diff --git a/src/server/game/Maps/PhaseMgr.h b/src/server/game/Maps/PhaseMgr.h
new file mode 100644
index 00000000000..3d23a8584ec
--- /dev/null
+++ b/src/server/game/Maps/PhaseMgr.h
@@ -0,0 +1,179 @@
+/*
+ * 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 TRINITY_PHASEMGR_H
+#define TRINITY_PHASEMGR_H
+
+#include "SharedDefines.h"
+#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
+#include "ConditionMgr.h"
+
+class ObjectMgr;
+class Player;
+
+// Phasing (visibility)
+enum PhasingFlags
+{
+ PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases
+ PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied)
+ PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask
+};
+
+enum PhaseUpdateFlag
+{
+ PHASE_UPDATE_FLAG_ZONE_UPDATE = 0x01,
+ PHASE_UPDATE_FLAG_AREA_UPDATE = 0x02,
+
+ // Internal flags
+ PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED = 0x08,
+ PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED = 0x10,
+};
+
+struct PhaseDefinition
+{
+ uint32 zoneId;
+ uint32 entry;
+ uint32 phasemask;
+ uint32 phaseId;
+ uint32 terrainswapmap;
+ uint8 flags;
+
+ bool IsOverwritingExistingPhases() const { return flags & PHASE_FLAG_OVERWRITE_EXISTING; }
+ bool IsLastDefinition() const { return flags & PHASE_FLAG_NO_MORE_PHASES; }
+ bool IsNegatingPhasemask() const { return flags & PHASE_FLAG_NEGATE_PHASE; }
+};
+
+typedef std::list<PhaseDefinition> PhaseDefinitionContainer;
+typedef UNORDERED_MAP<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore;
+
+struct SpellPhaseInfo
+{
+ uint32 spellId;
+ uint32 phasemask;
+ uint32 terrainswapmap;
+};
+
+typedef UNORDERED_MAP<uint32 /*spellId*/, SpellPhaseInfo> SpellPhaseStore;
+
+struct PhaseInfo
+{
+ PhaseInfo() : phasemask(0), terrainswapmap(0), phaseId(0) {}
+
+ uint32 phasemask;
+ uint32 terrainswapmap;
+ uint32 phaseId;
+
+ bool NeedsServerSideUpdate() const { return phasemask; }
+ bool NeedsClientSideUpdate() const { return terrainswapmap || phaseId; }
+};
+
+typedef UNORDERED_MAP<uint32 /*spellId*/, PhaseInfo> PhaseInfoContainer;
+
+struct PhaseData
+{
+ PhaseData(Player* _player) : _PhasemaskThroughDefinitions(0), _PhasemaskThroughAuras(0), _CustomPhasemask(0), player(_player) {}
+
+ uint32 _PhasemaskThroughDefinitions;
+ uint32 _PhasemaskThroughAuras;
+ uint32 _CustomPhasemask;
+
+ uint32 GetCurrentPhasemask() const;
+ inline uint32 GetPhaseMaskForSpawn() const;
+
+ void ResetDefinitions() { _PhasemaskThroughDefinitions = 0; activePhaseDefinitions.clear(); }
+ void AddPhaseDefinition(PhaseDefinition const* phaseDefinition);
+ bool HasActiveDefinitions() const { return !activePhaseDefinitions.empty(); }
+
+ void AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo);
+ uint32 RemoveAuraInfo(uint32 spellId);
+
+ void SendPhaseMaskToPlayer();
+ void SendPhaseshiftToPlayer();
+
+ void GetActivePhases(std::set<uint32>& phases) const;
+
+private:
+ Player* player;
+ std::list<PhaseDefinition const*> activePhaseDefinitions;
+ PhaseInfoContainer spellPhaseInfo;
+};
+
+struct PhaseUpdateData
+{
+ PhaseUpdateData(): _conditionTypeFlags(0), _questId(0) { }
+ void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); }
+ void AddQuestUpdate(uint32 const questId);
+
+ bool IsConditionRelated(Condition const* condition) const;
+
+private:
+ uint32 _conditionTypeFlags;
+ uint32 _questId;
+};
+
+class PhaseMgr
+{
+public:
+ PhaseMgr(Player* _player);
+ ~PhaseMgr() {}
+
+ uint32 GetCurrentPhasemask() { return phaseData.GetCurrentPhasemask(); };
+ inline uint32 GetPhaseMaskForSpawn() { return phaseData.GetCurrentPhasemask(); }
+
+ // Phase definitions update handling
+ void NotifyConditionChanged(PhaseUpdateData const& updateData);
+ void NotifyStoresReloaded() { Recalculate(); Update(); }
+
+ void Update();
+
+ // Aura phase effects
+ void RegisterPhasingAuraEffect(AuraEffect const* auraEffect);
+ void UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect);
+
+ // Update flags (delayed phasing)
+ void AddUpdateFlag(PhaseUpdateFlag updateFlag) { _UpdateFlags |= updateFlag; }
+ void RemoveUpdateFlag(PhaseUpdateFlag updateFlag);
+
+ // Needed for modify phase command
+ void SetCustomPhase(uint32 phaseMask);
+
+ // Debug
+ void SendDebugReportToPlayer(Player* const debugger);
+
+ static bool IsConditionTypeSupported(ConditionTypes conditionType);
+
+ void GetActivePhases(std::set<uint32>& phases) const;
+
+private:
+ void Recalculate();
+
+ inline bool CheckDefinition(PhaseDefinition const* phaseDefinition);
+
+ bool NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const;
+
+ inline bool IsUpdateInProgress() const { return (_UpdateFlags & PHASE_UPDATE_FLAG_ZONE_UPDATE) || (_UpdateFlags & PHASE_UPDATE_FLAG_AREA_UPDATE); }
+
+ PhaseDefinitionStore const* _PhaseDefinitionStore;
+ SpellPhaseStore const* _SpellPhaseStore;
+
+ Player* player;
+ PhaseData phaseData;
+ uint8 _UpdateFlags;
+};
+
+#endif
diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h
index 8d0e97dc765..924320ac198 100644
--- a/src/server/game/Miscellaneous/Formulas.h
+++ b/src/server/game/Miscellaneous/Formulas.h
@@ -128,6 +128,9 @@ namespace Trinity
case CONTENT_71_80:
nBaseExp = 580;
break;
+ case CONTENT_81_85:
+ nBaseExp = 1878;
+ break;
default:
TC_LOG_ERROR("misc", "BaseGain: Unsupported content level %u", content);
nBaseExp = 45;
@@ -221,6 +224,26 @@ namespace Trinity
return rate;
}
} // namespace Trinity::XP
+
+ namespace Currency
+ {
+ inline uint32 ConquestRatingCalculator(uint32 rate)
+ {
+ if (rate <= 1500)
+ return 1350; // Default conquest points
+ else if (rate > 3000)
+ rate = 3000;
+
+ // http://www.arenajunkies.com/topic/179536-conquest-point-cap-vs-personal-rating-chart/page__st__60#entry3085246
+ return uint32(1.4326 * ((1511.26 / (1 + 1639.28 / exp(0.00412 * rate))) + 850.15));
+ }
+
+ inline uint32 BgConquestRatingCalculator(uint32 rate)
+ {
+ // WowWiki: Battleground ratings receive a bonus of 22.2% to the cap they generate
+ return uint32((ConquestRatingCalculator(rate) * 1.222f) + 0.5f);
+ }
+ } // namespace Trinity::Currency
} // namespace Trinity
#endif
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 3102e2c6854..2e4d831288a 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -198,7 +198,15 @@ enum TrinityStrings
LANG_LIQUID_STATUS = 175,
LANG_INVALID_GAMEOBJECT_TYPE = 176,
LANG_GAMEOBJECT_DAMAGED = 177,
- // Room for more level 1 178-199 not used
+
+ LANG_PHASING_SUCCESS = 178,
+ LANG_PHASING_FAILED = 179,
+ LANG_PHASING_LAST_PHASE = 180,
+ LANG_PHASING_LIST = 181,
+ LANG_PHASING_PHASEMASK = 182,
+ LANG_PHASING_REPORT_STATUS = 183,
+ LANG_PHASING_NO_DEFINITIONS = 184, // Phasing
+ // Room for more level 1 185-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
@@ -721,12 +729,12 @@ enum TrinityStrings
LANG_DEBUG_ARENA_OFF = 738,
LANG_DEBUG_BG_ON = 739,
LANG_DEBUG_BG_OFF = 740,
- LANG_DIST_ARENA_POINTS_START = 741,
- LANG_DIST_ARENA_POINTS_ONLINE_START = 742,
- LANG_DIST_ARENA_POINTS_ONLINE_END = 743,
- LANG_DIST_ARENA_POINTS_TEAM_START = 744,
- LANG_DIST_ARENA_POINTS_TEAM_END = 745,
- LANG_DIST_ARENA_POINTS_END = 746,
+// LANG_DIST_ARENA_POINTS_START = 741,
+// LANG_DIST_ARENA_POINTS_ONLINE_START = 742,
+// LANG_DIST_ARENA_POINTS_ONLINE_END = 743,
+// LANG_DIST_ARENA_POINTS_TEAM_START = 744,
+// LANG_DIST_ARENA_POINTS_TEAM_END = 745,
+// LANG_DIST_ARENA_POINTS_END = 746,
LANG_BG_DISABLED = 747,
LANG_ARENA_DISABLED = 748,
// = 749, see LANG_PINFO_ACC_OS
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index e5d3a5312de..75e190ed20d 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -49,7 +49,8 @@ enum Expansions
EXPANSION_CLASSIC = 0,
EXPANSION_THE_BURNING_CRUSADE = 1,
EXPANSION_WRATH_OF_THE_LICH_KING = 2,
- MAX_EXPANSIONS = 3
+ EXPANSION_CATACLYSM = 3,
+ MAX_EXPANSIONS = 4
};
enum Gender
@@ -71,9 +72,9 @@ enum Races
RACE_TAUREN = 6,
RACE_GNOME = 7,
RACE_TROLL = 8,
- //RACE_GOBLIN = 9,
+ RACE_GOBLIN = 9,
RACE_BLOODELF = 10,
- RACE_DRAENEI = 11
+ RACE_DRAENEI = 11,
//RACE_FEL_ORC = 12,
//RACE_NAGA = 13,
//RACE_BROKEN = 14,
@@ -83,21 +84,23 @@ enum Races
//RACE_FOREST_TROLL = 18,
//RACE_TAUNKA = 19,
//RACE_NORTHREND_SKELETON = 20,
- //RACE_ICE_TROLL = 21
+ //RACE_ICE_TROLL = 21,
+ RACE_WORGEN = 22,
+ //RACE_GILNEAN = 23
};
// max+1 for player race
-#define MAX_RACES 12
+#define MAX_RACES 23
#define RACEMASK_ALL_PLAYABLE \
((1<<(RACE_HUMAN-1)) |(1<<(RACE_ORC-1)) |(1<<(RACE_DWARF-1)) | \
(1<<(RACE_NIGHTELF-1))|(1<<(RACE_UNDEAD_PLAYER-1))|(1<<(RACE_TAUREN-1)) | \
(1<<(RACE_GNOME-1)) |(1<<(RACE_TROLL-1)) |(1<<(RACE_BLOODELF-1))| \
- (1<<(RACE_DRAENEI-1)))
+ (1<<(RACE_DRAENEI-1)) |(1<<(RACE_GOBLIN-1)) |(1<<(RACE_WORGEN-1)))
#define RACEMASK_ALLIANCE \
((1<<(RACE_HUMAN-1)) | (1<<(RACE_DWARF-1)) | (1<<(RACE_NIGHTELF-1)) | \
- (1<<(RACE_GNOME-1)) | (1<<(RACE_DRAENEI-1)))
+ (1<<(RACE_GNOME-1)) | (1<<(RACE_DRAENEI-1)) | (1<<(RACE_WORGEN-1)))
#define RACEMASK_HORDE RACEMASK_ALL_PLAYABLE & ~RACEMASK_ALLIANCE
@@ -157,7 +160,7 @@ enum ReputationRank
#define MIN_REPUTATION_RANK (REP_HATED)
#define MAX_REPUTATION_RANK 8
-#define MAX_SPILLOVER_FACTIONS 4
+#define MAX_SPILLOVER_FACTIONS 5
enum MoneyConstants
{
@@ -183,14 +186,20 @@ enum Powers
POWER_RAGE = 1,
POWER_FOCUS = 2,
POWER_ENERGY = 3,
- POWER_HAPPINESS = 4,
- POWER_RUNE = 5,
+ POWER_UNUSED = 4,
+ POWER_RUNES = 5,
POWER_RUNIC_POWER = 6,
- MAX_POWERS = 7,
- POWER_ALL = 127, // default for class?
+ POWER_SOUL_SHARDS = 7,
+ POWER_ECLIPSE = 8,
+ POWER_HOLY_POWER = 9,
+ POWER_ALTERNATE_POWER = 10, // Used in some quests
+ MAX_POWERS = 11,
+ POWER_ALL = 127, // default for class?
POWER_HEALTH = 0xFFFFFFFE // (-2 as signed value)
};
+#define MAX_POWERS_PER_CLASS 5
+
enum SpellSchools
{
SPELL_SCHOOL_NORMAL = 0,
@@ -435,7 +444,7 @@ enum SpellAttr4
SPELL_ATTR4_UNK13 = 0x00002000, // 13
SPELL_ATTR4_DAMAGE_DOESNT_BREAK_AURAS = 0x00004000, // 14 doesn't break auras by damage from these spells
SPELL_ATTR4_UNK15 = 0x00008000, // 15
- SPELL_ATTR4_NOT_USABLE_IN_ARENA = 0x00010000, // 16
+ SPELL_ATTR4_NOT_USABLE_IN_ARENA_OR_RATED_BG = 0x00010000, // 16 Cannot be used in both Arenas or Rated Battlegrounds
SPELL_ATTR4_USABLE_IN_ARENA = 0x00020000, // 17
SPELL_ATTR4_AREA_TARGET_CHAIN = 0x00040000, // 18 (NYI)hits area targets one after another instead of all at once
SPELL_ATTR4_UNK19 = 0x00080000, // 19 proc dalayed, after damage or don't proc on absorb?
@@ -532,7 +541,7 @@ enum SpellAttr7
SPELL_ATTR7_REACTIVATE_AT_RESURRECT = 0x00000004, // 2 Paladin's auras and 65607 only.
SPELL_ATTR7_IS_CHEAT_SPELL = 0x00000008, // 3 Cannot cast if caster doesn't have UnitFlag2 & UNIT_FLAG2_ALLOW_CHEAT_SPELLS
SPELL_ATTR7_UNK4 = 0x00000010, // 4 Only 47883 (Soulstone Resurrection) and test spell.
- SPELL_ATTR7_SUMMON_PLAYER_TOTEM = 0x00000020, // 5 Only Shaman player totems.
+ SPELL_ATTR7_SUMMON_TOTEM = 0x00000020, // 5 Only Shaman totems.
SPELL_ATTR7_UNK6 = 0x00000040, // 6 Dark Surge, Surge of Light, Burning Breath triggers (boss spells).
SPELL_ATTR7_UNK7 = 0x00000080, // 7 66218 (Launch) spell.
SPELL_ATTR7_HORDE_ONLY = 0x00000100, // 8 Teleports, mounts and other spells.
@@ -561,11 +570,120 @@ enum SpellAttr7
SPELL_ATTR7_CLIENT_INDICATOR = 0x80000000
};
+enum SpellAttr8
+{
+ SPELL_ATTR8_CANT_MISS = 0x00000001, // 0
+ SPELL_ATTR8_UNK1 = 0x00000002, // 1
+ SPELL_ATTR8_UNK2 = 0x00000004, // 2
+ SPELL_ATTR8_UNK3 = 0x00000008, // 3
+ SPELL_ATTR8_UNK4 = 0x00000010, // 4
+ SPELL_ATTR8_UNK5 = 0x00000020, // 5
+ SPELL_ATTR8_UNK6 = 0x00000040, // 6
+ SPELL_ATTR8_UNK7 = 0x00000080, // 7
+ SPELL_ATTR8_AFFECT_PARTY_AND_RAID = 0x00000100, // 8 Nearly all spells have "all party and raid" in description
+ SPELL_ATTR8_DONT_RESET_PERIODIC_TIMER = 0x00000200, // 9 Periodic auras with this flag keep old periodic timer when refreshing at close to one tick remaining (kind of anti DoT clipping)
+ SPELL_ATTR8_NAME_CHANGED_DURING_TRANSFORM = 0x00000400, // 10 according to wowhead comments, name changes, title remains
+ SPELL_ATTR8_UNK11 = 0x00000800, // 11
+ SPELL_ATTR8_AURA_SEND_AMOUNT = 0x00001000, // 12 Aura must have flag AFLAG_ANY_EFFECT_AMOUNT_SENT to send amount
+ SPELL_ATTR8_UNK13 = 0x00002000, // 13
+ SPELL_ATTR8_UNK14 = 0x00004000, // 14
+ SPELL_ATTR8_WATER_MOUNT = 0x00008000, // 15 only one River Boat used in Thousand Needles
+ SPELL_ATTR8_UNK16 = 0x00010000, // 16
+ SPELL_ATTR8_UNK17 = 0x00020000, // 17
+ SPELL_ATTR8_REMEMBER_SPELLS = 0x00040000, // 18 at some point in time, these auras remember spells and allow to cast them later
+ SPELL_ATTR8_USE_COMBO_POINTS_ON_ANY_TARGET = 0x00080000, // 19 allows to consume combo points from dead targets
+ SPELL_ATTR8_ARMOR_SPECIALIZATION = 0x00100000, // 20
+ SPELL_ATTR8_UNK21 = 0x00200000, // 21
+ SPELL_ATTR8_UNK22 = 0x00400000, // 22
+ SPELL_ATTR8_UNK23 = 0x00800000, // 23
+ SPELL_ATTR8_HEALING_SPELL = 0x01000000, // 24
+ SPELL_ATTR8_UNK25 = 0x02000000, // 25
+ SPELL_ATTR8_RAID_MARKER = 0x04000000, // 26 probably spell no need learn to cast
+ SPELL_ATTR8_UNK27 = 0x08000000, // 27
+ SPELL_ATTR8_NOT_IN_BG_OR_ARENA = 0x10000000, // 28 not allow to cast or deactivate currently active effect, not sure about Fast Track
+ SPELL_ATTR8_MASTERY_SPECIALIZATION = 0x20000000, // 29
+ SPELL_ATTR8_UNK30 = 0x40000000, // 30
+ SPELL_ATTR8_ATTACK_IGNORE_IMMUNE_TO_PC_FLAG = 0x80000000 // 31 Do not check UNIT_FLAG_IMMUNE_TO_PC in IsValidAttackTarget
+};
+
+enum SpellAttr9
+{
+ SPELL_ATTR9_UNK0 = 0x00000001, // 0
+ SPELL_ATTR9_UNK1 = 0x00000002, // 1
+ SPELL_ATTR9_RESTRICTED_FLIGHT_AREA = 0x00000004, // 2 Dalaran and Wintergrasp flight area auras have it
+ SPELL_ATTR9_UNK3 = 0x00000008, // 3
+ SPELL_ATTR9_SPECIAL_DELAY_CALCULATION = 0x00000010, // 4
+ SPELL_ATTR9_SUMMON_PLAYER_TOTEM = 0x00000020, // 5
+ SPELL_ATTR9_UNK6 = 0x00000040, // 6
+ SPELL_ATTR9_UNK7 = 0x00000080, // 7
+ SPELL_ATTR9_AIMED_SHOT = 0x00000100, // 8
+ SPELL_ATTR9_NOT_USABLE_IN_ARENA = 0x00000200, // 9 Cannot be used in arenas
+ SPELL_ATTR9_UNK10 = 0x00000400, // 10
+ SPELL_ATTR9_UNK11 = 0x00000800, // 11
+ SPELL_ATTR9_UNK12 = 0x00001000, // 12
+ SPELL_ATTR9_SLAM = 0x00002000, // 13
+ SPELL_ATTR9_USABLE_IN_RATED_BATTLEGROUNDS = 0x00004000, // 14 Can be used in Rated Battlegrounds
+ SPELL_ATTR9_UNK15 = 0x00008000, // 15
+ SPELL_ATTR9_UNK16 = 0x00010000, // 16
+ SPELL_ATTR9_UNK17 = 0x00020000, // 17
+ SPELL_ATTR9_UNK18 = 0x00040000, // 18
+ SPELL_ATTR9_UNK19 = 0x00080000, // 19
+ SPELL_ATTR9_UNK20 = 0x00100000, // 20
+ SPELL_ATTR9_UNK21 = 0x00200000, // 21
+ SPELL_ATTR9_UNK22 = 0x00400000, // 22
+ SPELL_ATTR9_UNK23 = 0x00800000, // 23
+ SPELL_ATTR9_UNK24 = 0x01000000, // 24
+ SPELL_ATTR9_UNK25 = 0x02000000, // 25
+ SPELL_ATTR9_UNK26 = 0x04000000, // 26
+ SPELL_ATTR9_UNK27 = 0x08000000, // 27
+ SPELL_ATTR9_UNK28 = 0x10000000, // 28
+ SPELL_ATTR9_UNK29 = 0x20000000, // 29
+ SPELL_ATTR9_UNK30 = 0x40000000, // 30
+ SPELL_ATTR9_UNK31 = 0x80000000 // 31
+};
+
+enum SpellAttr10
+{
+ SPELL_ATTR10_UNK0 = 0x00000001, // 0
+ SPELL_ATTR10_UNK1 = 0x00000002, // 1
+ SPELL_ATTR10_UNK2 = 0x00000004, // 2
+ SPELL_ATTR10_UNK3 = 0x00000008, // 3
+ SPELL_ATTR10_WATER_SPOUT = 0x00000010, // 4
+ SPELL_ATTR10_UNK5 = 0x00000020, // 5
+ SPELL_ATTR10_UNK6 = 0x00000040, // 6
+ SPELL_ATTR10_TELEPORT_PLAYER = 0x00000080, // 7 4 Teleport Player spells
+ SPELL_ATTR10_UNK8 = 0x00000100, // 8
+ SPELL_ATTR10_UNK9 = 0x00000200, // 9
+ SPELL_ATTR10_UNK10 = 0x00000400, // 10
+ SPELL_ATTR10_HERB_GATHERING_MINING = 0x00000800, // 11 Only Herb Gathering and Mining
+ SPELL_ATTR10_UNK12 = 0x00001000, // 12
+ SPELL_ATTR10_UNK13 = 0x00002000, // 13
+ SPELL_ATTR10_UNK14 = 0x00004000, // 14
+ SPELL_ATTR10_UNK15 = 0x00008000, // 15
+ SPELL_ATTR10_UNK16 = 0x00010000, // 16
+ SPELL_ATTR10_UNK17 = 0x00020000, // 17
+ SPELL_ATTR10_UNK18 = 0x00040000, // 18
+ SPELL_ATTR10_UNK19 = 0x00080000, // 19
+ SPELL_ATTR10_UNK20 = 0x00100000, // 20
+ SPELL_ATTR10_UNK21 = 0x00200000, // 21
+ SPELL_ATTR10_UNK22 = 0x00400000, // 22
+ SPELL_ATTR10_UNK23 = 0x00800000, // 23
+ SPELL_ATTR10_UNK24 = 0x01000000, // 24
+ SPELL_ATTR10_UNK25 = 0x02000000, // 25
+ SPELL_ATTR10_UNK26 = 0x04000000, // 26
+ SPELL_ATTR10_UNK27 = 0x08000000, // 27
+ SPELL_ATTR10_UNK28 = 0x10000000, // 28
+ SPELL_ATTR10_UNK29 = 0x20000000, // 29
+ SPELL_ATTR10_UNK30 = 0x40000000, // 30
+ SPELL_ATTR10_UNK31 = 0x80000000 // 31
+};
+
#define MIN_TALENT_SPEC 0
#define MAX_TALENT_SPEC 1
#define MIN_TALENT_SPECS 1
#define MAX_TALENT_SPECS 2
-#define MAX_GLYPH_SLOT_INDEX 6
+#define MAX_GLYPH_SLOT_INDEX 9
+#define REQ_PRIMARY_TREE_TALENTS 31
// Custom values
enum SpellClickUserTypes
@@ -642,10 +760,12 @@ enum Language
LANG_ZOMBIE = 36,
LANG_GNOMISH_BINARY = 37,
LANG_GOBLIN_BINARY = 38,
+ LANG_WORGEN = 39,
+ LANG_GOBLIN = 40,
LANG_ADDON = 0xFFFFFFFF // used by addons, in 2.4.0 not exist, replaced by messagetype?
};
-#define LANGUAGES_COUNT 19
+#define LANGUAGES_COUNT 21
enum TeamId
{
@@ -671,7 +791,7 @@ enum SpellEffects
SPELL_EFFECT_INSTAKILL = 1,
SPELL_EFFECT_SCHOOL_DAMAGE = 2,
SPELL_EFFECT_DUMMY = 3,
- SPELL_EFFECT_PORTAL_TELEPORT = 4,
+ SPELL_EFFECT_PORTAL_TELEPORT = 4, // Unused (4.3.4)
SPELL_EFFECT_TELEPORT_UNITS = 5,
SPELL_EFFECT_APPLY_AURA = 6,
SPELL_EFFECT_ENVIRONMENTAL_DAMAGE = 7,
@@ -680,9 +800,9 @@ enum SpellEffects
SPELL_EFFECT_HEAL = 10,
SPELL_EFFECT_BIND = 11,
SPELL_EFFECT_PORTAL = 12,
- SPELL_EFFECT_RITUAL_BASE = 13,
- SPELL_EFFECT_RITUAL_SPECIALIZE = 14,
- SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15,
+ SPELL_EFFECT_RITUAL_BASE = 13, // Unused (4.3.4)
+ SPELL_EFFECT_RITUAL_SPECIALIZE = 14, // Unused (4.3.4)
+ SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL = 15, // Unused (4.3.4)
SPELL_EFFECT_QUEST_COMPLETE = 16,
SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL = 17,
SPELL_EFFECT_RESURRECT = 18,
@@ -712,14 +832,14 @@ enum SpellEffects
SPELL_EFFECT_JUMP_DEST = 42,
SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER = 43,
SPELL_EFFECT_SKILL_STEP = 44,
- SPELL_EFFECT_ADD_HONOR = 45,
+ SPELL_EFFECT_PLAY_MOVIE = 45,
SPELL_EFFECT_SPAWN = 46,
SPELL_EFFECT_TRADE_SKILL = 47,
SPELL_EFFECT_STEALTH = 48,
SPELL_EFFECT_DETECT = 49,
SPELL_EFFECT_TRANS_DOOR = 50,
- SPELL_EFFECT_FORCE_CRITICAL_HIT = 51,
- SPELL_EFFECT_GUARANTEE_HIT = 52,
+ SPELL_EFFECT_FORCE_CRITICAL_HIT = 51, // Unused (4.3.4)
+ SPELL_EFFECT_GUARANTEE_HIT = 52, // Unused (4.3.4)
SPELL_EFFECT_ENCHANT_ITEM = 53,
SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY = 54,
SPELL_EFFECT_TAMECREATURE = 55,
@@ -789,7 +909,7 @@ enum SpellEffects
SPELL_EFFECT_APPLY_AREA_AURA_PET = 119,
SPELL_EFFECT_TELEPORT_GRAVEYARD = 120,
SPELL_EFFECT_NORMALIZED_WEAPON_DMG = 121,
- SPELL_EFFECT_122 = 122,
+ SPELL_EFFECT_122 = 122, // Unused (4.3.4)
SPELL_EFFECT_SEND_TAXI = 123,
SPELL_EFFECT_PULL_TOWARDS = 124,
SPELL_EFFECT_MODIFY_THREAT_PERCENT = 125,
@@ -830,203 +950,236 @@ enum SpellEffects
SPELL_EFFECT_160 = 160,
SPELL_EFFECT_TALENT_SPEC_COUNT = 161,
SPELL_EFFECT_TALENT_SPEC_SELECT = 162,
- SPELL_EFFECT_163 = 163,
+ SPELL_EFFECT_163 = 163, // Unused (4.3.4)
SPELL_EFFECT_REMOVE_AURA = 164,
- TOTAL_SPELL_EFFECTS = 165
+ SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT = 165,
+ SPELL_EFFECT_GIVE_CURRENCY = 166,
+ SPELL_EFFECT_167 = 167,
+ SPELL_EFFECT_168 = 168,
+ SPELL_EFFECT_DESTROY_ITEM = 169,
+ SPELL_EFFECT_170 = 170,
+ SPELL_EFFECT_171 = 171, // Summons gamebject
+ SPELL_EFFECT_RESURRECT_WITH_AURA = 172,
+ SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB = 173, // Guild tab unlocked (guild perk)
+ SPELL_EFFECT_174 = 174,
+ SPELL_EFFECT_175 = 175, // Unused (4.3.4)
+ SPELL_EFFECT_176 = 176, // Some kind of sanctuary effect (Vanish)
+ SPELL_EFFECT_177 = 177,
+ SPELL_EFFECT_178 = 178, // Unused (4.3.4)
+ SPELL_EFFECT_CREATE_AREATRIGGER = 179,
+ SPELL_EFFECT_180 = 180, // Unused (4.3.4)
+ SPELL_EFFECT_181 = 181, // Unused (4.3.4)
+ SPELL_EFFECT_182 = 182,
+ TOTAL_SPELL_EFFECTS = 183,
};
enum SpellCastResult
{
- SPELL_FAILED_SUCCESS = 0,
- SPELL_FAILED_AFFECTING_COMBAT = 1,
- SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 2,
- SPELL_FAILED_ALREADY_AT_FULL_MANA = 3,
- SPELL_FAILED_ALREADY_AT_FULL_POWER = 4,
- SPELL_FAILED_ALREADY_BEING_TAMED = 5,
- SPELL_FAILED_ALREADY_HAVE_CHARM = 6,
- SPELL_FAILED_ALREADY_HAVE_SUMMON = 7,
- SPELL_FAILED_ALREADY_OPEN = 8,
- SPELL_FAILED_AURA_BOUNCED = 9,
- SPELL_FAILED_AUTOTRACK_INTERRUPTED = 10,
- SPELL_FAILED_BAD_IMPLICIT_TARGETS = 11,
- SPELL_FAILED_BAD_TARGETS = 12,
- SPELL_FAILED_CANT_BE_CHARMED = 13,
- SPELL_FAILED_CANT_BE_DISENCHANTED = 14,
- SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 15,
- SPELL_FAILED_CANT_BE_MILLED = 16,
- SPELL_FAILED_CANT_BE_PROSPECTED = 17,
- SPELL_FAILED_CANT_CAST_ON_TAPPED = 18,
- SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 19,
- SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 20,
- SPELL_FAILED_CANT_STEALTH = 21,
- SPELL_FAILED_CASTER_AURASTATE = 22,
- SPELL_FAILED_CASTER_DEAD = 23,
- SPELL_FAILED_CHARMED = 24,
- SPELL_FAILED_CHEST_IN_USE = 25,
- SPELL_FAILED_CONFUSED = 26,
- SPELL_FAILED_DONT_REPORT = 27,
- SPELL_FAILED_EQUIPPED_ITEM = 28,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS = 29,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 30,
- SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 31,
- SPELL_FAILED_ERROR = 32,
- SPELL_FAILED_FIZZLE = 33,
- SPELL_FAILED_FLEEING = 34,
- SPELL_FAILED_FOOD_LOWLEVEL = 35,
- SPELL_FAILED_HIGHLEVEL = 36,
- SPELL_FAILED_HUNGER_SATIATED = 37,
- SPELL_FAILED_IMMUNE = 38,
- SPELL_FAILED_INCORRECT_AREA = 39,
- SPELL_FAILED_INTERRUPTED = 40,
- SPELL_FAILED_INTERRUPTED_COMBAT = 41,
- SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 42,
- SPELL_FAILED_ITEM_GONE = 43,
- SPELL_FAILED_ITEM_NOT_FOUND = 44,
- SPELL_FAILED_ITEM_NOT_READY = 45,
- SPELL_FAILED_LEVEL_REQUIREMENT = 46,
- SPELL_FAILED_LINE_OF_SIGHT = 47,
- SPELL_FAILED_LOWLEVEL = 48,
- SPELL_FAILED_LOW_CASTLEVEL = 49,
- SPELL_FAILED_MAINHAND_EMPTY = 50,
- SPELL_FAILED_MOVING = 51,
- SPELL_FAILED_NEED_AMMO = 52,
- SPELL_FAILED_NEED_AMMO_POUCH = 53,
- SPELL_FAILED_NEED_EXOTIC_AMMO = 54,
- SPELL_FAILED_NEED_MORE_ITEMS = 55,
- SPELL_FAILED_NOPATH = 56,
- SPELL_FAILED_NOT_BEHIND = 57,
- SPELL_FAILED_NOT_FISHABLE = 58,
- SPELL_FAILED_NOT_FLYING = 59,
- SPELL_FAILED_NOT_HERE = 60,
- SPELL_FAILED_NOT_INFRONT = 61,
- SPELL_FAILED_NOT_IN_CONTROL = 62,
- SPELL_FAILED_NOT_KNOWN = 63,
- SPELL_FAILED_NOT_MOUNTED = 64,
- SPELL_FAILED_NOT_ON_TAXI = 65,
- SPELL_FAILED_NOT_ON_TRANSPORT = 66,
- SPELL_FAILED_NOT_READY = 67,
- SPELL_FAILED_NOT_SHAPESHIFT = 68,
- SPELL_FAILED_NOT_STANDING = 69,
- SPELL_FAILED_NOT_TRADEABLE = 70,
- SPELL_FAILED_NOT_TRADING = 71,
- SPELL_FAILED_NOT_UNSHEATHED = 72,
- SPELL_FAILED_NOT_WHILE_GHOST = 73,
- SPELL_FAILED_NOT_WHILE_LOOTING = 74,
- SPELL_FAILED_NO_AMMO = 75,
- SPELL_FAILED_NO_CHARGES_REMAIN = 76,
- SPELL_FAILED_NO_CHAMPION = 77,
- SPELL_FAILED_NO_COMBO_POINTS = 78,
- SPELL_FAILED_NO_DUELING = 79,
- SPELL_FAILED_NO_ENDURANCE = 80,
- SPELL_FAILED_NO_FISH = 81,
- SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 82,
- SPELL_FAILED_NO_MOUNTS_ALLOWED = 83,
- SPELL_FAILED_NO_PET = 84,
- SPELL_FAILED_NO_POWER = 85,
- SPELL_FAILED_NOTHING_TO_DISPEL = 86,
- SPELL_FAILED_NOTHING_TO_STEAL = 87,
- SPELL_FAILED_ONLY_ABOVEWATER = 88,
- SPELL_FAILED_ONLY_DAYTIME = 89,
- SPELL_FAILED_ONLY_INDOORS = 90,
- SPELL_FAILED_ONLY_MOUNTED = 91,
- SPELL_FAILED_ONLY_NIGHTTIME = 92,
- SPELL_FAILED_ONLY_OUTDOORS = 93,
- SPELL_FAILED_ONLY_SHAPESHIFT = 94,
- SPELL_FAILED_ONLY_STEALTHED = 95,
- SPELL_FAILED_ONLY_UNDERWATER = 96,
- SPELL_FAILED_OUT_OF_RANGE = 97,
- SPELL_FAILED_PACIFIED = 98,
- SPELL_FAILED_POSSESSED = 99,
- SPELL_FAILED_REAGENTS = 100,
- SPELL_FAILED_REQUIRES_AREA = 101,
- SPELL_FAILED_REQUIRES_SPELL_FOCUS = 102,
- SPELL_FAILED_ROOTED = 103,
- SPELL_FAILED_SILENCED = 104,
- SPELL_FAILED_SPELL_IN_PROGRESS = 105,
- SPELL_FAILED_SPELL_LEARNED = 106,
- SPELL_FAILED_SPELL_UNAVAILABLE = 107,
- SPELL_FAILED_STUNNED = 108,
- SPELL_FAILED_TARGETS_DEAD = 109,
- SPELL_FAILED_TARGET_AFFECTING_COMBAT = 110,
- SPELL_FAILED_TARGET_AURASTATE = 111,
- SPELL_FAILED_TARGET_DUELING = 112,
- SPELL_FAILED_TARGET_ENEMY = 113,
- SPELL_FAILED_TARGET_ENRAGED = 114,
- SPELL_FAILED_TARGET_FRIENDLY = 115,
- SPELL_FAILED_TARGET_IN_COMBAT = 116,
- SPELL_FAILED_TARGET_IS_PLAYER = 117,
- SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 118,
- SPELL_FAILED_TARGET_NOT_DEAD = 119,
- SPELL_FAILED_TARGET_NOT_IN_PARTY = 120,
- SPELL_FAILED_TARGET_NOT_LOOTED = 121,
- SPELL_FAILED_TARGET_NOT_PLAYER = 122,
- SPELL_FAILED_TARGET_NO_POCKETS = 123,
- SPELL_FAILED_TARGET_NO_WEAPONS = 124,
- SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 125,
- SPELL_FAILED_TARGET_UNSKINNABLE = 126,
- SPELL_FAILED_THIRST_SATIATED = 127,
- SPELL_FAILED_TOO_CLOSE = 128,
- SPELL_FAILED_TOO_MANY_OF_ITEM = 129,
- SPELL_FAILED_TOTEM_CATEGORY = 130,
- SPELL_FAILED_TOTEMS = 131,
- SPELL_FAILED_TRY_AGAIN = 132,
- SPELL_FAILED_UNIT_NOT_BEHIND = 133,
- SPELL_FAILED_UNIT_NOT_INFRONT = 134,
- SPELL_FAILED_WRONG_PET_FOOD = 135,
- SPELL_FAILED_NOT_WHILE_FATIGUED = 136,
- SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 137,
- SPELL_FAILED_NOT_WHILE_TRADING = 138,
- SPELL_FAILED_TARGET_NOT_IN_RAID = 139,
- SPELL_FAILED_TARGET_FREEFORALL = 140,
- SPELL_FAILED_NO_EDIBLE_CORPSES = 141,
- SPELL_FAILED_ONLY_BATTLEGROUNDS = 142,
- SPELL_FAILED_TARGET_NOT_GHOST = 143,
- SPELL_FAILED_TRANSFORM_UNUSABLE = 144,
- SPELL_FAILED_WRONG_WEATHER = 145,
- SPELL_FAILED_DAMAGE_IMMUNE = 146,
- SPELL_FAILED_PREVENTED_BY_MECHANIC = 147,
- SPELL_FAILED_PLAY_TIME = 148,
- SPELL_FAILED_REPUTATION = 149,
- SPELL_FAILED_MIN_SKILL = 150,
- SPELL_FAILED_NOT_IN_ARENA = 151,
- SPELL_FAILED_NOT_ON_SHAPESHIFT = 152,
- SPELL_FAILED_NOT_ON_STEALTHED = 153,
- SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 154,
- SPELL_FAILED_NOT_ON_MOUNTED = 155,
- SPELL_FAILED_TOO_SHALLOW = 156,
- SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 157,
- SPELL_FAILED_TARGET_IS_TRIVIAL = 158,
- SPELL_FAILED_BM_OR_INVISGOD = 159,
- SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 160,
- SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 161,
- SPELL_FAILED_NOT_IDLE = 162,
- SPELL_FAILED_NOT_INACTIVE = 163,
- SPELL_FAILED_PARTIAL_PLAYTIME = 164,
- SPELL_FAILED_NO_PLAYTIME = 165,
- SPELL_FAILED_NOT_IN_BATTLEGROUND = 166,
- SPELL_FAILED_NOT_IN_RAID_INSTANCE = 167,
- SPELL_FAILED_ONLY_IN_ARENA = 168,
- SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 169,
- SPELL_FAILED_ON_USE_ENCHANT = 170,
- SPELL_FAILED_NOT_ON_GROUND = 171,
- SPELL_FAILED_CUSTOM_ERROR = 172,
- SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 173,
- SPELL_FAILED_TOO_MANY_SOCKETS = 174,
- SPELL_FAILED_INVALID_GLYPH = 175,
- SPELL_FAILED_UNIQUE_GLYPH = 176,
- SPELL_FAILED_GLYPH_SOCKET_LOCKED = 177,
- SPELL_FAILED_NO_VALID_TARGETS = 178,
- SPELL_FAILED_ITEM_AT_MAX_CHARGES = 179,
- SPELL_FAILED_NOT_IN_BARBERSHOP = 180,
- SPELL_FAILED_FISHING_TOO_LOW = 181,
- SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 182,
- SPELL_FAILED_SUMMON_PENDING = 183,
- SPELL_FAILED_MAX_SOCKETS = 184,
- SPELL_FAILED_PET_CAN_RENAME = 185,
- SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 186,
- SPELL_FAILED_UNKNOWN = 187, // actually doesn't exist in client
-
- SPELL_CAST_OK = 255 // custom value, must not be sent to client
+ SPELL_FAILED_SUCCESS = 0,
+ SPELL_FAILED_AFFECTING_COMBAT = 1,
+ SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 2,
+ SPELL_FAILED_ALREADY_AT_FULL_MANA = 3,
+ SPELL_FAILED_ALREADY_AT_FULL_POWER = 4,
+ SPELL_FAILED_ALREADY_BEING_TAMED = 5,
+ SPELL_FAILED_ALREADY_HAVE_CHARM = 6,
+ SPELL_FAILED_ALREADY_HAVE_SUMMON = 7,
+ SPELL_FAILED_ALREADY_HAVE_PET = 8,
+ SPELL_FAILED_ALREADY_OPEN = 9,
+ SPELL_FAILED_AURA_BOUNCED = 10,
+ SPELL_FAILED_AUTOTRACK_INTERRUPTED = 11,
+ SPELL_FAILED_BAD_IMPLICIT_TARGETS = 12,
+ SPELL_FAILED_BAD_TARGETS = 13,
+ SPELL_FAILED_CANT_BE_CHARMED = 14,
+ SPELL_FAILED_CANT_BE_DISENCHANTED = 15,
+ SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 16,
+ SPELL_FAILED_CANT_BE_MILLED = 17,
+ SPELL_FAILED_CANT_BE_PROSPECTED = 18,
+ SPELL_FAILED_CANT_CAST_ON_TAPPED = 19,
+ SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 20,
+ SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 21,
+ SPELL_FAILED_CANT_STEALTH = 22,
+ SPELL_FAILED_CASTER_AURASTATE = 23,
+ SPELL_FAILED_CASTER_DEAD = 24,
+ SPELL_FAILED_CHARMED = 25,
+ SPELL_FAILED_CHEST_IN_USE = 26,
+ SPELL_FAILED_CONFUSED = 27,
+ SPELL_FAILED_DONT_REPORT = 28,
+ SPELL_FAILED_EQUIPPED_ITEM = 29,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS = 30,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 31,
+ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 32,
+ SPELL_FAILED_ERROR = 33,
+ SPELL_FAILED_FALLING = 34,
+ SPELL_FAILED_FIZZLE = 35,
+ SPELL_FAILED_FLEEING = 36,
+ SPELL_FAILED_FOOD_LOWLEVEL = 37,
+ SPELL_FAILED_HIGHLEVEL = 38,
+ SPELL_FAILED_HUNGER_SATIATED = 39,
+ SPELL_FAILED_IMMUNE = 40,
+ SPELL_FAILED_INCORRECT_AREA = 41,
+ SPELL_FAILED_INTERRUPTED = 42,
+ SPELL_FAILED_INTERRUPTED_COMBAT = 43,
+ SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 44,
+ SPELL_FAILED_ITEM_GONE = 45,
+ SPELL_FAILED_ITEM_NOT_FOUND = 46,
+ SPELL_FAILED_ITEM_NOT_READY = 47,
+ SPELL_FAILED_LEVEL_REQUIREMENT = 48,
+ SPELL_FAILED_LINE_OF_SIGHT = 49,
+ SPELL_FAILED_LOWLEVEL = 50,
+ SPELL_FAILED_LOW_CASTLEVEL = 51,
+ SPELL_FAILED_MAINHAND_EMPTY = 52,
+ SPELL_FAILED_MOVING = 53,
+ SPELL_FAILED_NEED_AMMO = 54,
+ SPELL_FAILED_NEED_AMMO_POUCH = 55,
+ SPELL_FAILED_NEED_EXOTIC_AMMO = 56,
+ SPELL_FAILED_NEED_MORE_ITEMS = 57,
+ SPELL_FAILED_NOPATH = 58,
+ SPELL_FAILED_NOT_BEHIND = 59,
+ SPELL_FAILED_NOT_FISHABLE = 60,
+ SPELL_FAILED_NOT_FLYING = 61,
+ SPELL_FAILED_NOT_HERE = 62,
+ SPELL_FAILED_NOT_INFRONT = 63,
+ SPELL_FAILED_NOT_IN_CONTROL = 64,
+ SPELL_FAILED_NOT_KNOWN = 65,
+ SPELL_FAILED_NOT_MOUNTED = 66,
+ SPELL_FAILED_NOT_ON_TAXI = 67,
+ SPELL_FAILED_NOT_ON_TRANSPORT = 68,
+ SPELL_FAILED_NOT_READY = 69,
+ SPELL_FAILED_NOT_SHAPESHIFT = 70,
+ SPELL_FAILED_NOT_STANDING = 71,
+ SPELL_FAILED_NOT_TRADEABLE = 72,
+ SPELL_FAILED_NOT_TRADING = 73,
+ SPELL_FAILED_NOT_UNSHEATHED = 74,
+ SPELL_FAILED_NOT_WHILE_GHOST = 75,
+ SPELL_FAILED_NOT_WHILE_LOOTING = 76,
+ SPELL_FAILED_NO_AMMO = 77,
+ SPELL_FAILED_NO_CHARGES_REMAIN = 78,
+ SPELL_FAILED_NO_CHAMPION = 79,
+ SPELL_FAILED_NO_COMBO_POINTS = 80,
+ SPELL_FAILED_NO_DUELING = 81,
+ SPELL_FAILED_NO_ENDURANCE = 82,
+ SPELL_FAILED_NO_FISH = 83,
+ SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 84,
+ SPELL_FAILED_NO_MOUNTS_ALLOWED = 85,
+ SPELL_FAILED_NO_PET = 86,
+ SPELL_FAILED_NO_POWER = 87,
+ SPELL_FAILED_NOTHING_TO_DISPEL = 88,
+ SPELL_FAILED_NOTHING_TO_STEAL = 89,
+ SPELL_FAILED_ONLY_ABOVEWATER = 90,
+ SPELL_FAILED_ONLY_DAYTIME = 91,
+ SPELL_FAILED_ONLY_INDOORS = 92,
+ SPELL_FAILED_ONLY_MOUNTED = 93,
+ SPELL_FAILED_ONLY_NIGHTTIME = 94,
+ SPELL_FAILED_ONLY_OUTDOORS = 95,
+ SPELL_FAILED_ONLY_SHAPESHIFT = 96,
+ SPELL_FAILED_ONLY_STEALTHED = 97,
+ SPELL_FAILED_ONLY_UNDERWATER = 98,
+ SPELL_FAILED_OUT_OF_RANGE = 99,
+ SPELL_FAILED_PACIFIED = 100,
+ SPELL_FAILED_POSSESSED = 101,
+ SPELL_FAILED_REAGENTS = 102,
+ SPELL_FAILED_REQUIRES_AREA = 103,
+ SPELL_FAILED_REQUIRES_SPELL_FOCUS = 104,
+ SPELL_FAILED_ROOTED = 105,
+ SPELL_FAILED_SILENCED = 106,
+ SPELL_FAILED_SPELL_IN_PROGRESS = 107,
+ SPELL_FAILED_SPELL_LEARNED = 108,
+ SPELL_FAILED_SPELL_UNAVAILABLE = 109,
+ SPELL_FAILED_STUNNED = 110,
+ SPELL_FAILED_TARGETS_DEAD = 111,
+ SPELL_FAILED_TARGET_AFFECTING_COMBAT = 112,
+ SPELL_FAILED_TARGET_AURASTATE = 113,
+ SPELL_FAILED_TARGET_DUELING = 114,
+ SPELL_FAILED_TARGET_ENEMY = 115,
+ SPELL_FAILED_TARGET_ENRAGED = 116,
+ SPELL_FAILED_TARGET_FRIENDLY = 117,
+ SPELL_FAILED_TARGET_IN_COMBAT = 118,
+ SPELL_FAILED_TARGET_IS_PLAYER = 119,
+ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 120,
+ SPELL_FAILED_TARGET_NOT_DEAD = 121,
+ SPELL_FAILED_TARGET_NOT_IN_PARTY = 122,
+ SPELL_FAILED_TARGET_NOT_LOOTED = 123,
+ SPELL_FAILED_TARGET_NOT_PLAYER = 124,
+ SPELL_FAILED_TARGET_NO_POCKETS = 125,
+ SPELL_FAILED_TARGET_NO_WEAPONS = 126,
+ SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 127,
+ SPELL_FAILED_TARGET_UNSKINNABLE = 128,
+ SPELL_FAILED_THIRST_SATIATED = 129,
+ SPELL_FAILED_TOO_CLOSE = 130,
+ SPELL_FAILED_TOO_MANY_OF_ITEM = 131,
+ SPELL_FAILED_TOTEM_CATEGORY = 132,
+ SPELL_FAILED_TOTEMS = 133,
+ SPELL_FAILED_TRY_AGAIN = 134,
+ SPELL_FAILED_UNIT_NOT_BEHIND = 135,
+ SPELL_FAILED_UNIT_NOT_INFRONT = 136,
+ SPELL_FAILED_VISION_OBSCURED = 137,
+ SPELL_FAILED_WRONG_PET_FOOD = 138,
+ SPELL_FAILED_NOT_WHILE_FATIGUED = 139,
+ SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 140,
+ SPELL_FAILED_NOT_WHILE_TRADING = 141,
+ SPELL_FAILED_TARGET_NOT_IN_RAID = 142,
+ SPELL_FAILED_TARGET_FREEFORALL = 143,
+ SPELL_FAILED_NO_EDIBLE_CORPSES = 144,
+ SPELL_FAILED_ONLY_BATTLEGROUNDS = 145,
+ SPELL_FAILED_TARGET_NOT_GHOST = 146,
+ SPELL_FAILED_TRANSFORM_UNUSABLE = 147,
+ SPELL_FAILED_WRONG_WEATHER = 148,
+ SPELL_FAILED_DAMAGE_IMMUNE = 149,
+ SPELL_FAILED_PREVENTED_BY_MECHANIC = 150,
+ SPELL_FAILED_PLAY_TIME = 151,
+ SPELL_FAILED_REPUTATION = 152,
+ SPELL_FAILED_MIN_SKILL = 153,
+ SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND = 154,
+ SPELL_FAILED_NOT_ON_SHAPESHIFT = 155,
+ SPELL_FAILED_NOT_ON_STEALTHED = 156,
+ SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 157,
+ SPELL_FAILED_NOT_ON_MOUNTED = 158,
+ SPELL_FAILED_TOO_SHALLOW = 159,
+ SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 160,
+ SPELL_FAILED_TARGET_IS_TRIVIAL = 161,
+ SPELL_FAILED_BM_OR_INVISGOD = 162,
+ SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 163,
+ SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 164,
+ SPELL_FAILED_NOT_IDLE = 165,
+ SPELL_FAILED_NOT_INACTIVE = 166,
+ SPELL_FAILED_PARTIAL_PLAYTIME = 167,
+ SPELL_FAILED_NO_PLAYTIME = 168,
+ SPELL_FAILED_NOT_IN_BATTLEGROUND = 169,
+ SPELL_FAILED_NOT_IN_RAID_INSTANCE = 170,
+ SPELL_FAILED_ONLY_IN_ARENA = 171,
+ SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 172,
+ SPELL_FAILED_ON_USE_ENCHANT = 173,
+ SPELL_FAILED_NOT_ON_GROUND = 174,
+ SPELL_FAILED_CUSTOM_ERROR = 175,
+ SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 176,
+ SPELL_FAILED_TOO_MANY_SOCKETS = 177,
+ SPELL_FAILED_INVALID_GLYPH = 178,
+ SPELL_FAILED_UNIQUE_GLYPH = 179,
+ SPELL_FAILED_GLYPH_SOCKET_LOCKED = 180,
+ SPELL_FAILED_NO_VALID_TARGETS = 181,
+ SPELL_FAILED_ITEM_AT_MAX_CHARGES = 182,
+ SPELL_FAILED_NOT_IN_BARBERSHOP = 183,
+ SPELL_FAILED_FISHING_TOO_LOW = 184,
+ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 185,
+ SPELL_FAILED_SUMMON_PENDING = 186,
+ SPELL_FAILED_MAX_SOCKETS = 187,
+ SPELL_FAILED_PET_CAN_RENAME = 188,
+ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED = 189,
+ SPELL_FAILED_NO_ACTIONS = 190,
+ SPELL_FAILED_CURRENCY_WEIGHT_MISMATCH = 191,
+ SPELL_FAILED_WEIGHT_NOT_ENOUGH = 192,
+ SPELL_FAILED_WEIGHT_TOO_MUCH = 193,
+ SPELL_FAILED_NO_VACANT_SEAT = 194,
+ SPELL_FAILED_NO_LIQUID = 195,
+ SPELL_FAILED_ONLY_NOT_SWIMMING = 196,
+ SPELL_FAILED_BY_NOT_MOVING = 197,
+ SPELL_FAILED_IN_COMBAT_RES_LIMIT_REACHED = 198,
+ SPELL_FAILED_NOT_IN_ARENA = 199,
+ SPELL_FAILED_TARGET_NOT_GROUNDED = 200,
+ SPELL_FAILED_EXCEEDED_WEEKLY_USAGE = 201,
+ SPELL_FAILED_NOT_IN_LFG_DUNGEON = 202,
+ SPELL_FAILED_UNKNOWN = 254, // custom value, default case
+ SPELL_CAST_OK = 255, // custom value, must not be sent to client
};
enum SpellCustomErrors
@@ -1099,38 +1252,80 @@ enum SpellCustomErrors
SPELL_CUSTOM_ERROR_GM_ONLY = 65, // Only GMs may use that. Your account has been reported for investigation.
SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_58 = 66, // You must reach level 58 to use this portal.
SPELL_CUSTOM_ERROR_AT_HONOR_CAP = 67, // You already have the maximum amount of honor.
- SPELL_CUSTOM_ERROR_68 = 68, // ""
- SPELL_CUSTOM_ERROR_69 = 69, // ""
- SPELL_CUSTOM_ERROR_70 = 70, // ""
- SPELL_CUSTOM_ERROR_71 = 71, // ""
- SPELL_CUSTOM_ERROR_72 = 72, // ""
- SPELL_CUSTOM_ERROR_73 = 73, // ""
- SPELL_CUSTOM_ERROR_74 = 74, // ""
+ SPELL_CUSTOM_ERROR_HAVE_HOT_ROD = 68, // You already have a Hot Rod.
+ SPELL_CUSTOM_ERROR_PARTYGOER_MORE_BUBBLY = 69, // This partygoer wants some more bubbly
+ SPELL_CUSTOM_ERROR_PARTYGOER_NEED_BUCKET = 70, // This partygoer needs a bucket!
+ SPELL_CUSTOM_ERROR_PARTYGOER_WANT_TO_DANCE = 71, // This partygoer wants to dance with you.
+ SPELL_CUSTOM_ERROR_PARTYGOER_WANT_FIREWORKS = 72, // This partygoer wants to see some fireworks.
+ SPELL_CUSTOM_ERROR_PARTYGOER_WANT_APPETIZER = 73, // This partygoer wants some more hors d'oeuvres.
+ SPELL_CUSTOM_ERROR_GOBLIN_BATTERY_DEPLETED = 74, // The Goblin All-In-1-Der Belt's battery is depleted.
SPELL_CUSTOM_ERROR_MUST_HAVE_DEMONIC_CIRCLE = 75, // You must have a demonic circle active.
SPELL_CUSTOM_ERROR_AT_MAX_RAGE = 76, // You already have maximum rage
SPELL_CUSTOM_ERROR_REQUIRES_350_ENGINEERING = 77, // Requires Engineering (350)
SPELL_CUSTOM_ERROR_SOUL_BELONGS_TO_LICH_KING = 78, // Your soul belongs to the Lich King
SPELL_CUSTOM_ERROR_ATTENDANT_HAS_PONY = 79, // Your attendant already has an Argent Pony
- SPELL_CUSTOM_ERROR_80 = 80, // ""
- SPELL_CUSTOM_ERROR_81 = 81, // ""
- SPELL_CUSTOM_ERROR_82 = 82, // ""
+ SPELL_CUSTOM_ERROR_GOBLIN_STARTING_MISSION = 80, // First, Overload the Defective Generator, Activate the Leaky Stove, and Drop a Cigar on the Flammable Bed.
+ SPELL_CUSTOM_ERROR_GASBOT_ALREADY_SENT = 81, // You've already sent in the Gasbot and destroyed headquarters!
+ SPELL_CUSTOM_ERROR_GOBLIN_IS_PARTIED_OUT = 82, // This goblin is all partied out!
SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM = 83, // You must have a Fire Totem active.
SPELL_CUSTOM_ERROR_CANT_TARGET_VAMPIRES = 84, // You may not bite other vampires.
SPELL_CUSTOM_ERROR_PET_ALREADY_AT_YOUR_LEVEL = 85, // Your pet is already at your level.
SPELL_CUSTOM_ERROR_MISSING_ITEM_REQUIREMENS = 86, // You do not meet the level requirements for this item.
SPELL_CUSTOM_ERROR_TOO_MANY_ABOMINATIONS = 87, // There are too many Mutated Abominations.
SPELL_CUSTOM_ERROR_ALL_POTIONS_USED = 88, // The potions have all been depleted by Professor Putricide.
- SPELL_CUSTOM_ERROR_89 = 89, // ""
+ SPELL_CUSTOM_ERROR_DEFEATED_ENOUGH_ALREADY = 89, // You have already defeated enough of them.
SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_65 = 90, // Requires level 65
- SPELL_CUSTOM_ERROR_91 = 91, // ""
- SPELL_CUSTOM_ERROR_92 = 92, // ""
- SPELL_CUSTOM_ERROR_93 = 93, // ""
- SPELL_CUSTOM_ERROR_94 = 94, // ""
- SPELL_CUSTOM_ERROR_95 = 95, // ""
+ SPELL_CUSTOM_ERROR_DESTROYED_KTC_OIL_PLATFORM = 91, // You have already destroyed the KTC Oil Platform.
+ SPELL_CUSTOM_ERROR_LAUNCHED_ENOUGH_CAGES = 92, // You have already launched enough cages.
+ SPELL_CUSTOM_ERROR_REQUIRES_BOOSTER_ROCKETS = 93, // Requires Single-Stage Booster Rockets. Return to Hobart Grapplehammer to get more.
+ SPELL_CUSTOM_ERROR_ENOUGH_WILD_CLUCKERS = 94, // You have already captured enough wild cluckers.
+ SPELL_CUSTOM_ERROR_REQUIRES_CONTROL_FIREWORKS = 95, // Requires Remote Control Fireworks. Return to Hobart Grapplehammer to get more.
SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_RECRUITS = 96, // You already have the max number of recruits.
SPELL_CUSTOM_ERROR_MAX_NUMBER_OF_VOLUNTEERS = 97, // You already have the max number of volunteers.
SPELL_CUSTOM_ERROR_FROSTMOURNE_RENDERED_RESSURECT = 98, // Frostmourne has rendered you unable to ressurect.
- SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99 // You can't mount while affected by that shapeshift.
+ SPELL_CUSTOM_ERROR_CANT_MOUNT_WITH_SHAPESHIFT = 99, // You can't mount while affected by that shapeshift.
+ SPELL_CUSTOM_ERROR_FAWNS_ALREADY_FOLLOWING = 100, // Three fawns are already following you!
+ SPELL_CUSTOM_ERROR_ALREADY_HAVE_RIVER_BOAT = 101, // You already have a River Boat.
+ SPELL_CUSTOM_ERROR_NO_ACTIVE_ENCHANTMENT = 102, // You have no active enchantment to unleash.
+ SPELL_CUSTOM_ERROR_ENOUGH_HIGHBOURNE_SOULS = 103, // You have bound enough Highborne souls. Return to Arcanist Valdurian.
+ SPELL_CUSTOM_ERROR_ATLEAST_40YD_FROM_OIL_DRILLING = 104, // You must be at least 40 yards away from all other Oil Drilling Rigs.
+ SPELL_CUSTOM_ERROR_ABOVE_ENSLAVED_PEARL_MINER = 106, // You must be above the Enslaved Pearl Miner.
+ SPELL_CUSTOM_ERROR_MUST_TARGET_CORPSE_SPECIAL_1 = 107, // You must target the corpse of a Seabrush Terrapin, Scourgut Remora, or Spinescale Hammerhead.
+ SPELL_CUSTOM_ERROR_SLAGHAMMER_ALREADY_PRISONER = 108, // Ambassador Slaghammer is already your prisoner.
+ SPELL_CUSTOM_ERROR_REQUIRE_ATTUNED_LOCATION_1 = 109, // Requires a location that is attuned with the Naz'jar Battlemaiden.
+ SPELL_CUSTOM_ERROR_NEED_TO_FREE_DRAKE_FIRST = 110, // Free the Drake from the net first!
+ SPELL_CUSTOM_ERROR_DRAGONMAW_ALLIES_ALREADY_FOLLOW = 111, // You already have three Dragonmaw allies following you.
+ SPELL_CUSTOM_ERROR_REQUIRE_OPPOSABLE_THUMBS = 112, // Requires Opposable Thumbs.
+ SPELL_CUSTOM_ERROR_NOT_ENOUGH_HEALTH_2 = 113, // Not enough health
+ SPELL_CUSTOM_ERROR_ENOUGH_FORSAKEN_TROOPERS = 114, // You already have enough Forsaken Troopers.
+ SPELL_CUSTOM_ERROR_CANNOT_JUMP_TO_BOULDER = 115, // You cannot jump to another boulder yet.
+ SPELL_CUSTOM_ERROR_SKILL_TOO_HIGH = 116, // Skill too high.
+ SPELL_CUSTOM_ERROR_ALREADY_6_SURVIVORS_RESCUED = 117, // You have already rescued 6 Survivors.
+ SPELL_CUSTOM_ERROR_MUST_FACE_SHIPS_FROM_BALLOON = 118, // You need to be facing the ships from the rescue balloon.
+ SPELL_CUSTOM_ERROR_CANNOT_SUPERVISE_MORE_CULTISTS = 119, // You cannot supervise more than 5 Arrested Cultists at a time.
+ SPELL_CUSTOM_ERROR_REQUIRES_LEVEL_85 = 120, // You must reach level 85 to use this portal.
+ SPELL_CUSTOM_ERROR_MUST_BE_BELOW_35_HEALTH = 121, // Your target must be below 35% health.
+ SPELL_CUSTOM_ERROR_MUST_SELECT_TALENT_SPECIAL = 122, // You must select a talent specialization first.
+ SPELL_CUSTOM_ERROR_TOO_WISE_AND_POWERFUL = 123, // You are too wise and powerful to gain any benefit from that item.
+ SPELL_CUSTOM_ERROR_TOO_CLOSE_ARGENT_LIGHTWELL = 124, // You are within 10 yards of another Argent Lightwell.
+ SPELL_CUSTOM_ERROR_NOT_WHILE_SHAPESHIFTED = 125, // You can't do that while shapeshifted.
+ SPELL_CUSTOM_ERROR_MANA_GEM_IN_BANK = 126, // You already have a Mana Gem in your bank.
+ SPELL_CUSTOM_ERROR_FLAME_SHOCK_NOT_ACTIVE = 127, // You must have at least one Flame Shock active.
+ SPELL_CUSTOM_ERROR_CANT_TRANSFORM = 128, // You cannot transform right now
+ SPELL_CUSTOM_ERROR_PET_MUST_BE_ATTACKING = 129, // Your pet must be attacking a target.
+ SPELL_CUSTOM_ERROR_GNOMISH_ENGINEERING = 130, // Requires Gnomish Engineering
+ SPELL_CUSTOM_ERROR_GOBLIN_ENGINEERING = 131, // Requires Goblin Engineering
+ SPELL_CUSTOM_ERROR_NO_TARGET = 132, // You have no target.
+ SPELL_CUSTOM_ERROR_PET_OUT_OF_RANGE = 133, // Your Pet is out of range of the target.
+ SPELL_CUSTOM_ERROR_HOLDING_FLAG = 134, // You can't do that while holding the flag.
+ SPELL_CUSTOM_ERROR_TARGET_HOLDING_FLAG = 135, // You can't do that to targets holding the flag.
+ SPELL_CUSTOM_ERROR_PORTAL_NOT_OPEN = 136, // The portal is not yet open. Continue helping the druids at the Sanctuary of Malorne.
+ SPELL_CUSTOM_ERROR_AGGRA_AIR_TOTEM = 137, // You need to be closer to Aggra's Air Totem, in the west.
+ SPELL_CUSTOM_ERROR_AGGRA_WATER_TOTEM = 138, // You need to be closer to Aggra's Water Totem, in the north.
+ SPELL_CUSTOM_ERROR_AGGRA_EARTH_TOTEM = 139, // You need to be closer to Aggra's Earth Totem, in the east.
+ SPELL_CUSTOM_ERROR_AGGRA_FIRE_TOTEM = 140, // You need to be closer to Aggra's Fire Totem, near Thrall.
+ SPELL_CUSTOM_ERROR_TARGET_HAS_STARTDUST_2 = 148, // Target is already affected by Stardust No. 2.
+ SPELL_CUSTOM_ERROR_ELEMENTIUM_GEM_CLUSTERS = 149 // You cannot deconstruct Elementium Gem Clusters while collecting them!
};
enum StealthType
@@ -1242,14 +1437,15 @@ enum Mechanics
MECHANIC_IMMUNE_SHIELD = 29, // Divine (Blessing) Shield/Protection and Ice Block
MECHANIC_SAPPED = 30,
MECHANIC_ENRAGED = 31,
- MAX_MECHANIC = 32
+ MECHANIC_WOUNDED = 32,
+ MAX_MECHANIC = 33
};
// Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967ca6)
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK (\
(1<<MECHANIC_CHARM)|(1<<MECHANIC_DISORIENTED)|(1<<MECHANIC_FEAR)| \
(1<<MECHANIC_ROOT)|(1<<MECHANIC_SLEEP)|(1<<MECHANIC_SNARE)| \
- (1<<MECHANIC_STUN)|(1<<MECHANIC_FREEZE)|(1<<MECHANIC_KNOCKOUT)| \
+ (1<<MECHANIC_STUN)|(1<<MECHANIC_FREEZE)|(1<<MECHANIC_SILENCE)|(1<<MECHANIC_DISARM)|(1<<MECHANIC_KNOCKOUT)| \
(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)|(1<<MECHANIC_SHACKLE)| \
(1<<MECHANIC_TURN)|(1<<MECHANIC_HORROR)|(1<<MECHANIC_DAZE)| \
(1<<MECHANIC_SAPPED))
@@ -1398,6 +1594,23 @@ enum Targets
TARGET_UNK_DEST_AREA_UNK_107 = 107, // not enough info - only generic spells avalible
TARGET_GAMEOBJECT_CONE = 108,
TARGET_DEST_UNK_110 = 110, // 1 spell
+ TARGET_UNK_111 = 111,
+ TARGET_UNK_112 = 112,
+ TARGET_UNK_113 = 113,
+ TARGET_UNK_114 = 114,
+ TARGET_UNK_115 = 115,
+ TARGET_UNK_116 = 116,
+ TARGET_UNK_117 = 117,
+ TARGET_UNK_118 = 118,
+ TARGET_UNK_119 = 119,
+ TARGET_UNK_120 = 120,
+ TARGET_UNK_121 = 121,
+ TARGET_UNK_122 = 122,
+ TARGET_UNK_123 = 123,
+ TARGET_UNK_124 = 124,
+ TARGET_UNK_125 = 125,
+ TARGET_UNK_126 = 126,
+ TARGET_UNK_127 = 127,
TOTAL_SPELL_TARGETS
};
@@ -1439,7 +1652,8 @@ enum SpellPreventionType
{
SPELL_PREVENTION_TYPE_NONE = 0,
SPELL_PREVENTION_TYPE_SILENCE = 1,
- SPELL_PREVENTION_TYPE_PACIFY = 2
+ SPELL_PREVENTION_TYPE_PACIFY = 2,
+ SPELL_PREVENTION_TYPE_UNK = 3 // Only a few spells have this, but most of the should be interruptable.
};
enum GameobjectTypes
@@ -1483,7 +1697,7 @@ enum GameobjectTypes
};
#define MAX_GAMEOBJECT_TYPE 36 // sending to client this or greater value can crash client.
-#define MAX_GAMEOBJECT_DATA 24 // Max number of uint32 vars in gameobject_template data field
+#define MAX_GAMEOBJECT_DATA 32 // Max number of uint32 vars in gameobject_template data field
enum GameObjectFlags
{
@@ -1769,7 +1983,8 @@ enum TextEmotes
TEXT_EMOTE_LOOK = 449,
TEXT_EMOTE_OBJECT = 450,
TEXT_EMOTE_SWEAT = 451,
- TEXT_EMOTE_YW = 453
+ TEXT_EMOTE_YW = 453,
+ TEXT_EMOTE_READ = 456
};
// Emotes.dbc
@@ -1949,7 +2164,19 @@ enum Emote
EMOTE_STATE_STRANGULATE = 473,
EMOTE_STATE_READY_SPELL_OMNI = 474,
EMOTE_STATE_HOLD_JOUST = 475,
- EMOTE_ONESHOT_CRY_JAINA = 476
+ EMOTE_ONESHOT_CRY_JAINA = 476,
+ EMOTE_ONESHOT_SPECIAL_UNARMED = 477,
+ EMOTE_STATE_DANCE_NOSHEATHE = 478,
+ EMOTE_ONESHOT_SNIFF = 479,
+ EMOTE_ONESHOT_DRAGONSTOMP = 480,
+ EMOTE_ONESHOT_KNOCKDOWN = 482,
+ EMOTE_STATE_READ = 483,
+ EMOTE_ONESHOT_FLYEMOTETALK = 485,
+ EMOTE_STATE_READ_ALLOWMOVEMENT = 492,
+ EMOTE_STATE_READY1H_ALLOW_MOVEMENT = 505,
+ EMOTE_STATE_READY2H_ALLOW_MOVEMENT = 506,
+ EMOTE_ONESHOT_OPEN = 517,
+ EMOTE_STATE_READ_CHRISTMAS = 518
};
// AnimationData.dbc
@@ -2460,7 +2687,161 @@ enum Anim
ANIM_CARRY2H = 502,
ANIM_CARRIED2H = 503,
ANIM_FLY_CARRY2H = 504,
- ANIM_FLY_CARRIED2H = 505
+ ANIM_FLY_CARRIED2H = 505,
+ ANIM_EMOTE_SNIFF = 506,
+ ANIM_EMOTE_FLY_SNIFF = 507,
+ ANIM_ATTACK_FIST1H = 508,
+ ANIM_FLY_ATTACK_FIST1H = 509,
+ ANIM_ATTACK_FIST_1H_OFF = 510,
+ ANIM_FLY_ATTACK_FIST_1H_OFF = 511,
+ ANIM_PARRY_FIST1H = 512,
+ ANIM_FLY_PARRY_FIST1H = 513,
+ ANIM_READY_FIST1H = 514,
+ ANIM_FLY_READY_FIST1H = 515,
+ ANIM_SPECIAL_FIST1H = 516,
+ ANIM_FLY_SPECIAL_FIST1H = 517,
+ ANIM_EMOTE_READ_START = 518,
+ ANIM_FLY_EMOTE_READ_START = 519,
+ ANIM_EMOTE_READ_LOOP = 520,
+ ANIM_FLY_EMOTE_READ_LOOP = 521,
+ ANIM_EMOTE_READ_END = 522,
+ ANIM_FLY_EMOTE_READ_END = 523,
+ ANIM_SWIM_RUN = 524,
+ ANIM_FLY_SWIM_RUN = 525,
+ ANIM_SWIM_WALK = 526,
+ ANIM_FLY_SWIM_WALK = 527,
+ ANIM_SWIM_WALK_BACKWARDS = 528,
+ ANIM_FLY_SWIM_WALK_BACKWARDS = 529,
+ ANIM_SWIM_SPRINT = 530,
+ ANIM_FLY_SWIM_SPRINT = 531,
+ ANIM_MOUNT_SWIM_IDLE = 532,
+ ANIM_FLY_MOUNT_SWIM_IDLE = 533,
+ ANIM_MOUNT_SWIM_BACKWARDS = 534,
+ ANIM_FLY_MOUNT_SWIM_BACKWARDS = 535,
+ ANIM_MOUNT_SWIM_LEFT = 536,
+ ANIM_FLY_MOUNT_SWIM_LEFT = 537,
+ ANIM_MOUNT_SWIM_RIGHT = 538,
+ ANIM_FLY_MOUNT_SWIM_RIGHT = 539,
+ ANIM_MOUNT_SWIM_RUN = 540,
+ ANIM_FLY_MOUNT_SWIM_RUN = 541,
+ ANIM_MOUNT_SWIM_SPRINT = 542,
+ ANIM_FLY_MOUNT_SWIM_SPRINT = 543,
+ ANIM_MOUNT_SWIM_WALK = 544,
+ ANIM_FLY_MOUNT_SWIM_WALK = 545,
+ ANIM_MOUNT_SWIM_WALK_BACKWARDS = 546,
+ ANIM_FLY_MOUNT_SWIM_WALK_BACKWARDS = 547,
+ ANIM_MOUNT_FLIGHT_IDLE = 548,
+ ANIM_FLY_MOUNT_FLIGHT_IDLE = 549,
+ ANIM_MOUNT_FLIGHT_BACKWARDS = 550,
+ ANIM_FLY_MOUNT_FLIGHT_BACKWARDS = 551,
+ ANIM_MOUNT_FLIGHT_LEFT = 552,
+ ANIM_FLY_MOUNT_FLIGHT_LEFT = 553,
+ ANIM_MOUNT_FLIGHT_RIGHT = 554,
+ ANIM_FLY_MOUNT_FLIGHT_RIGHT = 555,
+ ANIM_MOUNT_FLIGHT_RUN = 556,
+ ANIM_FLY_MOUNT_FLIGHT_RUN = 557,
+ ANIM_MOUNT_FLIGHT_SPRINT = 558,
+ ANIM_FLY_MOUNT_FLIGHT_SPRINT = 559,
+ ANIM_MOUNT_FLIGHT_WALK = 560,
+ ANIM_FLY_MOUNT_FLIGHT_WALK = 561,
+ ANIM_MOUNT_FLIGHT_WALK_BACKWARDS = 562,
+ ANIM_FLY_MOUNT_FLIGHT_WALK_BACKWARDS = 563,
+ ANIM_MOUNT_FLIGHT_START = 564,
+ ANIM_FLY_MOUNT_FLIGHT_START = 565,
+ ANIM_MOUNT_SWIM_START = 566,
+ ANIM_FLY_MOUNT_SWIM_START = 567,
+ ANIM_MOUNT_SWIM_LAND = 568,
+ ANIM_FLY_MOUNT_SWIM_LAND = 569,
+ ANIM_MOUNT_SWIM_LAND_RUN = 570,
+ ANIM_FLY_MOUNT_SWIM_LAND_RUN = 571,
+ ANIM_MOUNT_FLIGHT_LAND = 572,
+ ANIM_FLY_MOUNT_FLIGHT_LAND = 573,
+ ANIM_MOUNT_FLIGHT_LAND_RUN = 574,
+ ANIM_FLY_MOUNT_FLIGHT_LAND_RUN = 575,
+ ANIM_READY_BLOW_DART = 576,
+ ANIM_FLY_READY_BLOW_DART = 577,
+ ANIM_LOAD_BLOW_DART = 578,
+ ANIM_FLY_LOAD_BLOW_DART = 579,
+ ANIM_HOLD_BLOW_DART = 580,
+ ANIM_FLY_HOLD_BLOW_DART = 581,
+ ANIM_ATTACK_BLOW_DART = 582,
+ ANIM_FLY_ATTACK_BLOW_DART = 583,
+ ANIM_CARRIAGE_MOUNT = 584,
+ ANIM_FLY_CARRIAGE_MOUNT = 585,
+ ANIM_CARRIAGE_PASSENGER_MOUNT = 586,
+ ANIM_FLY_CARRIAGE_PASSENGER_MOUNT = 587,
+ ANIM_CARRIAGE_MOUNT_ATTACK = 588,
+ ANIM_FLY_CARRIAGE_MOUNT_ATTACK = 589,
+ ANIM_BARTENDER_STAND = 590,
+ ANIM_FLY_BARTENDER_STAND = 591,
+ ANIM_BARTENDER_WALK = 592,
+ ANIM_FLY_BARTENDER_WALK = 593,
+ ANIM_BARTENDER_RUN = 594,
+ ANIM_FLY_BARTENDER_RUN = 595,
+ ANIM_BARTENDER_SHUFFLE_LEFT = 596,
+ ANIM_FLY_BARTENDER_SHUFFLE_LEFT = 597,
+ ANIM_BARTENDER_SHUFFLE_RIGHT = 598,
+ ANIM_FLY_BARTENDER_SHUFFLE_RIGHT = 599,
+ ANIM_BARTENDER_EMOTE_TALK = 600,
+ ANIM_FLY_BARTENDER_EMOTE_TALK = 601,
+ ANIM_BARTENDER_EMOTE_POINT = 602,
+ ANIM_FLY_BARTENDER_EMOTE_POINT = 603,
+ ANIM_BARMAID_STAND = 604,
+ ANIM_FLY_BARMAID_STAND = 605,
+ ANIM_BARMAID_WALK = 606,
+ ANIM_FLY_BARMAID_WALK = 607,
+ ANIM_BARMAID_RUN = 608,
+ ANIM_FLY_BARMAID_RUN = 609,
+ ANIM_BARMAID_SHUFFLE_LEFT = 610,
+ ANIM_FLY_BARMAID_SHUFFLE_LEFT = 611,
+ ANIM_BARMAID_SHUFFLE_RIGHT = 612,
+ ANIM_FLY_BARMAID_SHUFFLE_RIGHT = 613,
+ ANIM_BARMAID_EMOTE_TALK = 614,
+ ANIM_FLY_BARMAID_EMOTE_TALK = 615,
+ ANIM_BARMAID_EMOTE_POINT = 616,
+ ANIM_FLY_BARMAID_EMOTE_POINT = 617,
+ ANIM_MOUNT_SELF_IDLE = 618,
+ ANIM_FLY_MOUNT_SELF_IDLE = 619,
+ ANIM_MOUNT_SELF_WALK = 620,
+ ANIM_FLY_MOUNT_SELF_WALK = 621,
+ ANIM_MOUNT_SELF_RUN = 622,
+ ANIM_FLY_MOUNT_SELF_RUN = 623,
+ ANIM_MOUNT_SELF_SPRINT = 624,
+ ANIM_FLY_MOUNT_SELF_SPRINT = 625,
+ ANIM_MOUNT_SELF_RUN_LEFT = 626,
+ ANIM_FLY_MOUNT_SELF_RUN_LEFT = 627,
+ ANIM_MOUNT_SELF_RUN_RIGHT = 628,
+ ANIM_FLY_MOUNT_SELF_RUN_RIGHT = 629,
+ ANIM_MOUNT_SELF_SHUFFLE_LEFT = 630,
+ ANIM_FLY_MOUNT_SELF_SHUFFLE_LEFT = 631,
+ ANIM_MOUNT_SELF_SHUFFLE_RIGHT = 632,
+ ANIM_FLY_MOUNT_SELF_SHUFFLE_RIGHT = 633,
+ ANIM_MOUNT_SELF_WALK_BACKWARDS = 634,
+ ANIM_FLY_MOUNT_SELF_WALK_BACKWARDS = 635,
+ ANIM_MOUNT_SELF_SPECIAL = 636,
+ ANIM_FLY_MOUNT_SELF_SPECIAL = 637,
+ ANIM_MOUNT_SELF_JUMP = 638,
+ ANIM_FLY_MOUNT_SELF_JUMP = 639,
+ ANIM_MOUNT_SELF_JUMP_START = 640,
+ ANIM_FLY_MOUNT_SELF_JUMP_START = 641,
+ ANIM_MOUNT_SELF_JUMP_END = 642,
+ ANIM_FLY_MOUNT_SELF_JUMP_END = 643,
+ ANIM_MOUNT_SELF_JUMP_LAND_RUN = 644,
+ ANIM_FLY_MOUNT_SELF_JUMP_LAND_RUN = 645,
+ ANIM_MOUNT_SELF_START = 646,
+ ANIM_FLY_MOUNT_SELF_START = 647,
+ ANIM_MOUNT_SELF_FALL = 648,
+ ANIM_FLY_MOUNT_SELF_FALL = 649,
+ ANIM_STORMSTRIKE = 650,
+ ANIM_FLY_STORMSTRIKE = 651,
+ ANIM_READY_JOUST_NO_SHEATHE = 652,
+ ANIM_FLY_READY_JOUST_NO_SHEATHE = 653,
+ ANIM_SLAM = 654,
+ ANIM_FLY_SLAM = 655,
+ ANIM_DEATH_STRIKE = 656,
+ ANIM_FLY_DEATH_STRIKE = 657,
+ ANIM_SWIM_ATTACK_UNARMED = 658,
+ ANIM_FLY_SWIM_ATTACK_UNARMED = 659
};
enum LockKeyType
@@ -2570,7 +2951,18 @@ enum CreatureFamily
CREATURE_FAMILY_RHINO = 43,
CREATURE_FAMILY_WASP = 44,
CREATURE_FAMILY_CORE_HOUND = 45,
- CREATURE_FAMILY_SPIRIT_BEAST = 46
+ CREATURE_FAMILY_SPIRIT_BEAST = 46,
+ CREATURE_FAMILY_WATER_ELEMENTAL = 49,
+ CREATURE_FAMILY_FOX = 50,
+ CREATURE_FAMILY_MONKEY = 51,
+ CREATURE_FAMILY_DOG = 52,
+ CREATURE_FAMILY_BEETLE = 53,
+ CREATURE_FAMILY_SHALE_SPIDER = 55,
+ CREATURE_FAMILY_ZOMBIE = 56,
+ CREATURE_FAMILY_BEETLE_OLD = 57,
+ CREATURE_FAMILY_SILITHID_2 = 59,
+ CREATURE_FAMILY_WASP_2 = 66,
+ CREATURE_FAMILY_HYDRA = 68,
};
enum CreatureTypeFlags
@@ -2609,6 +3001,18 @@ enum CreatureTypeFlags
CREATURE_TYPEFLAGS_UNK31 = 0x80000000
};
+enum CreatureTypeFlags2
+{
+ CREATURE_TYPEFLAGS_2_UNK1 = 0x00000001,
+ CREATURE_TYPEFLAGS_2_UNK2 = 0x00000002,
+ CREATURE_TYPEFLAGS_2_UNK3 = 0x00000004,
+ CREATURE_TYPEFLAGS_2_UNK4 = 0x00000008,
+ CREATURE_TYPEFLAGS_2_UNK5 = 0x00000010,
+ CREATURE_TYPEFLAGS_2_UNK6 = 0x00000020,
+ CREATURE_TYPEFLAGS_2_UNK7 = 0x00000040,
+ CREATURE_TYPEFLAGS_2_UNK8 = 0x00000080
+};
+
enum CreatureEliteType
{
CREATURE_ELITE_NORMAL = 0,
@@ -2649,7 +3053,14 @@ enum HolidayIds
HOLIDAY_DAY_OF_DEAD = 409,
HOLIDAY_CALL_TO_ARMS_IC = 420,
HOLIDAY_LOVE_IS_IN_THE_AIR = 423,
- HOLIDAY_KALU_AK_FISHING_DERBY = 424
+ HOLIDAY_KALU_AK_FISHING_DERBY = 424,
+ HOLIDAY_CALL_TO_ARMS_BFG = 435,
+ HOLIDAY_CALL_TO_ARMS_TP = 436,
+ HOLIDAY_RATED_BG_15_VS_15 = 442,
+ HOLIDAY_RATED_BG_25_VS_25 = 443,
+ HOLIDAY_ANNIVERSARY_7_YEARS = 467,
+ HOLIDAY_DARKMOON_FAIRE_TEROKKAR = 479,
+ HOLIDAY_ANNIVERSARY_8_YEARS = 484
};
// values based at QuestInfo.dbc
@@ -2711,7 +3122,12 @@ enum QuestSort
QUEST_SORT_JEWELCRAFTING = 373,
QUEST_SORT_NOBLEGARDEN = 374,
QUEST_SORT_PILGRIMS_BOUNTY = 375,
- QUEST_SORT_LOVE_IS_IN_THE_AIR = 376
+ QUEST_SORT_LOVE_IS_IN_THE_AIR = 376,
+ QUEST_SORT_ARCHAEOLOGY = 377,
+ QUEST_SORT_CHILDRENS_WEEK = 378,
+ QUEST_SORT_FIRELANDS_INVASION = 379,
+ QUEST_SORT_ZANDALARI = 380,
+ QUEST_SORT_ELEMENTAL_BONDS = 381
};
inline uint8 ClassByQuestSort(int32 QuestSort)
@@ -2857,7 +3273,7 @@ enum SkillType
SKILL_RACIAL_HUMAN = 754,
SKILL_JEWELCRAFTING = 755,
SKILL_RACIAL_BLOODELF = 756,
- SKILL_PET_EVENT_RC = 758,
+ SKILL_PET_EVENT_RC = 758, // SkillCategory = -1
SKILL_LANG_DRAENEI = 759,
SKILL_RACIAL_DRAENEI = 760,
SKILL_PET_FELGUARD = 761,
@@ -2885,10 +3301,34 @@ enum SkillType
SKILL_PET_WASP = 785,
SKILL_PET_EXOTIC_RHINO = 786,
SKILL_PET_EXOTIC_CORE_HOUND = 787,
- SKILL_PET_EXOTIC_SPIRIT_BEAST = 788
+ SKILL_PET_EXOTIC_SPIRIT_BEAST = 788,
+ SKILL_RACIAL_WORGEN = 789,
+ SKILL_RACIAL_GOBLIN = 790,
+ SKILL_LANG_WORGEN = 791,
+ SKILL_LANG_GOBLIN = 792,
+ SKILL_ARCHAEOLOGY = 794,
+ SKILL_GENERAL_HUNTER = 795,
+ SKILL_GENERAL_DEATH_KNIGHT = 796,
+ SKILL_GENERAL_ROGUE = 797,
+ SKILL_GENERAL_DRUID = 798,
+ SKILL_GENERAL_MAGE = 799,
+ SKILL_GENERAL_PALADIN = 800,
+ SKILL_GENERAL_SHAMAN = 801,
+ SKILL_GENERAL_WARLOCK = 802,
+ SKILL_GENERAL_WARRIOR = 803,
+ SKILL_GENERAL_PRIEST = 804,
+ SKILL_PET_WATER_ELEMENTAL = 805,
+ SKILL_PET_FOX = 808,
+ SKILL_ALL_GLYPHS = 810,
+ SKILL_PET_DOG = 811,
+ SKILL_PET_MONKEY = 815,
+ SKILL_PET_SHALE_SPIDER = 817,
+ SKILL_PET_BEETLE = 818,
+ SKILL_ALL_GUILD_PERKS = 821,
+ SKILL_PET_HYDRA = 824
};
-#define MAX_SKILL_TYPE 789
+#define MAX_SKILL_TYPE 825
inline SkillType SkillByLockType(LockType locktype)
{
@@ -2919,12 +3359,14 @@ inline uint32 SkillByQuestSort(int32 QuestSort)
case QUEST_SORT_FIRST_AID: return SKILL_FIRST_AID;
case QUEST_SORT_JEWELCRAFTING: return SKILL_JEWELCRAFTING;
case QUEST_SORT_INSCRIPTION: return SKILL_INSCRIPTION;
+ case QUEST_SORT_ARCHAEOLOGY: return SKILL_ARCHAEOLOGY;
}
return 0;
}
enum SkillCategory
{
+ SKILL_CATEGORY_UNK1 = 0,
SKILL_CATEGORY_ATTRIBUTES = 5,
SKILL_CATEGORY_WEAPON = 6,
SKILL_CATEGORY_CLASS = 7,
@@ -2968,7 +3410,9 @@ enum TotemCategory
TC_BLADED_PICKAXE = 168,
TC_FLINT_AND_TINDER = 169,
TC_RUNED_COBALT_ROD = 189,
- TC_RUNED_TITANIUM_ROD = 190
+ TC_RUNED_TITANIUM_ROD = 190,
+ TC_RUNED_ELEMENTIUM_ROD = 209,
+ TC_HIGH_POWERED_BOLT_GUN = 210,
};
enum UnitDynFlags
@@ -3003,62 +3447,75 @@ enum WeatherType
enum ChatMsg
{
- CHAT_MSG_ADDON = 0xFFFFFFFF, // -1
- CHAT_MSG_SYSTEM = 0x00,
- CHAT_MSG_SAY = 0x01,
- CHAT_MSG_PARTY = 0x02,
- CHAT_MSG_RAID = 0x03,
- CHAT_MSG_GUILD = 0x04,
- CHAT_MSG_OFFICER = 0x05,
- CHAT_MSG_YELL = 0x06,
- CHAT_MSG_WHISPER = 0x07,
- CHAT_MSG_WHISPER_FOREIGN = 0x08,
- CHAT_MSG_WHISPER_INFORM = 0x09,
- CHAT_MSG_EMOTE = 0x0A,
- CHAT_MSG_TEXT_EMOTE = 0x0B,
- CHAT_MSG_MONSTER_SAY = 0x0C,
- CHAT_MSG_MONSTER_PARTY = 0x0D,
- CHAT_MSG_MONSTER_YELL = 0x0E,
- CHAT_MSG_MONSTER_WHISPER = 0x0F,
- CHAT_MSG_MONSTER_EMOTE = 0x10,
- CHAT_MSG_CHANNEL = 0x11,
- CHAT_MSG_CHANNEL_JOIN = 0x12,
- CHAT_MSG_CHANNEL_LEAVE = 0x13,
- CHAT_MSG_CHANNEL_LIST = 0x14,
- CHAT_MSG_CHANNEL_NOTICE = 0x15,
- CHAT_MSG_CHANNEL_NOTICE_USER = 0x16,
- CHAT_MSG_AFK = 0x17,
- CHAT_MSG_DND = 0x18,
- CHAT_MSG_IGNORED = 0x19,
- CHAT_MSG_SKILL = 0x1A,
- CHAT_MSG_LOOT = 0x1B,
- CHAT_MSG_MONEY = 0x1C,
- CHAT_MSG_OPENING = 0x1D,
- CHAT_MSG_TRADESKILLS = 0x1E,
- CHAT_MSG_PET_INFO = 0x1F,
- CHAT_MSG_COMBAT_MISC_INFO = 0x20,
- CHAT_MSG_COMBAT_XP_GAIN = 0x21,
- CHAT_MSG_COMBAT_HONOR_GAIN = 0x22,
- CHAT_MSG_COMBAT_FACTION_CHANGE = 0x23,
- CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x24,
- CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x25,
- CHAT_MSG_BG_SYSTEM_HORDE = 0x26,
- CHAT_MSG_RAID_LEADER = 0x27,
- CHAT_MSG_RAID_WARNING = 0x28,
- CHAT_MSG_RAID_BOSS_EMOTE = 0x29,
- CHAT_MSG_RAID_BOSS_WHISPER = 0x2A,
- CHAT_MSG_FILTERED = 0x2B,
- CHAT_MSG_BATTLEGROUND = 0x2C,
- CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
- CHAT_MSG_RESTRICTED = 0x2E,
- CHAT_MSG_BATTLENET = 0x2F,
- CHAT_MSG_ACHIEVEMENT = 0x30,
- CHAT_MSG_GUILD_ACHIEVEMENT = 0x31,
- CHAT_MSG_ARENA_POINTS = 0x32,
- CHAT_MSG_PARTY_LEADER = 0x33
-};
-
-#define MAX_CHAT_MSG_TYPE 0x34
+ CHAT_MSG_ADDON = 0xFFFFFFFF, // -1
+ CHAT_MSG_SYSTEM = 0x00,
+ CHAT_MSG_SAY = 0x01,
+ CHAT_MSG_PARTY = 0x02,
+ CHAT_MSG_RAID = 0x03,
+ CHAT_MSG_GUILD = 0x04,
+ CHAT_MSG_OFFICER = 0x05,
+ CHAT_MSG_YELL = 0x06,
+ CHAT_MSG_WHISPER = 0x07,
+ CHAT_MSG_WHISPER_FOREIGN = 0x08,
+ CHAT_MSG_WHISPER_INFORM = 0x09,
+ CHAT_MSG_EMOTE = 0x0A,
+ CHAT_MSG_TEXT_EMOTE = 0x0B,
+ CHAT_MSG_MONSTER_SAY = 0x0C,
+ CHAT_MSG_MONSTER_PARTY = 0x0D,
+ CHAT_MSG_MONSTER_YELL = 0x0E,
+ CHAT_MSG_MONSTER_WHISPER = 0x0F,
+ CHAT_MSG_MONSTER_EMOTE = 0x10,
+ CHAT_MSG_CHANNEL = 0x11,
+ CHAT_MSG_CHANNEL_JOIN = 0x12,
+ CHAT_MSG_CHANNEL_LEAVE = 0x13,
+ CHAT_MSG_CHANNEL_LIST = 0x14,
+ CHAT_MSG_CHANNEL_NOTICE = 0x15,
+ CHAT_MSG_CHANNEL_NOTICE_USER = 0x16,
+ CHAT_MSG_AFK = 0x17,
+ CHAT_MSG_DND = 0x18,
+ CHAT_MSG_IGNORED = 0x19,
+ CHAT_MSG_SKILL = 0x1A,
+ CHAT_MSG_LOOT = 0x1B,
+ CHAT_MSG_MONEY = 0x1C,
+ CHAT_MSG_OPENING = 0x1D,
+ CHAT_MSG_TRADESKILLS = 0x1E,
+ CHAT_MSG_PET_INFO = 0x1F,
+ CHAT_MSG_COMBAT_MISC_INFO = 0x20,
+ CHAT_MSG_COMBAT_XP_GAIN = 0x21,
+ CHAT_MSG_COMBAT_HONOR_GAIN = 0x22,
+ CHAT_MSG_COMBAT_FACTION_CHANGE = 0x23,
+ CHAT_MSG_BG_SYSTEM_NEUTRAL = 0x24,
+ CHAT_MSG_BG_SYSTEM_ALLIANCE = 0x25,
+ CHAT_MSG_BG_SYSTEM_HORDE = 0x26,
+ CHAT_MSG_RAID_LEADER = 0x27,
+ CHAT_MSG_RAID_WARNING = 0x28,
+ CHAT_MSG_RAID_BOSS_EMOTE = 0x29,
+ CHAT_MSG_RAID_BOSS_WHISPER = 0x2A,
+ CHAT_MSG_FILTERED = 0x2B,
+ CHAT_MSG_BATTLEGROUND = 0x2C,
+ CHAT_MSG_BATTLEGROUND_LEADER = 0x2D,
+ CHAT_MSG_RESTRICTED = 0x2E,
+ CHAT_MSG_BATTLENET = 0x2F,
+ CHAT_MSG_ACHIEVEMENT = 0x30,
+ CHAT_MSG_GUILD_ACHIEVEMENT = 0x31,
+ CHAT_MSG_ARENA_POINTS = 0x32,
+ CHAT_MSG_PARTY_LEADER = 0x33,
+ CHAT_MSG_TARGETICONS = 0x34,
+ CHAT_MSG_BN_WHISPER = 0x35,
+ CHAT_MSG_BN_WHISPER_INFORM = 0x36,
+ CHAT_MSG_BN_CONVERSATION = 0x37,
+ CHAT_MSG_BN_CONVERSATION_NOTICE = 0x38,
+ CHAT_MSG_BN_CONVERSATION_LIST = 0x39,
+ CHAT_MSG_BN_INLINE_TOAST_ALERT = 0x3A,
+ CHAT_MSG_BN_INLINE_TOAST_BROADCAST = 0x3B,
+ CHAT_MSG_BN_INLINE_TOAST_BROADCAST_INFORM = 0x3C,
+ CHAT_MSG_BN_INLINE_TOAST_CONVERSATION = 0x3D,
+ CHAT_MSG_BN_WHISPER_PLAYER_OFFLINE = 0x3E,
+ CHAT_MSG_COMBAT_GUILD_XP_GAIN = 0x3F,
+ CHAT_MSG_CURRENCY = 0x40
+};
+
+#define MAX_CHAT_MSG_TYPE 0x41
enum ChatLinkColors
{
@@ -3091,6 +3548,7 @@ enum GuildLogs
{
GUILD_BANKLOG_MAX_RECORDS = 25,
GUILD_EVENTLOG_MAX_RECORDS = 100,
+ GUILD_NEWSLOG_MAX_RECORDS = 250
};
enum AiReaction
@@ -3161,7 +3619,8 @@ enum SummonType
SUMMON_TYPE_VEHICLE = 9,
SUMMON_TYPE_VEHICLE2 = 10, // Oculus and Argent Tournament vehicles (3.3.5a)
SUMMON_TYPE_LIGHTWELL = 11,
- SUMMON_TYPE_JEEVES = 12
+ SUMMON_TYPE_JEEVES = 12,
+ SUMMON_TYPE_UNK13 = 13
};
enum EventId
@@ -3260,36 +3719,38 @@ enum ResponseCodes
CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER = 73,
CHAR_DELETE_FAILED_GUILD_LEADER = 74,
CHAR_DELETE_FAILED_ARENA_CAPTAIN = 75,
-
- CHAR_LOGIN_IN_PROGRESS = 76,
- CHAR_LOGIN_SUCCESS = 77,
- CHAR_LOGIN_NO_WORLD = 78,
- CHAR_LOGIN_DUPLICATE_CHARACTER = 79,
- CHAR_LOGIN_NO_INSTANCES = 80,
- CHAR_LOGIN_FAILED = 81,
- CHAR_LOGIN_DISABLED = 82,
- CHAR_LOGIN_NO_CHARACTER = 83,
- CHAR_LOGIN_LOCKED_FOR_TRANSFER = 84,
- CHAR_LOGIN_LOCKED_BY_BILLING = 85,
- CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 86,
-
- CHAR_NAME_SUCCESS = 87,
- CHAR_NAME_FAILURE = 88,
- CHAR_NAME_NO_NAME = 89,
- CHAR_NAME_TOO_SHORT = 90,
- CHAR_NAME_TOO_LONG = 91,
- CHAR_NAME_INVALID_CHARACTER = 92,
- CHAR_NAME_MIXED_LANGUAGES = 93,
- CHAR_NAME_PROFANE = 94,
- CHAR_NAME_RESERVED = 95,
- CHAR_NAME_INVALID_APOSTROPHE = 96,
- CHAR_NAME_MULTIPLE_APOSTROPHES = 97,
- CHAR_NAME_THREE_CONSECUTIVE = 98,
- CHAR_NAME_INVALID_SPACE = 99,
- CHAR_NAME_CONSECUTIVE_SPACES = 100,
- CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 101,
- CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 102,
- CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 103
+ CHAR_DELETE_FAILED_HAS_HEIRLOOM_OR_MAIL = 76,
+
+ CHAR_LOGIN_IN_PROGRESS = 77,
+ CHAR_LOGIN_SUCCESS = 78,
+ CHAR_LOGIN_NO_WORLD = 79,
+ CHAR_LOGIN_DUPLICATE_CHARACTER = 80,
+ CHAR_LOGIN_NO_INSTANCES = 81,
+ CHAR_LOGIN_FAILED = 82,
+ CHAR_LOGIN_DISABLED = 83,
+ CHAR_LOGIN_NO_CHARACTER = 84,
+ CHAR_LOGIN_LOCKED_FOR_TRANSFER = 85,
+ CHAR_LOGIN_LOCKED_BY_BILLING = 86,
+ CHAR_LOGIN_LOCKED_BY_MOBILE_AH = 87,
+ CHAR_LOGIN_TEMPORARY_GM_LOCK = 88,
+
+ CHAR_NAME_SUCCESS = 89,
+ CHAR_NAME_FAILURE = 90,
+ CHAR_NAME_NO_NAME = 91,
+ CHAR_NAME_TOO_SHORT = 92,
+ CHAR_NAME_TOO_LONG = 93,
+ CHAR_NAME_INVALID_CHARACTER = 94,
+ CHAR_NAME_MIXED_LANGUAGES = 95,
+ CHAR_NAME_PROFANE = 96,
+ CHAR_NAME_RESERVED = 97,
+ CHAR_NAME_INVALID_APOSTROPHE = 98,
+ CHAR_NAME_MULTIPLE_APOSTROPHES = 99,
+ CHAR_NAME_THREE_CONSECUTIVE = 100,
+ CHAR_NAME_INVALID_SPACE = 101,
+ CHAR_NAME_CONSECUTIVE_SPACES = 102,
+ CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS = 103,
+ CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 104,
+ CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME = 105,
};
/// Ban function modes
@@ -3324,10 +3785,18 @@ enum BattlegroundTypeId
BATTLEGROUND_DS = 10, // Dalaran Sewers
BATTLEGROUND_RV = 11, // Ring of Valor
BATTLEGROUND_IC = 30, // Isle of Conquest
- BATTLEGROUND_RB = 32 // Random Battleground
+ BATTLEGROUND_RB = 32, // Random Battleground
+ BATTLEGROUND_RATED_10_VS_10 = 100, // Rated BG 10 vs 10
+ BATTLEGROUND_RATED_15_VS_15 = 101, // Rated BG 15 vs 15
+ BATTLEGROUND_RATED_25_VS_25 = 102, // Rated BG 25 vs 25
+ BATTLEGROUND_TP = 108, // Twin Peaks
+ BATTLEGROUND_BFG = 120, // Battle For Gilneas
+ // 441 = "Icecrown Citadel"
+ // 443 = "The Ruby Sanctum"
+ // 656 = "Rated Eye of the Storm"
};
-#define MAX_BATTLEGROUND_TYPE_ID 33
+#define MAX_BATTLEGROUND_TYPE_ID 121
enum MailResponseType
{
@@ -3376,35 +3845,44 @@ enum SpellFamilyNames
// 14 - unused
SPELLFAMILY_DEATHKNIGHT = 15,
// 16 - unused
- SPELLFAMILY_PET = 17
+ SPELLFAMILY_PET = 17,
+ SPELLFAMILY_UNK3 = 50,
};
enum TradeStatus
{
- TRADE_STATUS_BUSY = 0,
- TRADE_STATUS_BEGIN_TRADE = 1,
- TRADE_STATUS_OPEN_WINDOW = 2,
- TRADE_STATUS_TRADE_CANCELED = 3,
- TRADE_STATUS_TRADE_ACCEPT = 4,
- TRADE_STATUS_BUSY_2 = 5,
- TRADE_STATUS_NO_TARGET = 6,
- TRADE_STATUS_BACK_TO_TRADE = 7,
- TRADE_STATUS_TRADE_COMPLETE = 8,
- // 9?
- TRADE_STATUS_TARGET_TO_FAR = 10,
- TRADE_STATUS_WRONG_FACTION = 11,
- TRADE_STATUS_CLOSE_WINDOW = 12,
- // 13?
- TRADE_STATUS_IGNORE_YOU = 14,
- TRADE_STATUS_YOU_STUNNED = 15,
- TRADE_STATUS_TARGET_STUNNED = 16,
- TRADE_STATUS_YOU_DEAD = 17,
- TRADE_STATUS_TARGET_DEAD = 18,
- TRADE_STATUS_YOU_LOGOUT = 19,
- TRADE_STATUS_TARGET_LOGOUT = 20,
- TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action
- TRADE_STATUS_ONLY_CONJURED = 22, // You can only trade conjured items... (cross realm BG related).
- TRADE_STATUS_NOT_ELIGIBLE = 23 // Related to trading soulbound loot items
+ TRADE_STATUS_OPEN_WINDOW = 0,
+ // 1 - Related to EVENT_PLAYER_MONEY
+ TRADE_STATUS_NOT_ELIGIBLE = 2, // Related to trading soulbound loot items
+ TRADE_STATUS_YOU_LOGOUT = 3,
+ TRADE_STATUS_IGNORE_YOU = 4,
+ TRADE_STATUS_TARGET_DEAD = 5,
+ TRADE_STATUS_TRADE_ACCEPT = 6,
+ TRADE_STATUS_TARGET_LOGOUT = 7,
+ // 8 - nonexistent
+ TRADE_STATUS_TRADE_COMPLETE = 9,
+ TRADE_STATUS_TRIAL_ACCOUNT = 10, // Trial accounts can not perform that action
+ // 11 - nonexistent
+ TRADE_STATUS_BEGIN_TRADE = 12,
+ TRADE_STATUS_YOU_DEAD = 13,
+ // 14 - nonexistent
+ // 15 - nonexistent
+ TRADE_STATUS_TARGET_TO_FAR = 16,
+ TRADE_STATUS_NO_TARGET = 17,
+ TRADE_STATUS_BUSY_2 = 18,
+ TRADE_STATUS_CURRENCY_NOT_TRADABLE = 19, // new 4.x
+ TRADE_STATUS_WRONG_FACTION = 20,
+ TRADE_STATUS_BUSY = 21,
+ // 22 - equivalent to 335 unk status 9
+ TRADE_STATUS_TRADE_CANCELED = 23,
+ TRADE_STATUS_CURRENCY = 24, // new 4.x
+ TRADE_STATUS_BACK_TO_TRADE = 25,
+ TRADE_STATUS_ONLY_CONJURED = 26, // You can only trade conjured items... (cross realm BG related).
+ TRADE_STATUS_YOU_STUNNED = 27,
+ // 28 - nonexistent
+ TRADE_STATUS_TARGET_STUNNED = 29,
+ // 30 - nonexistent
+ TRADE_STATUS_CLOSE_WINDOW = 31,
};
enum XPColorChar
@@ -3441,6 +3919,12 @@ enum ActivateTaxiReply
ERR_TAXINOTSTANDING = 12
};
+enum ProfessionUI
+{
+ MAX_PRIMARY_PROFESSIONS = 2,
+ MAX_SECONDARY_SKILLS = 5
+};
+
enum DuelCompleteType
{
DUEL_INTERRUPTED = 0,
@@ -3457,32 +3941,44 @@ enum BattlegroundQueueTypeId
BATTLEGROUND_QUEUE_EY = 4,
BATTLEGROUND_QUEUE_SA = 5,
BATTLEGROUND_QUEUE_IC = 6,
- BATTLEGROUND_QUEUE_RB = 7,
- BATTLEGROUND_QUEUE_2v2 = 8,
- BATTLEGROUND_QUEUE_3v3 = 9,
- BATTLEGROUND_QUEUE_5v5 = 10,
+ BATTLEGROUND_QUEUE_TP = 7,
+ BATTLEGROUND_QUEUE_BFG = 8,
+ BATTLEGROUND_QUEUE_RB = 9,
+ BATTLEGROUND_QUEUE_2v2 = 10,
+ BATTLEGROUND_QUEUE_3v3 = 11,
+ BATTLEGROUND_QUEUE_5v5 = 12,
MAX_BATTLEGROUND_QUEUE_TYPES
};
enum GroupJoinBattlegroundResult
{
- // positive values are indexes in BattlemasterList.dbc
- ERR_GROUP_JOIN_BATTLEGROUND_FAIL = 0, // Your group has joined a battleground queue, but you are not eligible (showed for non existing BattlemasterList.dbc indexes)
- ERR_BATTLEGROUND_NONE = -1, // not show anything
- ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS = -2, // You cannot join the battleground yet because you or one of your party members is flagged as a Deserter.
- ERR_ARENA_TEAM_PARTY_SIZE = -3, // Incorrect party size for this arena.
- ERR_BATTLEGROUND_TOO_MANY_QUEUES = -4, // You can only be queued for 2 battles at once
- ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED = -5, // You cannot queue for a rated match while queued for other battles
- ERR_BATTLEDGROUND_QUEUED_FOR_RATED = -6, // You cannot queue for another battle while queued for a rated arena match
- ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = -7, // Your team has left the arena queue
- 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_FAILED = -12, // Join as a group failed (uint64 guid doesn't exist in client cache)
- ERR_LFG_CANT_USE_BATTLEGROUND = -13, // You cannot queue for a battleground or arena while using the dungeon system.
- ERR_IN_RANDOM_BG = -14, // Can't do that while in a Random Battleground queue.
- ERR_IN_NON_RANDOM_BG = -15 // Can't queue for Random Battleground while in another Battleground queue.
+ ERR_BATTLEGROUND_NONE = 0,
+ ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS = 2, // You cannot join the battleground yet because you or one of your party members is flagged as a Deserter.
+ ERR_ARENA_TEAM_PARTY_SIZE = 3, // Incorrect party size for this arena.
+ ERR_BATTLEGROUND_TOO_MANY_QUEUES = 4, // You can only be queued for 2 battles at once
+ ERR_BATTLEGROUND_CANNOT_QUEUE_FOR_RATED = 5, // You cannot queue for a rated match while queued for other battles
+ ERR_BATTLEDGROUND_QUEUED_FOR_RATED = 6, // You cannot queue for another battle while queued for a rated arena match
+ ERR_BATTLEGROUND_TEAM_LEFT_QUEUE = 7, // Your team has left the arena queue
+ 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 = 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.
+ ERR_IN_RANDOM_BG = 15, // Can't do that while in a Random Battleground queue.
+ ERR_IN_NON_RANDOM_BG = 16, // Can't queue for Random Battleground while in another Battleground queue.
+ ERR_BG_DEVELOPER_ONLY = 17,
+ ERR_BATTLEGROUND_INVITATION_DECLINED = 18,
+ ERR_MEETING_STONE_NOT_FOUND = 19,
+ ERR_WARGAME_REQUEST_FAILURE = 20,
+ ERR_BATTLEFIELD_TEAM_PARTY_SIZE = 22,
+ ERR_NOT_ON_TOURNAMENT_REALM = 23,
+ ERR_BATTLEGROUND_PLAYERS_FROM_DIFFERENT_REALMS = 24,
+ ERR_REMOVE_FROM_PVP_QUEUE_GRANT_LEVEL = 33,
+ ERR_REMOVE_FROM_PVP_QUEUE_FACTION_CHANGE = 34,
+ ERR_BATTLEGROUND_JOIN_FAILED = 35,
+ ERR_BATTLEGROUND_DUPE_QUEUE = 43
};
enum PetNameInvalidReason
@@ -3516,6 +4012,28 @@ enum DungeonStatusFlag
RAID_STATUSFLAG_25MAN_HEROIC = 0x08
};
+#define VOID_STORAGE_UNLOCK 100*GOLD
+#define VOID_STORAGE_STORE_ITEM 25*GOLD
+#define VOID_STORAGE_MAX_DEPOSIT 9
+#define VOID_STORAGE_MAX_WITHDRAW 9
+#define VOID_STORAGE_MAX_SLOT 80
+
+enum VoidTransferError
+{
+ VOID_TRANSFER_ERROR_NO_ERROR = 0,
+ VOID_TRANSFER_ERROR_INTERNAL_ERROR_1 = 1,
+ VOID_TRANSFER_ERROR_INTERNAL_ERROR_2 = 2,
+ VOID_TRANSFER_ERROR_FULL = 3,
+ VOID_TRANSFER_ERROR_INTERNAL_ERROR_3 = 4,
+ VOID_TRANSFER_ERROR_INTERNAL_ERROR_4 = 5,
+ VOID_TRANSFER_ERROR_NOT_ENOUGH_MONEY = 6,
+ VOID_TRANSFER_ERROR_INVENTORY_FULL = 7,
+ VOID_TRANSFER_ERROR_INTERNAL_ERROR_5 = 8,
+ VOID_TRANSFER_ERROR_TRANSFER_UNKNOWN = 9,
+};
+
+#define CURRENCY_PRECISION 100
+
enum PartyResult
{
ERR_PARTY_RESULT_OK = 0,
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index d224c21efe8..d8dee6dbe25 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -398,10 +398,7 @@ void MotionMaster::MoveFall(uint32 id /*=0*/)
return;
if (_owner->GetTypeId() == TYPEID_PLAYER)
- {
- _owner->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- _owner->m_movementInfo.SetFallTime(0);
- }
+ _owner->SetFall(true);
Movement::MoveSplineInit init(_owner);
init.MoveTo(_owner->GetPositionX(), _owner->GetPositionY(), tz, false);
diff --git a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
index 0a8a9f267dd..2b2b9bec288 100755..100644
--- a/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/IdleMovementGenerator.cpp
@@ -19,6 +19,7 @@
#include "IdleMovementGenerator.h"
#include "CreatureAI.h"
#include "Creature.h"
+#include <G3D/g3dmath.h>
IdleMovementGenerator si_idleMovement;
@@ -44,25 +45,17 @@ void RotateMovementGenerator::Initialize(Unit* owner)
owner->SetInFront(owner->GetVictim());
owner->AddUnitState(UNIT_STATE_ROTATING);
-
owner->AttackStop();
}
bool RotateMovementGenerator::Update(Unit* owner, uint32 diff)
{
float angle = owner->GetOrientation();
- if (m_direction == ROTATE_DIRECTION_LEFT)
- {
- angle += (float)diff * static_cast<float>(M_PI * 2) / m_maxDuration;
- while (angle >= static_cast<float>(M_PI * 2)) angle -= static_cast<float>(M_PI * 2);
- }
- else
- {
- angle -= (float)diff * static_cast<float>(M_PI * 2) / m_maxDuration;
- while (angle < 0) angle += static_cast<float>(M_PI * 2);
- }
+ angle += (float(diff) * static_cast<float>(M_PI * 2) / m_maxDuration) * (m_direction == ROTATE_DIRECTION_LEFT ? 1.0f : -1.0f);
+ angle = G3D::wrap(angle, 0.0f, float(G3D::twoPi()));
- owner->SetFacingTo(angle);
+ owner->SetOrientation(angle); // UpdateSplinePosition does not set orientation with UNIT_STATE_ROTATING
+ owner->SetFacingTo(angle); // Send spline movement to clients
if (m_duration > diff)
m_duration -= diff;
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index f1656592000..f1656592000 100644..100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index c181750a414..3c9a43a4557 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -102,7 +102,7 @@ bool WaypointMovementGenerator<Creature>::StartMove(Creature* creature)
if (Stopped())
return true;
- bool transportPath = creature->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && creature->GetTransGUID();
+ bool transportPath = creature->GetTransport() != NULL;
if (m_isArrivalDone)
{
@@ -280,6 +280,9 @@ void FlightPathMovementGenerator::DoReset(Player* player)
}
init.SetFirstPointId(GetCurrentNode());
init.SetFly();
+ init.SetSmooth();
+ init.SetUncompressed();
+ init.SetWalk(true);
init.SetVelocity(PLAYER_FLIGHT_SPEED);
init.Launch();
}
diff --git a/src/server/game/Movement/MovementStructures.cpp b/src/server/game/Movement/MovementStructures.cpp
new file mode 100644
index 00000000000..242b2aeaca7
--- /dev/null
+++ b/src/server/game/Movement/MovementStructures.cpp
@@ -0,0 +1,5451 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * 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 "MovementStructures.h"
+#include "Player.h"
+
+MovementStatusElements const PlayerMove[] =
+{
+ MSEHasFallData,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags2,
+ MSEHasSpline,
+ MSEHasTimestamp,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEMovementFlags2,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags,
+ MSEHasOrientation,
+ MSEHasGuidByte2,
+ MSEHasSplineElevation,
+ MSEZeroBit,
+ MSEHasGuidByte4,
+ MSEHasFallDirection,
+ MSEHasGuidByte5,
+ MSEHasTransportData,
+ MSEMovementFlags,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEHasPitch,
+ MSEGuidByte5,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSESplineElevation,
+ MSEGuidByte7,
+ MSEPositionY,
+ MSEGuidByte3,
+ MSETransportTime3,
+ MSETransportGuidByte6,
+ MSETransportSeat,
+ MSETransportGuidByte5,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportOrientation,
+ MSETransportGuidByte2,
+ MSETransportTime2,
+ MSETransportGuidByte0,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte4,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportTime,
+ MSEGuidByte4,
+ MSEPositionX,
+ MSEGuidByte6,
+ MSEPositionZ,
+ MSETimestamp,
+ MSEGuidByte2,
+ MSEPitch,
+ MSEGuidByte0,
+ MSEOrientation,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementFallLand[] =
+{
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasTransportData,
+ MSEHasGuidByte7,
+ MSEHasGuidByte1,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasOrientation,
+ MSEHasGuidByte6,
+ MSEHasTimestamp,
+ MSEZeroBit,
+ MSEHasPitch,
+ MSEHasGuidByte4,
+ MSEHasSpline,
+ MSEHasGuidByte5,
+ MSEHasMovementFlags,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte7,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportPositionY,
+ MSETransportPositionX,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportGuidByte1,
+ MSETransportSeat,
+ MSETransportTime2,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSETransportGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportGuidByte2,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEPitch,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementHeartBeat[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasFallData,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasGuidByte7,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasOrientation,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEZeroBit,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportOrientation,
+ MSETransportGuidByte4,
+ MSETransportPositionY,
+ MSETransportTime,
+ MSETransportPositionX,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportGuidByte7,
+ MSETransportTime3,
+ MSETransportTime2,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportGuidByte6,
+ MSEOrientation,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEPitch,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementJump[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasTimestamp,
+ MSEHasGuidByte5,
+ MSEHasMovementFlags,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte0,
+ MSEHasTransportData,
+ MSEHasGuidByte3,
+ MSEHasPitch,
+ MSEHasGuidByte7,
+ MSEHasFallData,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasGuidByte1,
+ MSEHasSplineElevation,
+ MSEZeroBit,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSETransportGuidByte1,
+ MSETransportGuidByte7,
+ MSETransportPositionX,
+ MSETransportGuidByte4,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportTime2,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportPositionY,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte5,
+ MSEPitch,
+ MSETimestamp,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetFacing[] =
+{
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasGuidByte6,
+ MSEHasTransportData,
+ MSEHasGuidByte4,
+ MSEHasSpline,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasTimestamp,
+ MSEHasPitch,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags,
+ MSEHasGuidByte3,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSETransportGuidByte0,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportTime2,
+ MSETransportGuidByte4,
+ MSETransportPositionZ,
+ MSETransportOrientation,
+ MSETransportGuidByte2,
+ MSETransportTime3,
+ MSETransportGuidByte3,
+ MSETransportSeat,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSESplineElevation,
+ MSEOrientation,
+ MSETimestamp,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetPitch[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasFallData,
+ MSEHasMovementFlags,
+ MSEHasGuidByte1,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasSplineElevation,
+ MSEHasGuidByte6,
+ MSEHasPitch,
+ MSEHasGuidByte4,
+ MSEHasSpline,
+ MSEHasGuidByte2,
+ MSEZeroBit,
+ MSEHasTimestamp,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime2,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSETransportGuidByte4,
+ MSETransportGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportOrientation,
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportTime,
+ MSETransportGuidByte2,
+ MSETransportPositionZ,
+ MSETransportGuidByte0,
+ MSETransportTime2,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportGuidByte7,
+ MSETransportPositionX,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEPitch,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartBackward[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasTransportData,
+ MSEHasGuidByte3,
+ MSEHasGuidByte0,
+ MSEHasGuidByte2,
+ MSEHasTimestamp,
+ MSEHasGuidByte7,
+ MSEHasPitch,
+ MSEZeroBit,
+ MSEHasMovementFlags,
+ MSEHasOrientation,
+ MSEHasSpline,
+ MSEHasMovementFlags2,
+ MSEHasFallData,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSETransportPositionZ,
+ MSETransportGuidByte2,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportGuidByte5,
+ MSETransportPositionY,
+ MSETransportGuidByte1,
+ MSETransportPositionX,
+ MSETransportTime2,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportSeat,
+ MSETransportGuidByte7,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSEPitch,
+ MSETimestamp,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartForward[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEZeroBit,
+ MSEHasMovementFlags,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasOrientation,
+ MSEHasGuidByte6,
+ MSEHasSpline,
+ MSEHasSplineElevation,
+ MSEHasGuidByte4,
+ MSEHasTransportData,
+ MSEHasTimestamp,
+ MSEHasPitch,
+ MSEHasMovementFlags2,
+ MSEHasFallData,
+ MSEMovementFlags,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime3,
+ MSEHasTransportTime2,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEFallVerticalSpeed,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportPositionZ,
+ MSETransportGuidByte1,
+ MSETransportGuidByte4,
+ MSETransportGuidByte7,
+ MSETransportOrientation,
+ MSETransportGuidByte2,
+ MSETransportPositionX,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSETransportTime2,
+ MSESplineElevation,
+ MSEPitch,
+ MSEOrientation,
+ MSETimestamp,
+
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartStrafeLeft[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasSplineElevation,
+ MSEHasGuidByte5,
+ MSEHasPitch,
+ MSEHasGuidByte6,
+ MSEHasTimestamp,
+ MSEHasGuidByte1,
+ MSEZeroBit,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasOrientation,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte7,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasTransportData,
+ MSEHasFallDirection,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSETransportSeat,
+ MSETransportGuidByte2,
+ MSETransportTime2,
+ MSETransportGuidByte3,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportGuidByte7,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte4,
+ MSETransportPositionX,
+ MSETimestamp,
+ MSEOrientation,
+ MSEPitch,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartStrafeRight[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasPitch,
+ MSEHasGuidByte1,
+ MSEHasOrientation,
+ MSEHasGuidByte4,
+ MSEHasSpline,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasFallData,
+ MSEHasSplineElevation,
+ MSEHasTimestamp,
+ MSEHasMovementFlags,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportGuidByte6,
+ MSETransportPositionY,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSETransportGuidByte2,
+ MSETransportSeat,
+ MSETransportPositionX,
+ MSETransportTime3,
+ MSETransportTime,
+ MSETransportGuidByte4,
+ MSETransportGuidByte7,
+ MSETransportTime2,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSEPitch,
+ MSEOrientation,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartTurnLeft[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasOrientation,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasTransportData,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasFallData,
+ MSEMovementFlags2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte6,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSETransportGuidByte0,
+ MSETransportPositionX,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportPositionZ,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportGuidByte2,
+ MSETransportGuidByte6,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportTime3,
+ MSETransportTime2,
+ MSETransportGuidByte5,
+ MSETransportGuidByte7,
+ MSETimestamp,
+ MSEPitch,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartTurnRight[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasMovementFlags,
+ MSEHasSpline,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasGuidByte7,
+ MSEZeroBit,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte1,
+ MSEHasTimestamp,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasSplineElevation,
+ MSEHasPitch,
+ MSEHasFallData,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime3,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSETransportPositionY,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSETransportGuidByte1,
+ MSETransportGuidByte6,
+ MSETransportGuidByte2,
+ MSETransportSeat,
+ MSETransportOrientation,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportPositionZ,
+ MSETransportPositionX,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportTime2,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEPitch,
+ MSEOrientation,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStop[] =
+{
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags,
+ MSEHasGuidByte5,
+ MSEHasFallData,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasTimestamp,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEZeroBit,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEHasPitch,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte2,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSETransportGuidByte4,
+ MSETransportGuidByte7,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportPositionY,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportGuidByte5,
+ MSETransportGuidByte6,
+ MSETimestamp,
+ MSEOrientation,
+ MSEPitch,
+ MSESplineElevation,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStopStrafe[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasGuidByte7,
+ MSEHasSplineElevation,
+ MSEHasGuidByte3,
+ MSEHasOrientation,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasMovementFlags,
+ MSEHasSpline,
+ MSEHasGuidByte0,
+ MSEZeroBit,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime3,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSETransportSeat,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte4,
+ MSETransportGuidByte5,
+ MSETransportTime,
+ MSETransportOrientation,
+ MSETransportPositionX,
+ MSETransportGuidByte0,
+ MSETransportPositionY,
+ MSETransportTime2,
+ MSETransportGuidByte7,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStopTurn[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasFallData,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasPitch,
+ MSEHasTransportData,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasTimestamp,
+ MSEHasMovementFlags2,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSESplineElevation,
+ MSETransportPositionX,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportOrientation,
+ MSETransportTime2,
+ MSETransportTime3,
+ MSETransportGuidByte7,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSETransportPositionY,
+ MSETransportPositionZ,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSEPitch,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartAscend[] =
+{
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte7,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasSplineElevation,
+ MSEHasFallData,
+ MSEHasSpline,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasOrientation,
+ MSEHasGuidByte4,
+ MSEMovementFlags,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportSeat,
+ MSETransportGuidByte2,
+ MSETransportOrientation,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSETransportTime2,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportGuidByte0,
+ MSETransportGuidByte1,
+ MSETransportPositionX,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSEPitch,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartDescend[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEHasGuidByte0,
+ MSEHasPitch,
+ MSEHasFallData,
+ MSEHasGuidByte4,
+ MSEHasOrientation,
+ MSEHasTimestamp,
+ MSEHasMovementFlags2,
+ MSEHasMovementFlags,
+ MSEHasGuidByte6,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasTransportData,
+ MSEHasSpline,
+ MSEHasSplineElevation,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEPitch,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportTime3,
+ MSETransportGuidByte6,
+ MSETransportTime2,
+ MSETransportGuidByte1,
+ MSETransportTime,
+ MSETransportGuidByte4,
+ MSETransportPositionY,
+ MSETransportPositionX,
+ MSETransportGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSEFallTime,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartSwim[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEZeroBit,
+ MSEHasPitch,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasMovementFlags,
+ MSEHasFallData,
+ MSEHasGuidByte5,
+ MSEHasTransportData,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasSpline,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime3,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEPitch,
+ MSETransportTime2,
+ MSETransportGuidByte2,
+ MSETransportPositionY,
+ MSETransportGuidByte3,
+ MSETransportTime,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportTime3,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportPositionZ,
+ MSETransportGuidByte1,
+ MSETransportGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEOrientation,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStopSwim[] =
+{
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasSpline,
+ MSEHasPitch,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags,
+ MSEHasGuidByte4,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasTransportData,
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEHasTimestamp,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasFallData,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSETransportTime3,
+ MSETransportGuidByte4,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSETransportGuidByte1,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSEFallVerticalSpeed,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSETimestamp,
+ MSEPitch,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStopAscend[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasGuidByte7,
+ MSEHasOrientation,
+ MSEHasPitch,
+ MSEHasSpline,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasMovementFlags,
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasTransportData,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+ MSEHasGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSETransportGuidByte2,
+ MSETransportGuidByte6,
+ MSETransportTime2,
+ MSETransportTime3,
+ MSETransportOrientation,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportSeat,
+ MSETransportGuidByte1,
+ MSETransportTime,
+ MSETransportGuidByte0,
+ MSETransportPositionX,
+ MSETransportPositionZ,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEPitch,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStopPitch[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasFallData,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasPitch,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEHasMovementFlags2,
+ MSEHasSplineElevation,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasTimestamp,
+ MSEHasTransportData,
+ MSEHasMovementFlags,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSETimestamp,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSETransportGuidByte1,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETransportSeat,
+ MSETransportGuidByte7,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartPitchDown[] =
+{
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasMovementFlags,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasPitch,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasTimestamp,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasFallData,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSETransportTime3,
+ MSETransportGuidByte3,
+ MSETransportTime2,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportPositionY,
+ MSETransportGuidByte6,
+ MSETransportGuidByte4,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportPositionX,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSETransportGuidByte2,
+ MSETransportGuidByte7,
+ MSETransportOrientation,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEPitch,
+ MSEOrientation,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementStartPitchUp[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasGuidByte4,
+ MSEHasMovementFlags,
+ MSEHasMovementFlags2,
+ MSEHasSpline,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEZeroBit,
+ MSEHasSplineElevation,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasTransportData,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEMovementFlags2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportOrientation,
+ MSETransportGuidByte7,
+ MSETransportTime2,
+ MSETransportSeat,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportPositionY,
+ MSETransportGuidByte4,
+ MSEFallTime,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEPitch,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveChngTransport[]=
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte2,
+ MSEHasTransportData,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasGuidByte6,
+ MSEHasTimestamp,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasPitch,
+ MSEZeroBit,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasGuidByte1,
+ MSEHasFallData,
+ MSEHasMovementFlags,
+ MSEHasMovementFlags2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSETransportPositionY,
+ MSETransportSeat,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportPositionX,
+ MSETransportTime3,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportTime2,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSEPitch,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSplineDone[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasGuidByte6,
+ MSEHasOrientation,
+ MSEHasFallData,
+ MSEHasTimestamp,
+ MSEHasGuidByte2,
+ MSEHasSplineElevation,
+ MSEHasGuidByte4,
+ MSEHasTransportData,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags,
+ MSEHasGuidByte0,
+ MSEZeroBit,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasPitch,
+ MSEHasSpline,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte7,
+
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte0,
+
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte3,
+
+ MSEFallVerticalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+
+ MSEPitch,
+ MSEOrientation,
+
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportGuidByte7,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETransportPositionX,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSETransportTime2,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportGuidByte6,
+ MSETransportGuidByte4,
+
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveNotActiveMover[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasMovementFlags2,
+ MSEHasTransportData,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasGuidByte3,
+ MSEZeroBit,
+ MSEHasTimestamp,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasGuidByte5,
+ MSEHasPitch,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasSpline,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasMovementFlags,
+
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte3,
+
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte3,
+
+ MSEFallVerticalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+
+ MSETransportTime3,
+ MSETransportGuidByte1,
+ MSETransportTime2,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSETransportGuidByte4,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportPositionY,
+ MSETransportPositionX,
+ MSETransportGuidByte2,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportTime,
+
+ MSETimestamp,
+ MSESplineElevation,
+ MSEPitch,
+ MSEOrientation,
+
+ MSEEnd,
+};
+
+MovementStatusElements const DismissControlledVehicle[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEHasSplineElevation,
+ MSEHasFallData,
+ MSEHasTransportData,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte2,
+ MSEHasOrientation,
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasPitch,
+ MSEHasTimestamp,
+ MSEHasGuidByte1,
+ MSEZeroBit,
+ MSEHasSpline,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags,
+ MSEHasGuidByte5,
+
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime2,
+
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte0,
+
+ MSETimestamp,
+
+ MSETransportTime3,
+ MSETransportGuidByte4,
+ MSETransportGuidByte7,
+ MSETransportTime2,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportGuidByte0,
+ MSETransportPositionX,
+ MSETransportGuidByte3,
+ MSETransportSeat,
+ MSETransportPositionY,
+ MSETransportOrientation,
+ MSETransportGuidByte1,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+
+ MSEOrientation,
+ MSESplineElevation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveUpdateTeleport[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasOrientation,
+
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasTransportData,
+ MSEHasGuidByte5,
+
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte2,
+
+ MSEZeroBit,
+
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasPitch,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEHasSplineElevation,
+ MSEMovementFlags,
+ MSEHasGuidByte1,
+
+ MSEGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportTime3,
+ MSETransportGuidByte1,
+ MSETransportTime2,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportSeat,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETransportPositionX,
+
+ MSEGuidByte6,
+ MSEPitch,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte1,
+
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSETimestamp,
+ MSEGuidByte0,
+
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetRunMode[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasTimestamp,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte1,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte7,
+ MSEHasTransportData,
+ MSEZeroBit,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasGuidByte5,
+ MSEHasPitch,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEHasFallData,
+ MSEHasOrientation,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte2,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEPitch,
+ MSETransportTime2,
+ MSETransportGuidByte3,
+ MSETransportPositionX,
+ MSETransportSeat,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportPositionZ,
+ MSETransportGuidByte2,
+ MSETransportGuidByte7,
+ MSETransportOrientation,
+ MSETransportGuidByte4,
+ MSETransportTime,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportPositionY,
+ MSETransportGuidByte6,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetWalkMode[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasGuidByte6,
+ MSEHasSpline,
+ MSEHasTimestamp,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasMovementFlags,
+ MSEHasPitch,
+ MSEHasGuidByte7,
+ MSEHasSplineElevation,
+ MSEHasGuidByte4,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEZeroBit,
+ MSEHasMovementFlags2,
+ MSEHasFallData,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSETransportGuidByte2,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportGuidByte4,
+ MSETransportTime2,
+ MSETransportOrientation,
+ MSETransportPositionX,
+ MSETransportTime3,
+ MSETransportGuidByte7,
+ MSETransportPositionY,
+ MSETransportGuidByte1,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSESplineElevation,
+ MSEPitch,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetCanFly[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasTransportData,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasMovementFlags,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte5,
+ MSEHasTimestamp,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEZeroBit,
+ MSEHasPitch,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportSeat,
+ MSETransportPositionX,
+ MSETransportGuidByte2,
+ MSETransportTime2,
+ MSETransportPositionY,
+ MSETransportGuidByte1,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportGuidByte6,
+ MSETransportTime3,
+ MSESplineElevation,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEPitch,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetCanTransitionBetweenSwimAndFlyAck[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSECounter,
+ MSEPositionX,
+ MSEHasGuidByte3,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasMovementFlags,
+ MSEHasMovementFlags2,
+ MSEHasSplineElevation,
+ MSEHasTimestamp,
+ MSEHasSpline,
+ MSEZeroBit,
+ MSEHasFallData,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasPitch,
+ MSEHasGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte1,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSETransportPositionY,
+ MSETransportPositionZ,
+ MSETransportGuidByte5,
+ MSETransportGuidByte1,
+ MSETransportGuidByte4,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETransportGuidByte0,
+ MSETransportGuidByte2,
+ MSETransportGuidByte7,
+ MSETransportPositionX,
+ MSETransportTime2,
+ MSETransportGuidByte6,
+ MSETransportOrientation,
+ MSETransportTime3,
+ MSEPitch,
+ MSEOrientation,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateSwimSpeed[] =
+{
+ MSEHasMovementFlags,
+ MSEHasGuidByte2,
+ MSEMovementFlags,
+ MSEHasGuidByte3,
+ MSEZeroBit,
+ MSEHasGuidByte7,
+ MSEHasFallDirection,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasOrientation,
+ MSEHasGuidByte1,
+ MSETransportGuidByte2,
+ MSETransportPositionX,
+ MSETransportGuidByte6,
+ MSETransportOrientation,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSETransportPositionY,
+ MSETransportTime,
+ MSETransportGuidByte1,
+ MSETransportGuidByte7,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSEPositionX,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEGuidByte7,
+ MSETimestamp,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEExtraElement,
+ MSEGuidByte4,
+ MSEOrientation,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateRunSpeed[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEExtraElement,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags2,
+ MSEHasPitch,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasTimestamp,
+ MSEHasGuidByte1,
+ MSEMovementFlags2,
+ MSEHasGuidByte3,
+ MSEMovementFlags,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasFallData,
+ MSEHasFallDirection,
+ MSEHasGuidByte4,
+ MSEZeroBit,
+ MSETransportGuidByte4,
+ MSETransportGuidByte5,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSETransportSeat,
+ MSETransportTime2,
+ MSETransportPositionY,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportTime3,
+ MSETransportPositionZ,
+ MSETimestamp,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEPitch,
+ MSEGuidByte6,
+ MSESplineElevation,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEOrientation,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateFlightSpeed[] =
+{
+ MSEPositionY,
+ MSEExtraElement,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasMovementFlags,
+ MSEHasGuidByte4,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEMovementFlags,
+ MSEHasGuidByte2,
+ MSEHasOrientation,
+ MSEHasGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasFallDirection,
+ MSEHasGuidByte0,
+ MSEPitch,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportGuidByte1,
+ MSETransportSeat,
+ MSETransportPositionX,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSETimestamp,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEOrientation,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateCollisionHeight[] =
+{
+ MSEPositionZ,
+ MSEExtraElement,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasOrientation,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEZeroBit,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags,
+ MSEHasFallDirection,
+ MSEHasGuidByte1,
+ MSEMovementFlags,
+ MSEGuidByte3,
+ MSETransportGuidByte7,
+ MSETransportTime,
+ MSETransportGuidByte4,
+ MSETransportGuidByte5,
+ MSETransportOrientation,
+ MSETransportPositionX,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportPositionY,
+ MSETransportGuidByte2,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSETransportGuidByte1,
+ MSETransportSeat,
+ MSEPitch,
+ MSEGuidByte6,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEGuidByte7,
+ MSEOrientation,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSETimestamp,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementForceRunSpeedChangeAck[] =
+{
+ MSECounter,
+ MSEPositionX,
+ MSEExtraElement,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEHasGuidByte7,
+ MSEHasOrientation,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasSpline,
+ MSEHasTransportData,
+ MSEHasTimestamp,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte6,
+ MSEZeroBit,
+ MSEHasSplineElevation,
+ MSEHasPitch,
+ MSEHasGuidByte5,
+ MSEHasMovementFlags,
+ MSEHasGuidByte3,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSETransportPositionZ,
+ MSETransportGuidByte6,
+ MSETransportGuidByte1,
+ MSETransportPositionY,
+ MSETransportGuidByte0,
+ MSETransportGuidByte5,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportTime,
+ MSETransportGuidByte7,
+ MSETransportOrientation,
+ MSETransportGuidByte3,
+ MSETransportTime3,
+ MSETransportGuidByte2,
+ MSETransportSeat,
+ MSETransportGuidByte4,
+ MSEFallVerticalSpeed,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSESplineElevation,
+ MSEPitch,
+ MSETimestamp,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetCollisionHeightAck[] =
+{
+ MSEExtraElement,
+ MSEPositionX,
+ MSEPositionZ,
+ MSECounter,
+ MSEPositionY,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEZeroBit,
+ MSEZeroBit,
+ MSEHasPitch,
+ MSEHasGuidByte5,
+ MSEZeroBit,
+ MSEHasGuidByte2,
+ MSEHasGuidByte1,
+ MSEHasFallData,
+ MSEHasGuidByte3,
+ MSEHasSpline,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags,
+ MSEHasTransportData,
+ MSEHasTimestamp,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags2,
+ MSEHasOrientation,
+ MSEHasGuidByte0,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSETransportPositionX,
+ MSETransportGuidByte4,
+ MSETransportTime2,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSETransportSeat,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportPositionZ,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementForceFlightSpeedChangeAck[] =
+{
+ MSECounter,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEExtraElement,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEZeroBit,
+ MSEHasMovementFlags,
+ MSEHasSplineElevation,
+ MSEHasGuidByte3,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte7,
+ MSEHasTransportData,
+ MSEHasGuidByte0,
+ MSEHasFallData,
+ MSEHasTimestamp,
+ MSEHasPitch,
+ MSEHasSpline,
+ MSEHasOrientation,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte4,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSETransportTime2,
+ MSETransportOrientation,
+ MSETransportGuidByte1,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportGuidByte2,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportPositionX,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEPitch,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementSetCanFlyAck[] =
+{
+ MSEPositionY,
+ MSECounter,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEHasGuidByte3,
+ MSEHasTimestamp,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasOrientation,
+ MSEHasFallData,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags2,
+ MSEZeroBit,
+ MSEHasGuidByte7,
+ MSEHasSpline,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasMovementFlags,
+ MSEHasTransportData,
+ MSEHasPitch,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSETransportTime2,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportTime3,
+ MSETransportGuidByte7,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportPositionX,
+ MSETransportGuidByte2,
+ MSETransportOrientation,
+ MSETransportSeat,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSEFallTime,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEPitch,
+ MSEOrientation,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementForceSwimSpeedChangeAck[] =
+{
+ MSEPositionX,
+ MSECounter,
+ MSEExtraElement,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEHasGuidByte4,
+ MSEHasOrientation,
+ MSEHasPitch,
+ MSEHasTransportData,
+ MSEHasMovementFlags,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasFallData,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasTimestamp,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSETransportGuidByte0,
+ MSETransportTime3,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportGuidByte7,
+ MSETransportSeat,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportPositionZ,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte2,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSETransportGuidByte1,
+ MSETransportGuidByte4,
+ MSEFallTime,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSEPitch,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementForceWalkSpeedChangeAck[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEExtraElement,
+ MSEPositionX,
+ MSECounter,
+ MSEHasGuidByte0,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags,
+ MSEHasFallData,
+ MSEHasOrientation,
+ MSEHasSpline,
+ MSEZeroBit,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasSplineElevation,
+ MSEHasTransportData,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasPitch,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEFallVerticalSpeed,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte5,
+ MSETransportPositionX,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportTime3,
+ MSETransportPositionY,
+ MSETransportGuidByte2,
+ MSETransportGuidByte4,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportOrientation,
+ MSETransportSeat,
+ MSETransportGuidByte6,
+ MSETransportTime2,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEOrientation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementForceRunBackSpeedChangeAck[] =
+{
+ MSEExtraElement,
+ MSECounter,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasTimestamp,
+ MSEHasTransportData,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasOrientation,
+ MSEHasFallData,
+ MSEHasMovementFlags2,
+ MSEHasMovementFlags,
+ MSEHasGuidByte7,
+ MSEHasSpline,
+ MSEHasPitch,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEZeroBit,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportGuidByte6,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportGuidByte2,
+ MSETransportPositionY,
+ MSETransportTime3,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportGuidByte3,
+ MSETransportTime,
+ MSETransportTime2,
+ MSETransportGuidByte4,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateRunBackSpeed[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEZeroBit,
+ MSEHasMovementFlags,
+ MSEHasGuidByte5,
+ MSEHasOrientation,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasGuidByte7,
+ MSETransportPositionX,
+ MSETransportGuidByte2,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSETransportPositionZ,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportGuidByte1,
+ MSETransportOrientation,
+ MSEGuidByte4,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSEGuidByte1,
+ MSEOrientation,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEPositionX,
+ MSEPositionY,
+ MSEPitch,
+ MSEGuidByte7,
+ MSEExtraElement,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEPositionZ,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateWalkSpeed[] =
+{
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasMovementFlags,
+ MSEHasGuidByte6,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEHasGuidByte4,
+ MSEPitch,
+ MSETransportGuidByte6,
+ MSETransportGuidByte0,
+ MSETransportGuidByte4,
+ MSETransportGuidByte2,
+ MSETransportPositionX,
+ MSETransportGuidByte7,
+ MSETransportTime,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportGuidByte5,
+ MSETransportOrientation,
+ MSETransportGuidByte1,
+ MSETransportPositionY,
+ MSETransportGuidByte3,
+ MSEFallVerticalSpeed,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSETimestamp,
+ MSEOrientation,
+ MSEPositionY,
+ MSEGuidByte0,
+ MSEPositionZ,
+ MSEPositionX,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEExtraElement,
+ MSEEnd,
+};
+
+MovementStatusElements const ForceMoveRootAck[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSECounter,
+ MSEPositionX,
+ MSEHasGuidByte3,
+ MSEHasTimestamp,
+ MSEHasTransportData,
+ MSEHasPitch,
+ MSEHasGuidByte2,
+ MSEHasOrientation,
+ MSEHasSplineElevation,
+ MSEHasFallData,
+ MSEHasSpline,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags2,
+ MSEHasMovementFlags,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte5,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSETransportGuidByte5,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportPositionZ,
+ MSETransportTime3,
+ MSETransportTime2,
+ MSETransportGuidByte7,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte3,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportPositionY,
+ MSETransportSeat,
+ MSETimestamp,
+ MSEFallVerticalSpeed,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallTime,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const ForceMoveUnrootAck[] =
+{
+ MSECounter,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasGuidByte7,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEZeroBit,
+ MSEHasTimestamp,
+ MSEHasMovementFlags,
+ MSEHasOrientation,
+ MSEHasPitch,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasTransportData,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEHasFallData,
+ MSEHasGuidByte6,
+ MSEHasFallDirection,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportTime3,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportTime2,
+ MSETransportGuidByte4,
+ MSETransportOrientation,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportGuidByte7,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementFallReset[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSEPositionY,
+ MSEHasGuidByte1,
+ MSEHasTimestamp,
+ MSEHasMovementFlags,
+ MSEZeroBit,
+ MSEHasGuidByte6,
+ MSEHasSplineElevation,
+ MSEHasPitch,
+ MSEHasGuidByte3,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags2,
+ MSEHasOrientation,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasSpline,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasFallData,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSETransportPositionX,
+ MSETransportGuidByte7,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportPositionY,
+ MSETransportPositionZ,
+ MSETransportSeat,
+ MSETransportTime2,
+ MSETransportGuidByte6,
+ MSETransportTime3,
+ MSETransportTime,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportGuidByte4,
+ MSETransportGuidByte1,
+ MSEFallVerticalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEOrientation,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementFeatherFallAck[] =
+{
+ MSEPositionZ,
+ MSECounter,
+ MSEPositionY,
+ MSEPositionX,
+ MSEZeroBit,
+ MSEHasGuidByte3,
+ MSEHasSplineElevation,
+ MSEHasGuidByte1,
+ MSEHasPitch,
+ MSEHasGuidByte2,
+ MSEHasSpline,
+ MSEHasTimestamp,
+ MSEHasGuidByte5,
+ MSEHasFallData,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte6,
+ MSEHasMovementFlags,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSETransportTime3,
+ MSETransportOrientation,
+ MSETransportPositionZ,
+ MSETransportGuidByte7,
+ MSETransportGuidByte5,
+ MSETransportGuidByte2,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportGuidByte6,
+ MSETransportTime2,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSETransportGuidByte4,
+ MSETransportGuidByte0,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETimestamp,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEFallVerticalSpeed,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementGravityDisableAck[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSECounter,
+ MSEPositionX,
+ MSEHasGuidByte3,
+ MSEHasTransportData,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasMovementFlags,
+ MSEHasOrientation,
+ MSEHasSpline,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasSplineElevation,
+ MSEHasTimestamp,
+ MSEHasPitch,
+ MSEHasMovementFlags2,
+ MSEZeroBit,
+ MSEHasGuidByte2,
+ MSEHasFallData,
+ MSEHasGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime2,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSETransportPositionZ,
+ MSETransportGuidByte2,
+ MSETransportGuidByte5,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportPositionY,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportGuidByte6,
+ MSETransportGuidByte1,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportTime2,
+ MSETransportPositionX,
+ MSETransportGuidByte7,
+ MSETransportTime3,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSESplineElevation,
+ MSETimestamp,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementGravityEnableAck[] =
+{
+ MSEPositionZ,
+ MSEPositionX,
+ MSECounter,
+ MSEPositionY,
+ MSEHasSplineElevation,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte6,
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEHasGuidByte5,
+ MSEHasSpline,
+ MSEHasGuidByte3,
+ MSEHasTransportData,
+ MSEHasPitch,
+ MSEHasGuidByte1,
+ MSEHasTimestamp,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags,
+ MSEHasFallData,
+ MSEHasGuidByte0,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasFallDirection,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallVerticalSpeed,
+ MSETransportGuidByte1,
+ MSETransportPositionX,
+ MSETransportTime3,
+ MSETransportOrientation,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportGuidByte7,
+ MSETransportGuidByte6,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportPositionZ,
+ MSETransportTime2,
+ MSETransportGuidByte5,
+ MSETransportTime,
+ MSETransportPositionY,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEPitch,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementHoverAck[] =
+{
+ MSECounter,
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasGuidByte4,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasTimestamp,
+ MSEHasSpline,
+ MSEHasMovementFlags,
+ MSEHasGuidByte1,
+ MSEHasPitch,
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEZeroBit,
+ MSEHasFallData,
+ MSEHasMovementFlags2,
+ MSEHasSplineElevation,
+ MSEHasOrientation,
+ MSEHasGuidByte3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime2,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSETimestamp,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEOrientation,
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte7,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportSeat,
+ MSETransportPositionX,
+ MSETransportPositionZ,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte0,
+ MSETransportPositionY,
+ MSETransportGuidByte5,
+ MSETransportTime2,
+ MSETransportGuidByte6,
+ MSESplineElevation,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementKnockBackAck[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSECounter,
+ MSEPositionX,
+ MSEHasGuidByte6,
+ MSEHasOrientation,
+ MSEHasPitch,
+ MSEHasSplineElevation,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasSpline,
+ MSEHasGuidByte7,
+ MSEZeroBit,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+ MSEHasGuidByte0,
+ MSEHasMovementFlags,
+ MSEHasTransportData,
+ MSEHasGuidByte5,
+ MSEHasFallData,
+ MSEMovementFlags,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte7,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSETransportPositionY,
+ MSETransportGuidByte4,
+ MSETransportTime2,
+ MSETransportGuidByte7,
+ MSETransportOrientation,
+ MSETransportGuidByte6,
+ MSETransportTime,
+ MSETransportGuidByte3,
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportGuidByte2,
+ MSETransportPositionZ,
+ MSETransportGuidByte0,
+ MSETransportGuidByte5,
+ MSETransportPositionX,
+ MSETransportSeat,
+ MSEPitch,
+ MSESplineElevation,
+ MSEOrientation,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementWaterWalkAck[] =
+{
+ MSEPositionY,
+ MSEPositionZ,
+ MSECounter,
+ MSEPositionX,
+ MSEHasTimestamp,
+ MSEHasPitch,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasOrientation,
+ MSEHasGuidByte1,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags,
+ MSEHasGuidByte3,
+ MSEHasTransportData,
+ MSEHasGuidByte6,
+ MSEHasFallData,
+ MSEHasGuidByte4,
+ MSEZeroBit,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte4,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEMovementFlags2,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSETransportPositionX,
+ MSETransportGuidByte1,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportGuidByte7,
+ MSETransportPositionY,
+ MSETransportTime2,
+ MSETransportTime,
+ MSETransportGuidByte5,
+ MSETransportSeat,
+ MSETransportPositionZ,
+ MSETransportGuidByte3,
+ MSETransportGuidByte2,
+ MSETransportGuidByte6,
+ MSETransportGuidByte4,
+ MSESplineElevation,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSEFallTime,
+ MSEOrientation,
+ MSETimestamp,
+ MSEPitch,
+ MSEEnd,
+};
+
+MovementStatusElements const MovementUpdateKnockBack[] =
+{
+ MSEZeroBit,
+ MSEHasGuidByte4,
+ MSEHasMovementFlags,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEHasOrientation,
+ MSEOrientation,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallCosAngle,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportGuidByte7,
+ MSETransportSeat,
+ MSETransportGuidByte3,
+ MSETransportGuidByte6,
+ MSETransportPositionZ,
+ MSETransportGuidByte1,
+ MSETransportPositionY,
+ MSETransportPositionX,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte4,
+ MSEPitch,
+ MSEPositionZ,
+ MSETimestamp,
+ MSEPositionX,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEPositionY,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetWalkSpeed[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEExtraElement,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetRunSpeed[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEExtraElement,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetRunBackSpeed[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEGuidByte1,
+ MSEExtraElement,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetSwimSpeed[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEExtraElement,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetSwimBackSpeed[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEExtraElement,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetTurnRate[] =
+{
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEExtraElement,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetFlightSpeed[] =
+{
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEExtraElement,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetFlightBackSpeed[] =
+{
+ MSEHasGuidByte2,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEGuidByte5,
+ MSEExtraElement,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetPitchRate[] =
+{
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEExtraElement,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetWalkSpeed[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEExtraElement,
+ MSEGuidByte2,
+ MSECounter,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetRunSpeed[] =
+{
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSECounter,
+ MSEExtraElement,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetRunBackSpeed[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEGuidByte5,
+ MSECounter,
+ MSEExtraElement,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetSwimSpeed[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEGuidByte0,
+ MSECounter,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEExtraElement,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetSwimBackSpeed[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSECounter,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEExtraElement,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetTurnRate[] =
+{
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEExtraElement,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSECounter,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetFlightSpeed[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEExtraElement,
+ MSECounter,
+ MSEGuidByte2,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetFlightBackSpeed[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEGuidByte3,
+ MSECounter,
+ MSEGuidByte6,
+ MSEExtraElement,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetPitchRate[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEExtraElement,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSECounter,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetCollisionHeight[] =
+{
+ MSEZeroBit,
+ MSEZeroBit,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSECounter,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEExtraElement,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetWalkMode[] =
+{
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetRunMode[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveGravityDisable[] =
+{
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveGravityEnable[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetHover[] =
+{
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveUnsetHover[] =
+{
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveStartSwim[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveStopSwim[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetFlying[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveUnsetFlying[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetWaterWalk[] =
+{
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetLandWalk[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetFeatherFall[] =
+{
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveSetNormalFall[] =
+{
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveRoot[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte2,
+ MSEHasGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte6,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const SplineMoveUnroot[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte3,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetCanFly[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte3,
+ MSECounter,
+ MSEGuidByte2,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveUnsetCanFly[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEHasGuidByte3,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte6,
+ MSECounter,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveSetHover[] =
+{
+ MSEHasGuidByte1,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSECounter,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveUnsetHover[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte0,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSECounter,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveWaterWalk[] =
+{
+ MSEHasGuidByte4,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte5,
+ MSEGuidByte2,
+ MSECounter,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveLandWalk[] =
+{
+ MSEHasGuidByte5,
+ MSEHasGuidByte1,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte0,
+ MSEHasGuidByte7,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEGuidByte4,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte2,
+ MSECounter,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveFeatherFall[] =
+{
+ MSEHasGuidByte3,
+ MSEHasGuidByte1,
+ MSEHasGuidByte7,
+ MSEHasGuidByte0,
+ MSEHasGuidByte4,
+ MSEHasGuidByte2,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEGuidByte5,
+ MSEGuidByte7,
+ MSEGuidByte2,
+ MSECounter,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveNormalFall[] =
+{
+ MSECounter,
+ MSEHasGuidByte3,
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte5,
+ MSEHasGuidByte7,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEHasGuidByte2,
+ MSEGuidByte2,
+ MSEGuidByte7,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte0,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveRoot[] =
+{
+ MSEHasGuidByte2,
+ MSEHasGuidByte7,
+ MSEHasGuidByte6,
+ MSEHasGuidByte0,
+ MSEHasGuidByte5,
+ MSEHasGuidByte4,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEGuidByte1,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSECounter,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte6,
+ MSEEnd,
+};
+
+MovementStatusElements const MoveUnroot[] =
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte3,
+ MSEHasGuidByte7,
+ MSEHasGuidByte5,
+ MSEHasGuidByte2,
+ MSEHasGuidByte4,
+ MSEHasGuidByte6,
+ MSEGuidByte3,
+ MSEGuidByte6,
+ MSEGuidByte1,
+ MSECounter,
+ MSEGuidByte2,
+ MSEGuidByte0,
+ MSEGuidByte7,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEEnd,
+};
+
+MovementStatusElements const ChangeSeatsOnControlledVehicle[] =
+{
+ MSEPositionY,
+ MSEPositionX,
+ MSEPositionZ,
+ MSEExtraElement,
+ MSEHasMovementFlags,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEExtraElement,
+ MSEExtraElement,
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEExtraElement,
+ MSEHasGuidByte7,
+ MSEExtraElement,
+ MSEHasTimestamp,
+ MSEHasSplineElevation,
+ MSEHasGuidByte5,
+ MSEExtraElement,
+ MSEHasMovementFlags2,
+ MSEHasPitch,
+ MSEExtraElement,
+ MSEHasGuidByte0,
+ MSEExtraElement,
+ MSEHasFallData,
+ MSEHasGuidByte1,
+ MSEHasSpline,
+ MSEMovementFlags,
+ MSEExtraElement,
+ MSEHasGuidByte3,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte6,
+ MSEMovementFlags2,
+ MSEHasFallDirection,
+ MSEExtraElement,
+ MSEGuidByte7,
+ MSEGuidByte5,
+ MSEExtraElement,
+ MSEExtraElement,
+ MSEGuidByte6,
+ MSEExtraElement,
+ MSEExtraElement,
+ MSEGuidByte3,
+ MSEExtraElement,
+ MSEGuidByte0,
+ MSEExtraElement,
+ MSEGuidByte4,
+ MSEGuidByte1,
+ MSEExtraElement,
+ MSEGuidByte2,
+ MSEPitch,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSETransportGuidByte2,
+ MSETransportTime2,
+ MSETransportTime3,
+ MSETransportGuidByte0,
+ MSETransportTime,
+ MSETransportSeat,
+ MSETransportPositionX,
+ MSETransportOrientation,
+ MSETransportGuidByte7,
+ MSETransportGuidByte4,
+ MSETransportGuidByte3,
+ MSETransportGuidByte5,
+ MSETransportPositionZ,
+ MSETransportGuidByte1,
+ MSETransportGuidByte6,
+ MSETransportPositionY,
+ MSESplineElevation,
+ MSEOrientation,
+ MSETimestamp,
+ MSEEnd,
+};
+
+MovementStatusElements const CastSpellEmbeddedMovement[] =
+{
+ MSEPositionZ,
+ MSEPositionY,
+ MSEPositionX,
+ MSEHasFallData,
+ MSEHasTimestamp,
+ MSEHasOrientation,
+ MSEZeroBit,
+ MSEHasSpline,
+ MSEHasGuidByte6,
+ MSEHasGuidByte4,
+ MSEHasMovementFlags2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte5,
+ MSEHasSplineElevation,
+ MSEHasPitch,
+ MSEHasGuidByte7,
+ MSEHasTransportData,
+ MSEHasGuidByte2,
+ MSEHasMovementFlags,
+ MSEHasGuidByte1,
+ MSEHasGuidByte0,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportTime2,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportTime3,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte3,
+ MSEMovementFlags2,
+ MSEMovementFlags,
+ MSEHasFallDirection,
+ MSEGuidByte1,
+ MSEGuidByte4,
+ MSEGuidByte7,
+ MSEGuidByte3,
+ MSEGuidByte0,
+ MSEGuidByte2,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSETransportSeat,
+ MSETransportOrientation,
+ MSETransportTime,
+ MSETransportGuidByte6,
+ MSETransportGuidByte5,
+ MSETransportTime3,
+ MSETransportPositionX,
+ MSETransportGuidByte4,
+ MSETransportPositionZ,
+ MSETransportGuidByte2,
+ MSETransportGuidByte0,
+ MSETransportTime2,
+ MSETransportGuidByte1,
+ MSETransportGuidByte3,
+ MSETransportPositionY,
+ MSETransportGuidByte7,
+ MSEOrientation,
+ MSESplineElevation,
+ MSEFallTime,
+ MSEFallHorizontalSpeed,
+ MSEFallSinAngle,
+ MSEFallCosAngle,
+ MSEFallVerticalSpeed,
+ MSETimestamp,
+ MSEPitch,
+ MSEEnd,
+};
+
+void Movement::ExtraMovementStatusElement::ReadNextElement(ByteBuffer& packet)
+{
+ MovementStatusElements const element = _elements[_index++];
+
+ switch (element)
+ {
+ case MSEHasGuidByte0:
+ case MSEHasGuidByte1:
+ case MSEHasGuidByte2:
+ case MSEHasGuidByte3:
+ case MSEHasGuidByte4:
+ case MSEHasGuidByte5:
+ case MSEHasGuidByte6:
+ case MSEHasGuidByte7:
+ Data.guid[element - MSEHasGuidByte0] = packet.ReadBit();
+ break;
+ case MSEGuidByte0:
+ case MSEGuidByte1:
+ case MSEGuidByte2:
+ case MSEGuidByte3:
+ case MSEGuidByte4:
+ case MSEGuidByte5:
+ case MSEGuidByte6:
+ case MSEGuidByte7:
+ packet.ReadByteSeq(Data.guid[element - MSEGuidByte0]);
+ break;
+ case MSEExtraFloat:
+ packet >> Data.floatData;
+ break;
+ case MSEExtraInt8:
+ packet >> Data.byteData;
+ break;
+ default:
+ ASSERT(PrintInvalidSequenceElement(element, __FUNCTION__));
+ break;
+ }
+}
+
+void Movement::ExtraMovementStatusElement::WriteNextElement(ByteBuffer& packet)
+{
+ MovementStatusElements const element = _elements[_index++];
+
+ switch (element)
+ {
+ case MSEHasGuidByte0:
+ case MSEHasGuidByte1:
+ case MSEHasGuidByte2:
+ case MSEHasGuidByte3:
+ case MSEHasGuidByte4:
+ case MSEHasGuidByte5:
+ case MSEHasGuidByte6:
+ case MSEHasGuidByte7:
+ packet.WriteBit(Data.guid[element - MSEHasGuidByte0]);
+ break;
+ case MSEGuidByte0:
+ case MSEGuidByte1:
+ case MSEGuidByte2:
+ case MSEGuidByte3:
+ case MSEGuidByte4:
+ case MSEGuidByte5:
+ case MSEGuidByte6:
+ case MSEGuidByte7:
+ packet.WriteByteSeq(Data.guid[element - MSEGuidByte0]);
+ break;
+ case MSEExtraFloat:
+ packet << Data.floatData;
+ break;
+ case MSEExtraInt8:
+ packet << Data.byteData;
+ break;
+ default:
+ ASSERT(PrintInvalidSequenceElement(element, __FUNCTION__));
+ break;
+ }
+}
+
+bool Movement::PrintInvalidSequenceElement(MovementStatusElements const element, char const* function)
+{
+ TC_LOG_ERROR("entities.unit", "Incorrect sequence element %d detected at %s", element, function);
+ return false;
+}
+
+Movement::PacketSender::PacketSender(Unit* unit, Opcodes serverControl, Opcodes playerControl, Opcodes broadcast /*= SMSG_PLAYER_MOVE*/, ExtraMovementStatusElement* extras /*= NULL*/)
+ : _extraElements(extras), _unit(unit)
+{
+ if (unit->GetTypeId() == TYPEID_PLAYER && unit->ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER)
+ {
+ _selfOpcode = playerControl;
+ _broadcast = broadcast;
+ }
+ else
+ {
+ _selfOpcode = NULL_OPCODE;
+ _broadcast = serverControl;
+ }
+}
+
+void Movement::PacketSender::Send() const
+{
+ bool isPlayerMovement = false;
+ if (Player* player = _unit->ToPlayer())
+ {
+ isPlayerMovement = player->m_mover->GetTypeId() == TYPEID_PLAYER;
+ if (isPlayerMovement && _selfOpcode != NULL_OPCODE)
+ {
+ WorldPacket data(_selfOpcode);
+ _unit->WriteMovementInfo(data, _extraElements);
+ player->SendDirectMessage(&data);
+ }
+ }
+
+ if (_broadcast != NULL_OPCODE)
+ {
+ ///! Need to reset current extra element index before writing another packet
+ if (_extraElements)
+ _extraElements->ResetIndex();
+
+ WorldPacket data(_broadcast);
+ _unit->WriteMovementInfo(data, _extraElements);
+ _unit->SendMessageToSet(&data, !isPlayerMovement);
+ }
+}
+
+MovementStatusElements const* GetMovementStatusElementsSequence(Opcodes opcode)
+{
+ switch (opcode)
+ {
+ case MSG_MOVE_FALL_LAND:
+ return MovementFallLand;
+ case MSG_MOVE_HEARTBEAT:
+ return MovementHeartBeat;
+ case MSG_MOVE_JUMP:
+ return MovementJump;
+ case MSG_MOVE_SET_FACING:
+ return MovementSetFacing;
+ case MSG_MOVE_SET_PITCH:
+ return MovementSetPitch;
+ case MSG_MOVE_START_ASCEND:
+ return MovementStartAscend;
+ case MSG_MOVE_START_BACKWARD:
+ return MovementStartBackward;
+ case MSG_MOVE_START_DESCEND:
+ return MovementStartDescend;
+ case MSG_MOVE_START_FORWARD:
+ return MovementStartForward;
+ case MSG_MOVE_START_PITCH_DOWN:
+ return MovementStartPitchDown;
+ case MSG_MOVE_START_PITCH_UP:
+ return MovementStartPitchUp;
+ case MSG_MOVE_START_STRAFE_LEFT:
+ return MovementStartStrafeLeft;
+ case MSG_MOVE_START_STRAFE_RIGHT:
+ return MovementStartStrafeRight;
+ case MSG_MOVE_START_SWIM:
+ return MovementStartSwim;
+ case MSG_MOVE_START_TURN_LEFT:
+ return MovementStartTurnLeft;
+ case MSG_MOVE_START_TURN_RIGHT:
+ return MovementStartTurnRight;
+ case MSG_MOVE_STOP:
+ return MovementStop;
+ case MSG_MOVE_STOP_ASCEND:
+ return MovementStopAscend;
+ case MSG_MOVE_STOP_PITCH:
+ return MovementStopPitch;
+ case MSG_MOVE_STOP_STRAFE:
+ return MovementStopStrafe;
+ case MSG_MOVE_STOP_SWIM:
+ return MovementStopSwim;
+ case MSG_MOVE_STOP_TURN:
+ return MovementStopTurn;
+ case SMSG_PLAYER_MOVE:
+ return PlayerMove;
+ case CMSG_MOVE_CHNG_TRANSPORT:
+ return MoveChngTransport;
+ case CMSG_MOVE_SPLINE_DONE:
+ return MoveSplineDone;
+ case CMSG_MOVE_NOT_ACTIVE_MOVER:
+ return MoveNotActiveMover;
+ case CMSG_DISMISS_CONTROLLED_VEHICLE:
+ return DismissControlledVehicle;
+ case SMSG_MOVE_UPDATE_TELEPORT:
+ return MoveUpdateTeleport;
+ case CMSG_FORCE_MOVE_ROOT_ACK:
+ return ForceMoveRootAck;
+ case CMSG_FORCE_MOVE_UNROOT_ACK:
+ return ForceMoveUnrootAck;
+ case CMSG_MOVE_FALL_RESET:
+ return MovementFallReset;
+ case CMSG_MOVE_FEATHER_FALL_ACK:
+ return MovementFeatherFallAck;
+ case CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK:
+ return MovementForceFlightSpeedChangeAck;
+ case CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK:
+ return MovementForceRunBackSpeedChangeAck;
+ case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK:
+ return MovementForceRunSpeedChangeAck;
+ case CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK:
+ return MovementForceSwimSpeedChangeAck;
+ case CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK:
+ return MovementForceWalkSpeedChangeAck;
+ case CMSG_MOVE_GRAVITY_DISABLE_ACK:
+ return MovementGravityDisableAck;
+ case CMSG_MOVE_GRAVITY_ENABLE_ACK:
+ return MovementGravityEnableAck;
+ case CMSG_MOVE_HOVER_ACK:
+ return MovementHoverAck;
+ case CMSG_MOVE_KNOCK_BACK_ACK:
+ return MovementKnockBackAck;
+ case CMSG_MOVE_SET_CAN_FLY:
+ return MovementSetCanFly;
+ case CMSG_MOVE_SET_CAN_FLY_ACK:
+ return MovementSetCanFlyAck;
+ case CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK:
+ return MovementSetCanTransitionBetweenSwimAndFlyAck;
+ case SMSG_MOVE_SET_COLLISION_HEIGHT:
+ return MoveSetCollisionHeight;
+ case CMSG_MOVE_SET_COLLISION_HEIGHT_ACK:
+ return MovementSetCollisionHeightAck;
+ case SMSG_MOVE_UPDATE_COLLISION_HEIGHT:
+ return MovementUpdateCollisionHeight;
+ case CMSG_MOVE_WATER_WALK_ACK:
+ return MovementWaterWalkAck;
+ case MSG_MOVE_SET_RUN_MODE:
+ return MovementSetRunMode;
+ case MSG_MOVE_SET_WALK_MODE:
+ return MovementSetWalkMode;
+ case SMSG_MOVE_UPDATE_FLIGHT_SPEED:
+ return MovementUpdateFlightSpeed;
+ case SMSG_MOVE_UPDATE_RUN_SPEED:
+ return MovementUpdateRunSpeed;
+ case SMSG_MOVE_UPDATE_KNOCK_BACK:
+ return MovementUpdateKnockBack;
+ case SMSG_MOVE_UPDATE_RUN_BACK_SPEED:
+ return MovementUpdateRunBackSpeed;
+ case SMSG_MOVE_UPDATE_SWIM_SPEED:
+ return MovementUpdateSwimSpeed;
+ case SMSG_MOVE_UPDATE_WALK_SPEED:
+ return MovementUpdateWalkSpeed;
+ case SMSG_SPLINE_MOVE_SET_WALK_SPEED:
+ return SplineMoveSetWalkSpeed;
+ case SMSG_SPLINE_MOVE_SET_RUN_SPEED:
+ return SplineMoveSetRunSpeed;
+ case SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED:
+ return SplineMoveSetRunBackSpeed;
+ case SMSG_SPLINE_MOVE_SET_SWIM_SPEED:
+ return SplineMoveSetSwimSpeed;
+ case SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED:
+ return SplineMoveSetSwimBackSpeed;
+ case SMSG_SPLINE_MOVE_SET_TURN_RATE:
+ return SplineMoveSetTurnRate;
+ case SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED:
+ return SplineMoveSetFlightSpeed;
+ case SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED:
+ return SplineMoveSetFlightBackSpeed;
+ case SMSG_SPLINE_MOVE_SET_PITCH_RATE:
+ return SplineMoveSetPitchRate;
+ case SMSG_MOVE_SET_WALK_SPEED:
+ return MoveSetWalkSpeed;
+ case SMSG_MOVE_SET_RUN_SPEED:
+ return MoveSetRunSpeed;
+ case SMSG_MOVE_SET_RUN_BACK_SPEED:
+ return MoveSetRunBackSpeed;
+ case SMSG_MOVE_SET_SWIM_SPEED:
+ return MoveSetSwimSpeed;
+ case SMSG_MOVE_SET_SWIM_BACK_SPEED:
+ return MoveSetSwimBackSpeed;
+ case SMSG_MOVE_SET_TURN_RATE:
+ return MoveSetTurnRate;
+ case SMSG_MOVE_SET_FLIGHT_SPEED:
+ return MoveSetFlightSpeed;
+ case SMSG_MOVE_SET_FLIGHT_BACK_SPEED:
+ return MoveSetFlightBackSpeed;
+ case SMSG_MOVE_SET_PITCH_RATE:
+ return MoveSetPitchRate;
+ case SMSG_SPLINE_MOVE_SET_WALK_MODE:
+ return SplineMoveSetWalkMode;
+ case SMSG_SPLINE_MOVE_SET_RUN_MODE:
+ return SplineMoveSetRunMode;
+ case SMSG_SPLINE_MOVE_GRAVITY_DISABLE:
+ return SplineMoveGravityDisable;
+ case SMSG_SPLINE_MOVE_GRAVITY_ENABLE:
+ return SplineMoveGravityEnable;
+ case SMSG_SPLINE_MOVE_SET_HOVER:
+ return SplineMoveSetHover;
+ case SMSG_SPLINE_MOVE_UNSET_HOVER:
+ return SplineMoveUnsetHover;
+ case SMSG_SPLINE_MOVE_START_SWIM:
+ return SplineMoveStartSwim;
+ case SMSG_SPLINE_MOVE_STOP_SWIM:
+ return SplineMoveStopSwim;
+ case SMSG_SPLINE_MOVE_SET_FLYING:
+ return SplineMoveSetFlying;
+ case SMSG_SPLINE_MOVE_UNSET_FLYING:
+ return SplineMoveUnsetFlying;
+ case SMSG_SPLINE_MOVE_SET_WATER_WALK:
+ return SplineMoveSetWaterWalk;
+ case SMSG_SPLINE_MOVE_SET_LAND_WALK:
+ return SplineMoveSetLandWalk;
+ case SMSG_SPLINE_MOVE_SET_FEATHER_FALL:
+ return SplineMoveSetFeatherFall;
+ case SMSG_SPLINE_MOVE_SET_NORMAL_FALL:
+ return SplineMoveSetNormalFall;
+ case SMSG_SPLINE_MOVE_ROOT:
+ return SplineMoveRoot;
+ case SMSG_SPLINE_MOVE_UNROOT:
+ return SplineMoveUnroot;
+ case SMSG_MOVE_SET_CAN_FLY:
+ return MoveSetCanFly;
+ case SMSG_MOVE_UNSET_CAN_FLY:
+ return MoveUnsetCanFly;
+ case SMSG_MOVE_SET_HOVER:
+ return MoveSetHover;
+ case SMSG_MOVE_UNSET_HOVER:
+ return MoveUnsetHover;
+ case SMSG_MOVE_WATER_WALK:
+ return MoveWaterWalk;
+ case SMSG_MOVE_LAND_WALK:
+ return MoveLandWalk;
+ case SMSG_MOVE_FEATHER_FALL:
+ return MoveFeatherFall;
+ case SMSG_MOVE_NORMAL_FALL:
+ return MoveNormalFall;
+ case SMSG_MOVE_ROOT:
+ return MoveRoot;
+ case SMSG_MOVE_UNROOT:
+ return MoveUnroot;
+ case CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE:
+ return ChangeSeatsOnControlledVehicle;
+ case CMSG_CAST_SPELL:
+ case CMSG_PET_CAST_SPELL:
+ case CMSG_USE_ITEM:
+ return CastSpellEmbeddedMovement;
+ default:
+ break;
+ }
+
+ return NULL;
+}
diff --git a/src/server/game/Movement/MovementStructures.h b/src/server/game/Movement/MovementStructures.h
new file mode 100644
index 00000000000..278eaa877fa
--- /dev/null
+++ b/src/server/game/Movement/MovementStructures.h
@@ -0,0 +1,158 @@
+/*
+* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+*
+* 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 _MOVEMENT_STRUCTURES_H
+#define _MOVEMENT_STRUCTURES_H
+
+#include "Opcodes.h"
+#include "Object.h"
+
+class ByteBuffer;
+class Unit;
+
+enum MovementStatusElements
+{
+ MSEHasGuidByte0,
+ MSEHasGuidByte1,
+ MSEHasGuidByte2,
+ MSEHasGuidByte3,
+ MSEHasGuidByte4,
+ MSEHasGuidByte5,
+ MSEHasGuidByte6,
+ MSEHasGuidByte7,
+ MSEHasMovementFlags,
+ MSEHasMovementFlags2,
+ MSEHasTimestamp,
+ MSEHasOrientation,
+ MSEHasTransportData,
+ MSEHasTransportGuidByte0,
+ MSEHasTransportGuidByte1,
+ MSEHasTransportGuidByte2,
+ MSEHasTransportGuidByte3,
+ MSEHasTransportGuidByte4,
+ MSEHasTransportGuidByte5,
+ MSEHasTransportGuidByte6,
+ MSEHasTransportGuidByte7,
+ MSEHasTransportTime2,
+ MSEHasTransportTime3,
+ MSEHasPitch,
+ MSEHasFallData,
+ MSEHasFallDirection,
+ MSEHasSplineElevation,
+ MSEHasSpline,
+
+ MSEGuidByte0,
+ MSEGuidByte1,
+ MSEGuidByte2,
+ MSEGuidByte3,
+ MSEGuidByte4,
+ MSEGuidByte5,
+ MSEGuidByte6,
+ MSEGuidByte7,
+ MSEMovementFlags,
+ MSEMovementFlags2,
+ MSETimestamp,
+ MSEPositionX,
+ MSEPositionY,
+ MSEPositionZ,
+ MSEOrientation,
+ MSETransportGuidByte0,
+ MSETransportGuidByte1,
+ MSETransportGuidByte2,
+ MSETransportGuidByte3,
+ MSETransportGuidByte4,
+ MSETransportGuidByte5,
+ MSETransportGuidByte6,
+ MSETransportGuidByte7,
+ MSETransportPositionX,
+ MSETransportPositionY,
+ MSETransportPositionZ,
+ MSETransportOrientation,
+ MSETransportSeat,
+ MSETransportTime,
+ MSETransportTime2,
+ MSETransportTime3,
+ MSEPitch,
+ MSEFallTime,
+ MSEFallVerticalSpeed,
+ MSEFallCosAngle,
+ MSEFallSinAngle,
+ MSEFallHorizontalSpeed,
+ MSESplineElevation,
+
+ MSECounter,
+
+ // Special
+ MSEZeroBit, // writes bit value 1 or skips read bit
+ MSEOneBit, // writes bit value 0 or skips read bit
+ MSEEnd, // marks end of parsing
+ MSEExtraElement, // Used to signalize reading into ExtraMovementStatusElement, element sequence inside it is declared as separate array
+ // Allowed internal elements are: GUID markers (not transport), MSEExtraFloat, MSEExtraInt8
+ MSEExtraFloat,
+ MSEExtraInt8,
+};
+
+namespace Movement
+{
+ class PacketSender;
+
+ class ExtraMovementStatusElement
+ {
+ friend class PacketSender;
+
+ public:
+ ExtraMovementStatusElement(MovementStatusElements const* elements) : _elements(elements), _index(0) { }
+
+ void ReadNextElement(ByteBuffer& packet);
+ void WriteNextElement(ByteBuffer& packet);
+
+ struct
+ {
+ ObjectGuid guid;
+ float floatData;
+ int8 byteData;
+ } Data;
+
+ protected:
+ void ResetIndex() { _index = 0; }
+
+ private:
+ MovementStatusElements const* _elements;
+ uint32 _index;
+ };
+
+ class PacketSender
+ {
+ public:
+ PacketSender(Unit* unit, Opcodes serverControl, Opcodes playerControl, Opcodes broadcast = SMSG_PLAYER_MOVE, ExtraMovementStatusElement* extras = NULL);
+
+ void Send() const;
+
+ private:
+ ExtraMovementStatusElement* _extraElements;
+ Unit* _unit;
+ Opcodes _selfOpcode;
+ Opcodes _broadcast;
+ };
+
+ bool PrintInvalidSequenceElement(MovementStatusElements element, char const* function);
+}
+
+MovementStatusElements const* GetMovementStatusElementsSequence(Opcodes opcode);
+
+#endif
diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp
index 91ad6d2b676..d8a300a2bab 100644
--- a/src/server/game/Movement/PathGenerator.cpp
+++ b/src/server/game/Movement/PathGenerator.cpp
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index 7291c6849c5..6e3d7680637 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -52,7 +52,7 @@ Location MoveSpline::ComputePosition() const
}
else
{
- if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling))
+ if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed | MoveSplineFlag::Falling | MoveSplineFlag::Unknown0))
{
Vector3 hermite;
spline.evaluate_derivative(point_Idx, u, hermite);
@@ -216,7 +216,7 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const
// each vertex offset packed into 11 bytes
bool MoveSplineInitArgs::_checkPathBounds() const
{
- if (!(flags & MoveSplineFlag::Mask_CatmullRom) && path.size() > 2)
+ if (!(flags & MoveSplineFlag::Catmullrom) && path.size() > 2)
{
enum{
MAX_OFFSET = (1 << 11) / 2
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index 2cac9034c84..f86ce6431ed 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -36,42 +36,45 @@ namespace Movement
enum eFlags
{
None = 0x00000000,
- // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
- Done = 0x00000100,
- Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
- No_Spline = 0x00000400,
- Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
- Walkmode = 0x00001000,
- Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
- OrientationFixed = 0x00004000, // Model orientation fixed
- Final_Point = 0x00008000,
- Final_Target = 0x00010000,
- Final_Angle = 0x00020000,
- Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
- Cyclic = 0x00080000, // Movement by cycled spline
- Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
- Animation = 0x00200000, // Plays animation after some time passed
- Frozen = 0x00400000, // Will never arrive
- TransportEnter = 0x00800000,
- TransportExit = 0x01000000,
- Unknown7 = 0x02000000,
- Unknown8 = 0x04000000,
- OrientationInversed = 0x08000000,
- Unknown10 = 0x10000000,
- Unknown11 = 0x20000000,
- Unknown12 = 0x40000000,
- Unknown13 = 0x80000000,
+ // x00-x07 used as animation Ids storage in pair with Animation flag
+ Unknown0 = 0x00000008, // NOT VERIFIED
+ FallingSlow = 0x00000010,
+ Done = 0x00000020,
+ Falling = 0x00000040, // Affects elevation computation, can't be combined with Parabolic flag
+ No_Spline = 0x00000080,
+ Unknown2 = 0x00000100, // NOT VERIFIED
+ Flying = 0x00000200, // Smooth movement(Catmullrom interpolation mode), flying animation
+ OrientationFixed = 0x00000400, // Model orientation fixed
+ Catmullrom = 0x00000800, // Used Catmullrom interpolation mode
+ Cyclic = 0x00001000, // Movement by cycled spline
+ Enter_Cycle = 0x00002000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
+ Frozen = 0x00004000, // Will never arrive
+ TransportEnter = 0x00008000,
+ TransportExit = 0x00010000,
+ Unknown3 = 0x00020000, // NOT VERIFIED
+ Unknown4 = 0x00040000, // NOT VERIFIED
+ OrientationInversed = 0x00080000,
+ SmoothGroundPath = 0x00100000,
+ Walkmode = 0x00200000,
+ UncompressedPath = 0x00400000,
+ Unknown6 = 0x00800000, // NOT VERIFIED
+ Animation = 0x01000000, // Plays animation after some time passed
+ Parabolic = 0x02000000, // Affects elevation computation, can't be combined with Falling flag
+ Final_Point = 0x04000000,
+ Final_Target = 0x08000000,
+ Final_Angle = 0x10000000,
+ Unknown7 = 0x20000000, // NOT VERIFIED
+ Unknown8 = 0x40000000, // NOT VERIFIED
+ Unknown9 = 0x80000000, // NOT VERIFIED
// Masks
Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
// animation ids stored here, see AnimType enum, used with Animation flag
- Mask_Animations = 0xFF,
+ Mask_Animations = 0x7,
// flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,
- // CatmullRom interpolation mode used
- Mask_CatmullRom = Flying | Catmullrom,
// Unused, not suported flags
- Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13
+ Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown0|Unknown2|Unknown3|Unknown4|Unknown6|Unknown7|Unknown8|Unknown9
};
inline uint32& raw() { return (uint32&)*this; }
@@ -83,7 +86,7 @@ namespace Movement
// Constant interface
- bool isSmooth() const { return raw() & Mask_CatmullRom; }
+ bool isSmooth() const { return raw() & Catmullrom; }
bool isLinear() const { return !isSmooth(); }
bool isFacing() const { return raw() & Mask_Final_Facing; }
@@ -99,42 +102,47 @@ namespace Movement
void operator &= (uint32 f) { raw() &= f; }
void operator |= (uint32 f) { raw() |= f; }
- void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic)) | Animation | anim; }
- void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation)) | Parabolic; }
- void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Flying | Animation)) | Falling; }
- void EnableFlying() { raw() = (raw() & ~(Falling | Catmullrom)) | Flying; }
- void EnableCatmullRom() { raw() = (raw() & ~Flying) | Catmullrom; }
+ void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations | Falling | Parabolic | FallingSlow)) | Animation | (anim & Mask_Animations); }
+ void EnableParabolic() { raw() = (raw() & ~(Mask_Animations | Falling | Animation | FallingSlow)) | Parabolic; }
+ void EnableFlying() { raw() = (raw() & ~(Falling)) | Flying; }
+ void EnableFalling() { raw() = (raw() & ~(Mask_Animations | Parabolic | Animation | Flying)) | Falling; }
+ void EnableCatmullRom() { raw() = (raw() & ~SmoothGroundPath) | Catmullrom; }
void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; }
void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
- uint8 animId : 8;
+ uint8 animId : 3;
+ bool unknown0 : 1;
+ bool fallingSlow : 1;
bool done : 1;
bool falling : 1;
bool no_spline : 1;
- bool parabolic : 1;
- bool walkmode : 1;
+ bool unknown2 : 1;
bool flying : 1;
bool orientationFixed : 1;
- bool final_point : 1;
- bool final_target : 1;
- bool final_angle : 1;
bool catmullrom : 1;
bool cyclic : 1;
bool enter_cycle : 1;
- bool animation : 1;
bool frozen : 1;
bool transportEnter : 1;
bool transportExit : 1;
+ bool unknown3 : 1;
+ bool unknown4 : 1;
+ bool orientationInversed : 1;
+ bool smoothGroundPath : 1;
+ bool walkmode : 1;
+ bool uncompressedPath : 1;
+ bool unknown6 : 1;
+ bool animation : 1;
+ bool parabolic : 1;
+ bool final_point : 1;
+ bool final_target : 1;
+ bool final_angle : 1;
bool unknown7 : 1;
bool unknown8 : 1;
- bool orientationInversed : 1;
- bool unknown10 : 1;
- bool unknown11 : 1;
- bool unknown12 : 1;
- bool unknown13 : 1;
+ bool unknown9 : 1;
};
#if defined( __GNUC__ )
#pragma pack()
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index 87d8e4a0c34..78c6c98cb59 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -60,13 +60,12 @@ namespace Movement
{
MoveSpline& move_spline = *unit->movespline;
- // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes (movementInfo.transport.guid is 0 in that case)
- bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID();
+ bool transport = unit->GetTransGUID();
Location real_position;
// there is a big chance that current position is unknown if current state is not finalized, need compute it
- // this also allows CalculatePath spline position and update map position in much greater intervals
+ // this also allows calculate spline position and update map position in much greater intervals
// Don't compute for transport movement if the unit is in a motion between two transports
- if (!move_spline.Finalized() && move_spline.onTransport == transport)
+ if (!move_spline.Finalized() && move_spline.onTransport == (unit->GetTransGUID() != 0))
real_position = move_spline.ComputePosition();
else
{
@@ -86,13 +85,13 @@ namespace Movement
if (args.path.empty())
return 0;
- // corrent first vertex
+ // correct first vertex
args.path[0] = real_position;
args.initialOrientation = real_position.orientation;
- move_spline.onTransport = transport;
+ move_spline.onTransport = (unit->GetTransGUID() != 0);
uint32 moveFlags = unit->m_movementInfo.GetMovementFlags();
- moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD);
+ moveFlags |= MOVEMENTFLAG_FORWARD;
if (moveFlags & MOVEMENTFLAG_ROOT)
moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
@@ -118,7 +117,7 @@ namespace Movement
WorldPacket data(SMSG_MONSTER_MOVE, 64);
data.append(unit->GetPackGUID());
- if (transport)
+ if (unit->GetTransGUID())
{
data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
data.appendPackGUID(unit->GetTransGUID());
@@ -139,7 +138,7 @@ namespace Movement
if (move_spline.Finalized())
return;
- bool transport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID();
+ bool transport = unit->GetTransGUID();
Location loc;
if (move_spline.onTransport == transport)
loc = move_spline.ComputePosition();
@@ -158,7 +157,7 @@ namespace Movement
}
args.flags = MoveSplineFlag::Done;
- unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED);
+ unit->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_FORWARD);
move_spline.onTransport = transport;
move_spline.Initialize(args);
@@ -179,10 +178,11 @@ namespace Movement
{
args.splineId = splineIdGen.NewId();
// Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
- args.TransformForTransport = unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit->GetTransGUID();
+ args.TransformForTransport = unit->GetTransGUID();
// mix existing state into new
args.flags.walkmode = unit->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
- args.flags.flying = unit->m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
+ args.flags.flying = unit->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY));
+ args.flags.smoothGroundPath = true; // enabled by default, CatmullRom mode or client config "pathSmoothing" will disable this
}
void MoveSplineInit::SetFacing(const Unit* target)
@@ -224,6 +224,12 @@ namespace Movement
args.path[1] = transform(dest);
}
+ void MoveSplineInit::SetFall()
+ {
+ args.flags.EnableFalling();
+ args.flags.fallingSlow = unit->HasUnitMovementFlag(MOVEMENTFLAG_FALLING_SLOW);
+ }
+
Vector3 TransportPathTransform::operator()(Vector3 input)
{
if (_transformForTransport)
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index a94c84d92f3..c968f660f58 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -102,27 +102,39 @@ namespace Movement
* if not enabled linear spline mode will be choosen. Disabled by default
*/
void SetSmooth();
- /* Enables CatmullRom spline interpolation mode, enables flying animation. Disabled by default
+
+ /* Waypoints in packets will be sent without compression
+ */
+ void SetUncompressed();
+
+ /* Enables flying animation. Disabled by default
*/
void SetFly();
+
/* Enables walk mode. Disabled by default
*/
void SetWalk(bool enable);
+
/* Makes movement cyclic. Disabled by default
*/
void SetCyclic();
+
/* Enables falling mode. Disabled by default
*/
void SetFall();
+
/* Enters transport. Disabled by default
*/
void SetTransportEnter();
+
/* Exits transport. Disabled by default
*/
void SetTransportExit();
+
/* Inverses unit model orientation. Disabled by default
*/
void SetOrientationInversed();
+
/* Fixes unit's model rotation. Disabled by default
*/
void SetOrientationFixed(bool enable);
@@ -148,8 +160,8 @@ namespace Movement
inline void MoveSplineInit::SetFly() { args.flags.EnableFlying(); }
inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable; }
inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom(); }
+ inline void MoveSplineInit::SetUncompressed() { args.flags.uncompressedPath = true; }
inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true; }
- inline void MoveSplineInit::SetFall() { args.flags.EnableFalling(); }
inline void MoveSplineInit::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); }
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
index 51932877666..0793e51b164 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -19,7 +19,8 @@
#include "MovementPacketBuilder.h"
#include "MoveSpline.h"
-#include "ByteBuffer.h"
+#include "WorldPacket.h"
+#include "Object.h"
namespace Movement
{
@@ -42,7 +43,7 @@ namespace Movement
MonsterMoveFacingAngle = 4
};
- void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, ByteBuffer& data)
+ void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
{
MoveSplineFlag splineflags = move_spline.splineflags;
@@ -96,10 +97,10 @@ namespace Movement
data << uint8(MonsterMoveStop);
}
- void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data)
+ void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data)
{
uint32 last_idx = spline.getPointCount() - 3;
- const Vector3 * real_path = &spline.getPoint(1);
+ Vector3 const* real_path = &spline.getPoint(1);
data << last_idx;
data << real_path[last_idx]; // destination
@@ -116,14 +117,14 @@ namespace Movement
}
}
- void WriteCatmullRomPath(const Spline<int32>& spline, ByteBuffer& data)
+ void WriteUncompressedPath(Spline<int32> const& spline, ByteBuffer& data)
{
uint32 count = spline.getPointCount() - 3;
data << count;
data.append<Vector3>(&spline.getPoint(2), count);
}
- void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data)
+ void WriteUncompressedCyclicPath(Spline<int32> const& spline, ByteBuffer& data)
{
uint32 count = spline.getPointCount() - 3;
data << uint32(count + 1);
@@ -131,61 +132,117 @@ namespace Movement
data.append<Vector3>(&spline.getPoint(1), count);
}
- void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, ByteBuffer& data)
+ void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data)
{
WriteCommonMonsterMovePart(move_spline, data);
- const Spline<int32>& spline = move_spline.spline;
+ Spline<int32> const& spline = move_spline.spline;
MoveSplineFlag splineflags = move_spline.splineflags;
- if (splineflags & MoveSplineFlag::Mask_CatmullRom)
+ if (splineflags & MoveSplineFlag::UncompressedPath)
{
- if (splineflags.cyclic)
- WriteCatmullRomCyclicPath(spline, data);
+ if (!splineflags.cyclic)
+ WriteUncompressedPath(spline, data);
else
- WriteCatmullRomPath(spline, data);
+ WriteUncompressedCyclicPath(spline, data);
}
else
WriteLinearPath(spline, data);
}
- void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data)
+ void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data)
{
- //WriteClientStatus(mov, data);
- //data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount);
- //if (mov.SplineEnabled())
+ if (!data.WriteBit(!moveSpline.Finalized()))
+ return;
+
+ data.WriteBits(uint8(moveSpline.spline.mode()), 2);
+ data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation));
+ data.WriteBits(moveSpline.getPath().size(), 22);
+ switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing)
+ {
+ case MoveSplineFlag::Final_Target:
+ {
+ ObjectGuid targetGuid = moveSpline.facing.target;
+ data.WriteBits(2, 2);
+ data.WriteBit(targetGuid[4]);
+ data.WriteBit(targetGuid[3]);
+ data.WriteBit(targetGuid[7]);
+ data.WriteBit(targetGuid[2]);
+ data.WriteBit(targetGuid[6]);
+ data.WriteBit(targetGuid[1]);
+ data.WriteBit(targetGuid[0]);
+ data.WriteBit(targetGuid[5]);
+ break;
+ }
+ case MoveSplineFlag::Final_Angle:
+ data.WriteBits(0, 2);
+ break;
+ case MoveSplineFlag::Final_Point:
+ data.WriteBits(1, 2);
+ break;
+ default:
+ data.WriteBits(3, 2);
+ break;
+ }
+
+ data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration());
+ data.WriteBits(moveSpline.splineflags.raw(), 25);
+ }
+
+ void PacketBuilder::WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data)
+ {
+ if (!moveSpline.Finalized())
{
- MoveSplineFlag const& splineFlags = move_spline.splineflags;
+ MoveSplineFlag const& splineFlags = moveSpline.splineflags;
- data << splineFlags.raw();
+ if ((splineFlags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration())
+ data << moveSpline.vertical_acceleration; // added in 3.1
+
+ data << moveSpline.timePassed();
if (splineFlags.final_angle)
- {
- data << move_spline.facing.angle;
- }
+ data << moveSpline.facing.angle;
else if (splineFlags.final_target)
{
- data << move_spline.facing.target;
+ ObjectGuid facingGuid = moveSpline.facing.target;
+ data.WriteByteSeq(facingGuid[5]);
+ data.WriteByteSeq(facingGuid[3]);
+ data.WriteByteSeq(facingGuid[7]);
+ data.WriteByteSeq(facingGuid[1]);
+ data.WriteByteSeq(facingGuid[6]);
+ data.WriteByteSeq(facingGuid[4]);
+ data.WriteByteSeq(facingGuid[2]);
+ data.WriteByteSeq(facingGuid[0]);
}
- else if (splineFlags.final_point)
+
+ uint32 nodes = moveSpline.getPath().size();
+ for (uint32 i = 0; i < nodes; ++i)
{
- data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
+ data << float(moveSpline.getPath()[i].z);
+ data << float(moveSpline.getPath()[i].x);
+ data << float(moveSpline.getPath()[i].y);
}
- data << move_spline.timePassed();
- data << move_spline.Duration();
- data << move_spline.GetId();
+ if (splineFlags.final_point)
+ data << moveSpline.facing.f.x << moveSpline.facing.f.z << moveSpline.facing.f.y;
- data << float(1.f); // splineInfo.duration_mod; added in 3.1
data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
+ data << moveSpline.Duration();
+ if (splineFlags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
+ data << moveSpline.effect_start_time; // added in 3.1
- data << move_spline.vertical_acceleration; // added in 3.1
- data << move_spline.effect_start_time; // added in 3.1
+ data << float(1.f); // splineInfo.duration_mod; added in 3.1
+ }
- uint32 nodes = move_spline.getPath().size();
- data << nodes;
- data.append<Vector3>(&move_spline.getPath()[0], nodes);
- data << uint8(move_spline.spline.mode()); // added in 3.1
- data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination());
+ if (!moveSpline.isCyclic())
+ {
+ Vector3 dest = moveSpline.FinalDestination();
+ data << float(dest.z);
+ data << float(dest.x);
+ data << float(dest.y);
}
+ else
+ data << Vector3::zero();
+
+ data << moveSpline.GetId();
}
}
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h
index d1ad3d61eec..750cdc0fdbf 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.h
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h
@@ -20,27 +20,25 @@
#ifndef TRINITYSERVER_PACKET_BUILDER_H
#define TRINITYSERVER_PACKET_BUILDER_H
-#include "Define.h"
+#include "Define.h" // for uint32
+#include "G3D/Vector3.h"
+using G3D::Vector3;
class ByteBuffer;
-namespace G3D
-{
- class Vector3;
-}
+class WorldPacket;
namespace Movement
{
- using G3D::Vector3;
-
class MoveSpline;
class PacketBuilder
{
- static void WriteCommonMonsterMovePart(const MoveSpline& mov, ByteBuffer& data);
+ static void WriteCommonMonsterMovePart(const MoveSpline& mov, WorldPacket& data);
public:
- static void WriteMonsterMove(const MoveSpline& mov, ByteBuffer& data);
+ static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data);
static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data);
- static void WriteCreate(const MoveSpline& mov, ByteBuffer& data);
+ static void WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data);
+ static void WriteCreateData(MoveSpline const& moveSpline, ByteBuffer& data);
};
}
#endif // TRINITYSERVER_PACKET_BUILDER_H
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
index ffc19f10454..1a0f3d54d27 100644
--- a/src/server/game/Movement/Spline/MovementTypedefs.h
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -79,6 +79,8 @@ namespace Movement
extern double gravity;
extern UInt32Counter splineIdGen;
+ extern std::string MovementFlags_ToString(uint32 flags);
+ extern std::string MovementFlagsExtra_ToString(uint32 flags);
}
#endif // TRINITYSERVER_TYPEDEFS_H
diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp
index 375859263ab..f5bdba378d1 100644
--- a/src/server/game/Movement/Spline/MovementUtil.cpp
+++ b/src/server/game/Movement/Spline/MovementUtil.cpp
@@ -98,82 +98,86 @@ namespace Movement
STR(Pitch_Up ), // 0x00000040,
STR(Pitch_Down ), // 0x00000080,
- STR(Walk ), // 0x00000100, // Walking
- STR(Ontransport ), // 0x00000200,
- STR(Levitation ), // 0x00000400,
- STR(Root ), // 0x00000800,
- STR(Falling ), // 0x00001000,
- STR(Fallingfar ), // 0x00002000,
- STR(Pendingstop ), // 0x00004000,
- STR(PendingSTRafestop ), // 0x00008000,
- STR(Pendingforward ), // 0x00010000,
- STR(Pendingbackward ), // 0x00020000,
- STR(PendingSTRafeleft ), // 0x00040000,
- STR(PendingSTRaferight ), // 0x00080000,
- STR(Pendingroot ), // 0x00100000,
- STR(Swimming ), // 0x00200000, // Appears With Fly Flag Also
- STR(Ascending ), // 0x00400000, // Swim Up Also
- STR(Descending ), // 0x00800000, // Swim Down Also
- STR(Can_Fly ), // 0x01000000, // Can Fly In 3.3?
- STR(Flying ), // 0x02000000, // Actual Flying Mode
- STR(Spline_Elevation ), // 0x04000000, // Used For Flight Paths
- STR(Spline_Enabled ), // 0x08000000, // Used For Flight Paths
- STR(Waterwalking ), // 0x10000000, // Prevent Unit From Falling Through Water
- STR(Safe_Fall ), // 0x20000000, // Active Rogue Safe Fall Spell (Passive)
- STR(Hover ), // 0x40000000
- STR(Unknown13 ), // 0x80000000
- STR(Unk1 ),
- STR(Unk2 ),
- STR(Unk3 ),
- STR(Fullspeedturning ),
- STR(Fullspeedpitching ),
- STR(Allow_Pitching ),
- STR(Unk4 ),
- STR(Unk5 ),
- STR(Unk6 ),
- STR(Unk7 ),
- STR(Interp_Move ),
- STR(Interp_Turning ),
- STR(Interp_Pitching ),
- STR(Unk8 ),
- STR(Unk9 ),
- STR(Unk10 ),
+ STR(Walking ), // 0x00000100, // Walking
+ STR(DisableGravity ), // 0x00000200,
+ STR(Root ), // 0x00000400,
+ STR(Falling ), // 0x00000800,
+ STR(FallingFar ), // 0x00001000,
+ STR(PendingStop ), // 0x00002000,
+ STR(PendingStrafeStop ), // 0x00004000,
+ STR(PendingForward ), // 0x00008000,
+ STR(PendingBackward ), // 0x00010000,
+ STR(PendingStrafeLeft ), // 0x00020000,
+ STR(PendingStrafeRight ), // 0x00040000,
+ STR(PendingRoot ), // 0x00080000,
+ STR(Swimming ), // 0x00100000, // Appears With Fly Flag Also
+ STR(Ascending ), // 0x00200000, // Swim Up Also
+ STR(Descending ), // 0x00400000, // Swim Down Also
+ STR(Can_Fly ), // 0x00800000, // Can Fly In 3.3?
+ STR(Flying ), // 0x01000000, // Actual Flying Mode
+ STR(Spline_Elevation ), // 0x02000000, // Used For Flight Paths
+ STR(Waterwalking ), // 0x04000000, // Prevent Unit From Falling Through Water
+ STR(Safe_Fall ), // 0x08000000, // Active Rogue Safe Fall Spell (Passive)
+ STR(Hover ), // 0x10000000
+ STR(Local_Dirty ), // 0x20000000
+ STR(None31 ), // 0x40000000
+ STR(None32 ), // 0x80000000
+ };
+
+ char const* g_MovementFlagExtra_names[] =
+ {
+ STR(NoStrafe ),
+ STR(NoJump ),
+ STR(FullSpeedTurning ),
+ STR(FullSpeedPitching ),
+ STR(Allow_Pitching ),
+ STR(Unk6 ),
+ STR(Unk7 ),
+ STR(Unk8 ),
+ STR(Unk9 ),
+ STR(Unk10 ),
+ STR(Unk11 ),
+ STR(Unk12 ),
+ STR(Unk13 ),
+ STR(Interpolated_Movement),
+ STR(Interpolated_Turning ),
+ STR(Interpolated_Pitching),
};
char const* g_SplineFlag_names[32] =
{
- STR(AnimBit1 ), // 0x00000001,
- STR(AnimBit2 ), // 0x00000002,
- STR(AnimBit3 ), // 0x00000004,
- STR(AnimBit4 ), // 0x00000008,
- STR(AnimBit5 ), // 0x00000010,
- STR(AnimBit6 ), // 0x00000020,
- STR(AnimBit7 ), // 0x00000040,
- STR(AnimBit8 ), // 0x00000080,
- STR(Done ), // 0x00000100,
- STR(Falling ), // 0x00000200, // Not Compartible With Trajectory Movement
- STR(No_Spline ), // 0x00000400,
- STR(Trajectory ), // 0x00000800, // Not Compartible With Fall Movement
- STR(Walkmode ), // 0x00001000,
- STR(Flying ), // 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
- STR(Knockback ), // 0x00004000, // Model Orientation Fixed
- STR(Final_Point ), // 0x00008000,
- STR(Final_Target ), // 0x00010000,
- STR(Final_Angle ), // 0x00020000,
- STR(Catmullrom ), // 0x00040000, // Used Catmullrom Interpolation Mode
- STR(Cyclic ), // 0x00080000, // Movement By Cycled Spline
- STR(Enter_Cycle ), // 0x00100000, // Everytime Appears With Cyclic Flag In Monster Move Packet
- STR(Animation ), // 0x00200000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement
- STR(Unknown4 ), // 0x00400000, // Disables Movement By Path
- STR(Unknown5 ), // 0x00800000,
- STR(Unknown6 ), // 0x01000000,
- STR(Unknown7 ), // 0x02000000,
- STR(Unknown8 ), // 0x04000000,
- STR(OrientationInversed ), // 0x08000000, // Appears With Runmode Flag, Nodes ), // 1, Handles Orientation
- STR(Unknown10 ), // 0x10000000,
- STR(Unknown11 ), // 0x20000000,
- STR(Unknown12 ), // 0x40000000,
- STR(Unknown13 ), // 0x80000000,
+ STR(AnimBit1 ), // 0x00000001,
+ STR(AnimBit2 ), // 0x00000002,
+ STR(AnimBit3 ), // 0x00000004,
+ STR(Unknown0 ), // 0x00000008,
+ STR(FallingSlow ), // 0x00000010,
+ STR(Done ), // 0x00000020,
+ STR(Falling ), // 0x00000040, // Not Compartible With Trajectory Movement
+ STR(No_Spline ), // 0x00000080,
+ STR(Unknown2 ), // 0x00000100,
+ STR(Flying ), // 0x00000200, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
+ STR(OrientationFixed ), // 0x00000400, // Model Orientation Fixed
+ STR(Catmullrom ), // 0x00000800, // Used Catmullrom Interpolation Mode
+ STR(Cyclic ), // 0x00001000, // Movement By Cycled Spline
+ STR(Enter_Cycle ), // 0x00002000, // Everytime Appears With Cyclic Flag In Monster Move Packet
+ STR(Frozen ), // 0x00004000,
+ STR(TransportEnter ), // 0x00008000
+ STR(TransportExit ), // 0x00010000
+ STR(Unknown3 ), // 0x00020000,
+ STR(Unknown4 ), // 0x00040000,
+ STR(OrientationInversed), // 0x00080000, // Appears With Runmode Flag, Nodes ), // 1, Handles Orientation
+ STR(SmoothGroundPath ), // 0x00100000,
+ STR(Walkmode ), // 0x00200000,
+ STR(UncompressedPath ), // 0x00400000,
+ STR(Unknown6 ), // 0x00800000,
+ STR(Animation ), // 0x01000000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement
+ STR(Parabolic ), // 0x02000000, // Not Compartible With Fall Movement
+ STR(Final_Point ), // 0x04000000,
+ STR(Final_Target ), // 0x08000000,
+ STR(Final_Angle ), // 0x10000000,
+ STR(Unknown7 ), // 0x20000000,
+ STR(Unknown8 ), // 0x40000000,
+ STR(Unknown9 ), // 0x80000000,
};
template<class Flags, int N>
@@ -192,4 +196,18 @@ namespace Movement
print_flags(raw(), g_SplineFlag_names, str);
return str;
}
+
+ std::string MovementFlags_ToString(uint32 flags)
+ {
+ std::string str;
+ print_flags(flags, g_MovementFlag_names, str);
+ return str;
+ }
+
+ std::string MovementFlagsExtra_ToString(uint32 flags)
+ {
+ std::string str;
+ print_flags(flags, g_MovementFlagExtra_names, str);
+ return str;
+ }
}
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h
index 9ea81ded055..c2248c72fd0 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvP.h
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.h
@@ -30,11 +30,10 @@ enum OutdoorPvPTypes
OUTDOOR_PVP_NA = 2,
OUTDOOR_PVP_TF = 3,
OUTDOOR_PVP_ZM = 4,
- OUTDOOR_PVP_SI = 5,
- OUTDOOR_PVP_EP = 6
+ OUTDOOR_PVP_SI = 5
};
-#define MAX_OUTDOORPVP_TYPES 7
+#define MAX_OUTDOORPVP_TYPES 6
enum ObjectiveStates
{
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 9b3732d232b..0f54e0af6c1 100644
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -19,20 +19,21 @@
#include "QuestDef.h"
#include "Player.h"
#include "World.h"
+#include "ObjectMgr.h"
Quest::Quest(Field* questRecord)
{
Id = questRecord[0].GetUInt32();
Method = questRecord[1].GetUInt8();
Level = questRecord[2].GetInt16();
- MinLevel = questRecord[3].GetUInt8();
- MaxLevel = questRecord[4].GetUInt8();
+ MinLevel = uint32(questRecord[3].GetInt16());
+ MaxLevel = uint32(questRecord[4].GetInt16());
ZoneOrSort = questRecord[5].GetInt16();
Type = questRecord[6].GetUInt16();
SuggestedPlayers = questRecord[7].GetUInt8();
LimitTime = questRecord[8].GetUInt32();
RequiredClasses = questRecord[9].GetUInt16();
- RequiredRaces = questRecord[10].GetUInt16();
+ RequiredRaces = questRecord[10].GetUInt32();
RequiredSkillId = questRecord[11].GetUInt16();
RequiredSkillPoints = questRecord[12].GetUInt16();
RequiredFactionId1 = questRecord[13].GetUInt16();
@@ -61,91 +62,117 @@ Quest::Quest(Field* questRecord)
SourceSpellid = questRecord[36].GetUInt32();
Flags = questRecord[37].GetUInt32();
SpecialFlags = questRecord[38].GetUInt8();
- RewardTitleId = questRecord[39].GetUInt8();
- RequiredPlayerKills = questRecord[40].GetUInt8();
- RewardTalents = questRecord[41].GetUInt8();
- RewardArenaPoints = questRecord[42].GetUInt16();
-
+ MinimapTargetMark = questRecord[39].GetUInt8();
+ RewardTitleId = questRecord[40].GetUInt8();
+ RequiredPlayerKills = questRecord[41].GetUInt8();
+ RewardTalents = questRecord[42].GetUInt8();
+ RewardArenaPoints = questRecord[43].GetUInt16();
+ RewardSkillId = questRecord[44].GetUInt16();
+ RewardSkillPoints = questRecord[45].GetUInt8();
+ RewardReputationMask = questRecord[46].GetUInt8();
+ QuestGiverPortrait = questRecord[47].GetUInt32();
+ QuestTurnInPortrait = questRecord[48].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewardItemId[i] = questRecord[43+i].GetUInt32();
+ RewardItemId[i] = questRecord[49+i].GetUInt32();
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
- RewardItemIdCount[i] = questRecord[47+i].GetUInt16();
+ RewardItemIdCount[i] = questRecord[53+i].GetUInt16();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewardChoiceItemId[i] = questRecord[51+i].GetUInt32();
+ RewardChoiceItemId[i] = questRecord[57+i].GetUInt32();
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
- RewardChoiceItemCount[i] = questRecord[57+i].GetUInt16();
+ RewardChoiceItemCount[i] = questRecord[63+i].GetUInt16();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewardFactionId[i] = questRecord[63+i].GetUInt16();
+ RewardFactionId[i] = questRecord[69+i].GetUInt16();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewardFactionValueId[i] = questRecord[68+i].GetInt32();
+ RewardFactionValueId[i] = questRecord[74+i].GetInt32();
for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i)
- RewardFactionValueIdOverride[i] = questRecord[73+i].GetInt32();
-
- PointMapId = questRecord[78].GetUInt16();
- PointX = questRecord[79].GetFloat();
- PointY = questRecord[80].GetFloat();
- PointOption = questRecord[81].GetUInt32();
- Title = questRecord[82].GetString();
- Objectives = questRecord[83].GetString();
- Details = questRecord[84].GetString();
- EndText = questRecord[85].GetString();
- OfferRewardText = questRecord[86].GetString();
- RequestItemsText = questRecord[87].GetString();
- CompletedText = questRecord[88].GetString();
+ RewardFactionValueIdOverride[i] = questRecord[79+i].GetInt32();
+
+ PointMapId = questRecord[84].GetUInt16();
+ PointX = questRecord[85].GetFloat();
+ PointY = questRecord[86].GetFloat();
+ PointOption = questRecord[87].GetUInt32();
+ Title = questRecord[88].GetString();
+ Objectives = questRecord[89].GetString();
+ Details = questRecord[90].GetString();
+ EndText = questRecord[91].GetString();
+ CompletedText = questRecord[92].GetString();
+ OfferRewardText = questRecord[93].GetString();
+ RequestItemsText = questRecord[94].GetString();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- RequiredNpcOrGo[i] = questRecord[89+i].GetInt32();
+ RequiredNpcOrGo[i] = questRecord[95+i].GetInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- RequiredNpcOrGoCount[i] = questRecord[93+i].GetUInt16();
+ RequiredNpcOrGoCount[i] = questRecord[99+i].GetUInt16();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemId[i] = questRecord[97+i].GetUInt32();
+ RequiredSourceItemId[i] = questRecord[103+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
- RequiredSourceItemCount[i] = questRecord[101+i].GetUInt16();
+ RequiredSourceItemCount[i] = questRecord[107+i].GetUInt16();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
- RequiredItemId[i] = questRecord[105+i].GetUInt32();
+ RequiredItemId[i] = questRecord[111+i].GetUInt32();
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
- RequiredItemCount[i] = questRecord[111+i].GetUInt16();
+ RequiredItemCount[i] = questRecord[117+i].GetUInt16();
- // int8 Unknown0 = questRecord[117].GetUInt8();
+ RequiredSpell = questRecord[123].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
- ObjectiveText[i] = questRecord[118+i].GetString();
+ ObjectiveText[i] = questRecord[124+i].GetString();
+
+ for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ RewardCurrencyId[i] = questRecord[128+i].GetUInt16();
+
+ for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ RewardCurrencyCount[i] = questRecord[132+i].GetUInt8();
+
+ for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ RequiredCurrencyId[i] = questRecord[136+i].GetUInt16();
+
+ for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ RequiredCurrencyCount[i] = questRecord[140+i].GetUInt8();
+
+ QuestGiverTextWindow = questRecord[144].GetString();
+ QuestGiverTargetName = questRecord[145].GetString();
+ QuestTurnTextWindow = questRecord[146].GetString();
+ QuestTurnTargetName = questRecord[147].GetString();
+ SoundAccept = questRecord[148].GetUInt16();
+ SoundTurnIn = questRecord[149].GetUInt16();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmote[i] = questRecord[122+i].GetUInt16();
+ DetailsEmote[i] = questRecord[150+i].GetUInt16();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- DetailsEmoteDelay[i] = questRecord[126+i].GetUInt32();
+ DetailsEmoteDelay[i] = questRecord[154+i].GetUInt32();
- EmoteOnIncomplete = questRecord[130].GetUInt16();
- EmoteOnComplete = questRecord[131].GetUInt16();
+ EmoteOnIncomplete = questRecord[158].GetUInt16();
+ EmoteOnComplete = questRecord[159].GetUInt16();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmote[i] = questRecord[132+i].GetInt16();
+ OfferRewardEmote[i] = questRecord[160+i].GetInt16();
for (int i = 0; i < QUEST_EMOTE_COUNT; ++i)
- OfferRewardEmoteDelay[i] = questRecord[136+i].GetInt32();
+ OfferRewardEmoteDelay[i] = questRecord[164+i].GetInt32();
- //int32 WDBVerified = questRecord[140].GetInt32();
+ // int32 WDBVerified = questRecord[168].GetInt32();
if (SpecialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT)
Flags |= QUEST_FLAGS_AUTO_ACCEPT;
_reqItemsCount = 0;
- _reqCreatureOrGOcount = 0;
+ _reqNpcOrGoCount = 0;
_rewItemsCount = 0;
_rewChoiceItemsCount = 0;
+ _rewCurrencyCount = 0;
+ _reqCurrencyCount = 0;
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
if (RequiredItemId[i])
@@ -153,7 +180,7 @@ Quest::Quest(Field* questRecord)
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
if (RequiredNpcOrGo[i])
- ++_reqCreatureOrGOcount;
+ ++_reqNpcOrGoCount;
for (int i = 0; i < QUEST_REWARDS_COUNT; ++i)
if (RewardItemId[i])
@@ -162,6 +189,14 @@ Quest::Quest(Field* questRecord)
for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
if (RewardChoiceItemId[i])
++_rewChoiceItemsCount;
+
+ for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ if (RewardCurrencyId[i])
+ ++_rewCurrencyCount;
+
+ for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
+ if (RequiredCurrencyId[i])
+ ++_reqCurrencyCount;
}
uint32 Quest::XPValue(Player* player) const
@@ -203,6 +238,79 @@ int32 Quest::GetRewOrReqMoney() const
return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_DROP_MONEY));
}
+void Quest::BuildExtraQuestInfo(WorldPacket& data, Player* player) const
+{
+ data << uint32(GetRewChoiceItemsCount());
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
+ data << uint32(RewardChoiceItemId[i]);
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
+ data << uint32(RewardChoiceItemCount[i]);
+ for (uint8 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
+ {
+ if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(RewardChoiceItemId[i]))
+ data << uint32(itemTemplate->DisplayInfoID);
+ else
+ data << uint32(0);
+ }
+
+ data << uint32(GetReqItemsCount());
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ data << uint32(RewardItemId[i]);
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ data << uint32(RewardItemIdCount[i]);
+ for (uint8 i = 0; i < QUEST_REWARDS_COUNT; ++i)
+ {
+ if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(RewardItemId[i]))
+ data << uint32(itemTemplate->DisplayInfoID);
+ else
+ data << uint32(0);
+ }
+
+ data << uint32(GetRewOrReqMoney());
+ data << uint32(XPValue(player) * sWorld->getRate(RATE_XP_QUEST));
+
+ data << uint32(GetCharTitleId());
+ data << uint32(0); // unk
+ data << float(0.0f); // unk
+ data << uint32(GetBonusTalents());
+ data << uint32(0); // unk
+ data << uint32(GetRewardReputationMask());
+
+ /* Pre cata struct, some of these unks might be the missing values in cata:
+ // rewarded honor points. Multiply with 10 to satisfy client
+ data << 10 * Trinity::Honor::hk_honor_at_level(_session->GetPlayer()->getLevel(), quest->GetRewHonorMultiplier());
+ data << float(0); // unk, honor multiplier?
+ data << uint32(0x08); // unused by client?
+ data << uint32(quest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0)
+ data << int32(quest->GetRewSpellCast()); // casted spell
+ data << uint32(0); // unknown
+ data << uint32(quest->GetBonusTalents()); // bonus talents
+ data << uint32(quest->GetRewArenaPoints()); // arena points
+ data << uint32(0);
+ */
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward factions ids
+ data << uint32(RewardFactionId[i]);
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // columnid in QuestFactionReward.dbc (zero based)?
+ data << int32(RewardFactionValueId[i]);
+
+ for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // reward reputation override?
+ data << uint32(RewardFactionValueIdOverride[i]);
+
+ data << uint32(GetRewSpell());
+ data << uint32(GetRewSpellCast());
+
+ for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ data << uint32(RewardCurrencyId[i]);
+
+ for (uint8 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
+ data << uint32(RewardCurrencyCount[i]);
+
+ data << uint32(GetRewardSkillId());
+ data << uint32(GetRewardSkillPoints());
+}
+
uint32 Quest::GetRewMoneyMaxLevel() const
{
if (HasFlag(QUEST_FLAGS_NO_MONEY_FROM_XP))
@@ -253,7 +361,7 @@ uint32 Quest::CalculateHonorGain(uint8 level) const
uint32 honor = 0;
- if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f)
+ /*if (GetRewHonorAddition() > 0 || GetRewHonorMultiplier() > 0.0f)
{
// values stored from 0.. for 1...
TeamContributionPointsEntry const* tc = sTeamContributionPointsStore.LookupEntry(level);
@@ -262,7 +370,7 @@ uint32 Quest::CalculateHonorGain(uint8 level) const
honor = uint32(tc->value * GetRewHonorMultiplier() * 0.1f);
honor += GetRewHonorAddition();
- }
+ }*/
return honor;
}
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 995396c37f5..4ab41ba13f8 100644
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -22,6 +22,7 @@
#include "Define.h"
#include "DatabaseEnv.h"
#include "SharedDefines.h"
+#include "WorldPacket.h"
#include "DBCEnums.h"
#include <string>
@@ -42,6 +43,8 @@ class ObjectMgr;
#define QUEST_REPUTATIONS_COUNT 5
#define QUEST_EMOTE_COUNT 4
#define QUEST_PVP_KILL_SLOT 0
+#define QUEST_REWARD_CURRENCY_COUNT 4
+#define QUEST_REQUIRED_CURRENCY_COUNT 4
enum QuestFailedReason
{
@@ -108,25 +111,25 @@ enum QuestStatus
enum QuestGiverStatus
{
- DIALOG_STATUS_NONE = 0,
- DIALOG_STATUS_UNAVAILABLE = 1,
- DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 2,
- DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 3,
- DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 4,
- DIALOG_STATUS_INCOMPLETE = 5,
- DIALOG_STATUS_REWARD_REP = 6,
- DIALOG_STATUS_AVAILABLE_REP = 7,
- DIALOG_STATUS_AVAILABLE = 8,
- DIALOG_STATUS_REWARD2 = 9, // no yellow dot on minimap
- DIALOG_STATUS_REWARD = 10, // yellow dot on minimap
+ DIALOG_STATUS_NONE = 0x000,
+ DIALOG_STATUS_UNK = 0x001,
+ DIALOG_STATUS_UNAVAILABLE = 0x002,
+ DIALOG_STATUS_LOW_LEVEL_AVAILABLE = 0x004,
+ DIALOG_STATUS_LOW_LEVEL_REWARD_REP = 0x008,
+ DIALOG_STATUS_LOW_LEVEL_AVAILABLE_REP = 0x010,
+ DIALOG_STATUS_INCOMPLETE = 0x020,
+ DIALOG_STATUS_REWARD_REP = 0x040,
+ DIALOG_STATUS_AVAILABLE_REP = 0x080,
+ DIALOG_STATUS_AVAILABLE = 0x100,
+ DIALOG_STATUS_REWARD2 = 0x200, // no yellow dot on minimap
+ DIALOG_STATUS_REWARD = 0x400, // yellow dot on minimap
// Custom value meaning that script call did not return any valid quest status
- DIALOG_STATUS_SCRIPTED_NO_STATUS = 0x1000,
+ DIALOG_STATUS_SCRIPTED_NO_STATUS = 0x1000
};
enum QuestFlags
{
- // Flags used at server and sent to client
QUEST_FLAGS_NONE = 0x00000000,
QUEST_FLAGS_STAY_ALIVE = 0x00000001, // Not used currently
QUEST_FLAGS_PARTY_ACCEPT = 0x00000002, // Not used currently. If player in party, all players that can accept this quest will receive confirmation box to accept quest CMSG_QUEST_CONFIRM_ACCEPT/SMSG_QUEST_CONFIRM_ACCEPT
@@ -148,7 +151,11 @@ enum QuestFlags
QUEST_FLAGS_DISPLAY_ITEM_IN_TRACKER = 0x00020000, // Displays usable item in quest tracker
QUEST_FLAGS_OBJ_TEXT = 0x00040000, // use Objective text as Complete text
QUEST_FLAGS_AUTO_ACCEPT = 0x00080000, // The client recognizes this flag as auto-accept. However, NONE of the current quests (3.3.5a) have this flag. Maybe blizz used to use it, or will use it in the future.
-
+ QUEST_FLAGS_AUTO_SUBMIT = 0x00100000, // Quests with this flag player submit automatically by special button in player gui
+ QUEST_FLAGS_AUTO_TAKE = 0x00200000, // Automatically suggestion of accepting quest. Not from npc.
+ //QUEST_FLAGS_UNK2 = 0x00400000,
+ //QUEST_FLAGS_UNK3 = 0x00800000, // Found in quest 14069
+ //QUEST_FLAGS_UNK4 = 0x01000000,
// ... 4.x added flags up to 0x80000000 - all unknown for now
};
@@ -185,6 +192,11 @@ struct QuestLocale
StringVector EndText;
StringVector CompletedText;
std::vector< StringVector > ObjectiveText;
+ // new on 4.x
+ StringVector QuestGiverTextWindow;
+ StringVector QuestGiverTargetName;
+ StringVector QuestTurnTextWindow;
+ StringVector QuestTurnTargetName;
};
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
@@ -244,6 +256,10 @@ class Quest
std::string const& GetRequestItemsText() const { return RequestItemsText; }
std::string const& GetEndText() const { return EndText; }
std::string const& GetCompletedText() const { return CompletedText; }
+ std::string const& GetQuestGiverTextWindow() const { return QuestGiverTextWindow; }
+ std::string const& GetQuestGiverTargetName() const { return QuestGiverTargetName; }
+ std::string const& GetQuestTurnTextWindow() const { return QuestTurnTextWindow; }
+ std::string const& GetQuestTurnTargetName() const { return QuestTurnTargetName; }
int32 GetRewOrReqMoney() const;
uint32 GetRewHonorAddition() const { return RewardHonor; }
float GetRewHonorMultiplier() const { return RewardHonorMultiplier; }
@@ -256,12 +272,22 @@ class Quest
float GetPointX() const { return PointX; }
float GetPointY() const { return PointY; }
uint32 GetPointOpt() const { return PointOption; }
+ uint32 GetRequiredSpell() const { return RequiredSpell; }
+ uint32 GetSoundAccept() const { return SoundAccept; }
+ uint32 GetSoundTurnIn() const { return SoundTurnIn; }
uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; }
uint32 GetCompleteEmote() const { return EmoteOnComplete; }
bool IsRepeatable() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE; }
bool IsAutoAccept() const;
bool IsAutoComplete() const;
uint32 GetFlags() const { return Flags; }
+ uint32 GetSpecialFlags() const { return SpecialFlags; }
+ uint32 GetMinimapTargetMark() const { return MinimapTargetMark; }
+ uint32 GetRewardSkillId() const { return RewardSkillId; }
+ uint32 GetRewardSkillPoints() const { return RewardSkillPoints; }
+ uint32 GetRewardReputationMask() const { return RewardReputationMask; }
+ uint32 GetQuestGiverPortrait() const { return QuestGiverPortrait; }
+ uint32 GetQuestTurnInPortrait() const { return QuestTurnInPortrait; }
bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; }
bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; }
bool IsMonthly() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_MONTHLY; }
@@ -291,11 +317,20 @@ class Quest
uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT];
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT];
uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT];
+ // 4.x
+ uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT];
+ uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT];
+ uint32 RequiredCurrencyId[QUEST_REQUIRED_CURRENCY_COUNT];
+ uint32 RequiredCurrencyCount[QUEST_REQUIRED_CURRENCY_COUNT];
uint32 GetReqItemsCount() const { return _reqItemsCount; }
- uint32 GetReqCreatureOrGOcount() const { return _reqCreatureOrGOcount; }
+ uint32 GetReqCreatureOrGOcount() const { return _reqNpcOrGoCount; }
uint32 GetRewChoiceItemsCount() const { return _rewChoiceItemsCount; }
uint32 GetRewItemsCount() const { return _rewItemsCount; }
+ uint32 GetRewCurrencyCount() const { return _rewCurrencyCount; }
+ uint32 GetReqCurrencyCount() const { return _reqCurrencyCount; }
+
+ void BuildExtraQuestInfo(WorldPacket& data, Player* player) const;
typedef std::vector<int32> PrevQuests;
PrevQuests prevQuests;
@@ -305,9 +340,11 @@ class Quest
// cached data
private:
uint32 _reqItemsCount;
- uint32 _reqCreatureOrGOcount;
+ uint32 _reqNpcOrGoCount;
uint32 _rewChoiceItemsCount;
uint32 _rewItemsCount;
+ uint32 _rewCurrencyCount;
+ uint32 _reqCurrencyCount;
// table data
protected:
@@ -366,6 +403,20 @@ class Quest
uint32 PointOption;
uint32 EmoteOnIncomplete;
uint32 EmoteOnComplete;
+ // new in 4.x
+ uint32 MinimapTargetMark;
+ uint32 RewardSkillId;
+ uint32 RewardSkillPoints;
+ uint32 RewardReputationMask;
+ uint32 QuestGiverPortrait;
+ uint32 QuestTurnInPortrait;
+ uint32 RequiredSpell;
+ std::string QuestGiverTextWindow;
+ std::string QuestGiverTargetName;
+ std::string QuestTurnTextWindow;
+ std::string QuestTurnTargetName;
+ uint32 SoundAccept;
+ uint32 SoundTurnIn;
uint32 SpecialFlags; // custom flags, not sniffed/WDB
};
diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp
index 69e677bd89d..df6497f2513 100644
--- a/src/server/game/Reputation/ReputationMgr.cpp
+++ b/src/server/game/Reputation/ReputationMgr.cpp
@@ -25,6 +25,7 @@
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "Opcodes.h"
+#include "WorldSession.h"
const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000};
@@ -198,7 +199,7 @@ void ReputationMgr::SendState(FactionState const* faction)
void ReputationMgr::SendInitialReputations()
{
- uint8 count = 128;
+ uint16 count = 256;
WorldPacket data(SMSG_INITIALIZE_FACTIONS, 4 + count * 5);
data << uint32(count);
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 8da94ef2852..e4d2922cb6c 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -104,6 +104,10 @@ void AddSC_boss_balinda();
void AddSC_boss_drekthar();
void AddSC_boss_galvangar();
void AddSC_boss_vanndar();
+void AddSC_boss_alizabal(); //Baradin Hold
+void AddSC_boss_occuthar();
+void AddSC_boss_pit_lord_argaloth();
+void AddSC_instance_baradin_hold();
void AddSC_blackrock_depths(); //Blackrock Depths
void AddSC_boss_ambassador_flamelash();
void AddSC_boss_anubshiah();
@@ -240,28 +244,22 @@ void AddSC_boss_halazzi();
void AddSC_boss_hex_lord_malacrass();
void AddSC_boss_janalai();
void AddSC_boss_nalorakk();
-void AddSC_boss_zuljin();
+void AddSC_boss_daakara();
void AddSC_instance_zulaman();
void AddSC_zulaman();
-void AddSC_boss_jeklik(); //Zul'Gurub
-void AddSC_boss_venoxis();
-void AddSC_boss_marli();
-void AddSC_boss_mandokir();
-void AddSC_boss_gahzranka();
-void AddSC_boss_thekal();
-void AddSC_boss_arlokk();
-void AddSC_boss_jindo();
-void AddSC_boss_hakkar();
-void AddSC_boss_grilek();
+void AddSC_boss_grilek(); // Zul'Gurub
void AddSC_boss_hazzarah();
+void AddSC_boss_jindo_the_godbreaker();
+void AddSC_boss_kilnara();
+void AddSC_boss_mandokir();
void AddSC_boss_renataki();
+void AddSC_boss_venoxis();
void AddSC_boss_wushoolay();
+void AddSC_boss_zanzil();
void AddSC_instance_zulgurub();
-
//void AddSC_alterac_mountains();
void AddSC_arathi_highlands();
void AddSC_blasted_lands();
-void AddSC_boss_kruul();
void AddSC_burning_steppes();
void AddSC_duskwood();
void AddSC_eastern_plaguelands();
@@ -352,12 +350,17 @@ void AddSC_instance_wailing_caverns();
void AddSC_boss_zum_rah(); //Zul'Farrak
void AddSC_zulfarrak();
void AddSC_instance_zulfarrak();
+void AddSC_instance_halls_of_origination();
+void AddSC_boss_temple_guardian_anhuur();
+void AddSC_boss_earthrager_ptah();
+void AddSC_boss_anraphet();
+void AddSC_instance_firelands();
+void AddSC_boss_alysrazor();
void AddSC_ashenvale();
void AddSC_azshara();
void AddSC_azuremyst_isle();
void AddSC_bloodmyst_isle();
-void AddSC_boss_azuregos();
void AddSC_darkshore();
void AddSC_desolace();
void AddSC_durotar();
@@ -672,6 +675,9 @@ void AddSC_shattrath_city();
void AddSC_terokkar_forest();
void AddSC_zangarmarsh();
+// Maelstrom
+void AddSC_kezan();
+
// Events
void AddSC_event_childrens_week();
@@ -686,7 +692,6 @@ void AddSC_shaman_pet_scripts();
// battlegrounds
// outdoor pvp
-void AddSC_outdoorpvp_ep();
void AddSC_outdoorpvp_hp();
void AddSC_outdoorpvp_na();
void AddSC_outdoorpvp_si();
@@ -710,6 +715,7 @@ void AddScripts()
AddKalimdorScripts();
AddOutlandScripts();
AddNorthrendScripts();
+ AddMaelstromScripts();
AddEventScripts();
AddPetScripts();
AddBattlegroundScripts();
@@ -815,6 +821,10 @@ void AddEasternKingdomsScripts()
AddSC_boss_drekthar();
AddSC_boss_galvangar();
AddSC_boss_vanndar();
+ AddSC_boss_alizabal(); //Baradin Hold
+ AddSC_boss_occuthar();
+ AddSC_boss_pit_lord_argaloth();
+ AddSC_instance_baradin_hold();
AddSC_blackrock_depths(); //Blackrock Depths
AddSC_boss_ambassador_flamelash();
AddSC_boss_anubshiah();
@@ -951,28 +961,23 @@ void AddEasternKingdomsScripts()
AddSC_boss_hex_lord_malacrass();
AddSC_boss_janalai();
AddSC_boss_nalorakk();
- AddSC_boss_zuljin();
+ AddSC_boss_daakara();
AddSC_instance_zulaman();
AddSC_zulaman();
- AddSC_boss_jeklik(); //Zul'Gurub
- AddSC_boss_venoxis();
- AddSC_boss_marli();
- AddSC_boss_mandokir();
- AddSC_boss_gahzranka();
- AddSC_boss_thekal();
- AddSC_boss_arlokk();
- AddSC_boss_jindo();
- AddSC_boss_hakkar();
- AddSC_boss_grilek();
+ AddSC_boss_grilek(); // Zul'Gurub
AddSC_boss_hazzarah();
+ AddSC_boss_jindo_the_godbreaker();
+ AddSC_boss_kilnara();
+ AddSC_boss_mandokir();
AddSC_boss_renataki();
+ AddSC_boss_venoxis();
AddSC_boss_wushoolay();
+ AddSC_boss_zanzil();
AddSC_instance_zulgurub();
//AddSC_alterac_mountains();
AddSC_arathi_highlands();
AddSC_blasted_lands();
- AddSC_boss_kruul();
AddSC_burning_steppes();
AddSC_duskwood();
AddSC_eastern_plaguelands();
@@ -1072,7 +1077,6 @@ void AddKalimdorScripts()
AddSC_azshara();
AddSC_azuremyst_isle();
AddSC_bloodmyst_isle();
- AddSC_boss_azuregos();
AddSC_darkshore();
AddSC_desolace();
AddSC_durotar();
@@ -1091,6 +1095,14 @@ void AddKalimdorScripts()
AddSC_thunder_bluff();
AddSC_ungoro_crater();
AddSC_winterspring();
+
+ AddSC_instance_halls_of_origination();
+ AddSC_boss_temple_guardian_anhuur();
+ AddSC_boss_earthrager_ptah();
+ AddSC_boss_anraphet();
+
+ AddSC_instance_firelands();
+ AddSC_boss_alysrazor();
#endif
}
@@ -1395,6 +1407,14 @@ void AddNorthrendScripts()
#endif
}
+
+void AddMaelstromScripts()
+{
+#ifdef SCRIPTS
+ AddSC_kezan();
+#endif
+}
+
void AddEventScripts()
{
#ifdef SCRIPTS
@@ -1417,7 +1437,6 @@ void AddPetScripts()
void AddOutdoorPvPScripts()
{
#ifdef SCRIPTS
- AddSC_outdoorpvp_ep();
AddSC_outdoorpvp_hp();
AddSC_outdoorpvp_na();
AddSC_outdoorpvp_si();
diff --git a/src/server/game/Scripting/ScriptLoader.h b/src/server/game/Scripting/ScriptLoader.h
index db4c5b0cf46..a68f78997b3 100644
--- a/src/server/game/Scripting/ScriptLoader.h
+++ b/src/server/game/Scripting/ScriptLoader.h
@@ -27,6 +27,7 @@ void AddEasternKingdomsScripts();
void AddKalimdorScripts();
void AddOutlandScripts();
void AddNorthrendScripts();
+void AddMaelstromScripts();
void AddEventScripts();
void AddPetScripts();
void AddBattlegroundScripts();
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index d7a2c147edb..f035810eca3 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -1163,7 +1163,7 @@ void ScriptMgr::OnPlayerTalentsReset(Player* player, bool noCost)
FOREACH_SCRIPT(PlayerScript)->OnTalentsReset(player, noCost);
}
-void ScriptMgr::OnPlayerMoneyChanged(Player* player, int32& amount)
+void ScriptMgr::OnPlayerMoneyChanged(Player* player, int64& amount)
{
FOREACH_SCRIPT(PlayerScript)->OnMoneyChanged(player, amount);
}
@@ -1299,12 +1299,12 @@ void ScriptMgr::OnGuildDisband(Guild* guild)
FOREACH_SCRIPT(GuildScript)->OnDisband(guild);
}
-void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair)
+void ScriptMgr::OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint64 &amount, bool isRepair)
{
FOREACH_SCRIPT(GuildScript)->OnMemberWitdrawMoney(guild, player, amount, isRepair);
}
-void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount)
+void ScriptMgr::OnGuildMemberDepositMoney(Guild* guild, Player* player, uint64 &amount)
{
FOREACH_SCRIPT(GuildScript)->OnMemberDepositMoney(guild, player, amount);
}
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index a0724ac47fb..ada1953c305 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -61,7 +61,6 @@ class WorldPacket;
class WorldSocket;
class WorldObject;
-struct AchievementCriteriaData;
struct AuctionEntry;
struct ConditionSourceInfo;
struct Condition;
@@ -702,7 +701,7 @@ class PlayerScript : public UnitScript
virtual void OnTalentsReset(Player* /*player*/, bool /*noCost*/) { }
// Called when a player's money is modified (before the modification is done)
- virtual void OnMoneyChanged(Player* /*player*/, int32& /*amount*/) { }
+ virtual void OnMoneyChanged(Player* /*player*/, int64& /*amount*/) { }
// Called when a player gains XP (before anything is given)
virtual void OnGiveXP(Player* /*player*/, uint32& /*amount*/, Unit* /*victim*/) { }
@@ -792,10 +791,10 @@ class GuildScript : public ScriptObject
virtual void OnDisband(Guild* /*guild*/) { }
// Called when a guild member withdraws money from a guild bank.
- virtual void OnMemberWitdrawMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/, bool /*isRepair*/) { }
+ virtual void OnMemberWitdrawMoney(Guild* /*guild*/, Player* /*player*/, uint64& /*amount*/, bool /*isRepair*/) { }
// Called when a guild member deposits money in a guild bank.
- virtual void OnMemberDepositMoney(Guild* /*guild*/, Player* /*player*/, uint32& /*amount*/) { }
+ virtual void OnMemberDepositMoney(Guild* /*guild*/, Player* /*player*/, uint64& /*amount*/) { }
// Called when a guild member moves an item in a guild bank.
virtual void OnItemMove(Guild* /*guild*/, Player* /*player*/, Item* /*pItem*/, bool /*isSrcBank*/, uint8 /*srcContainer*/, uint8 /*srcSlotId*/,
@@ -1014,7 +1013,7 @@ class ScriptMgr
void OnPlayerLevelChanged(Player* player, uint8 oldLevel);
void OnPlayerFreeTalentPointsChanged(Player* player, uint32 newPoints);
void OnPlayerTalentsReset(Player* player, bool noCost);
- void OnPlayerMoneyChanged(Player* player, int32& amount);
+ void OnPlayerMoneyChanged(Player* player, int64& amount);
void OnGivePlayerXP(Player* player, uint32& amount, Unit* victim);
void OnPlayerReputationChange(Player* player, uint32 factionID, int32& standing, bool incremental);
void OnPlayerDuelRequest(Player* target, Player* challenger);
@@ -1044,8 +1043,8 @@ class ScriptMgr
void OnGuildInfoChanged(Guild* guild, const std::string& newInfo);
void OnGuildCreate(Guild* guild, Player* leader, const std::string& name);
void OnGuildDisband(Guild* guild);
- void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint32 &amount, bool isRepair);
- void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint32 &amount);
+ void OnGuildMemberWitdrawMoney(Guild* guild, Player* player, uint64 &amount, bool isRepair);
+ void OnGuildMemberDepositMoney(Guild* guild, Player* player, uint64 &amount);
void OnGuildItemMove(Guild* guild, Player* player, Item* pItem, bool isSrcBank, uint8 srcContainer, uint8 srcSlotId,
bool isDestBank, uint8 destContainer, uint8 destSlotId);
void OnGuildEvent(Guild* guild, uint8 eventType, uint32 playerGuid1, uint32 playerGuid2, uint8 newRank);
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index ea02b83f2e8..4f682f83ae4 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -16,1325 +16,1643 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- \ingroup u2w
-*/
-
#include "Opcodes.h"
#include "WorldSession.h"
+OpcodeTable opcodeTable;
+
+template<bool isInValidRange, bool isNonZero>
+void OpcodeTable::ValidateAndSetOpcode(uint16 /*opcode*/, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
+{
+ // if for some reason we are here, that means NUM_OPCODE_HANDLERS == 0 (or your compiler is broken)
+}
+
+template<>
+void OpcodeTable::ValidateAndSetOpcode<true, true>(uint16 opcode, char const* name, SessionStatus status, PacketProcessing processing, pOpcodeHandler handler)
+{
+ if (_internalTable[opcode] != NULL)
+ {
+ TC_LOG_ERROR("network", "Tried to override handler of %s with %s (opcode %u)", opcodeTable[opcode]->Name, name, opcode);
+ return;
+ }
+
+ _internalTable[opcode] = new OpcodeHandler(name, status, processing, handler);
+}
+
+template<>
+void OpcodeTable::ValidateAndSetOpcode<false, true>(uint16 opcode, char const* /*name*/, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
+{
+ TC_LOG_ERROR("network", "Tried to set handler for an invalid opcode %d", opcode);
+}
+
+template<>
+void OpcodeTable::ValidateAndSetOpcode<true, false>(uint16 /*opcode*/, char const* name, SessionStatus /*status*/, PacketProcessing /*processing*/, pOpcodeHandler /*handler*/)
+{
+ TC_LOG_ERROR("network", "Opcode %s got value 0", name);
+}
+
/// Correspondence between opcodes and their names
-OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
+void OpcodeTable::Initialize()
{
- /*0x000*/ { "MSG_NULL_ACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x001*/ { "CMSG_BOOTME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x002*/ { "CMSG_DBLOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x003*/ { "SMSG_DBLOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x008*/ { "CMSG_WORLD_TELEPORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode },
- /*0x009*/ { "CMSG_TELEPORT_TO_UNIT", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x00A*/ { "CMSG_ZONE_MAP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x00B*/ { "SMSG_ZONE_MAP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x00F*/ { "CMSG_RECHARGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x010*/ { "CMSG_LEARN_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x011*/ { "CMSG_CREATEMONSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x012*/ { "CMSG_DESTROYMONSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x013*/ { "CMSG_CREATEITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x014*/ { "CMSG_CREATEGAMEOBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x015*/ { "SMSG_CHECK_FOR_BOTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x017*/ { "CMSG_BOT_DETECTED2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x018*/ { "CMSG_FORCEACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x019*/ { "CMSG_FORCEACTIONONOTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x01A*/ { "CMSG_FORCEACTIONSHOW", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x01B*/ { "SMSG_FORCEACTIONSHOW", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x01C*/ { "CMSG_PETGODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x01D*/ { "SMSG_PETGODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x020*/ { "CMSG_UNDRESSPLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x021*/ { "CMSG_BEASTMASTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x022*/ { "CMSG_GODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x023*/ { "SMSG_GODMODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x024*/ { "CMSG_CHEAT_SETMONEY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x025*/ { "CMSG_LEVEL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x026*/ { "CMSG_PET_LEVEL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x027*/ { "CMSG_SET_WORLDSTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x028*/ { "CMSG_COOLDOWN_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x029*/ { "CMSG_USE_SKILL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02A*/ { "CMSG_FLAG_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02C*/ { "CMSG_CLEAR_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02D*/ { "CMSG_SEND_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02E*/ { "CMSG_DEBUG_AISTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x02F*/ { "SMSG_DEBUG_AISTATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x034*/ { "CMSG_AUTH_SRP6_PROOF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x035*/ { "CMSG_AUTH_SRP6_RECODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x036*/ { "CMSG_CHAR_CREATE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCreateOpcode },
- /*0x037*/ { "CMSG_CHAR_ENUM", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode },
- /*0x038*/ { "CMSG_CHAR_DELETE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharDeleteOpcode },
- /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x03A*/ { "SMSG_CHAR_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x03B*/ { "SMSG_CHAR_ENUM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x03C*/ { "SMSG_CHAR_DELETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x03D*/ { "CMSG_PLAYER_LOGIN", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLoginOpcode },
- /*0x03E*/ { "SMSG_NEW_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x03F*/ { "SMSG_TRANSFER_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x040*/ { "SMSG_TRANSFER_ABORTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x043*/ { "SMSG_GAMETIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x044*/ { "CMSG_GAMETIME_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x045*/ { "SMSG_GAMETIME_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x046*/ { "CMSG_GAMESPEED_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x047*/ { "SMSG_GAMESPEED_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x048*/ { "CMSG_SERVERTIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x049*/ { "SMSG_SERVERTIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x04A*/ { "CMSG_PLAYER_LOGOUT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLogoutOpcode },
- /*0x04B*/ { "CMSG_LOGOUT_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutRequestOpcode },
- /*0x04C*/ { "SMSG_LOGOUT_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x04D*/ { "SMSG_LOGOUT_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x04E*/ { "CMSG_LOGOUT_CANCEL", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode },
- /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x050*/ { "CMSG_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNameQueryOpcode },
- /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x052*/ { "CMSG_PET_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery },
- /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x054*/ { "CMSG_GUILD_QUERY", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode },
- /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleItemQuerySingleOpcode },
- /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode },
- /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x05C*/ { "CMSG_QUEST_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode },
- /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGameObjectQueryOpcode },
- /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x060*/ { "CMSG_CREATURE_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleCreatureQueryOpcode },
- /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x062*/ { "CMSG_WHO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode },
- /*0x063*/ { "SMSG_WHO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x064*/ { "CMSG_WHOIS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode },
- /*0x065*/ { "SMSG_WHOIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x066*/ { "CMSG_CONTACT_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleContactListOpcode },
- /*0x067*/ { "SMSG_CONTACT_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x068*/ { "SMSG_FRIEND_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x069*/ { "CMSG_ADD_FRIEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddFriendOpcode },
- /*0x06A*/ { "CMSG_DEL_FRIEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode },
- /*0x06B*/ { "CMSG_SET_CONTACT_NOTES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetContactNotesOpcode },
- /*0x06C*/ { "CMSG_ADD_IGNORE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddIgnoreOpcode },
- /*0x06D*/ { "CMSG_DEL_IGNORE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode },
- /*0x06E*/ { "CMSG_GROUP_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode },
- /*0x06F*/ { "SMSG_GROUP_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x070*/ { "CMSG_GROUP_CANCEL", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x071*/ { "SMSG_GROUP_CANCEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x072*/ { "CMSG_GROUP_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAcceptOpcode },
- /*0x073*/ { "CMSG_GROUP_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDeclineOpcode },
- /*0x074*/ { "SMSG_GROUP_DECLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x075*/ { "CMSG_GROUP_UNINVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode },
- /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode },
- /*0x077*/ { "SMSG_GROUP_UNINVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x078*/ { "CMSG_GROUP_SET_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode },
- /*0x079*/ { "SMSG_GROUP_SET_LEADER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x07A*/ { "CMSG_LOOT_METHOD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode },
- /*0x07B*/ { "CMSG_GROUP_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode },
- /*0x07C*/ { "SMSG_GROUP_DESTROYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x07D*/ { "SMSG_GROUP_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x081*/ { "CMSG_GUILD_CREATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildCreateOpcode },
- /*0x082*/ { "CMSG_GUILD_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode },
- /*0x083*/ { "SMSG_GUILD_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x084*/ { "CMSG_GUILD_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode },
- /*0x085*/ { "CMSG_GUILD_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode },
- /*0x086*/ { "SMSG_GUILD_DECLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x087*/ { "CMSG_GUILD_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInfoOpcode },
- /*0x088*/ { "SMSG_GUILD_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x089*/ { "CMSG_GUILD_ROSTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRosterOpcode },
- /*0x08A*/ { "SMSG_GUILD_ROSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x08B*/ { "CMSG_GUILD_PROMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode },
- /*0x08C*/ { "CMSG_GUILD_DEMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode },
- /*0x08D*/ { "CMSG_GUILD_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode },
- /*0x08E*/ { "CMSG_GUILD_REMOVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode },
- /*0x08F*/ { "CMSG_GUILD_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode },
- /*0x090*/ { "CMSG_GUILD_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaderOpcode },
- /*0x091*/ { "CMSG_GUILD_MOTD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode },
- /*0x092*/ { "SMSG_GUILD_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x094*/ { "UMSG_UPDATE_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x095*/ { "CMSG_MESSAGECHAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode },
- /*0x096*/ { "SMSG_MESSAGECHAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x097*/ { "CMSG_JOIN_CHANNEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel },
- /*0x098*/ { "CMSG_LEAVE_CHANNEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel },
- /*0x099*/ { "SMSG_CHANNEL_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x09A*/ { "CMSG_CHANNEL_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList },
- /*0x09B*/ { "SMSG_CHANNEL_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x09C*/ { "CMSG_CHANNEL_PASSWORD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelPassword },
- /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelSetOwner },
- /*0x09E*/ { "CMSG_CHANNEL_OWNER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelOwner },
- /*0x09F*/ { "CMSG_CHANNEL_MODERATOR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator },
- /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmoderator },
- /*0x0A1*/ { "CMSG_CHANNEL_MUTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute },
- /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmute },
- /*0x0A3*/ { "CMSG_CHANNEL_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite },
- /*0x0A4*/ { "CMSG_CHANNEL_KICK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick },
- /*0x0A5*/ { "CMSG_CHANNEL_BAN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan },
- /*0x0A6*/ { "CMSG_CHANNEL_UNBAN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnban },
- /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements },
- /*0x0A8*/ { "CMSG_CHANNEL_MODERATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL },
- /*0x0A9*/ { "SMSG_UPDATE_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0AA*/ { "SMSG_DESTROY_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0AB*/ { "CMSG_USE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode },
- /*0x0AC*/ { "CMSG_OPEN_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode },
- /*0x0AD*/ { "CMSG_READ_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem },
- /*0x0AE*/ { "SMSG_READ_ITEM_OK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0AF*/ { "SMSG_READ_ITEM_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0B0*/ { "SMSG_ITEM_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0B1*/ { "CMSG_GAMEOBJ_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameObjectUseOpcode },
- /*0x0B2*/ { "CMSG_DESTROY_ITEMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0B4*/ { "CMSG_AREATRIGGER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaTriggerOpcode },
- /*0x0B5*/ { "MSG_MOVE_START_FORWARD", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0B6*/ { "MSG_MOVE_START_BACKWARD", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0B7*/ { "MSG_MOVE_STOP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BB*/ { "MSG_MOVE_JUMP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BE*/ { "MSG_MOVE_STOP_TURN", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0C1*/ { "MSG_MOVE_STOP_PITCH", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0C5*/ { "MSG_MOVE_TELEPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck },
- /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0C9*/ { "MSG_MOVE_FALL_LAND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0CA*/ { "MSG_MOVE_START_SWIM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0CB*/ { "MSG_MOVE_STOP_SWIM", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0DA*/ { "MSG_MOVE_SET_FACING", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0DB*/ { "MSG_MOVE_SET_PITCH", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK", STATUS_TRANSFER, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode },
- /*0x0DD*/ { "SMSG_MONSTER_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0DE*/ { "SMSG_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0DF*/ { "SMSG_MOVE_LAND_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0E0*/ { "CMSG_MOVE_CHARM_PORT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck },
- /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck },
- /*0x0EC*/ { "MSG_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0ED*/ { "MSG_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0EE*/ { "MSG_MOVE_HEARTBEAT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveKnockBackAck },
- /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F4*/ { "SMSG_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck },
- /*0x0F7*/ { "MSG_MOVE_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0F9*/ { "CMSG_OPENING_CINEMATIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera },
- /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCompleteCinematic },
- /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x0FE*/ { "CMSG_TUTORIAL_FLAG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag },
- /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear },
- /*0x100*/ { "CMSG_TUTORIAL_RESET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset },
- /*0x101*/ { "CMSG_STANDSTATECHANGE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStandStateChangeOpcode },
- /*0x102*/ { "CMSG_EMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEmoteOpcode },
- /*0x103*/ { "SMSG_EMOTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x104*/ { "CMSG_TEXT_EMOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode },
- /*0x105*/ { "SMSG_TEXT_EMOTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode },
- /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode },
- /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode },
- /*0x10C*/ { "CMSG_SWAP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapItem },
- /*0x10D*/ { "CMSG_SWAP_INV_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapInvItemOpcode },
- /*0x10E*/ { "CMSG_SPLIT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSplitItemOpcode },
- /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode },
- /*0x110*/ { "CMSG_UNCLAIM_LICENSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x111*/ { "CMSG_DESTROYITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDestroyItemOpcode },
- /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x113*/ { "SMSG_OPEN_CONTAINER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x114*/ { "CMSG_INSPECT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode },
- /*0x115*/ { "SMSG_INSPECT_RESULTS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x116*/ { "CMSG_INITIATE_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode },
- /*0x117*/ { "CMSG_BEGIN_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode },
- /*0x118*/ { "CMSG_BUSY_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode },
- /*0x119*/ { "CMSG_IGNORE_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode },
- /*0x11A*/ { "CMSG_ACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode },
- /*0x11B*/ { "CMSG_UNACCEPT_TRADE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode },
- /*0x11C*/ { "CMSG_CANCEL_TRADE", STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode },
- /*0x11D*/ { "CMSG_SET_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode },
- /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode },
- /*0x11F*/ { "CMSG_SET_TRADE_GOLD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode },
- /*0x120*/ { "SMSG_TRADE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x122*/ { "SMSG_INITIALIZE_FACTIONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x123*/ { "SMSG_SET_FACTION_VISIBLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x124*/ { "SMSG_SET_FACTION_STANDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x125*/ { "CMSG_SET_FACTION_ATWAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar },
- /*0x126*/ { "CMSG_SET_FACTION_CHEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionCheat },
- /*0x127*/ { "SMSG_SET_PROFICIENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x128*/ { "CMSG_SET_ACTION_BUTTON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionButtonOpcode },
- /*0x129*/ { "SMSG_ACTION_BUTTONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x12A*/ { "SMSG_INITIAL_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x12B*/ { "SMSG_LEARNED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x12C*/ { "SMSG_SUPERCEDED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x12D*/ { "CMSG_NEW_SPELL_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x12E*/ { "CMSG_CAST_SPELL", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode },
- /*0x12F*/ { "CMSG_CANCEL_CAST", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode },
- /*0x130*/ { "SMSG_CAST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x131*/ { "SMSG_SPELL_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x132*/ { "SMSG_SPELL_GO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x133*/ { "SMSG_SPELL_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x134*/ { "SMSG_SPELL_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x135*/ { "SMSG_COOLDOWN_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x136*/ { "CMSG_CANCEL_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode },
- /*0x137*/ { "SMSG_EQUIPMENT_SET_SAVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x138*/ { "SMSG_PET_CAST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x139*/ { "MSG_CHANNEL_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x13A*/ { "MSG_CHANNEL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x13B*/ { "CMSG_CANCEL_CHANNELLING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling },
- /*0x13C*/ { "SMSG_AI_REACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x13D*/ { "CMSG_SET_SELECTION", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode },
- /*0x13E*/ { "CMSG_DELETEEQUIPMENT_SET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete },
- /*0x13F*/ { "CMSG_INSTANCE_LOCK_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse },
- /*0x140*/ { "CMSG_DEBUG_PASSIVE_AURA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x141*/ { "CMSG_ATTACKSWING", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode },
- /*0x142*/ { "CMSG_ATTACKSTOP", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode },
- /*0x143*/ { "SMSG_ATTACKSTART", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x144*/ { "SMSG_ATTACKSTOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x146*/ { "SMSG_ATTACKSWING_BADFACING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x147*/ { "SMSG_INSTANCE_LOCK_WARNING_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x14C*/ { "CMSG_PERFORM_ACTION_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x14D*/ { "SMSG_RESUME_CAST_BAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x151*/ { "SMSG_SPELLENERGIZELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x152*/ { "SMSG_BREAK_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x153*/ { "CMSG_SAVE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x154*/ { "CMSG_SETDEATHBINDPOINT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x155*/ { "SMSG_BINDPOINTUPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x156*/ { "CMSG_GETDEATHBINDZONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x157*/ { "SMSG_BINDZONEREPLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x158*/ { "SMSG_PLAYERBOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x15A*/ { "CMSG_REPOP_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode },
- /*0x15B*/ { "SMSG_RESURRECT_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x15C*/ { "CMSG_RESURRECT_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResurrectResponseOpcode },
- /*0x15D*/ { "CMSG_LOOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootOpcode },
- /*0x15E*/ { "CMSG_LOOT_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMoneyOpcode },
- /*0x15F*/ { "CMSG_LOOT_RELEASE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootReleaseOpcode },
- /*0x160*/ { "SMSG_LOOT_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x162*/ { "SMSG_LOOT_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x166*/ { "SMSG_ITEM_PUSH_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x167*/ { "SMSG_DUEL_REQUESTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x169*/ { "SMSG_DUEL_INBOUNDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x16A*/ { "SMSG_DUEL_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x16B*/ { "SMSG_DUEL_WINNER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x16C*/ { "CMSG_DUEL_ACCEPTED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelAcceptedOpcode },
- /*0x16D*/ { "CMSG_DUEL_CANCELLED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelCancelledOpcode },
- /*0x16E*/ { "SMSG_MOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x16F*/ { "SMSG_DISMOUNTRESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x170*/ { "SMSG_REMOVED_FROM_PVP_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode },
- /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x173*/ { "SMSG_PET_TAME_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x174*/ { "CMSG_PET_SET_ACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction },
- /*0x175*/ { "CMSG_PET_ACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction },
- /*0x176*/ { "CMSG_PET_ABANDON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon },
- /*0x177*/ { "CMSG_PET_RENAME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename },
- /*0x178*/ { "SMSG_PET_NAME_INVALID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x179*/ { "SMSG_PET_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x17A*/ { "SMSG_PET_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x17B*/ { "CMSG_GOSSIP_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode },
- /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode },
- /*0x17D*/ { "SMSG_GOSSIP_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x17E*/ { "SMSG_GOSSIP_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x17F*/ { "CMSG_NPC_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode },
- /*0x180*/ { "SMSG_NPC_TEXT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x181*/ { "SMSG_NPC_WONT_TALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode},
- /*0x183*/ { "SMSG_QUESTGIVER_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x184*/ { "CMSG_QUESTGIVER_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode },
- /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode},
- /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQuestAutoLaunch },
- /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode},
- /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest },
- /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode},
- /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode},
- /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x190*/ { "CMSG_QUESTGIVER_CANCEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCancel },
- /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogSwapQuest },
- /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest },
- /*0x195*/ { "SMSG_QUESTLOG_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x196*/ { "SMSG_QUESTUPDATE_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept },
- /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty },
- /*0x19E*/ { "CMSG_LIST_INVENTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode },
- /*0x19F*/ { "SMSG_LIST_INVENTORY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1A0*/ { "CMSG_SELL_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode },
- /*0x1A1*/ { "SMSG_SELL_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1A2*/ { "CMSG_BUY_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode },
- /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemInSlotOpcode },
- /*0x1A4*/ { "SMSG_BUY_ITEM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1A5*/ { "SMSG_BUY_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1A6*/ { "CMSG_TAXICLEARALLNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1A8*/ { "CMSG_TAXISHOWNODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1A9*/ { "SMSG_SHOWTAXINODES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode },
- /*0x1AB*/ { "SMSG_TAXINODE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes },
- /*0x1AD*/ { "CMSG_ACTIVATETAXI", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode },
- /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1AF*/ { "SMSG_NEW_TAXI_PATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B0*/ { "CMSG_TRAINER_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode },
- /*0x1B1*/ { "SMSG_TRAINER_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode },
- /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B5*/ { "CMSG_BINDER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode },
- /*0x1B6*/ { "SMSG_PLAYERBINDERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B7*/ { "CMSG_BANKER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode },
- /*0x1B8*/ { "SMSG_SHOW_BANK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1B9*/ { "CMSG_BUY_BANK_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode },
- /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1BB*/ { "CMSG_PETITION_SHOWLIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowListOpcode },
- /*0x1BC*/ { "SMSG_PETITION_SHOWLIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1BD*/ { "CMSG_PETITION_BUY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode },
- /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowSignOpcode },
- /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1C0*/ { "CMSG_PETITION_SIGN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionSignOpcode },
- /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1C2*/ { "MSG_PETITION_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode },
- /*0x1C3*/ { "CMSG_OFFER_PETITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode },
- /*0x1C4*/ { "CMSG_TURN_IN_PETITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode },
- /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1C6*/ { "CMSG_PETITION_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionQueryOpcode },
- /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1C9*/ { "SMSG_FISH_ESCAPED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1CA*/ { "CMSG_BUG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode },
- /*0x1CB*/ { "SMSG_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1CC*/ { "CMSG_PLAYED_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayedTime },
- /*0x1CD*/ { "SMSG_PLAYED_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1CE*/ { "CMSG_QUERY_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryTimeOpcode },
- /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D0*/ { "SMSG_LOG_XPGAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D1*/ { "SMSG_AURACASTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D2*/ { "CMSG_RECLAIM_CORPSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode },
- /*0x1D3*/ { "CMSG_WRAP_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode },
- /*0x1D4*/ { "SMSG_LEVELUP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D5*/ { "MSG_MINIMAP_PING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode },
- /*0x1D6*/ { "SMSG_RESISTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D7*/ { "SMSG_ENCHANTMENTLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1D9*/ { "SMSG_START_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1DC*/ { "CMSG_PING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess },
- /*0x1DD*/ { "SMSG_PONG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1E0*/ { "CMSG_SETSHEATHED", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode },
- /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1E2*/ { "SMSG_SPELL_DELAYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1E3*/ { "CMSG_QUEST_POI_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery },
- /*0x1E4*/ { "SMSG_QUEST_POI_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1E5*/ { "CMSG_GHOST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1E6*/ { "CMSG_GM_INVIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1E8*/ { "MSG_GM_BIND_OTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1E9*/ { "MSG_GM_SUMMON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1EC*/ { "SMSG_AUTH_CHALLENGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1ED*/ { "CMSG_AUTH_SESSION", STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess },
- /*0x1EE*/ { "SMSG_AUTH_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1EF*/ { "MSG_GM_SHOWLABEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1F0*/ { "CMSG_PET_CAST_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode },
- /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode },
- /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode},
- /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1F4*/ { "CMSG_ZONEUPDATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleZoneUpdateOpcode },
- /*0x1F5*/ { "SMSG_PARTYKILLLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1FA*/ { "CMSG_GM_NUKE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1FB*/ { "MSG_RANDOM_ROLL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode },
- /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1FD*/ { "CMSG_CHANGEPLAYER_DIFFICULTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x1FE*/ { "SMSG_RWHOIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x1FF*/ { "SMSG_LFG_PLAYER_REWARD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x200*/ { "SMSG_LFG_TELEPORT_DENIED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x201*/ { "CMSG_UNLEARN_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x202*/ { "CMSG_UNLEARN_SKILL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode },
- /*0x203*/ { "SMSG_REMOVED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x204*/ { "CMSG_DECHARGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x205*/ { "CMSG_GMTICKET_CREATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketCreateOpcode },
- /*0x206*/ { "SMSG_GMTICKET_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode },
- /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData },
- /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData },
- /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x20E*/ { "SMSG_CHANGEPLAYER_DIFFICULTY_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x20F*/ { "CMSG_GM_TEACH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x211*/ { "CMSG_GMTICKET_GETTICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode },
- /*0x212*/ { "SMSG_GMTICKET_GETTICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x213*/ { "CMSG_UNLEARN_TALENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x214*/ { "SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x216*/ { "MSG_CORPSE_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode },
- /*0x217*/ { "CMSG_GMTICKET_DELETETICKET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode },
- /*0x218*/ { "SMSG_GMTICKET_DELETETICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x219*/ { "SMSG_CHAT_WRONG_FACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode},
- /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpiritHealerActivateOpcode},
- /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x21E*/ { "SMSG_QUEST_FORCE_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x224*/ { "SMSG_GOSSIP_POI", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x225*/ { "CMSG_CHAT_IGNORED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode },
- /*0x226*/ { "CMSG_GM_VISION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x227*/ { "CMSG_SERVER_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x228*/ { "CMSG_GM_SILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x229*/ { "CMSG_GM_REVEALTO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22A*/ { "CMSG_GM_RESURRECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22B*/ { "CMSG_GM_SUMMONMOB", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22C*/ { "CMSG_GM_MOVECORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22D*/ { "CMSG_GM_FREEZE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22E*/ { "CMSG_GM_UBERINVIS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x230*/ { "SMSG_GM_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x231*/ { "CMSG_GUILD_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRankOpcode },
- /*0x232*/ { "CMSG_GUILD_ADD_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode },
- /*0x233*/ { "CMSG_GUILD_DEL_RANK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode },
- /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetPublicNoteOpcode },
- /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetOfficerNoteOpcode },
- /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x237*/ { "CMSG_CLEAR_EXPLORATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x238*/ { "CMSG_SEND_MAIL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail },
- /*0x239*/ { "SMSG_SEND_MAIL_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x23A*/ { "CMSG_GET_MAIL_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetMailList },
- /*0x23B*/ { "SMSG_MAIL_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x23C*/ { "CMSG_BATTLEFIELD_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode },
- /*0x23D*/ { "SMSG_BATTLEFIELD_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x23F*/ { "SMSG_FORCE_SET_VEHICLE_REC_ID", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x240*/ { "CMSG_SET_VEHICLE_REC_ID_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x241*/ { "CMSG_TAXICLEARNODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x242*/ { "CMSG_TAXIENABLENODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x243*/ { "CMSG_ITEM_TEXT_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery },
- /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x245*/ { "CMSG_MAIL_TAKE_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney },
- /*0x246*/ { "CMSG_MAIL_TAKE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem },
- /*0x247*/ { "CMSG_MAIL_MARK_AS_READ", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailMarkAsRead },
- /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender },
- /*0x249*/ { "CMSG_MAIL_DELETE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailDelete },
- /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailCreateTextItem },
- /*0x24B*/ { "SMSG_SPELLLOGMISS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x24C*/ { "SMSG_SPELLLOGEXECUTE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x24D*/ { "SMSG_DEBUGAURAPROC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x24E*/ { "SMSG_PERIODICAURALOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x251*/ { "CMSG_LEARN_TALENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode },
- /*0x252*/ { "SMSG_RESURRECT_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x253*/ { "CMSG_TOGGLE_PVP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP },
- /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x255*/ { "MSG_AUCTION_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode },
- /*0x256*/ { "CMSG_AUCTION_SELL_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem },
- /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem },
- /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems },
- /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems },
- /*0x25A*/ { "CMSG_AUCTION_PLACE_BID", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid },
- /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x260*/ { "SMSG_PROCRESIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x261*/ { "SMSG_COMBAT_EVENT_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x262*/ { "SMSG_DISPEL_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems },
- /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x268*/ { "CMSG_SET_AMMO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetAmmoOpcode },
- /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode },
- /*0x26B*/ { "CMSG_PET_CANCEL_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode },
- /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode},
- /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x26F*/ { "MSG_LIST_STABLED_PETS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode },
- /*0x270*/ { "CMSG_STABLE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStablePet },
- /*0x271*/ { "CMSG_UNSTABLE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnstablePet },
- /*0x272*/ { "CMSG_BUY_STABLE_SLOT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyStableSlot },
- /*0x273*/ { "SMSG_STABLE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x274*/ { "CMSG_STABLE_REVIVE_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet },
- /*0x275*/ { "CMSG_STABLE_SWAP_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet },
- /*0x276*/ { "MSG_QUEST_PUSH_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult },
- /*0x277*/ { "SMSG_PLAY_MUSIC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x279*/ { "CMSG_REQUEST_PET_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode },
- /*0x27A*/ { "CMSG_FAR_SIGHT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode },
- /*0x27B*/ { "SMSG_SPELLDISPELLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode },
- /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode},
- /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x281*/ { "CMSG_RESET_FACTION_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode },
- /*0x283*/ { "CMSG_AUTOBANK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode },
- /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime },
- /*0x285*/ { "SMSG_RECEIVED_MAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x286*/ { "SMSG_RAID_GROUP_ONLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x28B*/ { "CMSG_SET_PVP_TITLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x28C*/ { "SMSG_PVP_CREDIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode },
- /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode},
- /*0x290*/ { "CMSG_BUYBACK_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem },
- /*0x291*/ { "SMSG_SERVER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x292*/ { "CMSG_SET_SAVED_INSTANCE_EXTEND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend },
- /*0x293*/ { "SMSG_LFG_OFFER_CONTINUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x294*/ { "CMSG_TEST_DROP_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x295*/ { "SMSG_TEST_DROP_RATE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x296*/ { "CMSG_LFG_GET_STATUS", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetStatus },
- /*0x297*/ { "SMSG_SHOW_MAILBOX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x298*/ { "SMSG_RESET_RANGED_COMBAT_TIMER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x29A*/ { "SMSG_CHAT_NOT_IN_PARTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode },
- /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x29D*/ { "SMSG_STANDSTATE_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x29E*/ { "SMSG_LOOT_ALL_PASSED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x29F*/ { "SMSG_LOOT_ROLL_WON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A0*/ { "CMSG_LOOT_ROLL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll },
- /*0x2A1*/ { "SMSG_LOOT_START_ROLL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A2*/ { "SMSG_LOOT_ROLL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode },
- /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2A8*/ { "CMSG_REPAIR_ITEM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode },
- /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode },
- /*0x2AB*/ { "SMSG_SUMMON_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2AC*/ { "CMSG_SUMMON_RESPONSE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSummonResponseOpcode },
- /*0x2AD*/ { "MSG_DEV_SHOWLABEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2AF*/ { "SMSG_PET_BROKEN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2B1*/ { "MSG_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2B2*/ { "CMSG_SERVER_BROADCAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2B3*/ { "CMSG_SELF_RES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode },
- /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2B5*/ { "CMSG_RUN_SCRIPT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2B9*/ { "CMSG_SHOWING_HELM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode },
- /*0x2BA*/ { "CMSG_SHOWING_CLOAK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode },
- /*0x2BB*/ { "SMSG_LFG_ROLE_CHOSEN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2BC*/ { "SMSG_PLAYER_SKINNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2BE*/ { "CMSG_SET_EXPLORATION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarToggles },
- /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2C1*/ { "MSG_PETITION_RENAME", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameOpcode },
- /*0x2C2*/ { "SMSG_INIT_WORLD_STATES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemNameQueryOpcode },
- /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2C7*/ { "CMSG_CHAR_RENAME", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode },
- /*0x2C8*/ { "SMSG_CHAR_RENAME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSplineDoneOpcode },
- /*0x2CA*/ { "CMSG_MOVE_FALL_RESET", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode },
- /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode },
- /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck },
- /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck },
- /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover },
- /*0x2D2*/ { "SMSG_PLAY_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode },
- /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode },
- /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode },
- /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterHelloOpcode },
- /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x2E0*/ { "MSG_PVP_LOG_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode },
- /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldLeaveOpcode },
- /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode},
- /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode},
- /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2E5*/ { "CMSG_GM_UNTEACH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2E6*/ { "SMSG_WARDEN_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2E7*/ { "CMSG_WARDEN_DATA", STATUS_AUTHED, PROCESS_THREADSAFE, &WorldSession::HandleWardenDataOpcode },
- /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode},
- /*0x2EA*/ { "CMSG_PET_STOP_ATTACK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack },
- /*0x2EB*/ { "SMSG_BINDER_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode },
- /*0x2EF*/ { "SMSG_ADDON_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F0*/ { "CMSG_PET_UNLEARN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode },
- /*0x2F4*/ { "SMSG_WEATHER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F6*/ { "SMSG_MINIGAME_SETUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F7*/ { "SMSG_MINIGAME_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2F8*/ { "CMSG_MINIGAME_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2FB*/ { "SMSG_COMPRESSED_MOVES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode },
- /*0x2FD*/ { "SMSG_CHAT_RESTRICTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x310*/ { "MSG_GM_DESTROY_CORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiExpressOpcode },
- /*0x313*/ { "SMSG_SET_FACTION_ATWAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x314*/ { "SMSG_GAMETIMEBIAS_SET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x315*/ { "CMSG_DEBUG_ACTIONS_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x317*/ { "CMSG_SET_FACTION_INACTIVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode },
- /*0x318*/ { "CMSG_SET_WATCHED_FACTION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode },
- /*0x319*/ { "MSG_MOVE_TIME_SKIPPED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x31C*/ { "SMSG_INVALIDATE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x31D*/ { "CMSG_RESET_INSTANCES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResetInstancesOpcode },
- /*0x31E*/ { "SMSG_INSTANCE_RESET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x321*/ { "MSG_RAID_TARGET_UPDATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode },
- /*0x322*/ { "MSG_RAID_READY_CHECK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode },
- /*0x323*/ { "CMSG_LUA_USAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x324*/ { "SMSG_PET_ACTION_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x325*/ { "SMSG_PET_DISMISS_SOUND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x326*/ { "SMSG_GHOSTEE_GONE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetDungeonDifficultyOpcode},
- /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMSurveySubmit },
- /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x331*/ { "CMSG_CHAT_FILTERED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x333*/ { "SMSG_SPELLSTEALLOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x338*/ { "SMSG_CHARACTER_PROFILE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x33A*/ { "SMSG_DEFENSE_MESSAGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x33D*/ { "SMSG_MOTD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x33E*/ { "SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x33F*/ { "SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x340*/ { "CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode },
- /*0x346*/ { "CMSG_MOVE_SET_FLY", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x347*/ { "CMSG_SOCKET_GEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode },
- /*0x348*/ { "CMSG_ARENA_TEAM_CREATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x34A*/ { "MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamQueryOpcode },
- /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode },
- /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamInviteOpcode },
- /*0x350*/ { "SMSG_ARENA_TEAM_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamAcceptOpcode },
- /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDeclineOpcode },
- /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaveOpcode },
- /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRemoveOpcode },
- /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDisbandOpcode },
- /*0x356*/ { "CMSG_ARENA_TEAM_LEADER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaderOpcode },
- /*0x357*/ { "SMSG_ARENA_TEAM_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena },
- /*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode },
- /*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode },
- /*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrJoinOpcode },
- /*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode },
- /*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x361*/ { "SMSG_LFG_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgProposalResultOpcode },
- /*0x363*/ { "SMSG_LFG_ROLE_CHECK_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x364*/ { "SMSG_LFG_JOIN_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x365*/ { "SMSG_LFG_QUEUE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x366*/ { "CMSG_SET_LFG_COMMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetCommentOpcode },
- /*0x367*/ { "SMSG_LFG_UPDATE_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x368*/ { "SMSG_LFG_UPDATE_PARTY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x369*/ { "SMSG_LFG_UPDATE_SEARCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x36A*/ { "CMSG_LFG_SET_ROLES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode },
- /*0x36B*/ { "CMSG_LFG_SET_NEEDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x36C*/ { "CMSG_LFG_SET_BOOT_VOTE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetBootVoteOpcode },
- /*0x36D*/ { "SMSG_LFG_BOOT_PROPOSAL_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x36E*/ { "CMSG_LFD_PLAYER_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPlayerLockInfoRequestOpcode},
- /*0x36F*/ { "SMSG_LFG_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x370*/ { "CMSG_LFG_TELEPORT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode },
- /*0x371*/ { "CMSG_LFD_PARTY_LOCK_INFO_REQUEST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgPartyLockInfoRequestOpcode},
- /*0x372*/ { "SMSG_LFG_PARTY_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x373*/ { "SMSG_TITLE_EARNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x374*/ { "CMSG_SET_TITLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode },
- /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode },
- /*0x376*/ { "SMSG_ARENA_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode },
- /*0x378*/ { "SMSG_DEATH_RELEASE_LOC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode},
- /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck },
- /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode },
- /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x38B*/ { "SMSG_REALM_SPLIT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x38C*/ { "CMSG_REALM_SPLIT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode },
- /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x38E*/ { "MSG_PARTY_ASSIGNMENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode },
- /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x390*/ { "SMSG_TIME_SYNC_REQ", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x391*/ { "CMSG_TIME_SYNC_RESP", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeSyncResp },
- /*0x392*/ { "CMSG_SEND_LOCAL_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x397*/ { "SMSG_REAL_GROUP_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x398*/ { "SMSG_LFG_DISABLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3A7*/ { "MSG_MOVE_START_DESCEND", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes },
- /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3AC*/ { "SMSG_DISMOUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode },
- /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3B2*/ { "CMSG_GM_WHISPER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3B3*/ { "SMSG_GM_MESSAGECHAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3B4*/ { "MSG_GM_GEARRATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3BF*/ { "SMSG_CLEAR_TARGET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3C0*/ { "CMSG_BOT_DETECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3C5*/ { "SMSG_KICK_REASON", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode},
- /*0x3C7*/ { "CMSG_COMPLAIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleComplainOpcode },
- /*0x3C8*/ { "SMSG_COMPLAIN_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3CB*/ { "CMSG_GM_UNSQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3D0*/ { "CMSG_TARGET_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery },
- /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel },
- /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetChannelMemberCount },
- /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode },
- /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3DD*/ { "CMSG_PARTY_SILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3DE*/ { "CMSG_PARTY_UNSILENCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E4*/ { "CMSG_REPORT_PVP_AFK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK },
- /*0x3E5*/ { "SMSG_REPORT_PVP_AFK_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate },
- /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab },
- /*0x3E8*/ { "SMSG_GUILD_BANK_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems },
- /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab },
- /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab },
- /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney },
- /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney },
- /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery },
- /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetChannelWatch },
- /*0x3F0*/ { "SMSG_USERLIST_ADD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F1*/ { "SMSG_USERLIST_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F2*/ { "SMSG_USERLIST_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3F4*/ { "SMSG_INSPECT_TALENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3F8*/ { "CMSG_SPELLCLICK", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick },
- /*0x3F9*/ { "SMSG_LOOT_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x3FC*/ { "SMSG_VOICESESSION_FULL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x3FD*/ { "MSG_GUILD_PERMISSIONS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions },
- /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn },
- /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode },
- /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMirrorImageDataRequest },
- /*0x402*/ { "SMSG_MIRRORIMAGE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x407*/ { "CMSG_KEEP_ALIVE", STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess },
- /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode },
- /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText },
- /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText },
- /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x40D*/ { "CMSG_GRANT_LEVEL", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel },
- /*0x40E*/ { "CMSG_REFER_A_FRIEND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleChannelDeclineInvite },
- /*0x411*/ { "SMSG_GROUPACTION_THROTTLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x412*/ { "SMSG_OVERRIDE_LIGHT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x413*/ { "SMSG_TOTEM_CREATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x414*/ { "CMSG_TOTEM_DESTROYED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed },
- /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x416*/ { "CMSG_NO_SPELL_VARIANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery},
- /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames },
- /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x41D*/ { "SMSG_SERVER_BUCK_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel },
- /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x424*/ { "SMSG_SUMMON_CANCEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x426*/ { "CMSG_ALTER_APPEARANCE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance },
- /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x428*/ { "SMSG_BARBER_SHOP_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetCalendar },
- /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetEvent },
- /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter },
- /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam },
- /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent },
- /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent },
- /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent },
- /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarCopyEvent },
- /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventInvite },
- /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRsvp },
- /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite },
- /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventStatus },
- /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventModeratorStatus},
- /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x446*/ { "CMSG_CALENDAR_COMPLAIN", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarComplain },
- /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending },
- /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x449*/ { "CMSG_SAVE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x44A*/ { "SMSG_NOTIFY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x44B*/ { "CMSG_PLAY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x44C*/ { "SMSG_PLAY_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x44D*/ { "CMSG_LOAD_DANCES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x44E*/ { "CMSG_STOP_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x44F*/ { "SMSG_STOP_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x450*/ { "CMSG_SYNC_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x451*/ { "CMSG_DANCE_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x453*/ { "SMSG_INVALIDATE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x454*/ { "CMSG_DELETE_DANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x456*/ { "CMSG_LEARN_DANCE_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x458*/ { "CMSG_SET_RUNE_COUNT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x45F*/ { "CMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x460*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x461*/ { "SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory },
- /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x465*/ { "CMSG_COMPLETE_MOVIE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x466*/ { "CMSG_SET_GLYPH_SLOT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x467*/ { "CMSG_SET_GLYPH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x46A*/ { "SMSG_CRITERIA_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements },
- /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle },
- /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x471*/ { "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize },
- /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x475*/ { "SMSG_PET_RENAMEABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestVehicleExit },
- /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle},
- /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle},
- /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle},
- /*0x47A*/ { "CMSG_PET_LEARN_TALENT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent },
- /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x47C*/ { "SMSG_SET_PHASE_SHIFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x47F*/ { "SMSG_HEALTH_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x480*/ { "SMSG_POWER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameobjectReportUse },
- /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x483*/ { "SMSG_THREAT_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x484*/ { "SMSG_THREAT_REMOVE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x485*/ { "SMSG_THREAT_CLEAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x486*/ { "SMSG_CONVERT_RUNE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x487*/ { "SMSG_RESYNC_RUNES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x488*/ { "SMSG_ADD_RUNE_POWER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x489*/ { "CMSG_START_QUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x48A*/ { "CMSG_REMOVE_GLYPH", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRemoveGlyph },
- /*0x48B*/ { "CMSG_DUMP_OBJECTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x48D*/ { "CMSG_DISMISS_CRITTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter },
- /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListPendingSales },
- /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x491*/ { "SMSG_MODIFY_COOLDOWN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x493*/ { "CMSG_ENABLETAXI", STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes },
- /*0x494*/ { "SMSG_PRE_RESURRECT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x495*/ { "SMSG_AURA_UPDATE_ALL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x496*/ { "SMSG_AURA_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x499*/ { "SMSG_PET_LEARNED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x49A*/ { "SMSG_PET_REMOVED_SPELL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle},
- /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect },
- /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x49E*/ { "SMSG_CRITERIA_DELETED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4A4*/ { "CMSG_SET_BREATH", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4A5*/ { "CMSG_QUERY_VEHICLE_STATUS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4A6*/ { "SMSG_BATTLEGROUND_INFO_THROTTLED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4A7*/ { "SMSG_PLAYER_VEHICLE_DATA", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4A8*/ { "CMSG_PLAYER_VEHICLE_ENTER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEnterPlayerVehicle },
- /*0x4A9*/ { "CMSG_CONTROLLER_EJECT_PASSENGER", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEjectPassenger },
- /*0x4AA*/ { "SMSG_PET_GUIDS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4AB*/ { "SMSG_CLIENTCACHE_VERSION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4AC*/ { "CMSG_CHANGE_GDF_ARENA_RATING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4AD*/ { "CMSG_SET_ARENA_TEAM_RATING_BY_INDEX", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4AE*/ { "CMSG_SET_ARENA_TEAM_WEEKLY_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4AF*/ { "CMSG_SET_ARENA_TEAM_SEASON_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4B0*/ { "CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4B1*/ { "CMSG_SET_ARENA_MEMBER_SEASON_GAMES", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4B2*/ { "SMSG_ITEM_REFUND_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4B3*/ { "CMSG_ITEM_REFUND_INFO", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest },
- /*0x4B4*/ { "CMSG_ITEM_REFUND", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund },
- /*0x4B5*/ { "SMSG_ITEM_REFUND_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4B6*/ { "CMSG_CORPSE_MAP_POSITION_QUERY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery },
- /*0x4B7*/ { "SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4B8*/ { "CMSG_UNUSED5", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL },
- /*0x4B9*/ { "CMSG_UNUSED6", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4BA*/ { "CMSG_CALENDAR_EVENT_SIGNUP", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventSignup },
- /*0x4BB*/ { "SMSG_CALENDAR_CLEAR_PENDING_ACTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4BC*/ { "SMSG_EQUIPMENT_SET_LIST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4BD*/ { "CMSG_EQUIPMENT_SET_SAVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave },
- /*0x4BE*/ { "CMSG_UPDATE_PROJECTILE_POSITION", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition },
- /*0x4BF*/ { "SMSG_SET_PROJECTILE_POSITION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4C0*/ { "SMSG_TALENTS_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4C1*/ { "CMSG_LEARN_PREVIEW_TALENTS", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents },
- /*0x4C2*/ { "CMSG_LEARN_PREVIEW_TALENTS_PET", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet },
- /*0x4C3*/ { "CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4C4*/ { "CMSG_GM_GRANT_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4C5*/ { "CMSG_GM_REMOVE_ACHIEVEMENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4C6*/ { "CMSG_GM_SET_CRITERIA_FOR_PLAYER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4C7*/ { "SMSG_ARENA_UNIT_DESTROYED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4C8*/ { "SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4C9*/ { "CMSG_PROFILEDATA_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4CA*/ { "SMSG_PROFILEDATA_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4CB*/ { "CMSG_START_BATTLEFIELD_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4CC*/ { "CMSG_END_BATTLEFIELD_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4CE*/ { "SMSG_MOVE_GRAVITY_DISABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4CF*/ { "CMSG_MOVE_GRAVITY_DISABLE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4D0*/ { "SMSG_MOVE_GRAVITY_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D1*/ { "CMSG_MOVE_GRAVITY_ENABLE_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4D2*/ { "MSG_MOVE_GRAVITY_CHNG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D3*/ { "SMSG_SPLINE_MOVE_GRAVITY_DISABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D4*/ { "SMSG_SPLINE_MOVE_GRAVITY_ENABLE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse },
- /*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D7*/ { "CMSG_FORCE_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4D8*/ { "SMSG_FORCE_ANIM", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4D9*/ { "CMSG_CHAR_FACTION_CHANGE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange },
- /*0x4DA*/ { "SMSG_CHAR_FACTION_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4DB*/ { "CMSG_PVP_QUEUE_STATS_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4DC*/ { "SMSG_PVP_QUEUE_STATS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4DD*/ { "CMSG_SET_PAID_SERVICE_CHEAT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse },
- /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse },
- /*0x4E3*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4E4*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E5*/ { "SMSG_BATTLEFIELD_MGR_EJECT_PENDING", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E6*/ { "SMSG_BATTLEFIELD_MGR_EJECTED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E7*/ { "CMSG_BATTLEFIELD_MGR_EXIT_REQUEST", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest },
- /*0x4E8*/ { "SMSG_BATTLEFIELD_MGR_STATE_CHANGE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4E9*/ { "CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4EA*/ { "CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4EB*/ { "MSG_SET_RAID_DIFFICULTY", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode },
- /*0x4EC*/ { "CMSG_TOGGLE_XP_GAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4ED*/ { "SMSG_TOGGLE_XP_GAIN", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4EE*/ { "SMSG_GMRESPONSE_DB_ERROR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4EF*/ { "SMSG_GMRESPONSE_RECEIVED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4F0*/ { "CMSG_GMRESPONSE_RESOLVE", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMResponseResolve },
- /*0x4F1*/ { "SMSG_GMRESPONSE_STATUS_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4F2*/ { "SMSG_GMRESPONSE_CREATE_TICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4F3*/ { "CMSG_GMRESPONSE_CREATE_TICKET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4F4*/ { "CMSG_SERVERINFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4F5*/ { "SMSG_SERVERINFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4F6*/ { "CMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate },
- /*0x4F7*/ { "SMSG_WORLD_STATE_UI_TIMER_UPDATE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4F8*/ { "CMSG_CHAR_RACE_CHANGE", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange },
- /*0x4F9*/ { "MSG_VIEW_PHASE_SHIFT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4FA*/ { "SMSG_TALENTS_INVOLUNTARILY_RESET", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4FB*/ { "CMSG_DEBUG_SERVER_GEO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4FC*/ { "SMSG_DEBUG_SERVER_GEO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4FD*/ { "SMSG_LOOT_SLOT_CHANGED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x4FE*/ { "UMSG_UPDATE_GROUP_INFO", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x4FF*/ { "CMSG_READY_FOR_ACCOUNT_DATA_TIMES", STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadyForAccountDataTimes },
- /*0x500*/ { "CMSG_QUERY_QUESTS_COMPLETED", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted },
- /*0x501*/ { "SMSG_QUERY_QUESTS_COMPLETED_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x502*/ { "CMSG_GM_REPORT_LAG", STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag },
- /*0x503*/ { "CMSG_AFK_MONITOR_INFO_REQUEST", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x504*/ { "SMSG_AFK_MONITOR_INFO_RESPONSE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x505*/ { "CMSG_AFK_MONITOR_INFO_CLEAR", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x506*/ { "SMSG_CORPSE_IS_NOT_IN_INSTANCE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x507*/ { "CMSG_GM_NUKE_CHARACTER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x508*/ { "CMSG_SET_ALLOW_LOW_LEVEL_RAID1", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x509*/ { "CMSG_SET_ALLOW_LOW_LEVEL_RAID2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x50A*/ { "SMSG_CAMERA_SHAKE", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x50B*/ { "SMSG_SOCKET_GEMS_RESULT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x50C*/ { "CMSG_SET_CHARACTER_MODEL", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x50D*/ { "SMSG_REDIRECT_CLIENT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x50E*/ { "CMSG_REDIRECTION_FAILED", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x50F*/ { "SMSG_SUSPEND_COMMS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x510*/ { "CMSG_SUSPEND_COMMS_ACK", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x511*/ { "SMSG_FORCE_SEND_QUEUED_PACKETS", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x512*/ { "CMSG_REDIRECTION_AUTH_PROOF", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x513*/ { "CMSG_DROP_NEW_CONNECTION", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x514*/ { "SMSG_SEND_ALL_COMBAT_LOG", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x515*/ { "SMSG_OPEN_LFG_DUNGEON_FINDER", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x516*/ { "SMSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x517*/ { "CMSG_MOVE_SET_COLLISION_HGT_ACK", STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x518*/ { "MSG_MOVE_SET_COLLISION_HGT", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x519*/ { "CMSG_CLEAR_RANDOM_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x51A*/ { "CMSG_CLEAR_HOLIDAY_BG_WIN_TIME", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x51B*/ { "CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL },
- /*0x51C*/ { "SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x51D*/ { "SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
- /*0x51E*/ { "SMSG_COMPRESSED_UNKNOWN_1310", STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide },
+#define DEFINE_OPCODE_HANDLER(opcode, status, processing, handler) \
+ ValidateAndSetOpcode<(opcode < NUM_OPCODE_HANDLERS), (opcode != 0)>(opcode, #opcode, status, processing, handler);
+
+ DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_LEVEL_GRANT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptGrantLevel );
+ DEFINE_OPCODE_HANDLER(CMSG_ACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAcceptTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ACTIVATETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ACTIVATETAXIEXPRESS, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleActivateTaxiExpressOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ADDON_REGISTERED_PREFIXES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonRegisteredPrefixesOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_ADD_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddFriendOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ADD_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddIgnoreOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ADD_VOICE_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_ALTER_APPEARANCE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAlterAppearance );
+ DEFINE_OPCODE_HANDLER(CMSG_AREATRIGGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaTriggerOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueryOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_AREA_SPIRIT_HEALER_QUEUE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAreaSpiritHealerQueueOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamAcceptOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamCreateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDeclineOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamDisbandOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamInviteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaderOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamLeaveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRemoveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ARENA_TEAM_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleArenaTeamRosterOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ATTACKSTOP, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackStopOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ATTACKSWING, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAttackSwingOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_BIDDER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListBidderItems );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListItems );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_OWNER_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListOwnerItems );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_LIST_PENDING_SALES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionListPendingSales );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_PLACE_BID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionPlaceBid );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_REMOVE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionRemoveItem );
+ DEFINE_OPCODE_HANDLER(CMSG_AUCTION_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionSellItem );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOBANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoEquipItemSlotOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_BAG_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBagItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_LOOT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutostoreLootItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_AUTO_DECLINE_GUILD_INVITES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoDeclineGuildInvites );
+ DEFINE_OPCODE_HANDLER(CMSG_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBankerActivateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LEAVE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBattlefieldLeaveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldListOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfEntryInviteResponse );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_PORT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattleFieldPortOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlefieldStatusOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEGROUND_PLAYER_POSITIONS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBattlegroundPlayerPositionsOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_ARENA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterJoinArena );
+ DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_JOIN_RATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBeginTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBinderActivateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BUG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBugOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BUSY_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBusyTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BUYBACK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuybackItem );
+ DEFINE_OPCODE_HANDLER(CMSG_BUY_BANK_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyBankSlotOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_ADD_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_ARENA_TEAM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarArenaTeam );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_COMPLAIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarComplain );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_COPY_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarCopyEvent );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventInvite );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_MODERATOR_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventModeratorStatus);
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_REMOVE_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRemoveInvite );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_RSVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventRsvp );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_SIGNUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventSignup );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_STATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarEventStatus );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_CALENDAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetCalendar );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetEvent );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GET_NUM_PENDING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGetNumPending );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_GUILD_FILTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarGuildFilter );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_REMOVE_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarRemoveEvent );
+ DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_UPDATE_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarUpdateEvent );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_AUTO_REPEAT_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAutoRepeatSpellOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_CHANNELLING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelChanneling );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_MOUNT_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelMountAuraOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_QUEUED_SPELL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_TEMP_ENCHANTMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTempEnchantmentOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_CANCEL_TRADE, STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelTradeOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANGEPLAYER_DIFFICULTY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle);
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_ANNOUNCEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelAnnouncements );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_BAN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelBan );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_DISPLAY_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelDisplayListQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelInvite );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_KICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelKick );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelList );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MODERATE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MODERATOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerator );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_MUTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelMute );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelOwner );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_PASSWORD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelPassword );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_ROSTER_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SET_OWNER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelSetOwner );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SILENCE_ALL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_SILENCE_VOICE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNBAN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnban );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNMODERATOR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmoderator );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNMUTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelUnmute );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNSILENCE_ALL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_UNSILENCE_VOICE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_VOICE_OFF, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHANNEL_VOICE_ON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelVoiceOnOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_CREATE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCreateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_CUSTOMIZE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharCustomize );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_DELETE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharDeleteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_ENUM, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharEnumOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_FACTION_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_RACE_CHANGE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharFactionOrRaceChange );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAR_RENAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleCharRenameOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAT_FILTERED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CHAT_IGNORED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CLEAR_CHANNEL_WATCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CLEAR_RAID_MARKER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CLEAR_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleClearTradeItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_ENTER_INSTANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_EXIT_INSTANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_MAP_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_PARTY_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_INSTANCE_COMMAND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMMENTATOR_START_WARGAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_COMPLAIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleComplainOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCompleteCinematic );
+ DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_MOVIE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CONNECT_TO_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_CONTACT_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleContactListOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_CORPSE_MAP_POSITION_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseMapPositionQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_CREATURE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleCreatureQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_DANCE_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_DEL_VOICE_IGNORE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_DESTROY_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDestroyItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_DISMISS_CONTROLLED_VEHICLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissControlledVehicle );
+ DEFINE_OPCODE_HANDLER(CMSG_DISMISS_CRITTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDismissCritter );
+ DEFINE_OPCODE_HANDLER(CMSG_DUEL_ACCEPTED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelAcceptedOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_DUEL_CANCELLED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDuelCancelledOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_EJECT_PASSENGER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEmoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ENABLETAXI, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes );
+ DEFINE_OPCODE_HANDLER(CMSG_ENABLE_NAGLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetDelete );
+ DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_SAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetSave );
+ DEFINE_OPCODE_HANDLER(CMSG_EQUIPMENT_SET_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEquipmentSetUse );
+ DEFINE_OPCODE_HANDLER(CMSG_FAR_SIGHT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleFarSightOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_FORCE_MOVE_ROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveRootAck );
+ DEFINE_OPCODE_HANDLER(CMSG_FORCE_MOVE_UNROOT_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveUnRootAck );
+ DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJECT_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGameObjectQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJ_REPORT_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameobjectReportUse );
+ DEFINE_OPCODE_HANDLER(CMSG_GAMEOBJ_USE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGameObjectUseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GET_MAIL_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetMailList );
+ DEFINE_OPCODE_HANDLER(CMSG_GET_MIRRORIMAGE_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMirrorImageDataRequest );
+ DEFINE_OPCODE_HANDLER(CMSG_GMRESPONSE_RESOLVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMResponseResolve );
+ DEFINE_OPCODE_HANDLER(CMSG_GMSURVEY_SUBMIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMSurveySubmit );
+ DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketCreateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_DELETETICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketDeleteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_GETTICKET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketGetTicketOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_SYSTEMSTATUS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketSystemStatusOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_GMTICKET_UPDATETEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGMTicketUpdateOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GM_REPORT_LAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportLag );
+ DEFINE_OPCODE_HANDLER(CMSG_GOSSIP_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipHelloOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GOSSIP_SELECT_OPTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGossipSelectOptionOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GRANT_LEVEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGrantLevel );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_ASSISTANT_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupAssistantLeaderOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_CHANGE_SUB_GROUP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupChangeSubGroupOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupDisbandOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupInviteResponseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_RAID_CONVERT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupRaidConvertOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_REQUEST_JOIN_UPDATES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_LEADER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSetLeaderOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_SET_ROLES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGroupSetRolesOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_SWAP_SUB_GROUP, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupSwapSubGroupOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE_GUID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteGuidOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAcceptOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAchievementProgressQuery);
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ADD_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAddRankOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ASSIGN_MEMBER_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildAssignRankOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANKER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankerActivate );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_BUY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankBuyTab );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_DEPOSIT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankDepositMoney );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankLogQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankMoneyWithdrawn );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankQueryTab );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_QUERY_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryGuildBankTabText );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_SWAP_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankSwapItems );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_UPDATE_TAB, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankUpdateTab );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_WITHDRAW_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildBankWithdrawMoney );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_CHANGE_NAME_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDeclineOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEL_RANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDelRankOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_DEMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDemoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_DISBAND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildDisbandOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_EVENT_LOG_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildEventLogQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildChangeInfoTextOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInviteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildLeaveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_MEMBER_SEND_SOR_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_MOTD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildMOTDOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_NEWS_UPDATE_STICKY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildNewsUpdateStickyOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPermissions );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_PROMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildPromoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_NEWS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildQueryNewsOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_QUERY_RANKS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryRanksOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_REMOVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRemoveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_REPLACE_GUILD_MASTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_REQUEST_CHALLENGE_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_REQUEST_MAX_DAILY_XP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRequestMaxDailyXP );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_REQUEST_PARTY_STATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRequestPartyState );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_ROSTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildRosterOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_ACHIEVEMENT_TRACKING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_GUILD_MASTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetGuildMaster );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_NOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetNoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_SET_RANK_PERMISSIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildSetRankPermissionsOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_GUILD_SWITCH_RANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_HEARTH_AND_RESURRECT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleHearthAndResurrect );
+ DEFINE_OPCODE_HANDLER(CMSG_IGNORE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleIgnoreTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_INITIATE_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInitiateTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_INSPECT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_INSPECT_HONOR_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectHonorStatsOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_WARNING_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefund );
+ DEFINE_OPCODE_HANDLER(CMSG_ITEM_REFUND_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemRefundInfoRequest );
+ DEFINE_OPCODE_HANDLER(CMSG_ITEM_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleItemTextQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_JOIN_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleJoinChannel );
+ DEFINE_OPCODE_HANDLER(CMSG_KEEP_ALIVE, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(CMSG_LEARN_PREVIEW_TALENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalents );
+ DEFINE_OPCODE_HANDLER(CMSG_LEARN_PREVIEW_TALENTS_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnPreviewTalentsPet );
+ DEFINE_OPCODE_HANDLER(CMSG_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLearnTalentOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LEAVE_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLeaveChannel );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_GET_STATUS, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetStatus );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgJoinOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgLeaveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_LFR_JOIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_LFR_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_LOCK_INFO_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleLfgGetLockInfoOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_PROPOSAL_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgProposalResultOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_BOOT_VOTE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetBootVoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_COMMENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_ROLES, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetRolesOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LFG_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgTeleportOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_ADD_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderAddRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_BROWSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderBrowse );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_DECLINE_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderDeclineRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_APPLICATIONS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetApplications);
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_GET_RECRUITS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderGetRecruits );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_POST_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderPostRequest );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_REMOVE_RECRUIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderRemoveRecruit );
+ DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_SET_GUILD_POST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildFinderSetGuildPost );
+ DEFINE_OPCODE_HANDLER(CMSG_LIST_INVENTORY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleListInventoryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOAD_SCREEN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleLoadScreenOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOGOUT_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutCancelOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOGOUT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLogoutRequestOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOG_DISCONNECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_CURRENCY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_MASTER_GIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMasterGiveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_METHOD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMethodOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootMoneyOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_RELEASE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootReleaseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_LOOT_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLootRoll );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_CREATE_TEXT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailCreateTextItem );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_DELETE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailDelete );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_MARK_AS_READ, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailMarkAsRead );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_RETURN_TO_SENDER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailReturnToSender );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_TAKE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeItem );
+ DEFINE_OPCODE_HANDLER(CMSG_MAIL_TAKE_MONEY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMailTakeMoney );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_BATTLEGROUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_ADDON_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAddonMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_BATTLEGROUND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_CHANNEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_DND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_GUILD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_OFFICER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_PARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_RAID, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_RAID_WARNING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_SAY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_WHISPER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MESSAGECHAT_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMessagechatOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MINIGAME_MOVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_MOUNTSPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHNG_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FALL_RESET, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FEATHER_FALL_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleFeatherFallAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleForceSpeedChangeAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_GRAVITY_DISABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_GRAVITY_ENABLE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_HOVER_ACK, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveHoverAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_KNOCK_BACK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveKnockBackAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_NOT_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveNotActiveMover );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_FLY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_FLY_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveSetCanFlyAckOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_COLLISION_HEIGHT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleSetCollisionHeightAck );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_SPLINE_DONE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveSplineDoneOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_TIME_SKIPPED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleMoveTimeSkippedOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_MOVE_WATER_WALK_ACK, STATUS_UNHANDLED, PROCESS_THREADSAFE, &WorldSession::HandleMoveWaterWalkAck );
+ DEFINE_OPCODE_HANDLER(CMSG_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNameQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_NEXT_CINEMATIC_CAMERA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNextCinematicCamera );
+ DEFINE_OPCODE_HANDLER(CMSG_NPC_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleNpcTextQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_OBJECT_UPDATE_FAILED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleObjectUpdateFailedOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_OBJECT_UPDATE_RESCUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_OFFER_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOfferPetitionOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_OPENING_CINEMATIC, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpeningCinematic );
+ DEFINE_OPCODE_HANDLER(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_OPT_OUT_OF_LOOT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleOptOutOfLootOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PAGE_TEXT_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePageTextQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PARTY_SILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_PARTY_UNSILENCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_PETITION_BUY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionBuyOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PETITION_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PETITION_SHOWLIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowListOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PETITION_SHOW_SIGNATURES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionShowSignOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PETITION_SIGN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionSignOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_ABANDON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAbandon );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetAction );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCancelAuraOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_LEARN_TALENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetLearnTalent );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_NAME_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetNameQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetRename );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_SET_ACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSetAction );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_SPELL_AUTOCAST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetSpellAutocastOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PET_STOP_ATTACK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetStopAttack );
+ DEFINE_OPCODE_HANDLER(CMSG_PING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(CMSG_PLAYED_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayedTime );
+ DEFINE_OPCODE_HANDLER(CMSG_PLAYER_LOGIN, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLoginOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_PLAYER_VEHICLE_ENTER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEnterPlayerVehicle );
+ DEFINE_OPCODE_HANDLER(CMSG_PLAY_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_PUSHQUESTTOPARTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePushQuestToParty );
+ DEFINE_OPCODE_HANDLER(CMSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandlePVPLogDataOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_BATTLEFIELD_STATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleGuildRewardsQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_XP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildQueryXPOpcode ); // STATUS_AUTHED
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_INSPECT_ACHIEVEMENTS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryInspectAchievements );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_QUESTS_COMPLETED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryQuestsCompleted );
+ DEFINE_OPCODE_HANDLER(CMSG_QUERY_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryTimeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_ACCEPT_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverAcceptQuestOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_CHOOSE_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverChooseRewardOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_COMPLETE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCompleteQuest );
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverHelloOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_QUERY_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQueryQuestOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_REQUEST_REWARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverRequestRewardOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverStatusMultipleQuery);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleQuestgiverStatusQueryOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_QUESTLOG_REMOVE_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogRemoveQuest );
+ DEFINE_OPCODE_HANDLER(CMSG_QUEST_CONFIRM_ACCEPT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestConfirmAccept );
+ DEFINE_OPCODE_HANDLER(CMSG_QUEST_NPC_QUERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_QUEST_POI_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPOIQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_QUEST_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_RANDOMIZE_CHAR_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomizeCharNameOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_READY_FOR_ACCOUNT_DATA_TIMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleReadyForAccountDataTimes );
+ DEFINE_OPCODE_HANDLER(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItem );
+ DEFINE_OPCODE_HANDLER(CMSG_REALM_SPLIT, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRealmSplitOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_RECLAIM_CORPSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReclaimCorpseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REDIRECTION_AUTH_PROOF, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_REFORGE_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleReforgeItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REORDER_CHARACTERS, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleReorderCharacters );
+ DEFINE_OPCODE_HANDLER(CMSG_REPAIR_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepairItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REPOP_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRepopRequestOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REPORT_PVP_AFK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReportPvPAFK );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestAccountData );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CATEGORY_COOLDOWNS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleRequestCategoryCooldowns );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_CEMETERY_LIST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_HOTFIX, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleRequestHotfix );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PARTY_MEMBER_STATS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPartyMemberStatsOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PET_INFO, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestPetInfoOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_OPTIONS_ENABLED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleRequestPvpOptions );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_PVP_REWARDS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleRequestPvpReward );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RAID_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestRaidInfoOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RATED_BG_INFO, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleRequestRatedBgInfo );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RATED_BG_STATS, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleRequestRatedBgStats );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_RESEARCH_HISTORY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_EXIT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRequestVehicleExit );
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_NEXT_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle);
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_PREV_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle);
+ DEFINE_OPCODE_HANDLER(CMSG_REQUEST_VEHICLE_SWITCH_SEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChangeSeatsOnControlledVehicle);
+ DEFINE_OPCODE_HANDLER(CMSG_RESET_FACTION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_RESET_INSTANCES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResetInstancesOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_RESURRECT_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleResurrectResponseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_RETURN_TO_GRAVEYARD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReturnToGraveyard );
+ DEFINE_OPCODE_HANDLER(CMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SAVE_CUF_PROFILES, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSaveCUFProfiles );
+ DEFINE_OPCODE_HANDLER(CMSG_SELF_RES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSelfResOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SELL_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSellItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SEND_MAIL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSendMail );
+ DEFINE_OPCODE_HANDLER(CMSG_SEND_SOR_REQUEST_VIA_ADDRESS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SETSHEATHED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSheathedOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIONBAR_TOGGLES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionBarToggles );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ACTION_BUTTON, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActionButtonOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_MOVER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveMoverOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetActiveVoiceChannel ); // STATUS_AUTHED
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ALLOW_LOW_LEVEL_RAID1, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_ALLOW_LOW_LEVEL_RAID2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_CHANNEL_WATCH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetChannelWatch );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_CONTACT_NOTES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetContactNotesOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_CURRENCY_FLAGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_EVERYONE_IS_ASSISTANT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_ATWAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionAtWar );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_INACTIVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionInactiveOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_GUILD_BANK_TEXT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetGuildBankTabText );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_PET_SLOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_PLAYER_DECLINED_NAMES, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleSetPlayerDeclinedNames );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_PREFERED_CEMETERY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_PRIMARY_TALENT_TREE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_RELATIVE_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_SAVED_INSTANCE_EXTEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetSavedInstanceExtend );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_SELECTION, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleSetSelectionOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_TAXI_BENCHMARK_MODE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTaxiBenchmarkOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_TITLE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTitleOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_CURRENCY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_GOLD, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeGoldOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_TRADE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetTradeItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_VEHICLE_REC_ID_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SET_WATCHED_FACTION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetWatchedFactionOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SHOWING_CLOAK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingCloakOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SHOWING_HELM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleShowingHelmOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SOCKET_GEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSocketOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SPELLCLICK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpellClick );
+ DEFINE_OPCODE_HANDLER(CMSG_SPIRIT_HEALER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSpiritHealerActivateOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_SPLIT_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSplitItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_STANDSTATECHANGE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStandStateChangeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_STOP_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SUBMIT_BUG, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SUBMIT_COMPLAIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SUGGESTION_SUBMIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SUMMON_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSummonResponseOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SUSPEND_TOKEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_SWAP_INV_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapInvItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSwapItem );
+ DEFINE_OPCODE_HANDLER(CMSG_SYNC_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_TAXINODE_STATUS_QUERY, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiNodeStatusQueryOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_TAXIQUERYAVAILABLENODES, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleTaxiQueryAvailableNodes );
+ DEFINE_OPCODE_HANDLER(CMSG_TELEPORT_TO_UNIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_TEXT_EMOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTextEmoteOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_TIME_ADJUSTMENT_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_TIME_SYNC_RESP, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTimeSyncResp );
+ DEFINE_OPCODE_HANDLER(CMSG_TIME_SYNC_RESP_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_TOGGLE_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP );
+ DEFINE_OPCODE_HANDLER(CMSG_TOTEM_DESTROYED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTotemDestroyed );
+ DEFINE_OPCODE_HANDLER(CMSG_TRAINER_BUY_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerBuySpellOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTrainerListOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_TRANSMOGRIFY_ITEMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTransmogrifyItems );
+ DEFINE_OPCODE_HANDLER(CMSG_TURN_IN_PETITION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTurnInPetitionOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_CLEAR, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialClear );
+ DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_FLAG, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialFlag );
+ DEFINE_OPCODE_HANDLER(CMSG_TUTORIAL_RESET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTutorialReset );
+ DEFINE_OPCODE_HANDLER(CMSG_UNACCEPT_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnacceptTradeOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SKILL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnlearnSkillOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SPECIALIZATION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnregisterAddonPrefixesOpcode);
+ DEFINE_OPCODE_HANDLER(CMSG_UPDATE_ACCOUNT_DATA, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateAccountData );
+ DEFINE_OPCODE_HANDLER(CMSG_UPDATE_MISSILE_TRAJECTORY, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateMissileTrajectory );
+ DEFINE_OPCODE_HANDLER(CMSG_UPDATE_PROJECTILE_POSITION, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleUpdateProjectilePosition );
+ DEFINE_OPCODE_HANDLER(CMSG_USED_FOLLOW, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_VIOLENCE_LEVEL, STATUS_AUTHED, PROCESS_INPLACE, &WorldSession::HandleViolenceLevel );
+ DEFINE_OPCODE_HANDLER(CMSG_VOICE_SESSION_ENABLE, STATUS_AUTHED, PROCESS_THREADUNSAFE, &WorldSession::HandleVoiceSessionEnableOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_QUERY, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageQuery );
+ DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_TRANSFER, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageTransfer );
+ DEFINE_OPCODE_HANDLER(CMSG_VOID_STORAGE_UNLOCK, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidStorageUnlock );
+ DEFINE_OPCODE_HANDLER(CMSG_VOID_SWAP_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleVoidSwapItem );
+ DEFINE_OPCODE_HANDLER(CMSG_WARDEN_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWardenDataOpcode ); // STATUS_AUTHED
+ DEFINE_OPCODE_HANDLER(CMSG_WARGAME_ACCEPT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_WARGAME_START, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(CMSG_WHO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_WHOIS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleWhoisOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleWorldStateUITimerUpdate );
+ DEFINE_OPCODE_HANDLER(CMSG_WORLD_TELEPORT, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWorldTeleportOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_WRAP_ITEM, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleWrapItemOpcode );
+ DEFINE_OPCODE_HANDLER(CMSG_ZONEUPDATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleZoneUpdateOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_AUCTION_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAuctionHelloOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(MSG_CHANNEL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(MSG_CORPSE_QUERY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCorpseQueryOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_INSPECT_ARENA_TEAMS, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInspectArenaTeamsOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_LIST_STABLED_PETS, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleListStabledPetsOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_FALL_LAND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_HEARTBEAT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_JUMP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FACING, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_WALK_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_ASCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_BACKWARD, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_DESCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_FORWARD, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_PITCH_DOWN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_PITCH_UP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_STRAFE_LEFT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_STRAFE_RIGHT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_TURN_LEFT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_START_TURN_RIGHT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_ASCEND, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_PITCH, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_STRAFE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_TURN, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_ACK, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMoveTeleportAck );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_TELEPORT_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_TIME_SKIPPED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_COLLISION_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_MOVE_WORLDPORT_ACK, STATUS_TRANSFER, PROCESS_THREADUNSAFE, &WorldSession::HandleMoveWorldportAckOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_NOTIFY_PARTY_SQUELCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_PARTY_ASSIGNMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePartyAssignmentOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_PETITION_DECLINE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionDeclineOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_PETITION_RENAME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetitionRenameOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_QUERY_NEXT_MAIL_TIME, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQueryNextMailTime );
+ DEFINE_OPCODE_HANDLER(MSG_QUEST_PUSH_RESULT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestPushResult );
+ DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_CONFIRM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(MSG_RAID_READY_CHECK_FINISHED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidReadyCheckFinishedOpcode);
+ DEFINE_OPCODE_HANDLER(MSG_RAID_TARGET_UPDATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRaidTargetUpdateOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_RANDOM_ROLL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRandomRollOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_SET_DUNGEON_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetDungeonDifficultyOpcode);
+ DEFINE_OPCODE_HANDLER(MSG_SET_RAID_DIFFICULTY, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetRaidDifficultyOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode);
+ DEFINE_OPCODE_HANDLER(MSG_TALENT_WIPE_CONFIRM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTalentWipeConfirmOpcode );
+ DEFINE_OPCODE_HANDLER(MSG_VERIFY_CONNECTIVITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess );
+ DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_INFO_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACCOUNT_RESTRICTED_WARNING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACTION_BUTTONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ACTIVATETAXIREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ADDON_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ADD_RUNE_POWER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AREA_SPIRIT_HEALER_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AREA_TRIGGER_MOVEMENT_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_UNIT_DESTROYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ARENA_TEAM_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKERSTATEUPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTART, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSTOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_BADFACING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_CANT_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_DEADTARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ATTACKSWING_NOTINRANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_BIDDER_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_LIST_PENDING_SALES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_OWNER_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_OWNER_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUCTION_REMOVED_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AURA_POINTS_DEPLETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AURA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AURA_UPDATE_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUTH_CHALLENGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AUTH_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AVAILABLE_VOICE_CHANNEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_AVERAGE_ITEM_LEVEL_INFORM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BARBER_SHOP_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EJECT_PENDING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTERED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_MGR_STATE_CHANGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PLAYER_POSITIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_PORT_DENIED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_RATED_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_QUEUED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_ACTIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEFIELD_STATUS_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_INFO_THROTTLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_JOINED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BATTLEGROUND_PLAYER_LEFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BINDPOINTUPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BREAK_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_BUY_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_ARENA_TEAM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_CLEAR_PENDING_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_REMOVED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_EVENT_UPDATED_ALERT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_FILTER_GUILD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_ADDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_CALENDAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_SEND_NUM_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CAMERA_SHAKE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CANCEL_AUTO_REPEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CANCEL_COMBAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_MEMBER_COUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHANNEL_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_LOGIN_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_CUSTOMIZE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_DELETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_ENUM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_FACTION_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAR_RENAME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_IGNORED_ACCOUNT_MUTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_NOT_IN_PARTY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_PLAYER_AMBIGUOUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_PLAYER_NOT_FOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_RESTRICTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_SERVER_DISCONNECTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_SERVER_RECONNECTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CHAT_WRONG_FACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLEAR_BOSS_EMOTES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLEAR_COOLDOWNS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLEAR_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLIENTCACHE_VERSION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CLIENT_CONTROL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMBAT_EVENT_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_MAP_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_PARTY_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_PLAYER_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_STATE_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMPLAIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMPRESSED_MOVES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMSAT_CONNECT_FAIL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMSAT_DISCONNECT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COMSAT_RECONNECT_TRY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CONVERT_RUNE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CORPSE_NOT_IN_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CREATURE_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CRITERIA_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CROSSED_INEBRIATION_THRESHOLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_REMOVED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CURRENCY_LOOT_RESTORED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_CUSTOM_LOAD_SCREEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_CALC_LOG, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DANCE_QUERY_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DB_REPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DEATH_RELEASE_LOC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DEBUG_RUNE_REGEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DEFENSE_MESSAGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DESTROY_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DIFFERENT_INSTANCE_FROM_PARTY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DISENCHANT_CREDIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DISMOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DISMOUNTRESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DISPEL_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DISPLAY_GAME_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DROP_NEW_CONNECTION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_COUNTDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_INBOUNDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_OUTOFBOUNDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_REQUESTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUEL_WINNER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DUMP_RIDE_TICKETS_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_DURABILITY_DAMAGE_DEATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ECHO_PARTY_SQUELCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EMOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ENABLE_BARBER_SHOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ENCHANTMENTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ENVIRONMENTALDAMAGELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_SAVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_USE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FAILED_PLAYER_CONDITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FEIGN_DEATH_RESISTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FISH_ESCAPED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FISH_NOT_HOOKED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FLIGHT_SPLINE_SYNC, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FLOOD_DETECTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FORCED_DEATH_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FORCE_SEND_QUEUED_PACKETS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FORCE_SET_VEHICLE_REC_ID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FORGE_MASTER_SET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_FRIEND_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_CUSTOM_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_DESPAWN_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_PAGETEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMEOBJECT_RESET_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMESPEED_SET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMETIME_SET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAMETIME_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAME_EVENT_DEBUG_LOG, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_DB_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_RECEIVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_STATUS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_CREATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_DELETETICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_GETTICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_SYSTEMSTATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GMTICKET_UPDATETEXT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GM_MESSAGECHAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GM_PLAYER_INFO, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GM_TICKET_STATUS_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GODMODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GOSSIP_POI, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUPACTION_THROTTLED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_DESTROYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_LEADER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_SET_ROLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GROUP_UNINVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ACHIEVEMENT_MEMBERS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_LOG_QUERY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_MONEY_WITHDRAWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_BANK_QUERY_TEXT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_COMPLETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHALLENGE_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CHANGE_NAME_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_COMMAND_RESULT_2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_CRITERIA_DELETED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_DECLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_EVENT_LOG_QUERY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_FLAGGED_FOR_RENAME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_INVITE_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MAX_DAILY_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBERS_FOR_RECIPE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_DAILY_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MEMBER_UPDATE_NOTE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_MOVE_STARTING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_NEWS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_RANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_RANKS_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_RECIPES, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_RENAMED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_WEEKLY_CAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_RESET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_REWARDS_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_ROSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_UPDATE_ROSTER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_HEALTH_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_HIGHEST_THREAT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_HOTFIX_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_HOTFIX_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INITIAL_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INIT_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RATED_BG_STATS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSPECT_RESULTS_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSPECT_TALENT, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_LOCK_WARNING_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_RESET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_RESET_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INSTANCE_SAVE_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INVALIDATE_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INVALIDATE_PLAYER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INVALID_PROMOTION_CODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_INVENTORY_CHANGE_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_ADD_PASSIVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_REFUND_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_REFUND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_REMOVE_PASSIVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_SEND_PASSIVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_OFFER_CONTINUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_PLAYER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_QUEUE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_ROLE_CHECK_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_ROLE_CHOSEN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_SLOT_INVALID, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_TELEPORT_DENIED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_SEARCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_STATUS_NONE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICANT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_BROWSE_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_POST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_RECRUIT_LIST_UPDATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LIST_INVENTORY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOGIN_SETTIMESPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOGIN_VERIFY_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_CANCEL_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOGOUT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOG_XPGAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_ALL_PASSED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_CLEAR_MONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_CONTENTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_ITEM_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_MASTER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_MONEY_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_RELEASE_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_REMOVED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_ROLL_WON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_SLOT_CHANGED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_LOOT_START_ROLL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MAIL_LIST_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MAP_OBJ_EVENTS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_IN_PROGRESS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MESSAGECHAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MESSAGE_BOX, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_SETUP, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_STATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MIRRORIMAGE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MONEY_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MONSTER_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MONSTER_MOVE_TRANSPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOUNTRESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOUNTSPECIAL_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_DISABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_GRAVITY_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COMPOUND_STATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_COLLISION_HEIGHT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_FLIGHT_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_PITCH_RATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_BACK_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_BACK_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_SWIM_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_TURN_RATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_WALK_SPEED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NEW_TAXI_PATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NEW_WORLD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NEW_WORLD_ABORT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NOTIFICATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NOTIFY_DANCE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NOTIFY_DEST_LOC_SPELL_CAST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_NPC_TEXT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_OFFER_PETITION_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_OPEN_CONTAINER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_OPEN_LFG_DUNGEON_FINDER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_OVERRIDE_LIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PAGE_TEXT_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PARTYKILLLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PARTY_COMMAND_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PARTY_MEMBER_STATS_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PAUSE_MIRROR_TIMER, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PERIODICAURALOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETGODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETITION_ALREADY_SIGNED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETITION_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETITION_SHOWLIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETITION_SHOW_SIGNATURES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PETITION_SIGN_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_ACTION_FEEDBACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_ACTION_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_ADDED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_BROKEN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_DISMISS_SOUND, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_GUIDS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_MODE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_NAME_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_RENAMEABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_SLOT_UPDATED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PET_UPDATE_COMBO_POINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYERBINDERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYERBOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYER_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAYER_VEHICLE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_MUSIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PONG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PRE_RESURRECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PROCRESIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PROPOSE_LEVEL_GRANT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PVP_CREDIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PVP_LOG_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_PVP_OPTIONS_ENABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_OFFER_REWARD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_DETAILS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_INVALID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_QUEST_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_REQUEST_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTGIVER_STATUS_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTLOG_FULL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_ADD_PVP_KILL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUESTUPDATE_FAILEDTIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUEST_NPC_QUERY_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUEST_POI_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_QUEST_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_GROUP_ONLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_INSTANCE_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_MARKERS_CHANGED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_THROTTLED_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RAID_SUMMON_FAILED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RANDOMIZE_CHAR_NAME, STATUS_NEVER, PROCESS_THREADUNSAFE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RATED_BG_RATING, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RATED_BG_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_READ_ITEM_OK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REALM_SPLIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REAL_GROUP_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RECEIVED_MAIL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REDIRECT_CLIENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_EXPIRED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REFER_A_FRIEND_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REFORGE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REMOVED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REPORT_PVP_AFK_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESEARCH_SETUP_HISTORY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESET_FAILED_NOTIFY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESURRECT_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RESYNC_RUNES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ROLE_POLL_BEGIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_RWHOIS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SELL_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SEND_MAIL_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SEND_UNLEARN_SPELLS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVERTIME, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVER_INFO_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVER_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SERVER_PERF, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_ATWAR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SET_PROJECTILE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SHOWTAXINODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SHOW_RATINGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SOCKET_GEMS_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SOR_START_EXPERIENCE_INCOMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLBREAKLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLDAMAGESHIELD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLDISPELLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLENERGIZELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLHEALLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLINSTAKILLLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLINTERRUPTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLLOGEXECUTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLLOGMISS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLNONMELEEDAMAGELOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLORDAMAGE_IMMUNE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELLSTEALLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_CATEGORY_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_DELAYED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_FAILED_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_GO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_STABLE_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_STANDSTATE_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_STOP_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_STOP_MIRROR_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_STREAMING_MOVIE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUMMON_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUMMON_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUPERCEDED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUPPRESS_NPC_GREETINGS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUSPEND_COMMS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_SUSPEND_TOKEN_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TALENTS_ERROR, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TALENTS_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TALENTS_INVOLUNTARILY_RESET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TAXINODE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TEST_DROP_RATE_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TEXT_EMOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_THREAT_CLEAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_THREAT_REMOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_THREAT_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TIME_ADJUSTMENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TIME_SYNC_REQ, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TITLE_EARNED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TOGGLE_XP_GAIN, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TOTEM_CREATED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRADE_STATUS_EXTENDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRAINER_BUY_SUCCEEDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRAINER_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_ABORTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRANSFER_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRIGGER_CINEMATIC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TRIGGER_MOVIE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TURN_IN_PETITION_RESULTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_TUTORIAL_FLAGS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UNIT_HEALTH_FREQUENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UNIT_SPELLCAST_START, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_COMBO_POINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_CURRENCY_WEEK_LIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_INSTANCE_OWNERSHIP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_LAST_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_SERVER_PLAYER_POSITION, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_UPDATE_WORLD_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_USERLIST_ADD, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_USERLIST_REMOVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICESESSION_FULL, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ROSTER_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOICE_SET_TALKER_MUTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOID_ITEM_SWAP_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_CONTENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOID_STORAGE_TRANSFER_CHANGES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_VOID_TRANSFER_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WAIT_QUEUE_FINISH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WARGAME_CHECK_ENTRY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WARGAME_REQUEST_SENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WEATHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_LAST_RESET, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_RESET_CURRENCY, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE_UPDATE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WHO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WHOIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_WORLD_STATE_UI_TIMER_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_XP_GAIN_ABORTED, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ DEFINE_OPCODE_HANDLER(SMSG_ZONE_UNDER_ATTACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+
+ // These opcodes are not in WPP
+
+ //DEFINE_OPCODE_HANDLER(CMSG_ACTIVE_PVP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_ADD_PVP_MEDAL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_ADVANCE_SPAWN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AFK_MONITOR_INFO_CLEAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AFK_MONITOR_INFO_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_BEGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_PROOF, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AUTH_SRP6_RECODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AUTOEQUIP_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_AUTOSTORE_GROUND_ITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_JOIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BATTLEFIELD_REQUEST_SCORE_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); Need to send the response
+ //DEFINE_OPCODE_HANDLER(CMSG_BATTLEMASTER_HELLO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBattlemasterHelloOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_BEASTMASTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BOOTME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BOT_DETECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BOT_DETECTED2, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BUY_ITEM_IN_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyItemInSlotOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_BUY_LOTTERY_TICKET_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_BUY_STABLE_SLOT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyStableSlot );
+ //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CALENDAR_EVENT_INVITE_NOTES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CANCEL_GROWTH_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelGrowthAuraOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHANGE_GDF_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHANGE_PERSONAL_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHARACTER_POINT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_PLAYER_LOGIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_PLAYER_LOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SETMONEY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SET_ARENA_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHEAT_SET_HONOR_CURRENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CHECK_LOGIN_CRITERIA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_EXPLORATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_HOLIDAY_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_RANDOM_BG_WIN_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CLEAR_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_COMPLETE_ACHIEVEMENT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CONTROLLER_EJECT_PASSENGER, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleEjectPassenger );
+ //DEFINE_OPCODE_HANDLER(CMSG_COOLDOWN_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CREATEGAMEOBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CREATEITEM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_CREATEMONSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DBLOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_ACTIONS_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_ACTIONS_STOP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_AISTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_CHANGECELLZONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_LIST_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_PASSIVE_AURA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEBUG_SERVER_GEO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DECHARGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DECLINE_CHANNEL_INVITE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleChannelDeclineInvite );
+ //DEFINE_OPCODE_HANDLER(CMSG_DELETE_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DEL_PVP_MEDAL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DESTROYMONSTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DESTROY_ITEMS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DISABLE_PVP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DROP_NEW_CONNECTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_DUMP_OBJECTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_ENABLE_DAMAGE_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_END_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_EXPIRE_RAID_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FLAG_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FLAG_QUEST_FINISH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FLOOD_GRACE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTIONONOTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FORCEACTIONSHOW, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FORCE_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_FORCE_SAY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GAMESPEED_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GAMETIME_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GETDEATHBINDZONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GET_CHANNEL_MEMBER_COUNT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGetChannelMemberCount );
+ //DEFINE_OPCODE_HANDLER(CMSG_GHOST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GMRESPONSE_CREATE_TICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_CHARACTER_RESTORE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_CHARACTER_SAVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_CREATE_ITEM_TARGET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_DESTROY_ONLINE_CORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_FREEZE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_GRANT_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_INVIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_MOVECORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE_ACCOUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_NUKE_CHARACTER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_REMOVE_ACHIEVEMENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_REQUEST_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_RESURRECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_REVEALTO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_SET_CRITERIA_FOR_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_SET_SECURITY_GROUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_SHOW_COMPLAINTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_SILENCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_SUMMONMOB, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_TEACH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_UBERINVIS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_UNSQUELCH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_UNTEACH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_UPDATE_TICKET_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_VISION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GM_WHISPER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GROUP_CANCEL, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GROUP_UNINVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGroupUninviteOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_GUILD_BANK_NOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_GUILD_CREATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildCreateOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_GUILD_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleGuildInfoOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_KNOCKBACK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_IGNORE_REQUIREMENTS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_INSTANCE_LOCK_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleInstanceLockResponse );
+ //DEFINE_OPCODE_HANDLER(CMSG_LEARN_DANCE_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LEARN_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LEVEL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LFG_SET_NEEDS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LF_GUILD_JOIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LOAD_DANCES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LOTTERY_QUERY_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_LUA_USAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_GM_SENT_MAIL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_INVALIDATE_CACHE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MAELSTROM_RENAME_GUILD, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MAKEMONSTERATTACKGUID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_COMPLETE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(CMSG_MEETINGSTONE_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARACTER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_PORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_CHARM_TELEPORT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_RELATIVE_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_SET_VEHICLE_REC_ID_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_START_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_NEW_SPELL_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_NO_SPELL_VARIANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PERFORM_ACTION_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PETGODMODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PET_LEVEL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PET_NAME_CACHE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PET_UNLEARN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PET_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_AI_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_DIFFICULTY_CHANGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PLAYER_LOGOUT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePlayerLogoutOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_PROFILEDATA_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_PVP_QUEUE_STATS_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUERY_GUILD_MAX_XP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUERY_OBJECT_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUERY_OBJECT_ROTATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUERY_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUERY_VEHICLE_STATUS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_CANCEL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverCancel );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUESTGIVER_QUEST_AUTOLAUNCH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestgiverQuestAutoLaunch );
+ //DEFINE_OPCODE_HANDLER(CMSG_QUESTLOG_SWAP_QUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleQuestLogSwapQuest );
+ //DEFINE_OPCODE_HANDLER(CMSG_RECHARGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_REDIRECTION_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_REFER_A_FRIEND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_REMOVE_GLYPH, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleRemoveGlyph );
+ //DEFINE_OPCODE_HANDLER(CMSG_REPLACE_ACCOUNT_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_RUN_SCRIPT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SAVE_DANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SAVE_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEARCH_LFG_JOIN, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrJoinOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEARCH_LFG_LEAVE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfrLeaveOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEND_COMBAT_TRIGGER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEND_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEND_GENERAL_TRIGGER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SEND_LOCAL_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SERVERTIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SERVER_BROADCAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SERVER_COMMAND, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SERVER_INFO_QUERY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SETDEATHBINDPOINT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_MEMBER_SEASON_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_RATING_BY_INDEX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_SEASON_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_ARENA_TEAM_WEEKLY_GAMES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_BREATH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_CHARACTER_MODEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_CRITERIA_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_DURABILITY_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_EXPLORATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_EXPLORATION_ALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_FACTION_CHEAT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSetFactionCheat );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_GLYPH_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_GRANTABLE_LEVELS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_LFG_COMMENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetCommentOpcode );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_PAID_SERVICE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_PVP_RANK_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_PVP_TITLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_RUNE_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_RUNE_COUNT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_SKILL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_STAT_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_TITLE_SUFFIX, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SET_WORLDSTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SKILL_BUY_RANK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SKILL_BUY_STEP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_STABLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStablePet );
+ //DEFINE_OPCODE_HANDLER(CMSG_STABLE_REVIVE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableRevivePet );
+ //DEFINE_OPCODE_HANDLER(CMSG_STABLE_SWAP_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleStableSwapPet );
+ //DEFINE_OPCODE_HANDLER(CMSG_START_BATTLEFIELD_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_START_QUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_STORE_LOOT_IN_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_SUSPEND_COMMS_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TARGET_CAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TARGET_SCRIPT_CAST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TAXICLEARALLNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TAXICLEARNODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TAXIENABLEALLNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TAXIENABLENODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TAXISHOWNODES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TEST_DROP_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TOGGLE_XP_GAIN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_TRIGGER_CINEMATIC_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNCLAIM_LICENSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNDRESSPLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNITANIMTIER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_DANCE_MOVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNLEARN_TALENTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNSTABLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUnstablePet );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNUSED5, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_UNUSED6, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_USE_SKILL_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_VOICE_SET_TALKER_MUTED_REQUEST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_WEATHER_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_XP_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(CMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_DELAY_GHOST_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_DEV_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_ACCOUNT_ONLINE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_BIND_OTHER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_CHANGE_ARENA_RATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_DESTROY_CORPSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_GEARRATING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_RESETINSTANCELIMIT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_GM_SUMMON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_ALL_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_FLIGHT_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_PITCH_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RAW_POSITION_ACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_RUN_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_SWIM_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_TURN_RATE_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_SET_WALK_SPEED_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_START_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_STOP_SWIM_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_FALL_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_MOVE_TOGGLE_LOGGING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_NULL_ACTION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(MSG_PVP_LOG_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePVPLogDataOpcode );
+ //DEFINE_OPCODE_HANDLER(MSG_VIEW_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_AFK_MONITOR_INFO_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_AURACASTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_BINDZONEREPLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_BUY_BANK_SLOT_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_ACTION_PENDING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CALENDAR_UPDATE_INVITE_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHANGEPLAYER_DIFFICULTY_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_PROFILE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHARACTER_PROFILE_REALM_CONNECTED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHEAT_PLAYER_LOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CHECK_FOR_BOTS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_COMBAT_LOG_MULTIPLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_COMMENTATOR_GET_PLAYER_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_COMPLETION_NPC_RESPONCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_CORPSE_IS_NOT_IN_INSTANCE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DAMAGE_DONE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DBLOOKUP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DEBUGAURAPROC, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_AISTATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_LIST_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DEBUG_SERVER_GEO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DUMP_OBJECTS_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_DYNAMIC_DROP_ROLL_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_FORCEACTIONSHOW, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_FORCE_ANIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_FORCE_DISPLAY_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GAMETIMEBIAS_SET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GHOSTEE_GONE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GMRESPONSE_CREATE_TICKET, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GOGOGO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_CANCEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_KNOWN_RECIPES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_SET_NOTE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_TRADESKILL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_GUILD_XP_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_IGNORE_REQUIREMENTS_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_INSPECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_JOINED_BATTLEGROUND_QUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_LFG_OPEN_FROM_GOSSIP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_LFG_UPDATE_LIST, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_LF_GUILD_SEARCH_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_LOTTERY_QUERY_RESULT_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_LOTTERY_RESULT_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_MEMBER_ADDED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MEETINGSTONE_SETQUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MINIGAME_MOVE_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_CHARACTER_CHEAT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_VEHICLE_REC_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_WALK_IN_AIR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_NPC_WONT_TALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_PET_UNLEARN_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_PLAYER_UNK_DEAD_ALIVE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_PROFILEDATA_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_PUREMOUNT_CANCELLED_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_PVP_QUEUE_STATS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_QUERY_OBJECT_POSITION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_QUERY_OBJECT_ROTATION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_RAID_READY_CHECK_ERROR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_REMOVED_FROM_PVP_QUEUE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_RESET_RANGED_COMBAT_TIMER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_RESISTLOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_RESUME_CAST_BAR, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_RESURRECT_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SCRIPT_MESSAGE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SEND_ALL_COMBAT_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SERVERINFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SERVER_BUCK_DATA_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SET_EXTRA_AURA_INFO_OBSOLETE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_PROC_LOG, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPELL_CHANCE_RESIST_PUSHBACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ADJUST_PRIORITY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_VOICE_SESSION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_ZONE_MAP, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+
+#undef DEFINE_OPCODE_HANDLER
};
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index e581d7d1544..8f77f09ba2d 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -25,1327 +25,1356 @@
#include "Common.h"
-// Note: this include need for be sure have full definition of class WorldSession
-// if this class definition not complete then VS for x64 release use different size for
-// struct OpcodeHandler in this header and Opcode.cpp and get totally wrong data from
-// table opcodeTable in source when Opcode.h included but WorldSession.h not included
-#include "WorldSession.h"
-
/// List of Opcodes
enum Opcodes
{
- MSG_NULL_ACTION = 0x000,
- CMSG_BOOTME = 0x001,
- CMSG_DBLOOKUP = 0x002,
- SMSG_DBLOOKUP = 0x003,
- CMSG_QUERY_OBJECT_POSITION = 0x004,
- SMSG_QUERY_OBJECT_POSITION = 0x005,
- CMSG_QUERY_OBJECT_ROTATION = 0x006,
- SMSG_QUERY_OBJECT_ROTATION = 0x007,
- CMSG_WORLD_TELEPORT = 0x008,
- CMSG_TELEPORT_TO_UNIT = 0x009,
- CMSG_ZONE_MAP = 0x00A,
- SMSG_ZONE_MAP = 0x00B,
- CMSG_DEBUG_CHANGECELLZONE = 0x00C,
- CMSG_MOVE_CHARACTER_CHEAT = 0x00D,
- SMSG_MOVE_CHARACTER_CHEAT = 0x00E,
- CMSG_RECHARGE = 0x00F,
- CMSG_LEARN_SPELL = 0x010,
- CMSG_CREATEMONSTER = 0x011,
- CMSG_DESTROYMONSTER = 0x012,
- CMSG_CREATEITEM = 0x013,
- CMSG_CREATEGAMEOBJECT = 0x014,
- SMSG_CHECK_FOR_BOTS = 0x015,
- CMSG_MAKEMONSTERATTACKGUID = 0x016,
- CMSG_BOT_DETECTED2 = 0x017,
- CMSG_FORCEACTION = 0x018,
- CMSG_FORCEACTIONONOTHER = 0x019,
- CMSG_FORCEACTIONSHOW = 0x01A,
- SMSG_FORCEACTIONSHOW = 0x01B,
- CMSG_PETGODMODE = 0x01C,
- SMSG_PETGODMODE = 0x01D,
- SMSG_REFER_A_FRIEND_EXPIRED = 0x01E,
- CMSG_WEATHER_SPEED_CHEAT = 0x01F,
- CMSG_UNDRESSPLAYER = 0x020,
- CMSG_BEASTMASTER = 0x021,
- CMSG_GODMODE = 0x022,
- SMSG_GODMODE = 0x023,
- CMSG_CHEAT_SETMONEY = 0x024,
- CMSG_LEVEL_CHEAT = 0x025,
- CMSG_PET_LEVEL_CHEAT = 0x026,
- CMSG_SET_WORLDSTATE = 0x027,
- CMSG_COOLDOWN_CHEAT = 0x028,
- CMSG_USE_SKILL_CHEAT = 0x029,
- CMSG_FLAG_QUEST = 0x02A,
- CMSG_FLAG_QUEST_FINISH = 0x02B,
- CMSG_CLEAR_QUEST = 0x02C,
- CMSG_SEND_EVENT = 0x02D,
- CMSG_DEBUG_AISTATE = 0x02E,
- SMSG_DEBUG_AISTATE = 0x02F,
- CMSG_DISABLE_PVP_CHEAT = 0x030,
- CMSG_ADVANCE_SPAWN_TIME = 0x031,
- SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x032,
- CMSG_AUTH_SRP6_BEGIN = 0x033,
- CMSG_AUTH_SRP6_PROOF = 0x034,
- CMSG_AUTH_SRP6_RECODE = 0x035,
- CMSG_CHAR_CREATE = 0x036,
- CMSG_CHAR_ENUM = 0x037,
- CMSG_CHAR_DELETE = 0x038,
- SMSG_AUTH_SRP6_RESPONSE = 0x039,
- SMSG_CHAR_CREATE = 0x03A,
- SMSG_CHAR_ENUM = 0x03B,
- SMSG_CHAR_DELETE = 0x03C,
- CMSG_PLAYER_LOGIN = 0x03D,
- SMSG_NEW_WORLD = 0x03E,
- SMSG_TRANSFER_PENDING = 0x03F,
- SMSG_TRANSFER_ABORTED = 0x040,
- SMSG_CHARACTER_LOGIN_FAILED = 0x041,
- SMSG_LOGIN_SETTIMESPEED = 0x042,
- SMSG_GAMETIME_UPDATE = 0x043,
- CMSG_GAMETIME_SET = 0x044,
- SMSG_GAMETIME_SET = 0x045,
- CMSG_GAMESPEED_SET = 0x046,
- SMSG_GAMESPEED_SET = 0x047,
- CMSG_SERVERTIME = 0x048,
- SMSG_SERVERTIME = 0x049,
- CMSG_PLAYER_LOGOUT = 0x04A,
- CMSG_LOGOUT_REQUEST = 0x04B,
- SMSG_LOGOUT_RESPONSE = 0x04C,
- SMSG_LOGOUT_COMPLETE = 0x04D,
- CMSG_LOGOUT_CANCEL = 0x04E,
- SMSG_LOGOUT_CANCEL_ACK = 0x04F,
- CMSG_NAME_QUERY = 0x050,
- SMSG_NAME_QUERY_RESPONSE = 0x051,
- CMSG_PET_NAME_QUERY = 0x052,
- SMSG_PET_NAME_QUERY_RESPONSE = 0x053,
- CMSG_GUILD_QUERY = 0x054,
- SMSG_GUILD_QUERY_RESPONSE = 0x055,
- CMSG_ITEM_QUERY_SINGLE = 0x056,
- CMSG_ITEM_QUERY_MULTIPLE = 0x057,
- SMSG_ITEM_QUERY_SINGLE_RESPONSE = 0x058,
- SMSG_ITEM_QUERY_MULTIPLE_RESPONSE = 0x059,
- CMSG_PAGE_TEXT_QUERY = 0x05A,
- SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x05B,
- CMSG_QUEST_QUERY = 0x05C,
- SMSG_QUEST_QUERY_RESPONSE = 0x05D,
- CMSG_GAMEOBJECT_QUERY = 0x05E,
- SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x05F,
- CMSG_CREATURE_QUERY = 0x060,
- SMSG_CREATURE_QUERY_RESPONSE = 0x061,
- CMSG_WHO = 0x062,
- SMSG_WHO = 0x063,
- CMSG_WHOIS = 0x064,
- SMSG_WHOIS = 0x065,
- CMSG_CONTACT_LIST = 0x066,
- SMSG_CONTACT_LIST = 0x067,
- SMSG_FRIEND_STATUS = 0x068,
- CMSG_ADD_FRIEND = 0x069,
- CMSG_DEL_FRIEND = 0x06A,
- CMSG_SET_CONTACT_NOTES = 0x06B,
- CMSG_ADD_IGNORE = 0x06C,
- CMSG_DEL_IGNORE = 0x06D,
- CMSG_GROUP_INVITE = 0x06E,
- SMSG_GROUP_INVITE = 0x06F,
- CMSG_GROUP_CANCEL = 0x070,
- SMSG_GROUP_CANCEL = 0x071,
- CMSG_GROUP_ACCEPT = 0x072,
- CMSG_GROUP_DECLINE = 0x073,
- SMSG_GROUP_DECLINE = 0x074,
- CMSG_GROUP_UNINVITE = 0x075,
- CMSG_GROUP_UNINVITE_GUID = 0x076,
- SMSG_GROUP_UNINVITE = 0x077,
- CMSG_GROUP_SET_LEADER = 0x078,
- SMSG_GROUP_SET_LEADER = 0x079,
- CMSG_LOOT_METHOD = 0x07A,
- CMSG_GROUP_DISBAND = 0x07B,
- SMSG_GROUP_DESTROYED = 0x07C,
- SMSG_GROUP_LIST = 0x07D,
- SMSG_PARTY_MEMBER_STATS = 0x07E,
- SMSG_PARTY_COMMAND_RESULT = 0x07F,
- UMSG_UPDATE_GROUP_MEMBERS = 0x080,
- CMSG_GUILD_CREATE = 0x081,
- CMSG_GUILD_INVITE = 0x082,
- SMSG_GUILD_INVITE = 0x083,
- CMSG_GUILD_ACCEPT = 0x084,
- CMSG_GUILD_DECLINE = 0x085,
- SMSG_GUILD_DECLINE = 0x086,
- CMSG_GUILD_INFO = 0x087,
- SMSG_GUILD_INFO = 0x088,
- CMSG_GUILD_ROSTER = 0x089,
- SMSG_GUILD_ROSTER = 0x08A,
- CMSG_GUILD_PROMOTE = 0x08B,
- CMSG_GUILD_DEMOTE = 0x08C,
- CMSG_GUILD_LEAVE = 0x08D,
- CMSG_GUILD_REMOVE = 0x08E,
- CMSG_GUILD_DISBAND = 0x08F,
- CMSG_GUILD_LEADER = 0x090,
- CMSG_GUILD_MOTD = 0x091,
- SMSG_GUILD_EVENT = 0x092,
- SMSG_GUILD_COMMAND_RESULT = 0x093,
- UMSG_UPDATE_GUILD = 0x094,
- CMSG_MESSAGECHAT = 0x095,
- SMSG_MESSAGECHAT = 0x096,
- CMSG_JOIN_CHANNEL = 0x097,
- CMSG_LEAVE_CHANNEL = 0x098,
- SMSG_CHANNEL_NOTIFY = 0x099,
- CMSG_CHANNEL_LIST = 0x09A,
- SMSG_CHANNEL_LIST = 0x09B,
- CMSG_CHANNEL_PASSWORD = 0x09C,
- CMSG_CHANNEL_SET_OWNER = 0x09D,
- CMSG_CHANNEL_OWNER = 0x09E,
- CMSG_CHANNEL_MODERATOR = 0x09F,
- CMSG_CHANNEL_UNMODERATOR = 0x0A0,
- CMSG_CHANNEL_MUTE = 0x0A1,
- CMSG_CHANNEL_UNMUTE = 0x0A2,
- CMSG_CHANNEL_INVITE = 0x0A3,
- CMSG_CHANNEL_KICK = 0x0A4,
- CMSG_CHANNEL_BAN = 0x0A5,
- CMSG_CHANNEL_UNBAN = 0x0A6,
- CMSG_CHANNEL_ANNOUNCEMENTS = 0x0A7,
- CMSG_CHANNEL_MODERATE = 0x0A8,
- SMSG_UPDATE_OBJECT = 0x0A9,
- SMSG_DESTROY_OBJECT = 0x0AA,
- CMSG_USE_ITEM = 0x0AB,
- CMSG_OPEN_ITEM = 0x0AC,
- CMSG_READ_ITEM = 0x0AD,
- SMSG_READ_ITEM_OK = 0x0AE,
- SMSG_READ_ITEM_FAILED = 0x0AF,
- SMSG_ITEM_COOLDOWN = 0x0B0,
- CMSG_GAMEOBJ_USE = 0x0B1,
- CMSG_DESTROY_ITEMS = 0x0B2,
- SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x0B3,
- CMSG_AREATRIGGER = 0x0B4,
- MSG_MOVE_START_FORWARD = 0x0B5,
- MSG_MOVE_START_BACKWARD = 0x0B6,
- MSG_MOVE_STOP = 0x0B7,
- MSG_MOVE_START_STRAFE_LEFT = 0x0B8,
- MSG_MOVE_START_STRAFE_RIGHT = 0x0B9,
- MSG_MOVE_STOP_STRAFE = 0x0BA,
- MSG_MOVE_JUMP = 0x0BB,
- MSG_MOVE_START_TURN_LEFT = 0x0BC,
- MSG_MOVE_START_TURN_RIGHT = 0x0BD,
- MSG_MOVE_STOP_TURN = 0x0BE,
- MSG_MOVE_START_PITCH_UP = 0x0BF,
- MSG_MOVE_START_PITCH_DOWN = 0x0C0,
- MSG_MOVE_STOP_PITCH = 0x0C1,
- MSG_MOVE_SET_RUN_MODE = 0x0C2,
- MSG_MOVE_SET_WALK_MODE = 0x0C3,
- MSG_MOVE_TOGGLE_LOGGING = 0x0C4,
- MSG_MOVE_TELEPORT = 0x0C5,
- MSG_MOVE_TELEPORT_CHEAT = 0x0C6,
- MSG_MOVE_TELEPORT_ACK = 0x0C7,
- MSG_MOVE_TOGGLE_FALL_LOGGING = 0x0C8,
- MSG_MOVE_FALL_LAND = 0x0C9,
- MSG_MOVE_START_SWIM = 0x0CA,
- MSG_MOVE_STOP_SWIM = 0x0CB,
- MSG_MOVE_SET_RUN_SPEED_CHEAT = 0x0CC,
- MSG_MOVE_SET_RUN_SPEED = 0x0CD,
- MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0x0CE,
- MSG_MOVE_SET_RUN_BACK_SPEED = 0x0CF,
- MSG_MOVE_SET_WALK_SPEED_CHEAT = 0x0D0,
- MSG_MOVE_SET_WALK_SPEED = 0x0D1,
- MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0x0D2,
- MSG_MOVE_SET_SWIM_SPEED = 0x0D3,
- MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0x0D4,
- MSG_MOVE_SET_SWIM_BACK_SPEED = 0x0D5,
- MSG_MOVE_SET_ALL_SPEED_CHEAT = 0x0D6,
- MSG_MOVE_SET_TURN_RATE_CHEAT = 0x0D7,
- MSG_MOVE_SET_TURN_RATE = 0x0D8,
- MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0x0D9,
- MSG_MOVE_SET_FACING = 0x0DA,
- MSG_MOVE_SET_PITCH = 0x0DB,
- MSG_MOVE_WORLDPORT_ACK = 0x0DC,
- SMSG_MONSTER_MOVE = 0x0DD,
- SMSG_MOVE_WATER_WALK = 0x0DE,
- SMSG_MOVE_LAND_WALK = 0x0DF,
- CMSG_MOVE_CHARM_PORT_CHEAT = 0x0E0,
- CMSG_MOVE_SET_RAW_POSITION = 0x0E1,
- SMSG_FORCE_RUN_SPEED_CHANGE = 0x0E2,
- CMSG_FORCE_RUN_SPEED_CHANGE_ACK = 0x0E3,
- SMSG_FORCE_RUN_BACK_SPEED_CHANGE = 0x0E4,
- CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0x0E5,
- SMSG_FORCE_SWIM_SPEED_CHANGE = 0x0E6,
- CMSG_FORCE_SWIM_SPEED_CHANGE_ACK = 0x0E7,
- SMSG_FORCE_MOVE_ROOT = 0x0E8,
- CMSG_FORCE_MOVE_ROOT_ACK = 0x0E9,
- SMSG_FORCE_MOVE_UNROOT = 0x0EA,
- CMSG_FORCE_MOVE_UNROOT_ACK = 0x0EB,
- MSG_MOVE_ROOT = 0x0EC,
- MSG_MOVE_UNROOT = 0x0ED,
- MSG_MOVE_HEARTBEAT = 0x0EE,
- SMSG_MOVE_KNOCK_BACK = 0x0EF,
- CMSG_MOVE_KNOCK_BACK_ACK = 0x0F0,
- MSG_MOVE_KNOCK_BACK = 0x0F1,
- SMSG_MOVE_FEATHER_FALL = 0x0F2,
- SMSG_MOVE_NORMAL_FALL = 0x0F3,
- SMSG_MOVE_SET_HOVER = 0x0F4,
- SMSG_MOVE_UNSET_HOVER = 0x0F5,
- CMSG_MOVE_HOVER_ACK = 0x0F6,
- MSG_MOVE_HOVER = 0x0F7,
- CMSG_TRIGGER_CINEMATIC_CHEAT = 0x0F8,
- CMSG_OPENING_CINEMATIC = 0x0F9,
- SMSG_TRIGGER_CINEMATIC = 0x0FA,
- CMSG_NEXT_CINEMATIC_CAMERA = 0x0FB,
- CMSG_COMPLETE_CINEMATIC = 0x0FC,
- SMSG_TUTORIAL_FLAGS = 0x0FD,
- CMSG_TUTORIAL_FLAG = 0x0FE,
- CMSG_TUTORIAL_CLEAR = 0x0FF,
- CMSG_TUTORIAL_RESET = 0x100,
- CMSG_STANDSTATECHANGE = 0x101,
- CMSG_EMOTE = 0x102,
- SMSG_EMOTE = 0x103,
- CMSG_TEXT_EMOTE = 0x104,
- SMSG_TEXT_EMOTE = 0x105,
- CMSG_AUTOEQUIP_GROUND_ITEM = 0x106,
- CMSG_AUTOSTORE_GROUND_ITEM = 0x107,
- CMSG_AUTOSTORE_LOOT_ITEM = 0x108,
- CMSG_STORE_LOOT_IN_SLOT = 0x109,
- CMSG_AUTOEQUIP_ITEM = 0x10A,
- CMSG_AUTOSTORE_BAG_ITEM = 0x10B,
- CMSG_SWAP_ITEM = 0x10C,
- CMSG_SWAP_INV_ITEM = 0x10D,
- CMSG_SPLIT_ITEM = 0x10E,
- CMSG_AUTOEQUIP_ITEM_SLOT = 0x10F,
- CMSG_UNCLAIM_LICENSE = 0x110,
- CMSG_DESTROYITEM = 0x111,
- SMSG_INVENTORY_CHANGE_FAILURE = 0x112,
- SMSG_OPEN_CONTAINER = 0x113,
- CMSG_INSPECT = 0x114,
- SMSG_INSPECT_RESULTS_UPDATE = 0x115,
- CMSG_INITIATE_TRADE = 0x116,
- CMSG_BEGIN_TRADE = 0x117,
- CMSG_BUSY_TRADE = 0x118,
- CMSG_IGNORE_TRADE = 0x119,
- CMSG_ACCEPT_TRADE = 0x11A,
- CMSG_UNACCEPT_TRADE = 0x11B,
- CMSG_CANCEL_TRADE = 0x11C,
- CMSG_SET_TRADE_ITEM = 0x11D,
- CMSG_CLEAR_TRADE_ITEM = 0x11E,
- CMSG_SET_TRADE_GOLD = 0x11F,
- SMSG_TRADE_STATUS = 0x120,
- SMSG_TRADE_STATUS_EXTENDED = 0x121,
- SMSG_INITIALIZE_FACTIONS = 0x122,
- SMSG_SET_FACTION_VISIBLE = 0x123,
- SMSG_SET_FACTION_STANDING = 0x124,
- CMSG_SET_FACTION_ATWAR = 0x125,
- CMSG_SET_FACTION_CHEAT = 0x126,
- SMSG_SET_PROFICIENCY = 0x127,
- CMSG_SET_ACTION_BUTTON = 0x128,
- SMSG_ACTION_BUTTONS = 0x129,
- SMSG_INITIAL_SPELLS = 0x12A,
- SMSG_LEARNED_SPELL = 0x12B,
- SMSG_SUPERCEDED_SPELL = 0x12C,
- CMSG_NEW_SPELL_SLOT = 0x12D,
- CMSG_CAST_SPELL = 0x12E,
- CMSG_CANCEL_CAST = 0x12F,
- SMSG_CAST_FAILED = 0x130,
- SMSG_SPELL_START = 0x131,
- SMSG_SPELL_GO = 0x132,
- SMSG_SPELL_FAILURE = 0x133,
- SMSG_SPELL_COOLDOWN = 0x134,
- SMSG_COOLDOWN_EVENT = 0x135,
- CMSG_CANCEL_AURA = 0x136,
- SMSG_EQUIPMENT_SET_SAVED = 0x137,
- SMSG_PET_CAST_FAILED = 0x138,
- MSG_CHANNEL_START = 0x139,
- MSG_CHANNEL_UPDATE = 0x13A,
- CMSG_CANCEL_CHANNELLING = 0x13B,
- SMSG_AI_REACTION = 0x13C,
- CMSG_SET_SELECTION = 0x13D,
- CMSG_DELETEEQUIPMENT_SET = 0x13E,
- CMSG_INSTANCE_LOCK_RESPONSE = 0x13F,
- CMSG_DEBUG_PASSIVE_AURA = 0x140,
- CMSG_ATTACKSWING = 0x141,
- CMSG_ATTACKSTOP = 0x142,
- SMSG_ATTACKSTART = 0x143,
- SMSG_ATTACKSTOP = 0x144,
- SMSG_ATTACKSWING_NOTINRANGE = 0x145,
- SMSG_ATTACKSWING_BADFACING = 0x146,
- SMSG_INSTANCE_LOCK_WARNING_QUERY = 0x147,
- SMSG_ATTACKSWING_DEADTARGET = 0x148,
- SMSG_ATTACKSWING_CANT_ATTACK = 0x149,
- SMSG_ATTACKERSTATEUPDATE = 0x14A,
- SMSG_BATTLEFIELD_PORT_DENIED = 0x14B,
- CMSG_PERFORM_ACTION_SET = 0x14C,
- SMSG_RESUME_CAST_BAR = 0x14D,
- SMSG_CANCEL_COMBAT = 0x14E,
- SMSG_SPELLBREAKLOG = 0x14F,
- SMSG_SPELLHEALLOG = 0x150,
- SMSG_SPELLENERGIZELOG = 0x151,
- SMSG_BREAK_TARGET = 0x152,
- CMSG_SAVE_PLAYER = 0x153,
- CMSG_SETDEATHBINDPOINT = 0x154,
- SMSG_BINDPOINTUPDATE = 0x155,
- CMSG_GETDEATHBINDZONE = 0x156,
- SMSG_BINDZONEREPLY = 0x157,
- SMSG_PLAYERBOUND = 0x158,
- SMSG_CLIENT_CONTROL_UPDATE = 0x159,
- CMSG_REPOP_REQUEST = 0x15A,
- SMSG_RESURRECT_REQUEST = 0x15B,
- CMSG_RESURRECT_RESPONSE = 0x15C,
- CMSG_LOOT = 0x15D,
- CMSG_LOOT_MONEY = 0x15E,
- CMSG_LOOT_RELEASE = 0x15F,
- SMSG_LOOT_RESPONSE = 0x160,
- SMSG_LOOT_RELEASE_RESPONSE = 0x161,
- SMSG_LOOT_REMOVED = 0x162,
- SMSG_LOOT_MONEY_NOTIFY = 0x163,
- SMSG_LOOT_ITEM_NOTIFY = 0x164,
- SMSG_LOOT_CLEAR_MONEY = 0x165,
- SMSG_ITEM_PUSH_RESULT = 0x166,
- SMSG_DUEL_REQUESTED = 0x167,
- SMSG_DUEL_OUTOFBOUNDS = 0x168,
- SMSG_DUEL_INBOUNDS = 0x169,
- SMSG_DUEL_COMPLETE = 0x16A,
- SMSG_DUEL_WINNER = 0x16B,
- CMSG_DUEL_ACCEPTED = 0x16C,
- CMSG_DUEL_CANCELLED = 0x16D,
- SMSG_MOUNTRESULT = 0x16E,
- SMSG_DISMOUNTRESULT = 0x16F,
- SMSG_REMOVED_FROM_PVP_QUEUE = 0x170,
- CMSG_MOUNTSPECIAL_ANIM = 0x171,
- SMSG_MOUNTSPECIAL_ANIM = 0x172,
- SMSG_PET_TAME_FAILURE = 0x173,
- CMSG_PET_SET_ACTION = 0x174,
- CMSG_PET_ACTION = 0x175,
- CMSG_PET_ABANDON = 0x176,
- CMSG_PET_RENAME = 0x177,
- SMSG_PET_NAME_INVALID = 0x178,
- SMSG_PET_SPELLS = 0x179,
- SMSG_PET_MODE = 0x17A,
- CMSG_GOSSIP_HELLO = 0x17B,
- CMSG_GOSSIP_SELECT_OPTION = 0x17C,
- SMSG_GOSSIP_MESSAGE = 0x17D,
- SMSG_GOSSIP_COMPLETE = 0x17E,
- CMSG_NPC_TEXT_QUERY = 0x17F,
- SMSG_NPC_TEXT_UPDATE = 0x180,
- SMSG_NPC_WONT_TALK = 0x181,
- CMSG_QUESTGIVER_STATUS_QUERY = 0x182,
- SMSG_QUESTGIVER_STATUS = 0x183,
- CMSG_QUESTGIVER_HELLO = 0x184,
- SMSG_QUESTGIVER_QUEST_LIST = 0x185,
- CMSG_QUESTGIVER_QUERY_QUEST = 0x186,
- CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x187,
- SMSG_QUESTGIVER_QUEST_DETAILS = 0x188,
- CMSG_QUESTGIVER_ACCEPT_QUEST = 0x189,
- CMSG_QUESTGIVER_COMPLETE_QUEST = 0x18A,
- SMSG_QUESTGIVER_REQUEST_ITEMS = 0x18B,
- CMSG_QUESTGIVER_REQUEST_REWARD = 0x18C,
- SMSG_QUESTGIVER_OFFER_REWARD = 0x18D,
- CMSG_QUESTGIVER_CHOOSE_REWARD = 0x18E,
- SMSG_QUESTGIVER_QUEST_INVALID = 0x18F,
- CMSG_QUESTGIVER_CANCEL = 0x190,
- SMSG_QUESTGIVER_QUEST_COMPLETE = 0x191,
- SMSG_QUESTGIVER_QUEST_FAILED = 0x192,
- CMSG_QUESTLOG_SWAP_QUEST = 0x193,
- CMSG_QUESTLOG_REMOVE_QUEST = 0x194,
- SMSG_QUESTLOG_FULL = 0x195,
- SMSG_QUESTUPDATE_FAILED = 0x196,
- SMSG_QUESTUPDATE_FAILEDTIMER = 0x197,
- SMSG_QUESTUPDATE_COMPLETE = 0x198,
- SMSG_QUESTUPDATE_ADD_KILL = 0x199,
- SMSG_QUESTUPDATE_ADD_ITEM = 0x19A,
- CMSG_QUEST_CONFIRM_ACCEPT = 0x19B,
- SMSG_QUEST_CONFIRM_ACCEPT = 0x19C,
- CMSG_PUSHQUESTTOPARTY = 0x19D,
- CMSG_LIST_INVENTORY = 0x19E,
- SMSG_LIST_INVENTORY = 0x19F,
- CMSG_SELL_ITEM = 0x1A0,
- SMSG_SELL_ITEM = 0x1A1,
- CMSG_BUY_ITEM = 0x1A2,
- CMSG_BUY_ITEM_IN_SLOT = 0x1A3,
- SMSG_BUY_ITEM = 0x1A4,
- SMSG_BUY_FAILED = 0x1A5,
- CMSG_TAXICLEARALLNODES = 0x1A6,
- CMSG_TAXIENABLEALLNODES = 0x1A7,
- CMSG_TAXISHOWNODES = 0x1A8,
- SMSG_SHOWTAXINODES = 0x1A9,
- CMSG_TAXINODE_STATUS_QUERY = 0x1AA,
- SMSG_TAXINODE_STATUS = 0x1AB,
- CMSG_TAXIQUERYAVAILABLENODES = 0x1AC,
- CMSG_ACTIVATETAXI = 0x1AD,
- SMSG_ACTIVATETAXIREPLY = 0x1AE,
- SMSG_NEW_TAXI_PATH = 0x1AF,
- CMSG_TRAINER_LIST = 0x1B0,
- SMSG_TRAINER_LIST = 0x1B1,
- CMSG_TRAINER_BUY_SPELL = 0x1B2,
- SMSG_TRAINER_BUY_SUCCEEDED = 0x1B3,
- SMSG_TRAINER_BUY_FAILED = 0x1B4,
- CMSG_BINDER_ACTIVATE = 0x1B5,
- SMSG_PLAYERBINDERROR = 0x1B6,
- CMSG_BANKER_ACTIVATE = 0x1B7,
- SMSG_SHOW_BANK = 0x1B8,
- CMSG_BUY_BANK_SLOT = 0x1B9,
- SMSG_BUY_BANK_SLOT_RESULT = 0x1BA,
- CMSG_PETITION_SHOWLIST = 0x1BB,
- SMSG_PETITION_SHOWLIST = 0x1BC,
- CMSG_PETITION_BUY = 0x1BD,
- CMSG_PETITION_SHOW_SIGNATURES = 0x1BE,
- SMSG_PETITION_SHOW_SIGNATURES = 0x1BF,
- CMSG_PETITION_SIGN = 0x1C0,
- SMSG_PETITION_SIGN_RESULTS = 0x1C1,
- MSG_PETITION_DECLINE = 0x1C2,
- CMSG_OFFER_PETITION = 0x1C3,
- CMSG_TURN_IN_PETITION = 0x1C4,
- SMSG_TURN_IN_PETITION_RESULTS = 0x1C5,
- CMSG_PETITION_QUERY = 0x1C6,
- SMSG_PETITION_QUERY_RESPONSE = 0x1C7,
- SMSG_FISH_NOT_HOOKED = 0x1C8,
- SMSG_FISH_ESCAPED = 0x1C9,
- CMSG_BUG = 0x1CA,
- SMSG_NOTIFICATION = 0x1CB,
- CMSG_PLAYED_TIME = 0x1CC,
- SMSG_PLAYED_TIME = 0x1CD,
- CMSG_QUERY_TIME = 0x1CE,
- SMSG_QUERY_TIME_RESPONSE = 0x1CF,
- SMSG_LOG_XPGAIN = 0x1D0,
- SMSG_AURACASTLOG = 0x1D1,
- CMSG_RECLAIM_CORPSE = 0x1D2,
- CMSG_WRAP_ITEM = 0x1D3,
- SMSG_LEVELUP_INFO = 0x1D4,
- MSG_MINIMAP_PING = 0x1D5,
- SMSG_RESISTLOG = 0x1D6,
- SMSG_ENCHANTMENTLOG = 0x1D7,
- CMSG_SET_SKILL_CHEAT = 0x1D8,
- SMSG_START_MIRROR_TIMER = 0x1D9,
- SMSG_PAUSE_MIRROR_TIMER = 0x1DA,
- SMSG_STOP_MIRROR_TIMER = 0x1DB,
- CMSG_PING = 0x1DC,
- SMSG_PONG = 0x1DD,
- SMSG_CLEAR_COOLDOWN = 0x1DE,
- SMSG_GAMEOBJECT_PAGETEXT = 0x1DF,
- CMSG_SETSHEATHED = 0x1E0,
- SMSG_COOLDOWN_CHEAT = 0x1E1,
- SMSG_SPELL_DELAYED = 0x1E2,
- CMSG_QUEST_POI_QUERY = 0x1E3,
- SMSG_QUEST_POI_QUERY_RESPONSE = 0x1E4,
- CMSG_GHOST = 0x1E5,
- CMSG_GM_INVIS = 0x1E6,
- SMSG_INVALID_PROMOTION_CODE = 0x1E7,
- MSG_GM_BIND_OTHER = 0x1E8,
- MSG_GM_SUMMON = 0x1E9,
- SMSG_ITEM_TIME_UPDATE = 0x1EA,
- SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x1EB,
- SMSG_AUTH_CHALLENGE = 0x1EC,
- CMSG_AUTH_SESSION = 0x1ED,
- SMSG_AUTH_RESPONSE = 0x1EE,
- MSG_GM_SHOWLABEL = 0x1EF,
- CMSG_PET_CAST_SPELL = 0x1F0,
- MSG_SAVE_GUILD_EMBLEM = 0x1F1,
- MSG_TABARDVENDOR_ACTIVATE = 0x1F2,
- SMSG_PLAY_SPELL_VISUAL = 0x1F3,
- CMSG_ZONEUPDATE = 0x1F4,
- SMSG_PARTYKILLLOG = 0x1F5,
- SMSG_COMPRESSED_UPDATE_OBJECT = 0x1F6,
- SMSG_PLAY_SPELL_IMPACT = 0x1F7,
- SMSG_EXPLORATION_EXPERIENCE = 0x1F8,
- CMSG_GM_SET_SECURITY_GROUP = 0x1F9,
- CMSG_GM_NUKE = 0x1FA,
- MSG_RANDOM_ROLL = 0x1FB,
- SMSG_ENVIRONMENTALDAMAGELOG = 0x1FC,
- CMSG_CHANGEPLAYER_DIFFICULTY = 0x1FD,
- SMSG_RWHOIS = 0x1FE,
- SMSG_LFG_PLAYER_REWARD = 0x1FF, // uint32, uint8, uint32, uint32, uint32, uint32, uint32, uint8, for (uint8) {uint32, uint32, uint32}
- SMSG_LFG_TELEPORT_DENIED = 0x200, // uint32 (1, 2, 4, 6;0, 5, 7)
- CMSG_UNLEARN_SPELL = 0x201,
- CMSG_UNLEARN_SKILL = 0x202,
- SMSG_REMOVED_SPELL = 0x203,
- CMSG_DECHARGE = 0x204,
- CMSG_GMTICKET_CREATE = 0x205,
- SMSG_GMTICKET_CREATE = 0x206,
- CMSG_GMTICKET_UPDATETEXT = 0x207,
- SMSG_GMTICKET_UPDATETEXT = 0x208,
- SMSG_ACCOUNT_DATA_TIMES = 0x209,
- CMSG_REQUEST_ACCOUNT_DATA = 0x20A,
- CMSG_UPDATE_ACCOUNT_DATA = 0x20B,
- SMSG_UPDATE_ACCOUNT_DATA = 0x20C,
- SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x20D,
- SMSG_CHANGEPLAYER_DIFFICULTY_RESULT = 0x20E,
- CMSG_GM_TEACH = 0x20F,
- CMSG_GM_CREATE_ITEM_TARGET = 0x210,
- CMSG_GMTICKET_GETTICKET = 0x211,
- SMSG_GMTICKET_GETTICKET = 0x212,
- CMSG_UNLEARN_TALENTS = 0x213,
- SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x214,
- SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x215,
- MSG_CORPSE_QUERY = 0x216,
- CMSG_GMTICKET_DELETETICKET = 0x217,
- SMSG_GMTICKET_DELETETICKET = 0x218,
- SMSG_CHAT_WRONG_FACTION = 0x219,
- CMSG_GMTICKET_SYSTEMSTATUS = 0x21A,
- SMSG_GMTICKET_SYSTEMSTATUS = 0x21B,
- CMSG_SPIRIT_HEALER_ACTIVATE = 0x21C,
- CMSG_SET_STAT_CHEAT = 0x21D,
- SMSG_QUEST_FORCE_REMOVE = 0x21E, // uint32 questid
- CMSG_SKILL_BUY_STEP = 0x21F,
- CMSG_SKILL_BUY_RANK = 0x220,
- CMSG_XP_CHEAT = 0x221,
- SMSG_SPIRIT_HEALER_CONFIRM = 0x222,
- CMSG_CHARACTER_POINT_CHEAT = 0x223,
- SMSG_GOSSIP_POI = 0x224,
- CMSG_CHAT_IGNORED = 0x225,
- CMSG_GM_VISION = 0x226,
- CMSG_SERVER_COMMAND = 0x227,
- CMSG_GM_SILENCE = 0x228,
- CMSG_GM_REVEALTO = 0x229,
- CMSG_GM_RESURRECT = 0x22A,
- CMSG_GM_SUMMONMOB = 0x22B,
- CMSG_GM_MOVECORPSE = 0x22C,
- CMSG_GM_FREEZE = 0x22D,
- CMSG_GM_UBERINVIS = 0x22E,
- CMSG_GM_REQUEST_PLAYER_INFO = 0x22F,
- SMSG_GM_PLAYER_INFO = 0x230,
- CMSG_GUILD_RANK = 0x231,
- CMSG_GUILD_ADD_RANK = 0x232,
- CMSG_GUILD_DEL_RANK = 0x233,
- CMSG_GUILD_SET_PUBLIC_NOTE = 0x234,
- CMSG_GUILD_SET_OFFICER_NOTE = 0x235,
- SMSG_LOGIN_VERIFY_WORLD = 0x236,
- CMSG_CLEAR_EXPLORATION = 0x237,
- CMSG_SEND_MAIL = 0x238,
- SMSG_SEND_MAIL_RESULT = 0x239,
- CMSG_GET_MAIL_LIST = 0x23A,
- SMSG_MAIL_LIST_RESULT = 0x23B,
- CMSG_BATTLEFIELD_LIST = 0x23C,
- SMSG_BATTLEFIELD_LIST = 0x23D,
- CMSG_BATTLEFIELD_JOIN = 0x23E,
- SMSG_FORCE_SET_VEHICLE_REC_ID = 0x23F,
- CMSG_SET_VEHICLE_REC_ID_ACK = 0x240,
- CMSG_TAXICLEARNODE = 0x241,
- CMSG_TAXIENABLENODE = 0x242,
- CMSG_ITEM_TEXT_QUERY = 0x243,
- SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x244,
- CMSG_MAIL_TAKE_MONEY = 0x245,
- CMSG_MAIL_TAKE_ITEM = 0x246,
- CMSG_MAIL_MARK_AS_READ = 0x247,
- CMSG_MAIL_RETURN_TO_SENDER = 0x248,
- CMSG_MAIL_DELETE = 0x249,
- CMSG_MAIL_CREATE_TEXT_ITEM = 0x24A,
- SMSG_SPELLLOGMISS = 0x24B,
- SMSG_SPELLLOGEXECUTE = 0x24C,
- SMSG_DEBUGAURAPROC = 0x24D,
- SMSG_PERIODICAURALOG = 0x24E,
- SMSG_SPELLDAMAGESHIELD = 0x24F,
- SMSG_SPELLNONMELEEDAMAGELOG = 0x250,
- CMSG_LEARN_TALENT = 0x251,
- SMSG_RESURRECT_FAILED = 0x252,
- CMSG_TOGGLE_PVP = 0x253,
- SMSG_ZONE_UNDER_ATTACK = 0x254,
- MSG_AUCTION_HELLO = 0x255,
- CMSG_AUCTION_SELL_ITEM = 0x256,
- CMSG_AUCTION_REMOVE_ITEM = 0x257,
- CMSG_AUCTION_LIST_ITEMS = 0x258,
- CMSG_AUCTION_LIST_OWNER_ITEMS = 0x259,
- CMSG_AUCTION_PLACE_BID = 0x25A,
- SMSG_AUCTION_COMMAND_RESULT = 0x25B,
- SMSG_AUCTION_LIST_RESULT = 0x25C,
- SMSG_AUCTION_OWNER_LIST_RESULT = 0x25D,
- SMSG_AUCTION_BIDDER_NOTIFICATION = 0x25E,
- SMSG_AUCTION_OWNER_NOTIFICATION = 0x25F,
- SMSG_PROCRESIST = 0x260,
- SMSG_COMBAT_EVENT_FAILED = 0x261,
- SMSG_DISPEL_FAILED = 0x262,
- SMSG_SPELLORDAMAGE_IMMUNE = 0x263,
- CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x264,
- SMSG_AUCTION_BIDDER_LIST_RESULT = 0x265,
- SMSG_SET_FLAT_SPELL_MODIFIER = 0x266,
- SMSG_SET_PCT_SPELL_MODIFIER = 0x267,
- CMSG_SET_AMMO = 0x268,
- SMSG_CORPSE_RECLAIM_DELAY = 0x269,
- CMSG_SET_ACTIVE_MOVER = 0x26A,
- CMSG_PET_CANCEL_AURA = 0x26B,
- CMSG_PLAYER_AI_CHEAT = 0x26C,
- CMSG_CANCEL_AUTO_REPEAT_SPELL = 0x26D,
- MSG_GM_ACCOUNT_ONLINE = 0x26E,
- MSG_LIST_STABLED_PETS = 0x26F,
- CMSG_STABLE_PET = 0x270,
- CMSG_UNSTABLE_PET = 0x271,
- CMSG_BUY_STABLE_SLOT = 0x272,
- SMSG_STABLE_RESULT = 0x273,
- CMSG_STABLE_REVIVE_PET = 0x274,
- CMSG_STABLE_SWAP_PET = 0x275,
- MSG_QUEST_PUSH_RESULT = 0x276,
- SMSG_PLAY_MUSIC = 0x277,
- SMSG_PLAY_OBJECT_SOUND = 0x278,
- CMSG_REQUEST_PET_INFO = 0x279,
- CMSG_FAR_SIGHT = 0x27A,
- SMSG_SPELLDISPELLOG = 0x27B,
- SMSG_DAMAGE_CALC_LOG = 0x27C,
- CMSG_ENABLE_DAMAGE_LOG = 0x27D,
- CMSG_GROUP_CHANGE_SUB_GROUP = 0x27E,
- CMSG_REQUEST_PARTY_MEMBER_STATS = 0x27F,
- CMSG_GROUP_SWAP_SUB_GROUP = 0x280,
- CMSG_RESET_FACTION_CHEAT = 0x281,
- CMSG_AUTOSTORE_BANK_ITEM = 0x282,
- CMSG_AUTOBANK_ITEM = 0x283,
- MSG_QUERY_NEXT_MAIL_TIME = 0x284,
- SMSG_RECEIVED_MAIL = 0x285,
- SMSG_RAID_GROUP_ONLY = 0x286,
- CMSG_SET_DURABILITY_CHEAT = 0x287,
- CMSG_SET_PVP_RANK_CHEAT = 0x288,
- CMSG_ADD_PVP_MEDAL_CHEAT = 0x289,
- CMSG_DEL_PVP_MEDAL_CHEAT = 0x28A,
- CMSG_SET_PVP_TITLE = 0x28B,
- SMSG_PVP_CREDIT = 0x28C,
- SMSG_AUCTION_REMOVED_NOTIFICATION = 0x28D,
- CMSG_GROUP_RAID_CONVERT = 0x28E,
- CMSG_GROUP_ASSISTANT_LEADER = 0x28F,
- CMSG_BUYBACK_ITEM = 0x290,
- SMSG_SERVER_MESSAGE = 0x291,
- CMSG_SET_SAVED_INSTANCE_EXTEND = 0x292,
- SMSG_LFG_OFFER_CONTINUE = 0x293,
- CMSG_TEST_DROP_RATE = 0x294,
- SMSG_TEST_DROP_RATE_RESULT = 0x295,
- CMSG_LFG_GET_STATUS = 0x296,
- SMSG_SHOW_MAILBOX = 0x297,
- SMSG_RESET_RANGED_COMBAT_TIMER = 0x298,
- SMSG_CHAT_NOT_IN_PARTY = 0x299, // uint32, errors: ERR_NOT_IN_GROUP (2, 51) and ERR_NOT_IN_RAID (3, 39, 40)
- CMSG_GMTICKETSYSTEM_TOGGLE = 0x29A,
- CMSG_CANCEL_GROWTH_AURA = 0x29B,
- SMSG_CANCEL_AUTO_REPEAT = 0x29C,
- SMSG_STANDSTATE_UPDATE = 0x29D,
- SMSG_LOOT_ALL_PASSED = 0x29E,
- SMSG_LOOT_ROLL_WON = 0x29F,
- CMSG_LOOT_ROLL = 0x2A0,
- SMSG_LOOT_START_ROLL = 0x2A1,
- SMSG_LOOT_ROLL = 0x2A2,
- CMSG_LOOT_MASTER_GIVE = 0x2A3,
- SMSG_LOOT_MASTER_LIST = 0x2A4,
- SMSG_SET_FORCED_REACTIONS = 0x2A5,
- SMSG_SPELL_FAILED_OTHER = 0x2A6,
- SMSG_GAMEOBJECT_RESET_STATE = 0x2A7,
- CMSG_REPAIR_ITEM = 0x2A8,
- SMSG_CHAT_PLAYER_NOT_FOUND = 0x2A9,
- MSG_TALENT_WIPE_CONFIRM = 0x2AA,
- SMSG_SUMMON_REQUEST = 0x2AB,
- CMSG_SUMMON_RESPONSE = 0x2AC,
- MSG_DEV_SHOWLABEL = 0x2AD,
- SMSG_MONSTER_MOVE_TRANSPORT = 0x2AE,
- SMSG_PET_BROKEN = 0x2AF,
- MSG_MOVE_FEATHER_FALL = 0x2B0,
- MSG_MOVE_WATER_WALK = 0x2B1,
- CMSG_SERVER_BROADCAST = 0x2B2,
- CMSG_SELF_RES = 0x2B3,
- SMSG_FEIGN_DEATH_RESISTED = 0x2B4,
- CMSG_RUN_SCRIPT = 0x2B5,
- SMSG_SCRIPT_MESSAGE = 0x2B6,
- SMSG_DUEL_COUNTDOWN = 0x2B7,
- SMSG_AREA_TRIGGER_MESSAGE = 0x2B8,
- CMSG_SHOWING_HELM = 0x2B9,
- CMSG_SHOWING_CLOAK = 0x2BA,
- SMSG_LFG_ROLE_CHOSEN = 0x2BB,
- SMSG_PLAYER_SKINNED = 0x2BC,
- SMSG_DURABILITY_DAMAGE_DEATH = 0x2BD,
- CMSG_SET_EXPLORATION = 0x2BE,
- CMSG_SET_ACTIONBAR_TOGGLES = 0x2BF,
- UMSG_DELETE_GUILD_CHARTER = 0x2C0,
- MSG_PETITION_RENAME = 0x2C1,
- SMSG_INIT_WORLD_STATES = 0x2C2,
- SMSG_UPDATE_WORLD_STATE = 0x2C3,
- CMSG_ITEM_NAME_QUERY = 0x2C4,
- SMSG_ITEM_NAME_QUERY_RESPONSE = 0x2C5,
- SMSG_PET_ACTION_FEEDBACK = 0x2C6,
- CMSG_CHAR_RENAME = 0x2C7,
- SMSG_CHAR_RENAME = 0x2C8,
- CMSG_MOVE_SPLINE_DONE = 0x2C9,
- CMSG_MOVE_FALL_RESET = 0x2CA,
- SMSG_INSTANCE_SAVE_CREATED = 0x2CB,
- SMSG_RAID_INSTANCE_INFO = 0x2CC,
- CMSG_REQUEST_RAID_INFO = 0x2CD,
- CMSG_MOVE_TIME_SKIPPED = 0x2CE,
- CMSG_MOVE_FEATHER_FALL_ACK = 0x2CF,
- CMSG_MOVE_WATER_WALK_ACK = 0x2D0,
- CMSG_MOVE_NOT_ACTIVE_MOVER = 0x2D1,
- SMSG_PLAY_SOUND = 0x2D2,
- CMSG_BATTLEFIELD_STATUS = 0x2D3,
- SMSG_BATTLEFIELD_STATUS = 0x2D4,
- CMSG_BATTLEFIELD_PORT = 0x2D5,
- MSG_INSPECT_HONOR_STATS = 0x2D6,
- CMSG_BATTLEMASTER_HELLO = 0x2D7,
- CMSG_MOVE_START_SWIM_CHEAT = 0x2D8,
- CMSG_MOVE_STOP_SWIM_CHEAT = 0x2D9,
- SMSG_FORCE_WALK_SPEED_CHANGE = 0x2DA,
- CMSG_FORCE_WALK_SPEED_CHANGE_ACK = 0x2DB,
- SMSG_FORCE_SWIM_BACK_SPEED_CHANGE = 0x2DC,
- CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0x2DD,
- SMSG_FORCE_TURN_RATE_CHANGE = 0x2DE,
- CMSG_FORCE_TURN_RATE_CHANGE_ACK = 0x2DF,
- MSG_PVP_LOG_DATA = 0x2E0,
- CMSG_LEAVE_BATTLEFIELD = 0x2E1,
- CMSG_AREA_SPIRIT_HEALER_QUERY = 0x2E2,
- CMSG_AREA_SPIRIT_HEALER_QUEUE = 0x2E3,
- SMSG_AREA_SPIRIT_HEALER_TIME = 0x2E4,
- CMSG_GM_UNTEACH = 0x2E5,
- SMSG_WARDEN_DATA = 0x2E6,
- CMSG_WARDEN_DATA = 0x2E7,
- SMSG_GROUP_JOINED_BATTLEGROUND = 0x2E8,
- MSG_BATTLEGROUND_PLAYER_POSITIONS = 0x2E9,
- CMSG_PET_STOP_ATTACK = 0x2EA,
- SMSG_BINDER_CONFIRM = 0x2EB,
- SMSG_BATTLEGROUND_PLAYER_JOINED = 0x2EC,
- SMSG_BATTLEGROUND_PLAYER_LEFT = 0x2ED,
- CMSG_BATTLEMASTER_JOIN = 0x2EE,
- SMSG_ADDON_INFO = 0x2EF,
- CMSG_PET_UNLEARN = 0x2F0, // Deprecated 3.x
- SMSG_PET_UNLEARN_CONFIRM = 0x2F1, // Deprecated 3.x
- SMSG_PARTY_MEMBER_STATS_FULL = 0x2F2,
- CMSG_PET_SPELL_AUTOCAST = 0x2F3,
- SMSG_WEATHER = 0x2F4,
- SMSG_PLAY_TIME_WARNING = 0x2F5,
- SMSG_MINIGAME_SETUP = 0x2F6,
- SMSG_MINIGAME_STATE = 0x2F7,
- CMSG_MINIGAME_MOVE = 0x2F8,
- SMSG_MINIGAME_MOVE_FAILED = 0x2F9,
- SMSG_RAID_INSTANCE_MESSAGE = 0x2FA,
- SMSG_COMPRESSED_MOVES = 0x2FB,
- CMSG_GUILD_INFO_TEXT = 0x2FC,
- SMSG_CHAT_RESTRICTED = 0x2FD,
- SMSG_SPLINE_SET_RUN_SPEED = 0x2FE,
- SMSG_SPLINE_SET_RUN_BACK_SPEED = 0x2FF,
- SMSG_SPLINE_SET_SWIM_SPEED = 0x300,
- SMSG_SPLINE_SET_WALK_SPEED = 0x301,
- SMSG_SPLINE_SET_SWIM_BACK_SPEED = 0x302,
- SMSG_SPLINE_SET_TURN_RATE = 0x303,
- SMSG_SPLINE_MOVE_UNROOT = 0x304,
- SMSG_SPLINE_MOVE_FEATHER_FALL = 0x305,
- SMSG_SPLINE_MOVE_NORMAL_FALL = 0x306,
- SMSG_SPLINE_MOVE_SET_HOVER = 0x307,
- SMSG_SPLINE_MOVE_UNSET_HOVER = 0x308,
- SMSG_SPLINE_MOVE_WATER_WALK = 0x309,
- SMSG_SPLINE_MOVE_LAND_WALK = 0x30A,
- SMSG_SPLINE_MOVE_START_SWIM = 0x30B,
- SMSG_SPLINE_MOVE_STOP_SWIM = 0x30C,
- SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x30D,
- SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x30E,
- CMSG_GM_NUKE_ACCOUNT = 0x30F,
- MSG_GM_DESTROY_CORPSE = 0x310,
- CMSG_GM_DESTROY_ONLINE_CORPSE = 0x311,
- CMSG_ACTIVATETAXIEXPRESS = 0x312,
- SMSG_SET_FACTION_ATWAR = 0x313,
- SMSG_GAMETIMEBIAS_SET = 0x314,
- CMSG_DEBUG_ACTIONS_START = 0x315,
- CMSG_DEBUG_ACTIONS_STOP = 0x316,
- CMSG_SET_FACTION_INACTIVE = 0x317,
- CMSG_SET_WATCHED_FACTION = 0x318,
- MSG_MOVE_TIME_SKIPPED = 0x319,
- SMSG_SPLINE_MOVE_ROOT = 0x31A,
- CMSG_SET_EXPLORATION_ALL = 0x31B,
- SMSG_INVALIDATE_PLAYER = 0x31C,
- CMSG_RESET_INSTANCES = 0x31D,
- SMSG_INSTANCE_RESET = 0x31E,
- SMSG_INSTANCE_RESET_FAILED = 0x31F,
- SMSG_UPDATE_LAST_INSTANCE = 0x320,
- MSG_RAID_TARGET_UPDATE = 0x321,
- MSG_RAID_READY_CHECK = 0x322,
- CMSG_LUA_USAGE = 0x323,
- SMSG_PET_ACTION_SOUND = 0x324,
- SMSG_PET_DISMISS_SOUND = 0x325,
- SMSG_GHOSTEE_GONE = 0x326,
- CMSG_GM_UPDATE_TICKET_STATUS = 0x327,
- SMSG_GM_TICKET_STATUS_UPDATE = 0x328,
- MSG_SET_DUNGEON_DIFFICULTY = 0x329,
- CMSG_GMSURVEY_SUBMIT = 0x32A,
- SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x32B,
- CMSG_IGNORE_KNOCKBACK_CHEAT = 0x32C,
- SMSG_CHAT_PLAYER_AMBIGUOUS = 0x32D,
- MSG_DELAY_GHOST_TELEPORT = 0x32E,
- SMSG_SPELLINSTAKILLLOG = 0x32F,
- SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x330,
- CMSG_CHAT_FILTERED = 0x331,
- SMSG_EXPECTED_SPAM_RECORDS = 0x332,
- SMSG_SPELLSTEALLOG = 0x333,
- CMSG_LOTTERY_QUERY_OBSOLETE = 0x334,
- SMSG_LOTTERY_QUERY_RESULT_OBSOLETE = 0x335,
- CMSG_BUY_LOTTERY_TICKET_OBSOLETE = 0x336,
- SMSG_LOTTERY_RESULT_OBSOLETE = 0x337,
- SMSG_CHARACTER_PROFILE = 0x338,
- SMSG_CHARACTER_PROFILE_REALM_CONNECTED = 0x339,
- SMSG_DEFENSE_MESSAGE = 0x33A,
- SMSG_INSTANCE_DIFFICULTY = 0x33B,
- MSG_GM_RESETINSTANCELIMIT = 0x33C,
- SMSG_MOTD = 0x33D,
- SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x33E,
- SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x33F,
- CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK= 0x340,
- MSG_MOVE_START_SWIM_CHEAT = 0x341,
- MSG_MOVE_STOP_SWIM_CHEAT = 0x342,
- SMSG_MOVE_SET_CAN_FLY = 0x343,
- SMSG_MOVE_UNSET_CAN_FLY = 0x344,
- CMSG_MOVE_SET_CAN_FLY_ACK = 0x345,
- CMSG_MOVE_SET_FLY = 0x346,
- CMSG_SOCKET_GEMS = 0x347,
- CMSG_ARENA_TEAM_CREATE = 0x348,
- SMSG_ARENA_TEAM_COMMAND_RESULT = 0x349,
- MSG_MOVE_UPDATE_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY= 0x34A,
- CMSG_ARENA_TEAM_QUERY = 0x34B,
- SMSG_ARENA_TEAM_QUERY_RESPONSE = 0x34C,
- CMSG_ARENA_TEAM_ROSTER = 0x34D,
- SMSG_ARENA_TEAM_ROSTER = 0x34E,
- CMSG_ARENA_TEAM_INVITE = 0x34F,
- SMSG_ARENA_TEAM_INVITE = 0x350,
- CMSG_ARENA_TEAM_ACCEPT = 0x351,
- CMSG_ARENA_TEAM_DECLINE = 0x352,
- CMSG_ARENA_TEAM_LEAVE = 0x353,
- CMSG_ARENA_TEAM_REMOVE = 0x354,
- CMSG_ARENA_TEAM_DISBAND = 0x355,
- CMSG_ARENA_TEAM_LEADER = 0x356,
- SMSG_ARENA_TEAM_EVENT = 0x357,
- CMSG_BATTLEMASTER_JOIN_ARENA = 0x358,
- MSG_MOVE_START_ASCEND = 0x359,
- MSG_MOVE_STOP_ASCEND = 0x35A,
- SMSG_ARENA_TEAM_STATS = 0x35B,
- CMSG_LFG_JOIN = 0x35C,
- CMSG_LFG_LEAVE = 0x35D,
- CMSG_SEARCH_LFG_JOIN = 0x35E,
- CMSG_SEARCH_LFG_LEAVE = 0x35F,
- SMSG_UPDATE_LFG_LIST = 0x360, // uint32, uint32, if (uint8) { uint32 count, for (count) { uint64} }, uint32 count2, uint32, for (count2) { uint64, uint32 flags, if (flags & 0x2) {string}, if (flags & 0x10) {for (3) uint8}, if (flags & 0x80) {uint64, uint32}}, uint32 count3, uint32, for (count3) {uint64, uint32 flags, if (flags & 0x1) {uint8, uint8, uint8, for (3) uint8, uint32, uint32, uint32, uint32, uint32, uint32, float, float, uint32, uint32, uint32, uint32, uint32, float, uint32, uint32, uint32, uint32, uint32, uint32}, if (flags&0x2) string, if (flags&0x4) uint8, if (flags&0x8) uint64, if (flags&0x10) uint8, if (flags&0x20) uint32, if (flags&0x40) uint8, if (flags& 0x80) {uint64, uint32}}
- SMSG_LFG_PROPOSAL_UPDATE = 0x361, // uint32, uint8, uint32, uint32, uint8, for (uint8) {uint32, uint8, uint8, uint8, uint8}
- CMSG_LFG_PROPOSAL_RESULT = 0x362,
- SMSG_LFG_ROLE_CHECK_UPDATE = 0x363, // uint32, uint8, for (uint8) uint32, uint8, for (uint8) { uint64, uint8, uint32, uint8, }
- SMSG_LFG_JOIN_RESULT = 0x364, // uint32 unk, uint32, if (unk == 6) { uint8 count, for (count) uint64 }
- SMSG_LFG_QUEUE_STATUS = 0x365, // uint32 dungeon, uint32 lfgtype, uint32, uint32, uint32, uint32, uint8, uint8, uint8, uint8
- CMSG_SET_LFG_COMMENT = 0x366,
- SMSG_LFG_UPDATE_PLAYER = 0x367, // uint8, if (uint8) { uint8, uint8, uint8, uint8, if (uint8) for (uint8) uint32, string}
- SMSG_LFG_UPDATE_PARTY = 0x368, // uint8, if (uint8) { uint8, uint8, uint8, for (3) uint8, uint8, if (uint8) for (uint8) uint32, string}
- SMSG_LFG_UPDATE_SEARCH = 0x369, // uint8
- CMSG_LFG_SET_ROLES = 0x36A,
- CMSG_LFG_SET_NEEDS = 0x36B,
- CMSG_LFG_SET_BOOT_VOTE = 0x36C,
- SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x36D, // uint8, uint8, uint8, uint64, uint32, uint32, uint32, uint32
- CMSG_LFD_PLAYER_LOCK_INFO_REQUEST = 0x36E,
- SMSG_LFG_PLAYER_INFO = 0x36F, // uint8, for (uint8) { uint32, uint8, uint32, uint32, uint32, uint32, uint8, for (uint8) {uint32, uint32, uint32}}, uint32, for (uint32) {uint32, uint32}
- CMSG_LFG_TELEPORT = 0x370,
- CMSG_LFD_PARTY_LOCK_INFO_REQUEST = 0x371,
- SMSG_LFG_PARTY_INFO = 0x372, // uint8, for (uint8) uint64
- SMSG_TITLE_EARNED = 0x373,
- CMSG_SET_TITLE = 0x374,
- CMSG_CANCEL_MOUNT_AURA = 0x375,
- SMSG_ARENA_ERROR = 0x376,
- MSG_INSPECT_ARENA_TEAMS = 0x377,
- SMSG_DEATH_RELEASE_LOC = 0x378,
- CMSG_CANCEL_TEMP_ENCHANTMENT = 0x379,
- SMSG_FORCED_DEATH_UPDATE = 0x37A,
- CMSG_CHEAT_SET_HONOR_CURRENCY = 0x37B,
- CMSG_CHEAT_SET_ARENA_CURRENCY = 0x37C,
- MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0x37D,
- MSG_MOVE_SET_FLIGHT_SPEED = 0x37E,
- MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT = 0x37F,
- MSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x380,
- SMSG_FORCE_FLIGHT_SPEED_CHANGE = 0x381,
- CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x382,
- SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE = 0x383,
- CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0x384,
- SMSG_SPLINE_SET_FLIGHT_SPEED = 0x385,
- SMSG_SPLINE_SET_FLIGHT_BACK_SPEED = 0x386,
- CMSG_MAELSTROM_INVALIDATE_CACHE = 0x387,
- SMSG_FLIGHT_SPLINE_SYNC = 0x388,
- CMSG_SET_TAXI_BENCHMARK_MODE = 0x389,
- SMSG_JOINED_BATTLEGROUND_QUEUE = 0x38A,
- SMSG_REALM_SPLIT = 0x38B,
- CMSG_REALM_SPLIT = 0x38C,
- CMSG_MOVE_CHNG_TRANSPORT = 0x38D,
- MSG_PARTY_ASSIGNMENT = 0x38E,
- SMSG_OFFER_PETITION_ERROR = 0x38F,
- SMSG_TIME_SYNC_REQ = 0x390,
- CMSG_TIME_SYNC_RESP = 0x391,
- CMSG_SEND_LOCAL_EVENT = 0x392,
- CMSG_SEND_GENERAL_TRIGGER = 0x393,
- CMSG_SEND_COMBAT_TRIGGER = 0x394,
- CMSG_MAELSTROM_GM_SENT_MAIL = 0x395,
- SMSG_RESET_FAILED_NOTIFY = 0x396,
- SMSG_REAL_GROUP_UPDATE = 0x397,
- SMSG_LFG_DISABLED = 0x398,
- CMSG_ACTIVE_PVP_CHEAT = 0x399,
- CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY = 0x39A,
- SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE = 0x39B,
- SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE = 0x39C,
- SMSG_UPDATE_COMBO_POINTS = 0x39D,
- SMSG_VOICE_SESSION_ROSTER_UPDATE = 0x39E,
- SMSG_VOICE_SESSION_LEAVE = 0x39F,
- SMSG_VOICE_SESSION_ADJUST_PRIORITY = 0x3A0,
- CMSG_VOICE_SET_TALKER_MUTED_REQUEST = 0x3A1,
- SMSG_VOICE_SET_TALKER_MUTED = 0x3A2,
- SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE = 0x3A3,
- SMSG_SET_EXTRA_AURA_INFO_OBSOLETE = 0x3A4,
- SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE = 0x3A5,
- SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE = 0x3A6,
- MSG_MOVE_START_DESCEND = 0x3A7,
- CMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A8,
- SMSG_IGNORE_REQUIREMENTS_CHEAT = 0x3A9,
- SMSG_SPELL_CHANCE_PROC_LOG = 0x3AA,
- CMSG_MOVE_SET_RUN_SPEED = 0x3AB,
- SMSG_DISMOUNT = 0x3AC,
- MSG_MOVE_UPDATE_CAN_FLY = 0x3AD,
- MSG_RAID_READY_CHECK_CONFIRM = 0x3AE,
- CMSG_VOICE_SESSION_ENABLE = 0x3AF,
- SMSG_VOICE_SESSION_ENABLE = 0x3B0,
- SMSG_VOICE_PARENTAL_CONTROLS = 0x3B1,
- CMSG_GM_WHISPER = 0x3B2,
- SMSG_GM_MESSAGECHAT = 0x3B3,
- MSG_GM_GEARRATING = 0x3B4,
- CMSG_COMMENTATOR_ENABLE = 0x3B5,
- SMSG_COMMENTATOR_STATE_CHANGED = 0x3B6,
- CMSG_COMMENTATOR_GET_MAP_INFO = 0x3B7,
- SMSG_COMMENTATOR_MAP_INFO = 0x3B8,
- CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3B9,
- SMSG_COMMENTATOR_GET_PLAYER_INFO = 0x3BA,
- SMSG_COMMENTATOR_PLAYER_INFO = 0x3BB,
- CMSG_COMMENTATOR_ENTER_INSTANCE = 0x3BC,
- CMSG_COMMENTATOR_EXIT_INSTANCE = 0x3BD,
- CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x3BE,
- SMSG_CLEAR_TARGET = 0x3BF,
- CMSG_BOT_DETECTED = 0x3C0,
- SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x3C1,
- CMSG_CHEAT_PLAYER_LOGIN = 0x3C2,
- CMSG_CHEAT_PLAYER_LOOKUP = 0x3C3,
- SMSG_CHEAT_PLAYER_LOOKUP = 0x3C4,
- SMSG_KICK_REASON = 0x3C5,
- MSG_RAID_READY_CHECK_FINISHED = 0x3C6,
- CMSG_COMPLAIN = 0x3C7,
- SMSG_COMPLAIN_RESULT = 0x3C8,
- SMSG_FEATURE_SYSTEM_STATUS = 0x3C9,
- CMSG_GM_SHOW_COMPLAINTS = 0x3CA,
- CMSG_GM_UNSQUELCH = 0x3CB,
- CMSG_CHANNEL_SILENCE_VOICE = 0x3CC,
- CMSG_CHANNEL_SILENCE_ALL = 0x3CD,
- CMSG_CHANNEL_UNSILENCE_VOICE = 0x3CE,
- CMSG_CHANNEL_UNSILENCE_ALL = 0x3CF,
- CMSG_TARGET_CAST = 0x3D0,
- CMSG_TARGET_SCRIPT_CAST = 0x3D1,
- CMSG_CHANNEL_DISPLAY_LIST = 0x3D2,
- CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x3D3,
- CMSG_GET_CHANNEL_MEMBER_COUNT = 0x3D4,
- SMSG_CHANNEL_MEMBER_COUNT = 0x3D5,
- CMSG_CHANNEL_VOICE_ON = 0x3D6,
- CMSG_CHANNEL_VOICE_OFF = 0x3D7,
- CMSG_DEBUG_LIST_TARGETS = 0x3D8,
- SMSG_DEBUG_LIST_TARGETS = 0x3D9,
- SMSG_AVAILABLE_VOICE_CHANNEL = 0x3DA,
- CMSG_ADD_VOICE_IGNORE = 0x3DB,
- CMSG_DEL_VOICE_IGNORE = 0x3DC,
- CMSG_PARTY_SILENCE = 0x3DD,
- CMSG_PARTY_UNSILENCE = 0x3DE,
- MSG_NOTIFY_PARTY_SQUELCH = 0x3DF,
- SMSG_COMSAT_RECONNECT_TRY = 0x3E0,
- SMSG_COMSAT_DISCONNECT = 0x3E1,
- SMSG_COMSAT_CONNECT_FAIL = 0x3E2,
- SMSG_VOICE_CHAT_STATUS = 0x3E3,
- CMSG_REPORT_PVP_AFK = 0x3E4,
- SMSG_REPORT_PVP_AFK_RESULT = 0x3E5,
- CMSG_GUILD_BANKER_ACTIVATE = 0x3E6,
- CMSG_GUILD_BANK_QUERY_TAB = 0x3E7,
- SMSG_GUILD_BANK_LIST = 0x3E8,
- CMSG_GUILD_BANK_SWAP_ITEMS = 0x3E9,
- CMSG_GUILD_BANK_BUY_TAB = 0x3EA,
- CMSG_GUILD_BANK_UPDATE_TAB = 0x3EB,
- CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x3EC,
- CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x3ED,
- MSG_GUILD_BANK_LOG_QUERY = 0x3EE,
- CMSG_SET_CHANNEL_WATCH = 0x3EF,
- SMSG_USERLIST_ADD = 0x3F0,
- SMSG_USERLIST_REMOVE = 0x3F1,
- SMSG_USERLIST_UPDATE = 0x3F2,
- CMSG_CLEAR_CHANNEL_WATCH = 0x3F3,
- SMSG_INSPECT_TALENT = 0x3F4,
- SMSG_GOGOGO_OBSOLETE = 0x3F5,
- SMSG_ECHO_PARTY_SQUELCH = 0x3F6,
- CMSG_SET_TITLE_SUFFIX = 0x3F7,
- CMSG_SPELLCLICK = 0x3F8,
- SMSG_LOOT_LIST = 0x3F9,
- CMSG_GM_CHARACTER_RESTORE = 0x3FA,
- CMSG_GM_CHARACTER_SAVE = 0x3FB,
- SMSG_VOICESESSION_FULL = 0x3FC,
- MSG_GUILD_PERMISSIONS = 0x3FD,
- MSG_GUILD_BANK_MONEY_WITHDRAWN = 0x3FE,
- MSG_GUILD_EVENT_LOG_QUERY = 0x3FF,
- CMSG_MAELSTROM_RENAME_GUILD = 0x400,
- CMSG_GET_MIRRORIMAGE_DATA = 0x401,
- SMSG_MIRRORIMAGE_DATA = 0x402,
- SMSG_FORCE_DISPLAY_UPDATE = 0x403,
- SMSG_SPELL_CHANCE_RESIST_PUSHBACK = 0x404,
- CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x405,
- SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT = 0x406,
- CMSG_KEEP_ALIVE = 0x407,
- SMSG_RAID_READY_CHECK_ERROR = 0x408,
- CMSG_OPT_OUT_OF_LOOT = 0x409,
- MSG_QUERY_GUILD_BANK_TEXT = 0x40A,
- CMSG_SET_GUILD_BANK_TEXT = 0x40B,
- CMSG_SET_GRANTABLE_LEVELS = 0x40C,
- CMSG_GRANT_LEVEL = 0x40D,
- CMSG_REFER_A_FRIEND = 0x40E,
- MSG_GM_CHANGE_ARENA_RATING = 0x40F,
- CMSG_DECLINE_CHANNEL_INVITE = 0x410,
- SMSG_GROUPACTION_THROTTLED = 0x411,
- SMSG_OVERRIDE_LIGHT = 0x412, // uint32 defaultMapLight, uint32 overrideLight, uint32 transitionTimeMs
- SMSG_TOTEM_CREATED = 0x413,
- CMSG_TOTEM_DESTROYED = 0x414,
- CMSG_EXPIRE_RAID_INSTANCE = 0x415,
- CMSG_NO_SPELL_VARIANCE = 0x416,
- CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x417,
- SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x418,
- CMSG_SET_PLAYER_DECLINED_NAMES = 0x419,
- SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x41A,
- CMSG_QUERY_SERVER_BUCK_DATA = 0x41B,
- CMSG_CLEAR_SERVER_BUCK_DATA = 0x41C,
- SMSG_SERVER_BUCK_DATA = 0x41D,
- SMSG_SEND_UNLEARN_SPELLS = 0x41E,
- SMSG_PROPOSE_LEVEL_GRANT = 0x41F,
- CMSG_ACCEPT_LEVEL_GRANT = 0x420,
- SMSG_REFER_A_FRIEND_FAILURE = 0x421,
- SMSG_SPLINE_MOVE_SET_FLYING = 0x422,
- SMSG_SPLINE_MOVE_UNSET_FLYING = 0x423,
- SMSG_SUMMON_CANCEL = 0x424,
- CMSG_CHANGE_PERSONAL_ARENA_RATING = 0x425,
- CMSG_ALTER_APPEARANCE = 0x426,
- SMSG_ENABLE_BARBER_SHOP = 0x427,
- SMSG_BARBER_SHOP_RESULT = 0x428,
- CMSG_CALENDAR_GET_CALENDAR = 0x429,
- CMSG_CALENDAR_GET_EVENT = 0x42A,
- CMSG_CALENDAR_GUILD_FILTER = 0x42B,
- CMSG_CALENDAR_ARENA_TEAM = 0x42C,
- CMSG_CALENDAR_ADD_EVENT = 0x42D,
- CMSG_CALENDAR_UPDATE_EVENT = 0x42E,
- CMSG_CALENDAR_REMOVE_EVENT = 0x42F,
- CMSG_CALENDAR_COPY_EVENT = 0x430,
- CMSG_CALENDAR_EVENT_INVITE = 0x431,
- CMSG_CALENDAR_EVENT_RSVP = 0x432,
- CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x433,
- CMSG_CALENDAR_EVENT_STATUS = 0x434,
- CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x435,
- SMSG_CALENDAR_SEND_CALENDAR = 0x436,
- SMSG_CALENDAR_SEND_EVENT = 0x437,
- SMSG_CALENDAR_FILTER_GUILD = 0x438,
- SMSG_CALENDAR_ARENA_TEAM = 0x439,
- SMSG_CALENDAR_EVENT_INVITE = 0x43A,
- SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x43B,
- SMSG_CALENDAR_EVENT_STATUS = 0x43C,
- SMSG_CALENDAR_COMMAND_RESULT = 0x43D,
- SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x43E,
- SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x43F,
- SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x440,
- SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x441,
- SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x442,
- SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x443,
- SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x444,
- SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x445,
- CMSG_CALENDAR_COMPLAIN = 0x446,
- CMSG_CALENDAR_GET_NUM_PENDING = 0x447,
- SMSG_CALENDAR_SEND_NUM_PENDING = 0x448,
- CMSG_SAVE_DANCE = 0x449,
- SMSG_NOTIFY_DANCE = 0x44A,
- CMSG_PLAY_DANCE = 0x44B,
- SMSG_PLAY_DANCE = 0x44C,
- CMSG_LOAD_DANCES = 0x44D,
- CMSG_STOP_DANCE = 0x44E,
- SMSG_STOP_DANCE = 0x44F,
- CMSG_SYNC_DANCE = 0x450,
- CMSG_DANCE_QUERY = 0x451,
- SMSG_DANCE_QUERY_RESPONSE = 0x452,
- SMSG_INVALIDATE_DANCE = 0x453,
- CMSG_DELETE_DANCE = 0x454,
- SMSG_LEARNED_DANCE_MOVES = 0x455,
- CMSG_LEARN_DANCE_MOVE = 0x456,
- CMSG_UNLEARN_DANCE_MOVE = 0x457,
- CMSG_SET_RUNE_COUNT = 0x458,
- CMSG_SET_RUNE_COOLDOWN = 0x459,
- MSG_MOVE_SET_PITCH_RATE_CHEAT = 0x45A,
- MSG_MOVE_SET_PITCH_RATE = 0x45B,
- SMSG_FORCE_PITCH_RATE_CHANGE = 0x45C,
- CMSG_FORCE_PITCH_RATE_CHANGE_ACK = 0x45D,
- SMSG_SPLINE_SET_PITCH_RATE = 0x45E,
- CMSG_CALENDAR_EVENT_INVITE_NOTES = 0x45F,
- SMSG_CALENDAR_EVENT_INVITE_NOTES = 0x460,
- SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT = 0x461,
- CMSG_UPDATE_MISSILE_TRAJECTORY = 0x462,
- SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x463,
- SMSG_TRIGGER_MOVIE = 0x464,
- CMSG_COMPLETE_MOVIE = 0x465,
- CMSG_SET_GLYPH_SLOT = 0x466,
- CMSG_SET_GLYPH = 0x467,
- SMSG_ACHIEVEMENT_EARNED = 0x468,
- SMSG_DYNAMIC_DROP_ROLL_RESULT = 0x469,
- SMSG_CRITERIA_UPDATE = 0x46A,
- CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x46B,
- SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x46C,
- CMSG_DISMISS_CONTROLLED_VEHICLE = 0x46D,
- CMSG_COMPLETE_ACHIEVEMENT_CHEAT = 0x46E,
- SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x46F,
- CMSG_SET_CRITERIA_CHEAT = 0x470,
- SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0x471,
- CMSG_UNITANIMTIER_CHEAT = 0x472,
- CMSG_CHAR_CUSTOMIZE = 0x473,
- SMSG_CHAR_CUSTOMIZE = 0x474,
- SMSG_PET_RENAMEABLE = 0x475,
- CMSG_REQUEST_VEHICLE_EXIT = 0x476,
- CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x477,
- CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x478,
- CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x479,
- CMSG_PET_LEARN_TALENT = 0x47A,
- CMSG_PET_UNLEARN_TALENTS = 0x47B,
- SMSG_SET_PHASE_SHIFT = 0x47C,
- SMSG_ALL_ACHIEVEMENT_DATA = 0x47D,
- CMSG_FORCE_SAY_CHEAT = 0x47E,
- SMSG_HEALTH_UPDATE = 0x47F,
- SMSG_POWER_UPDATE = 0x480,
- CMSG_GAMEOBJ_REPORT_USE = 0x481,
- SMSG_HIGHEST_THREAT_UPDATE = 0x482,
- SMSG_THREAT_UPDATE = 0x483,
- SMSG_THREAT_REMOVE = 0x484,
- SMSG_THREAT_CLEAR = 0x485,
- SMSG_CONVERT_RUNE = 0x486,
- SMSG_RESYNC_RUNES = 0x487,
- SMSG_ADD_RUNE_POWER = 0x488,
- CMSG_START_QUEST = 0x489,
- CMSG_REMOVE_GLYPH = 0x48A,
- CMSG_DUMP_OBJECTS = 0x48B,
- SMSG_DUMP_OBJECTS_DATA = 0x48C,
- CMSG_DISMISS_CRITTER = 0x48D,
- SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x48E,
- CMSG_AUCTION_LIST_PENDING_SALES = 0x48F,
- SMSG_AUCTION_LIST_PENDING_SALES = 0x490,
- SMSG_MODIFY_COOLDOWN = 0x491,
- SMSG_PET_UPDATE_COMBO_POINTS = 0x492,
- CMSG_ENABLETAXI = 0x493,
- SMSG_PRE_RESURRECT = 0x494,
- SMSG_AURA_UPDATE_ALL = 0x495,
- SMSG_AURA_UPDATE = 0x496,
- CMSG_FLOOD_GRACE_CHEAT = 0x497,
- SMSG_SERVER_FIRST_ACHIEVEMENT = 0x498,
- SMSG_PET_LEARNED_SPELL = 0x499,
- SMSG_PET_REMOVED_SPELL = 0x49A,
- CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x49B,
- CMSG_HEARTH_AND_RESURRECT = 0x49C,
- SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x49D,
- SMSG_CRITERIA_DELETED = 0x49E,
- SMSG_ACHIEVEMENT_DELETED = 0x49F,
- CMSG_SERVER_INFO_QUERY = 0x4A0,
- SMSG_SERVER_INFO_RESPONSE = 0x4A1,
- CMSG_CHECK_LOGIN_CRITERIA = 0x4A2,
- SMSG_SERVER_BUCK_DATA_START = 0x4A3,
- CMSG_SET_BREATH = 0x4A4,
- CMSG_QUERY_VEHICLE_STATUS = 0x4A5,
- SMSG_BATTLEGROUND_INFO_THROTTLED = 0x4A6, // empty, "You can't do that yet"
- SMSG_PLAYER_VEHICLE_DATA = 0x4A7, // guid+uint32 (vehicle)
- CMSG_PLAYER_VEHICLE_ENTER = 0x4A8, // uint64
- CMSG_CONTROLLER_EJECT_PASSENGER = 0x4A9, // uint64
- SMSG_PET_GUIDS = 0x4AA,
- SMSG_CLIENTCACHE_VERSION = 0x4AB,
- CMSG_CHANGE_GDF_ARENA_RATING = 0x4AC,
- CMSG_SET_ARENA_TEAM_RATING_BY_INDEX = 0x4AD,
- CMSG_SET_ARENA_TEAM_WEEKLY_GAMES = 0x4AE,
- CMSG_SET_ARENA_TEAM_SEASON_GAMES = 0x4AF,
- CMSG_SET_ARENA_MEMBER_WEEKLY_GAMES = 0x4B0,
- CMSG_SET_ARENA_MEMBER_SEASON_GAMES = 0x4B1,
- SMSG_ITEM_REFUND_INFO_RESPONSE = 0x4B2,
- CMSG_ITEM_REFUND_INFO = 0x4B3,
- CMSG_ITEM_REFUND = 0x4B4, // lua: ContainerRefundItemPurchase
- SMSG_ITEM_REFUND_RESULT = 0x4B5,
- CMSG_CORPSE_MAP_POSITION_QUERY = 0x4B6, // uint32
- SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x4B7, // 3*float+float
- CMSG_UNUSED5 = 0x4B8,
- CMSG_UNUSED6 = 0x4B9,
- CMSG_CALENDAR_EVENT_SIGNUP = 0x4BA, // uint64
- SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x4BB,
- SMSG_EQUIPMENT_SET_LIST = 0x4BC, // equipment manager list?
- CMSG_EQUIPMENT_SET_SAVE = 0x4BD,
- CMSG_UPDATE_PROJECTILE_POSITION = 0x4BE,
- SMSG_SET_PROJECTILE_POSITION = 0x4BF,
- SMSG_TALENTS_INFO = 0x4C0,
- CMSG_LEARN_PREVIEW_TALENTS = 0x4C1,
- CMSG_LEARN_PREVIEW_TALENTS_PET = 0x4C2,
- CMSG_SET_ACTIVE_TALENT_GROUP_OBSOLETE = 0x4C3,
- CMSG_GM_GRANT_ACHIEVEMENT = 0x4C4,
- CMSG_GM_REMOVE_ACHIEVEMENT = 0x4C5,
- CMSG_GM_SET_CRITERIA_FOR_PLAYER = 0x4C6,
- SMSG_ARENA_UNIT_DESTROYED = 0x4C7,
- SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x4C8, // uint32 "Can't modify arena team while queued or in a match."
- CMSG_PROFILEDATA_REQUEST = 0x4C9,
- SMSG_PROFILEDATA_RESPONSE = 0x4CA,
- CMSG_START_BATTLEFIELD_CHEAT = 0x4CB,
- CMSG_END_BATTLEFIELD_CHEAT = 0x4CC,
- SMSG_MULTIPLE_PACKETS = 0x4CD,
- SMSG_MOVE_GRAVITY_DISABLE = 0x4CE,
- CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x4CF,
- SMSG_MOVE_GRAVITY_ENABLE = 0x4D0,
- CMSG_MOVE_GRAVITY_ENABLE_ACK = 0x4D1,
- MSG_MOVE_GRAVITY_CHNG = 0x4D2,
- SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x4D3,
- SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x4D4,
- CMSG_EQUIPMENT_SET_USE = 0x4D5,
- SMSG_EQUIPMENT_SET_USE_RESULT = 0x4D6,
- CMSG_FORCE_ANIM = 0x4D7,
- SMSG_FORCE_ANIM = 0x4D8,
- CMSG_CHAR_FACTION_CHANGE = 0x4D9,
- SMSG_CHAR_FACTION_CHANGE = 0x4DA,
- CMSG_PVP_QUEUE_STATS_REQUEST = 0x4DB,
- SMSG_PVP_QUEUE_STATS = 0x4DC,
- CMSG_SET_PAID_SERVICE_CHEAT = 0x4DD,
- SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x4DE, // uint32
- CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x4DF,
- SMSG_BATTLEFIELD_MGR_ENTERED = 0x4E0, // uint32, uint8, uint8
- SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x4E1, // uint32
- CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x4E2,
- CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0x4E3,
- SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x4E4, // uint32, uint8
- SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x4E5, // uint32
- SMSG_BATTLEFIELD_MGR_EJECTED = 0x4E6, // uint32, uint32, uint8
- CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x4E7,
- SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0x4E8, // uint32, uint32
- CMSG_BATTLEFIELD_MANAGER_ADVANCE_STATE = 0x4E9,
- CMSG_BATTLEFIELD_MANAGER_SET_NEXT_TRANSITION_TIME= 0x4EA,
- MSG_SET_RAID_DIFFICULTY = 0x4EB,
- CMSG_TOGGLE_XP_GAIN = 0x4EC,
- SMSG_TOGGLE_XP_GAIN = 0x4ED, // enable/disable XP gain console message
- SMSG_GMRESPONSE_DB_ERROR = 0x4EE, // empty
- SMSG_GMRESPONSE_RECEIVED = 0x4EF, // uint32, uint32, string[2000], string[4000][4]
- CMSG_GMRESPONSE_RESOLVE = 0x4F0,
- SMSG_GMRESPONSE_STATUS_UPDATE = 0x4F1, // uint8 (1 - EVENT_GMSURVEY_DISPLAY, 0 - EVENT_UPDATE_TICKET)
- SMSG_GMRESPONSE_CREATE_TICKET = 0x4F2,
- CMSG_GMRESPONSE_CREATE_TICKET = 0x4F3,
- CMSG_SERVERINFO = 0x4F4,
- SMSG_SERVERINFO = 0x4F5,
- CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F6,
- SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4F7,
- CMSG_CHAR_RACE_CHANGE = 0x4F8,
- MSG_VIEW_PHASE_SHIFT = 0x4F9,
- SMSG_TALENTS_INVOLUNTARILY_RESET = 0x4FA, // uint8
- CMSG_DEBUG_SERVER_GEO = 0x4FB,
- SMSG_DEBUG_SERVER_GEO = 0x4FC,
- SMSG_LOOT_SLOT_CHANGED = 0x4FD,
- UMSG_UPDATE_GROUP_INFO = 0x4FE,
- CMSG_READY_FOR_ACCOUNT_DATA_TIMES = 0x4FF,
- CMSG_QUERY_QUESTS_COMPLETED = 0x500,
- SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0x501,
- CMSG_GM_REPORT_LAG = 0x502,
- CMSG_AFK_MONITOR_INFO_REQUEST = 0x503,
- SMSG_AFK_MONITOR_INFO_RESPONSE = 0x504,
- CMSG_AFK_MONITOR_INFO_CLEAR = 0x505,
- SMSG_CORPSE_NOT_IN_INSTANCE = 0x506,
- CMSG_GM_NUKE_CHARACTER = 0x507,
- CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0x508,
- CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0x509,
- SMSG_CAMERA_SHAKE = 0x50A, // uint32 SpellEffectCameraShakes.dbc index, uint32
- SMSG_SOCKET_GEMS_RESULT = 0x50B,
- CMSG_SET_CHARACTER_MODEL = 0x50C,
- SMSG_REDIRECT_CLIENT = 0x50D, // uint32 ip, uint16 port, uint32 unk, uint8[20] hash (ip + port, seed=sessionkey)
- CMSG_REDIRECTION_FAILED = 0x50E, // something with networking
- SMSG_SUSPEND_COMMS = 0x50F,
- CMSG_SUSPEND_COMMS_ACK = 0x510,
- SMSG_FORCE_SEND_QUEUED_PACKETS = 0x511,
- CMSG_REDIRECTION_AUTH_PROOF = 0x512,
- CMSG_DROP_NEW_CONNECTION = 0x513,
- SMSG_SEND_ALL_COMBAT_LOG = 0x514,
- SMSG_OPEN_LFG_DUNGEON_FINDER = 0x515,
- SMSG_MOVE_SET_COLLISION_HGT = 0x516,
- CMSG_MOVE_SET_COLLISION_HGT_ACK = 0x517,
- MSG_MOVE_SET_COLLISION_HGT = 0x518,
- CMSG_CLEAR_RANDOM_BG_WIN_TIME = 0x519,
- CMSG_CLEAR_HOLIDAY_BG_WIN_TIME = 0x51A,
- CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x51B,
- SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x51C,
- SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x51D,
- SMSG_MULTIPLE_MOVES = 0x51E, // uncompressed version of SMSG_COMPRESSED_MOVES
- NUM_MSG_TYPES = 0x51F
+ NUM_OPCODE_HANDLERS = (0x7FFF+1),
+ UNKNOWN_OPCODE = (0xFFFF+1),
+ NULL_OPCODE = 0,
+ COMPRESSED_OPCODE_MASK = 0x8000,
+
+ CMSG_ACCEPT_LEVEL_GRANT = 0x0205,
+ CMSG_ACCEPT_TRADE = 0x7110,
+ CMSG_ACTIVATETAXI = 0x6E06,
+ CMSG_ACTIVATETAXIEXPRESS = 0x0515,
+ CMSG_ADDON_REGISTERED_PREFIXES = 0x0954,
+ CMSG_ADD_FRIEND = 0x6527,
+ CMSG_ADD_IGNORE = 0x4726,
+ CMSG_ADD_VOICE_IGNORE = 0x0F06,
+ CMSG_ALTER_APPEARANCE = 0x0914,
+ CMSG_AREATRIGGER = 0x0937,
+ CMSG_AREA_SPIRIT_HEALER_QUERY = 0x4907,
+ CMSG_AREA_SPIRIT_HEALER_QUEUE = 0x4815,
+ CMSG_ARENA_TEAM_ACCEPT = 0x2A25,
+ CMSG_ARENA_TEAM_CREATE = 0x04A1,
+ CMSG_ARENA_TEAM_DECLINE = 0x6925,
+ CMSG_ARENA_TEAM_DISBAND = 0x6504,
+ CMSG_ARENA_TEAM_INVITE = 0x2F27,
+ CMSG_ARENA_TEAM_LEADER = 0x4204,
+ CMSG_ARENA_TEAM_LEAVE = 0x0E16,
+ CMSG_ARENA_TEAM_QUERY = 0x0514,
+ CMSG_ARENA_TEAM_REMOVE = 0x2F05,
+ CMSG_ARENA_TEAM_ROSTER = 0x6F37,
+ CMSG_ATTACKSTOP = 0x4106,
+ CMSG_ATTACKSWING = 0x0926,
+ CMSG_AUCTION_LIST_BIDDER_ITEMS = 0x6937,
+ CMSG_AUCTION_LIST_ITEMS = 0x0324,
+ CMSG_AUCTION_LIST_OWNER_ITEMS = 0x0206,
+ CMSG_AUCTION_LIST_PENDING_SALES = 0x2C17,
+ CMSG_AUCTION_PLACE_BID = 0x2306,
+ CMSG_AUCTION_REMOVE_ITEM = 0x6426,
+ CMSG_AUCTION_SELL_ITEM = 0x4A06,
+ CMSG_AUTH_SESSION = 0x0449,
+ CMSG_AUTOBANK_ITEM = 0x2537,
+ CMSG_AUTOEQUIP_GROUND_ITEM = 0x0000,
+ CMSG_AUTOEQUIP_ITEM = 0x4304,
+ CMSG_AUTOEQUIP_ITEM_SLOT = 0x4A17,
+ CMSG_AUTOSTORE_BAG_ITEM = 0x0236,
+ CMSG_AUTOSTORE_BANK_ITEM = 0x0607,
+ CMSG_AUTOSTORE_GROUND_ITEM = 0x0000,
+ CMSG_AUTOSTORE_LOOT_ITEM = 0x0E34,
+ CMSG_AUTO_DECLINE_GUILD_INVITES = 0x2034,
+ CMSG_BANKER_ACTIVATE = 0x0005,
+ CMSG_BATTLEFIELD_JOIN = 0x0000,
+ CMSG_BATTLEFIELD_LEAVE = 0x3018,
+ CMSG_BATTLEFIELD_LIST = 0x3814,
+ CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE = 0x05A3,
+ CMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x2490,
+ CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE = 0x0413,
+ CMSG_BATTLEFIELD_MGR_QUEUE_REQUEST = 0x710C,
+ CMSG_BATTLEFIELD_PORT = 0x711A,
+ CMSG_BATTLEFIELD_REQUEST_SCORE_DATA = 0x0000,
+ CMSG_BATTLEFIELD_STATUS = 0x2500,
+ CMSG_BATTLEGROUND_PLAYER_POSITIONS = 0x3902,
+ CMSG_BATTLEMASTER_JOIN = 0x7902,
+ CMSG_BATTLEMASTER_JOIN_ARENA = 0x701C,
+ CMSG_BATTLEMASTER_JOIN_RATED = 0x3B18,
+ CMSG_BEGIN_TRADE = 0x721E,
+ CMSG_BINDER_ACTIVATE = 0x4006,
+ CMSG_BOT_DETECTED2 = 0x0000,
+ CMSG_BUG = 0x4035,
+ CMSG_BUSY_TRADE = 0x331C,
+ CMSG_BUYBACK_ITEM = 0x6C17,
+ CMSG_BUY_BANK_SLOT = 0x0425,
+ CMSG_BUY_ITEM = 0x0736,
+ CMSG_CALENDAR_ADD_EVENT = 0x0726,
+ CMSG_CALENDAR_ARENA_TEAM = 0x0204,
+ CMSG_CALENDAR_COMPLAIN = 0x4C36,
+ CMSG_CALENDAR_CONTEXT_EVENT_SIGNUP = 0x0000,
+ CMSG_CALENDAR_COPY_EVENT = 0x0207,
+ CMSG_CALENDAR_EVENT_INVITE = 0x2435,
+ CMSG_CALENDAR_EVENT_MODERATOR_STATUS = 0x6B35,
+ CMSG_CALENDAR_EVENT_REMOVE_INVITE = 0x4337,
+ CMSG_CALENDAR_EVENT_RSVP = 0x0227,
+ CMSG_CALENDAR_EVENT_SIGNUP = 0x6606,
+ CMSG_CALENDAR_EVENT_STATUS = 0x2D24,
+ CMSG_CALENDAR_GET_CALENDAR = 0x2814,
+ CMSG_CALENDAR_GET_EVENT = 0x6416,
+ CMSG_CALENDAR_GET_NUM_PENDING = 0x4D05,
+ CMSG_CALENDAR_GUILD_FILTER = 0x4A16,
+ CMSG_CALENDAR_REMOVE_EVENT = 0x6636,
+ CMSG_CALENDAR_UPDATE_EVENT = 0x2114,
+ CMSG_CANCEL_AURA = 0x0E26,
+ CMSG_CANCEL_AUTO_REPEAT_SPELL = 0x6C35,
+ CMSG_CANCEL_CAST = 0x0115,
+ CMSG_CANCEL_CHANNELLING = 0x6C25,
+ CMSG_CANCEL_GROWTH_AURA = 0x0000,
+ CMSG_CANCEL_MOUNT_AURA = 0x0635,
+ CMSG_CANCEL_QUEUED_SPELL = 0x7B1C,
+ CMSG_CANCEL_TEMP_ENCHANTMENT = 0x6C37,
+ CMSG_CANCEL_TRADE = 0x731E,
+ CMSG_CAST_SPELL = 0x4C07,
+ CMSG_CHANGEPLAYER_DIFFICULTY = 0x6107,
+ CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE = 0x7310,
+ CMSG_CHANNEL_ANNOUNCEMENTS = 0x1146,
+ CMSG_CHANNEL_BAN = 0x3D56,
+ CMSG_CHANNEL_DISPLAY_LIST = 0x2144,
+ CMSG_CHANNEL_INVITE = 0x0144,
+ CMSG_CHANNEL_KICK = 0x3156,
+ CMSG_CHANNEL_LIST = 0x1556,
+ CMSG_CHANNEL_MODERATE = 0x2944,
+ CMSG_CHANNEL_MODERATOR = 0x0146,
+ CMSG_CHANNEL_MUTE = 0x2554,
+ CMSG_CHANNEL_OWNER = 0x3D44,
+ CMSG_CHANNEL_PASSWORD = 0x2556,
+ CMSG_CHANNEL_ROSTER_INFO = 0x3546,
+ CMSG_CHANNEL_SET_OWNER = 0x3556,
+ CMSG_CHANNEL_SILENCE_ALL = 0x2154,
+ CMSG_CHANNEL_SILENCE_VOICE = 0x2D54,
+ CMSG_CHANNEL_UNBAN = 0x2D46,
+ CMSG_CHANNEL_UNMODERATOR = 0x1954,
+ CMSG_CHANNEL_UNMUTE = 0x3554,
+ CMSG_CHANNEL_UNSILENCE_ALL = 0x2546,
+ CMSG_CHANNEL_UNSILENCE_VOICE = 0x3146,
+ CMSG_CHANNEL_VOICE_OFF = 0x3144,
+ CMSG_CHANNEL_VOICE_ON = 0x1144,
+ CMSG_CHAR_CREATE = 0x4A36,
+ CMSG_CHAR_CUSTOMIZE = 0x2C34,
+ CMSG_CHAR_DELETE = 0x6425,
+ CMSG_CHAR_ENUM = 0x0502,
+ CMSG_CHAR_FACTION_CHANGE = 0x2735,
+ CMSG_CHAR_RACE_CHANGE = 0x0D24,
+ CMSG_CHAR_RENAME = 0x2327,
+ CMSG_CHAT_FILTERED = 0x0946,
+ CMSG_CHAT_IGNORED = 0x0D54,
+ CMSG_CLEAR_CHANNEL_WATCH = 0x2604,
+ CMSG_CLEAR_RAID_MARKER = 0x7300,
+ CMSG_CLEAR_TRADE_ITEM = 0x7018,
+ CMSG_COMMENTATOR_ENABLE = 0x0B07,
+ CMSG_COMMENTATOR_ENTER_INSTANCE = 0x4105,
+ CMSG_COMMENTATOR_EXIT_INSTANCE = 0x6136,
+ CMSG_COMMENTATOR_GET_MAP_INFO = 0x0026,
+ CMSG_COMMENTATOR_GET_PARTY_INFO = 0x2412,
+ CMSG_COMMENTATOR_GET_PLAYER_INFO = 0x0D14,
+ CMSG_COMMENTATOR_INSTANCE_COMMAND = 0x0917,
+ CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x0025,
+ CMSG_COMMENTATOR_START_WARGAME = 0x25A0,
+ CMSG_COMPLAIN = 0x0427,
+ CMSG_COMPLETE_CINEMATIC = 0x2116,
+ CMSG_COMPLETE_MOVIE = 0x4136,
+ CMSG_CONNECT_TO_FAILED = 0x2533,
+ CMSG_CONTACT_LIST = 0x4534,
+ CMSG_CORPSE_MAP_POSITION_QUERY = 0x6205,
+ CMSG_CREATURE_QUERY = 0x2706,
+ CMSG_DANCE_QUERY = 0x4E07,
+ CMSG_DECLINE_CHANNEL_INVITE = 0x0000,
+ CMSG_DEL_FRIEND = 0x6A15,
+ CMSG_DEL_IGNORE = 0x6D26,
+ CMSG_DEL_VOICE_IGNORE = 0x0024,
+ CMSG_DESTROY_ITEM = 0x4A27,
+ CMSG_DISMISS_CONTROLLED_VEHICLE = 0x3218,
+ CMSG_DISMISS_CRITTER = 0x4227,
+ CMSG_DUEL_ACCEPTED = 0x2136,
+ CMSG_DUEL_CANCELLED = 0x6624,
+ CMSG_EJECT_PASSENGER = 0x6927,
+ CMSG_EMOTE = 0x4C26,
+ CMSG_ENABLETAXI = 0x0C16,
+ CMSG_ENABLE_NAGLE = 0x4449,
+ CMSG_EQUIPMENT_SET_DELETE = 0x4D07,
+ CMSG_EQUIPMENT_SET_SAVE = 0x4F27,
+ CMSG_EQUIPMENT_SET_USE = 0x0417,
+ CMSG_FAR_SIGHT = 0x4835,
+ CMSG_FORCE_MOVE_ROOT_ACK = 0x701E,
+ CMSG_FORCE_MOVE_UNROOT_ACK = 0x7808,
+ CMSG_GAMEOBJECT_QUERY = 0x4017,
+ CMSG_GAMEOBJ_REPORT_USE = 0x4827,
+ CMSG_GAMEOBJ_USE = 0x4E17,
+ CMSG_GAMESPEED_SET = 0x0000,
+ CMSG_GAMETIME_SET = 0x0000,
+ CMSG_GETDEATHBINDZONE = 0x0000,
+ CMSG_GET_MAIL_LIST = 0x4D37,
+ CMSG_GET_MIRRORIMAGE_DATA = 0x0C25,
+ CMSG_GHOST = 0x0000,
+ CMSG_GMRESPONSE_RESOLVE = 0x6506,
+ CMSG_GMSURVEY_SUBMIT = 0x2724,
+ CMSG_GMTICKET_CREATE = 0x0137,
+ CMSG_GMTICKET_DELETETICKET = 0x6B14,
+ CMSG_GMTICKET_GETTICKET = 0x0326,
+ CMSG_GMTICKET_SYSTEMSTATUS = 0x4205,
+ CMSG_GMTICKET_UPDATETEXT = 0x0636,
+ CMSG_GM_INVIS = 0x0000,
+ CMSG_GM_NUKE = 0x0000,
+ CMSG_GM_REPORT_LAG = 0x6726,
+ CMSG_GM_SET_SECURITY_GROUP = 0x0000,
+ CMSG_GOSSIP_HELLO = 0x4525,
+ CMSG_GOSSIP_SELECT_OPTION = 0x0216,
+ CMSG_GRANT_LEVEL = 0x6D16,
+ CMSG_GROUP_ASSISTANT_LEADER = 0x6025,
+ CMSG_GROUP_CANCEL = 0x0000,
+ CMSG_GROUP_CHANGE_SUB_GROUP = 0x4124,
+ CMSG_GROUP_DISBAND = 0x2804,
+ CMSG_GROUP_INVITE = 0x0513,
+ CMSG_GROUP_INVITE_RESPONSE = 0x0410,
+ CMSG_GROUP_RAID_CONVERT = 0x6E27,
+ CMSG_GROUP_REQUEST_JOIN_UPDATES = 0x2583,
+ CMSG_GROUP_SET_LEADER = 0x4C17,
+ CMSG_GROUP_SET_ROLES = 0x25B1,
+ CMSG_GROUP_SWAP_SUB_GROUP = 0x0034,
+ CMSG_GROUP_UNINVITE = 0x0000,
+ CMSG_GROUP_UNINVITE_GUID = 0x2E07,
+ CMSG_GUILD_ACCEPT = 0x2531,
+ CMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x3025,
+ CMSG_GUILD_ACHIEVEMENT_PROGRESS_QUERY = 0x3235,
+ CMSG_GUILD_ADD_RANK = 0x3030,
+ CMSG_GUILD_ASSIGN_MEMBER_RANK = 0x3032,
+ CMSG_GUILD_BANKER_ACTIVATE = 0x2E37,
+ CMSG_GUILD_BANK_BUY_TAB = 0x0C37,
+ CMSG_GUILD_BANK_DEPOSIT_MONEY = 0x0707,
+ CMSG_GUILD_BANK_LOG_QUERY = 0x3224,
+ CMSG_GUILD_BANK_MONEY_WITHDRAWN_QUERY = 0x1225,
+ CMSG_GUILD_BANK_NOTE = 0x0000,
+ CMSG_GUILD_BANK_QUERY_TAB = 0x2E35,
+ CMSG_GUILD_BANK_QUERY_TEXT = 0x3220,
+ CMSG_GUILD_BANK_SWAP_ITEMS = 0x2315,
+ CMSG_GUILD_BANK_UPDATE_TAB = 0x0106,
+ CMSG_GUILD_BANK_WITHDRAW_MONEY = 0x0037,
+ CMSG_GUILD_CHANGE_NAME_REQUEST = 0x1232,
+ CMSG_GUILD_DECLINE = 0x3231,
+ CMSG_GUILD_DEL_RANK = 0x3234,
+ CMSG_GUILD_DEMOTE = 0x1020,
+ CMSG_GUILD_DISBAND = 0x3226,
+ CMSG_GUILD_EVENT_LOG_QUERY = 0x1220,
+ CMSG_GUILD_INFO = 0x0000,
+ CMSG_GUILD_INFO_TEXT = 0x3227,
+ CMSG_GUILD_INVITE = 0x24B0,
+ CMSG_GUILD_LEAVE = 0x1021,
+ CMSG_GUILD_MEMBER_SEND_SOR_REQUEST = 0x3225,
+ CMSG_GUILD_MOTD = 0x1035,
+ CMSG_GUILD_NEWS_UPDATE_STICKY = 0x3223,
+ CMSG_GUILD_PERMISSIONS = 0x3022,
+ CMSG_GUILD_PROMOTE = 0x1030,
+ CMSG_GUILD_QUERY = 0x4426,
+ CMSG_GUILD_QUERY_NEWS = 0x3020,
+ CMSG_GUILD_QUERY_RANKS = 0x1026,
+ CMSG_GUILD_REMOVE = 0x1231,
+ CMSG_GUILD_REPLACE_GUILD_MASTER = 0x1034,
+ CMSG_GUILD_REQUEST_CHALLENGE_UPDATE = 0x1224,
+ CMSG_GUILD_REQUEST_MAX_DAILY_XP = 0x3232,
+ CMSG_GUILD_REQUEST_PARTY_STATE = 0x3900,
+ CMSG_GUILD_ROSTER = 0x1226,
+ CMSG_GUILD_SET_ACHIEVEMENT_TRACKING = 0x1027,
+ CMSG_GUILD_SET_GUILD_MASTER = 0x3034,
+ CMSG_GUILD_SET_NOTE = 0x1233,
+ CMSG_GUILD_SET_RANK_PERMISSIONS = 0x1024,
+ CMSG_GUILD_SWITCH_RANK = 0x1221,
+ CMSG_HEARTH_AND_RESURRECT = 0x4B34,
+ CMSG_IGNORE_TRADE = 0x7112,
+ CMSG_INITIATE_TRADE = 0x7916,
+ CMSG_INSPECT = 0x0927,
+ CMSG_INSPECT_HONOR_STATS = 0x791E,
+ CMSG_INSTANCE_LOCK_WARNING_RESPONSE = 0x6234,
+ CMSG_ITEM_REFUND = 0x6134,
+ CMSG_ITEM_REFUND_INFO = 0x2206,
+ CMSG_ITEM_TEXT_QUERY = 0x2406,
+ CMSG_JOIN_CHANNEL = 0x0156,
+ CMSG_KEEP_ALIVE = 0x0015,
+ CMSG_LEARN_PREVIEW_TALENTS = 0x2415,
+ CMSG_LEARN_PREVIEW_TALENTS_PET = 0x6E24,
+ CMSG_LEARN_TALENT = 0x0306,
+ CMSG_LEAVE_CHANNEL = 0x2D56,
+ CMSG_LFG_GET_STATUS = 0x2581,
+ CMSG_LFG_JOIN = 0x2430,
+ CMSG_LFG_LEAVE = 0x2433,
+ CMSG_LFG_LFR_JOIN = 0x0531,
+ CMSG_LFG_LFR_LEAVE = 0x0500,
+ CMSG_LFG_LOCK_INFO_REQUEST = 0x0412,
+ CMSG_LFG_PROPOSAL_RESULT = 0x0403,
+ CMSG_LFG_SET_BOOT_VOTE = 0x04B3,
+ CMSG_LFG_SET_COMMENT = 0x0530,
+ CMSG_LFG_SET_ROLES = 0x0480,
+ CMSG_LFG_TELEPORT = 0x2482,
+ CMSG_LF_GUILD_ADD_RECRUIT = 0x4448,
+ CMSG_LF_GUILD_BROWSE = 0x0548,
+ CMSG_LF_GUILD_DECLINE_RECRUIT = 0x1031,
+ CMSG_LF_GUILD_GET_APPLICATIONS = 0x1230,
+ CMSG_LF_GUILD_GET_RECRUITS = 0x3230,
+ CMSG_LF_GUILD_POST_REQUEST = 0x3237,
+ CMSG_LF_GUILD_REMOVE_RECRUIT = 0x3027,
+ CMSG_LF_GUILD_SET_GUILD_POST = 0x0448,
+ CMSG_LIST_INVENTORY = 0x2806,
+ CMSG_LOAD_SCREEN = 0x2422,
+ CMSG_LOGOUT_CANCEL = 0x2324,
+ CMSG_LOGOUT_REQUEST = 0x0A25,
+ CMSG_LOG_DISCONNECT = 0x446D,
+ CMSG_LOOT = 0x0127,
+ CMSG_LOOT_CURRENCY = 0x781C,
+ CMSG_LOOT_MASTER_GIVE = 0x4F35,
+ CMSG_LOOT_METHOD = 0x2F24,
+ CMSG_LOOT_MONEY = 0x6227,
+ CMSG_LOOT_RELEASE = 0x2007,
+ CMSG_LOOT_ROLL = 0x6934,
+ CMSG_MAIL_CREATE_TEXT_ITEM = 0x0B14,
+ CMSG_MAIL_DELETE = 0x6104,
+ CMSG_MAIL_MARK_AS_READ = 0x0C07,
+ CMSG_MAIL_RETURN_TO_SENDER = 0x0816,
+ CMSG_MAIL_TAKE_ITEM = 0x2B06,
+ CMSG_MAIL_TAKE_MONEY = 0x4034,
+ CMSG_MEETINGSTONE_INFO = 0x0000,
+ CMSG_MESSAGECHAT_ADDON_BATTLEGROUND = 0x0D46,
+ CMSG_MESSAGECHAT_ADDON_GUILD = 0x0544,
+ CMSG_MESSAGECHAT_ADDON_OFFICER = 0x3954,
+ CMSG_MESSAGECHAT_ADDON_PARTY = 0x0546,
+ CMSG_MESSAGECHAT_ADDON_RAID = 0x1D56,
+ CMSG_MESSAGECHAT_ADDON_WHISPER = 0x2146,
+ CMSG_MESSAGECHAT_AFK = 0x0D44,
+ CMSG_MESSAGECHAT_BATTLEGROUND = 0x2156,
+ CMSG_MESSAGECHAT_CHANNEL = 0x1D44,
+ CMSG_MESSAGECHAT_DND = 0x2946,
+ CMSG_MESSAGECHAT_EMOTE = 0x1156,
+ CMSG_MESSAGECHAT_GUILD = 0x3956,
+ CMSG_MESSAGECHAT_OFFICER = 0x1946,
+ CMSG_MESSAGECHAT_PARTY = 0x1D46,
+ CMSG_MESSAGECHAT_RAID = 0x2D44,
+ CMSG_MESSAGECHAT_RAID_WARNING = 0x0944,
+ CMSG_MESSAGECHAT_SAY = 0x1154,
+ CMSG_MESSAGECHAT_WHISPER = 0x0D56,
+ CMSG_MESSAGECHAT_YELL = 0x3544,
+ CMSG_MINIGAME_MOVE = 0x2A34,
+ CMSG_MOUNTSPECIAL_ANIM = 0x2807,
+ CMSG_MOVE_CHARM_TELEPORT_CHEAT = 0x0000,
+ CMSG_MOVE_CHNG_TRANSPORT = 0x3102,
+ CMSG_MOVE_ENABLE_SWIM_TO_FLY_TRANS_ACK = 0x0000,
+ CMSG_MOVE_FALL_RESET = 0x310A,
+ CMSG_MOVE_FEATHER_FALL_ACK = 0x3110,
+ CMSG_MOVE_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK = 0x310E,
+ CMSG_MOVE_FORCE_FLIGHT_SPEED_CHANGE_ACK = 0x7314,
+ CMSG_MOVE_FORCE_PITCH_RATE_CHANGE_ACK = 0x3100,
+ CMSG_MOVE_FORCE_RUN_BACK_SPEED_CHANGE_ACK = 0x3216,
+ CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK = 0x7818,
+ CMSG_MOVE_FORCE_SWIM_BACK_SPEED_CHANGE_ACK = 0x7A16,
+ CMSG_MOVE_FORCE_SWIM_SPEED_CHANGE_ACK = 0x7A10,
+ CMSG_MOVE_FORCE_TURN_RATE_CHANGE_ACK = 0x7316,
+ CMSG_MOVE_FORCE_WALK_SPEED_CHANGE_ACK = 0x7210,
+ CMSG_MOVE_GRAVITY_DISABLE_ACK = 0x3118,
+ CMSG_MOVE_GRAVITY_ENABLE_ACK = 0x700A,
+ CMSG_MOVE_HOVER_ACK = 0x3318,
+ CMSG_MOVE_KNOCK_BACK_ACK = 0x721C,
+ CMSG_MOVE_NOT_ACTIVE_MOVER = 0x7A1A,
+ CMSG_MOVE_SET_CAN_FLY = 0x720E,
+ CMSG_MOVE_SET_CAN_FLY_ACK = 0x790C,
+ CMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY_ACK = 0x3014,
+ CMSG_MOVE_SET_COLLISION_HEIGHT_ACK = 0x7114,
+ CMSG_MOVE_SET_RELATIVE_POSITION = 0x0000,
+ CMSG_MOVE_SET_VEHICLE_REC_ID_ACK = 0x0000,
+ CMSG_MOVE_SPLINE_DONE = 0x790E,
+ CMSG_MOVE_TIME_SKIPPED = 0x7A0A,
+ CMSG_MOVE_TOGGLE_COLLISION_ACK = 0x0000,
+ CMSG_MOVE_WATER_WALK_ACK = 0x3B00,
+ CMSG_NAME_QUERY = 0x2224,
+ CMSG_NEW_SPELL_SLOT = 0x0000,
+ CMSG_NEXT_CINEMATIC_CAMERA = 0x2014,
+ CMSG_NPC_TEXT_QUERY = 0x4E24,
+ CMSG_OBJECT_UPDATE_FAILED = 0x3808,
+ CMSG_OBJECT_UPDATE_RESCUED = 0x3906,
+ CMSG_OFFER_PETITION = 0x4817,
+ CMSG_OPENING_CINEMATIC = 0x0A16,
+ CMSG_OPEN_ITEM = 0x6A34,
+ CMSG_OPT_OUT_OF_LOOT = 0x6B16,
+ CMSG_PAGE_TEXT_QUERY = 0x6614,
+ CMSG_PARTY_SILENCE = 0x6B26,
+ CMSG_PARTY_UNSILENCE = 0x4D24,
+ CMSG_PETITION_BUY = 0x4E05,
+ CMSG_PETITION_QUERY = 0x4424,
+ CMSG_PETITION_SHOWLIST = 0x4617,
+ CMSG_PETITION_SHOW_SIGNATURES = 0x4F15,
+ CMSG_PETITION_SIGN = 0x0E04,
+ CMSG_PET_ABANDON = 0x0C24,
+ CMSG_PET_ACTION = 0x0226,
+ CMSG_PET_CANCEL_AURA = 0x4B25,
+ CMSG_PET_CAST_SPELL = 0x6337,
+ CMSG_PET_LEARN_TALENT = 0x6725,
+ CMSG_PET_NAME_CACHE = 0x0000,
+ CMSG_PET_NAME_QUERY = 0x6F24,
+ CMSG_PET_RENAME = 0x6406,
+ CMSG_PET_SET_ACTION = 0x6904,
+ CMSG_PET_SPELL_AUTOCAST = 0x2514,
+ CMSG_PET_STOP_ATTACK = 0x6C14,
+ CMSG_PING = 0x444D,
+ CMSG_PLAYED_TIME = 0x0804,
+ CMSG_PLAYER_DIFFICULTY_CHANGE = 0x0000,
+ CMSG_PLAYER_LOGIN = 0x05B1,
+ CMSG_PLAYER_LOGOUT = 0x0000,
+ CMSG_PLAYER_VEHICLE_ENTER = 0x2705,
+ CMSG_PLAY_DANCE = 0x6914,
+ CMSG_PUSHQUESTTOPARTY = 0x4B14,
+ CMSG_PVP_LOG_DATA = 0x7308,
+ CMSG_QUERY_BATTLEFIELD_STATE = 0x7202,
+ CMSG_QUERY_GUILD_MEMBERS_FOR_RECIPE = 0x1036,
+ CMSG_QUERY_GUILD_MEMBER_RECIPES = 0x1037,
+ CMSG_QUERY_GUILD_RECIPES = 0x3033,
+ CMSG_QUERY_GUILD_REWARDS = 0x3012,
+ CMSG_QUERY_GUILD_XP = 0x1237,
+ CMSG_QUERY_INSPECT_ACHIEVEMENTS = 0x4D27,
+ CMSG_QUERY_QUESTS_COMPLETED = 0x2317,
+ CMSG_QUERY_TIME = 0x0A36,
+ CMSG_QUESTGIVER_ACCEPT_QUEST = 0x6B37,
+ CMSG_QUESTGIVER_CANCEL = 0x0000,
+ CMSG_QUESTGIVER_CHOOSE_REWARD = 0x2125,
+ CMSG_QUESTGIVER_COMPLETE_QUEST = 0x0114,
+ CMSG_QUESTGIVER_HELLO = 0x0D17,
+ CMSG_QUESTGIVER_QUERY_QUEST = 0x2F14,
+ CMSG_QUESTGIVER_QUEST_AUTOLAUNCH = 0x0000,
+ CMSG_QUESTGIVER_REQUEST_REWARD = 0x2534,
+ CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY = 0x6305,
+ CMSG_QUESTGIVER_STATUS_QUERY = 0x4407,
+ CMSG_QUESTLOG_REMOVE_QUEST = 0x0D16,
+ CMSG_QUESTLOG_SWAP_QUEST = 0x0000,
+ CMSG_QUEST_CONFIRM_ACCEPT = 0x0D15,
+ CMSG_QUEST_NPC_QUERY = 0x7302,
+ CMSG_QUEST_POI_QUERY = 0x4037,
+ CMSG_QUEST_QUERY = 0x0D06,
+ CMSG_RANDOMIZE_CHAR_NAME = 0x2413,
+ CMSG_READY_FOR_ACCOUNT_DATA_TIMES = 0x2B16,
+ CMSG_READ_ITEM = 0x2F16,
+ CMSG_REALM_SPLIT = 0x2906,
+ CMSG_RECLAIM_CORPSE = 0x4036,
+ CMSG_REDIRECTION_AUTH_PROOF = 0x044D,
+ CMSG_REFORGE_ITEM = 0x331A,
+ CMSG_REORDER_CHARACTERS = 0x0593,
+ CMSG_REPAIR_ITEM = 0x2917,
+ CMSG_REPLACE_ACCOUNT_DATA = 0x0000,
+ CMSG_REPOP_REQUEST = 0x6235,
+ CMSG_REPORT_PVP_AFK = 0x6734,
+ CMSG_REQUEST_ACCOUNT_DATA = 0x6505,
+ CMSG_REQUEST_CATEGORY_COOLDOWNS = 0x7102,
+ CMSG_REQUEST_CEMETERY_LIST = 0x720A,
+ CMSG_REQUEST_HOTFIX = 0x2401,
+ CMSG_REQUEST_INSPECT_RATED_BG_STATS = 0x3010,
+ CMSG_REQUEST_PARTY_MEMBER_STATS = 0x0C04,
+ CMSG_REQUEST_PET_INFO = 0x4924,
+ CMSG_REQUEST_PVP_OPTIONS_ENABLED = 0x24A1,
+ CMSG_REQUEST_PVP_REWARDS = 0x780C,
+ CMSG_REQUEST_RAID_INFO = 0x2F26,
+ CMSG_REQUEST_RATED_BG_INFO = 0x2423,
+ CMSG_REQUEST_RATED_BG_STATS = 0x05B3,
+ CMSG_REQUEST_RESEARCH_HISTORY = 0x3306,
+ CMSG_REQUEST_VEHICLE_EXIT = 0x2B35,
+ CMSG_REQUEST_VEHICLE_NEXT_SEAT = 0x4434,
+ CMSG_REQUEST_VEHICLE_PREV_SEAT = 0x4C04,
+ CMSG_REQUEST_VEHICLE_SWITCH_SEAT = 0x4C14,
+ CMSG_RESET_FACTION_CHEAT = 0x4469,
+ CMSG_RESET_INSTANCES = 0x6E14,
+ CMSG_RESURRECT_RESPONSE = 0x6827,
+ CMSG_RETURN_TO_GRAVEYARD = 0x301E,
+ CMSG_ROLE_POLL_BEGIN = 0x0430,
+ CMSG_SAVE_CUF_PROFILES = 0x730E,
+ CMSG_SAVE_PLAYER = 0x0000,
+ CMSG_SEARCH_LFG_JOIN = 0x0000,
+ CMSG_SEARCH_LFG_LEAVE = 0x0000,
+ CMSG_SELF_RES = 0x6115,
+ CMSG_SELL_ITEM = 0x4E15,
+ CMSG_SEND_MAIL = 0x0523,
+ CMSG_SEND_SOR_REQUEST_VIA_ADDRESS = 0x0420,
+ CMSG_SEND_SOR_REQUEST_VIA_BNET_ACCOUNT_ID = 0x0482,
+ CMSG_SERVERTIME = 0x0000,
+ CMSG_SETDEATHBINDPOINT = 0x0000,
+ CMSG_SETSHEATHED = 0x4326,
+ CMSG_SET_ACTIONBAR_TOGGLES = 0x2506,
+ CMSG_SET_ACTION_BUTTON = 0x6F06,
+ CMSG_SET_ACTIVE_MOVER = 0x3314,
+ CMSG_SET_ACTIVE_VOICE_CHANNEL = 0x4305,
+ CMSG_SET_ALLOW_LOW_LEVEL_RAID1 = 0x4435,
+ CMSG_SET_ALLOW_LOW_LEVEL_RAID2 = 0x0536,
+ CMSG_SET_CHANNEL_WATCH = 0x4517,
+ CMSG_SET_CONTACT_NOTES = 0x6135,
+ CMSG_SET_CURRENCY_FLAGS = 0x7306,
+ CMSG_SET_EVERYONE_IS_ASSISTANT = 0x2530,
+ CMSG_SET_FACTION_ATWAR = 0x0706,
+ CMSG_SET_FACTION_CHEAT = 0x0000,
+ CMSG_SET_FACTION_INACTIVE = 0x0E37,
+ CMSG_SET_GUILD_BANK_TEXT = 0x3023,
+ CMSG_SET_LFG_COMMENT = 0x0000,
+ CMSG_SET_PET_SLOT = 0x3A04,
+ CMSG_SET_PLAYER_DECLINED_NAMES = 0x6316,
+ CMSG_SET_PREFERED_CEMETERY = 0x311E,
+ CMSG_SET_PRIMARY_TALENT_TREE = 0x4524,
+ CMSG_SET_RELATIVE_POSITION = 0x311A,
+ CMSG_SET_SAVED_INSTANCE_EXTEND = 0x6706,
+ CMSG_SET_SELECTION = 0x0506,
+ CMSG_SET_SKILL_CHEAT = 0x0000,
+ CMSG_SET_TAXI_BENCHMARK_MODE = 0x4314,
+ CMSG_SET_TITLE = 0x2117,
+ CMSG_SET_TRADE_CURRENCY = 0x3312,
+ CMSG_SET_TRADE_GOLD = 0x3008,
+ CMSG_SET_TRADE_ITEM = 0x7B0C,
+ CMSG_SET_VEHICLE_REC_ID_ACK = 0x3108,
+ CMSG_SET_WATCHED_FACTION = 0x2434,
+ CMSG_SHOWING_CLOAK = 0x4135,
+ CMSG_SHOWING_HELM = 0x0735,
+ CMSG_SOCKET_GEMS = 0x2F04,
+ CMSG_SPELLCLICK = 0x0805,
+ CMSG_SPIRIT_HEALER_ACTIVATE = 0x2E26,
+ CMSG_SPLIT_ITEM = 0x0F17,
+ CMSG_STANDSTATECHANGE = 0x0535,
+ CMSG_START_QUEST = 0x0000,
+ CMSG_STOP_DANCE = 0x2907,
+ CMSG_STORE_LOOT_IN_SLOT = 0x0000,
+ CMSG_SUBMIT_BUG = 0x2520,
+ CMSG_SUBMIT_COMPLAIN = 0x2501,
+ CMSG_SUGGESTION_SUBMIT = 0x2512,
+ CMSG_SUMMON_RESPONSE = 0x6F27,
+ CMSG_SUSPEND_TOKEN = 0x046D,
+ CMSG_SWAP_INV_ITEM = 0x2614,
+ CMSG_SWAP_ITEM = 0x6326,
+ CMSG_SYNC_DANCE = 0x0036,
+ CMSG_TAXICLEARALLNODES = 0x0000,
+ CMSG_TAXIENABLEALLNODES = 0x0000,
+ CMSG_TAXINODE_STATUS_QUERY = 0x2F25,
+ CMSG_TAXIQUERYAVAILABLENODES = 0x6C06,
+ CMSG_TAXISHOWNODES = 0x0000,
+ CMSG_TELEPORT_TO_UNIT = 0x4206,
+ CMSG_TEXT_EMOTE = 0x2E24,
+ CMSG_TIME_ADJUSTMENT_RESPONSE = 0x3818,
+ CMSG_TIME_SYNC_RESP = 0x3B0C,
+ CMSG_TIME_SYNC_RESP_FAILED = 0x710A,
+ CMSG_TOGGLE_PVP = 0x6815,
+ CMSG_TOTEM_DESTROYED = 0x4207,
+ CMSG_TRAINER_BUY_SPELL = 0x4415,
+ CMSG_TRAINER_LIST = 0x2336,
+ CMSG_TRANSMOGRIFY_ITEMS = 0x3B0E,
+ CMSG_TRIGGER_CINEMATIC_CHEAT = 0x0000,
+ CMSG_TURN_IN_PETITION = 0x0B27,
+ CMSG_TUTORIAL_CLEAR = 0x6515,
+ CMSG_TUTORIAL_FLAG = 0x6C26,
+ CMSG_TUTORIAL_RESET = 0x2726,
+ CMSG_UNACCEPT_TRADE = 0x391A,
+ CMSG_UNLEARN_SKILL = 0x6106,
+ CMSG_UNLEARN_SPECIALIZATION = 0x3210,
+ CMSG_UNREGISTER_ALL_ADDON_PREFIXES = 0x3D54,
+ CMSG_UPDATE_ACCOUNT_DATA = 0x4736,
+ CMSG_UPDATE_MISSILE_TRAJECTORY = 0x781E,
+ CMSG_UPDATE_PROJECTILE_POSITION = 0x0E24,
+ CMSG_USED_FOLLOW = 0x7912,
+ CMSG_USE_ITEM = 0x2C06,
+ CMSG_VIOLENCE_LEVEL = 0x7816,
+ CMSG_VOICE_SESSION_ENABLE = 0x2314,
+ CMSG_VOID_STORAGE_QUERY = 0x790A,
+ CMSG_VOID_STORAGE_TRANSFER = 0x380E,
+ CMSG_VOID_STORAGE_UNLOCK = 0x7B14,
+ CMSG_VOID_SWAP_ITEM = 0x3204,
+ CMSG_WARDEN_DATA = 0x25A2,
+ CMSG_WARGAME_ACCEPT = 0x2410,
+ CMSG_WARGAME_START = 0x05A0,
+ CMSG_WHO = 0x6C15,
+ CMSG_WHOIS = 0x6B05,
+ CMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4605,
+ CMSG_WORLD_TELEPORT = 0x24B2,
+ CMSG_WRAP_ITEM = 0x4F06,
+ CMSG_ZONEUPDATE = 0x4F37,
+ MSG_AUCTION_HELLO = 0x2307,
+ MSG_CHANNEL_START = 0x0A15, // SMSG only?
+ MSG_CHANNEL_UPDATE = 0x2417, // SMSG only?
+ MSG_CORPSE_QUERY = 0x4336,
+ MSG_GM_BIND_OTHER = 0x0000,
+ MSG_GM_SHOWLABEL = 0x0000,
+ MSG_GM_SUMMON = 0x0000,
+ MSG_INSPECT_ARENA_TEAMS = 0x2704,
+ MSG_LIST_STABLED_PETS = 0x0834,
+ MSG_MINIMAP_PING = 0x6635,
+ MSG_MOVE_CHARM_TELEPORT_CHEAT = 0x7A08,
+ MSG_MOVE_FALL_LAND = 0x380A,
+ MSG_MOVE_HEARTBEAT = 0x3914,
+ MSG_MOVE_JUMP = 0x7A06,
+ MSG_MOVE_SET_ALL_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_COLLISION_HEIGHT = 0x0000,
+ MSG_MOVE_SET_FACING = 0x7914,
+ MSG_MOVE_SET_FLIGHT_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_PITCH = 0x7312,
+ MSG_MOVE_SET_RAW_POSITION_ACK = 0x0000,
+ MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_RUN_MODE = 0x791A,
+ MSG_MOVE_SET_RUN_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_SWIM_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_SET_TURN_RATE_CHEAT = 0x0000,
+ MSG_MOVE_SET_WALK_MODE = 0x7002,
+ MSG_MOVE_SET_WALK_SPEED_CHEAT = 0x0000,
+ MSG_MOVE_START_ASCEND = 0x390A,
+ MSG_MOVE_START_BACKWARD = 0x330A,
+ MSG_MOVE_START_DESCEND = 0x3800,
+ MSG_MOVE_START_FORWARD = 0x7814,
+ MSG_MOVE_START_PITCH_DOWN = 0x3908,
+ MSG_MOVE_START_PITCH_UP = 0x3304,
+ MSG_MOVE_START_STRAFE_LEFT = 0x3A16,
+ MSG_MOVE_START_STRAFE_RIGHT = 0x3A02,
+ MSG_MOVE_START_SWIM = 0x3206,
+ MSG_MOVE_START_TURN_LEFT = 0x700C,
+ MSG_MOVE_START_TURN_RIGHT = 0x7000,
+ MSG_MOVE_STOP = 0x320A,
+ MSG_MOVE_STOP_ASCEND = 0x7B00,
+ MSG_MOVE_STOP_PITCH = 0x7216,
+ MSG_MOVE_STOP_STRAFE = 0x3002,
+ MSG_MOVE_STOP_SWIM = 0x3802,
+ MSG_MOVE_STOP_TURN = 0x331E,
+ MSG_MOVE_TELEPORT = 0x55A0,
+ MSG_MOVE_TELEPORT_ACK = 0x390C,
+ MSG_MOVE_TELEPORT_CHEAT = 0x3A10,
+ MSG_MOVE_TIME_SKIPPED = 0x19B3,
+ MSG_MOVE_TOGGLE_COLLISION_CHEAT = 0x7B04,
+ MSG_MOVE_TOGGLE_FALL_LOGGING = 0x0000,
+ MSG_MOVE_TOGGLE_LOGGING = 0x0000,
+ MSG_MOVE_UPDATE_MOUSE = 0x0000,
+ MSG_MOVE_WORLDPORT_ACK = 0x2411,
+ MSG_NOTIFY_PARTY_SQUELCH = 0x4D06,
+ MSG_PARTY_ASSIGNMENT = 0x0424,
+ MSG_PETITION_DECLINE = 0x4905,
+ MSG_PETITION_RENAME = 0x4005,
+ MSG_PVP_LOG_DATA = 0x0000,
+ MSG_QUERY_NEXT_MAIL_TIME = 0x0F04,
+ MSG_QUEST_PUSH_RESULT = 0x4515,
+ MSG_RAID_READY_CHECK = 0x2304,
+ MSG_RAID_READY_CHECK_CONFIRM = 0x4F05,
+ MSG_RAID_READY_CHECK_FINISHED = 0x2E15,
+ MSG_RAID_TARGET_UPDATE = 0x2C36,
+ MSG_RANDOM_ROLL = 0x0905,
+ MSG_SAVE_GUILD_EMBLEM = 0x2404,
+ MSG_SET_DUNGEON_DIFFICULTY = 0x4925,
+ MSG_SET_RAID_DIFFICULTY = 0x0614,
+ MSG_START_MOVE_FORWARD = 0x0000,
+ MSG_TABARDVENDOR_ACTIVATE = 0x6926,
+ MSG_TALENT_WIPE_CONFIRM = 0x0107,
+ MSG_VERIFY_CONNECTIVITY = 0x4F57,
+ SMSG_ACCOUNT_DATA_TIMES = 0x4B05,
+ SMSG_ACCOUNT_INFO_RESPONSE = 0x10A7,
+ SMSG_ACCOUNT_RESTRICTED_WARNING = 0x51A7,
+ SMSG_ACHIEVEMENT_DELETED = 0x6A16,
+ SMSG_ACHIEVEMENT_EARNED = 0x4405,
+ SMSG_ACTION_BUTTONS = 0x38B5,
+ SMSG_ACTIVATETAXIREPLY = 0x6A37,
+ SMSG_ADDON_INFO = 0x2C14,
+ SMSG_ADD_RUNE_POWER = 0x6915,
+ SMSG_AI_REACTION = 0x0637,
+ SMSG_ALL_ACHIEVEMENT_DATA = 0x58B1,
+ SMSG_AREA_SPIRIT_HEALER_TIME = 0x0734,
+ SMSG_AREA_TRIGGER_MESSAGE = 0x4505,
+ SMSG_AREA_TRIGGER_MOVEMENT_UPDATE = 0x3DB1,
+ SMSG_ARENA_ERROR = 0x2D17,
+ SMSG_ARENA_UNIT_DESTROYED = 0x2637,
+ SMSG_ARENA_TEAM_CHANGE_FAILED_QUEUED = 0x6E34,
+ SMSG_ARENA_TEAM_COMMAND_RESULT = 0x39B3,
+ SMSG_ARENA_TEAM_EVENT = 0x0617,
+ SMSG_ARENA_TEAM_INVITE = 0x0F36,
+ SMSG_ARENA_TEAM_QUERY_RESPONSE = 0x6336,
+ SMSG_ARENA_TEAM_ROSTER = 0x2717,
+ SMSG_ARENA_TEAM_STATS = 0x4425,
+ SMSG_ATTACKERSTATEUPDATE = 0x0B25,
+ SMSG_ATTACKSTART = 0x2D15,
+ SMSG_ATTACKSTOP = 0x0934,
+ SMSG_ATTACKSWING_BADFACING = 0x0B36,
+ SMSG_ATTACKSWING_CANT_ATTACK = 0x0016,
+ SMSG_ATTACKSWING_DEADTARGET = 0x2B26,
+ SMSG_ATTACKSWING_NOTINRANGE = 0x6C07,
+ SMSG_AUCTION_BIDDER_LIST_RESULT = 0x0027,
+ SMSG_AUCTION_BIDDER_NOTIFICATION = 0x4E27,
+ SMSG_AUCTION_COMMAND_RESULT = 0x4C25,
+ SMSG_AUCTION_LIST_PENDING_SALES = 0x6A27,
+ SMSG_AUCTION_LIST_RESULT = 0x6637,
+ SMSG_AUCTION_OWNER_LIST_RESULT = 0x6C34,
+ SMSG_AUCTION_OWNER_NOTIFICATION = 0x4116,
+ SMSG_AUCTION_REMOVED_NOTIFICATION = 0x2334,
+ SMSG_AURACASTLOG = 0x0000,
+ SMSG_AURA_POINTS_DEPLETED = 0x7CB7,
+ SMSG_AURA_UPDATE = 0x4707,
+ SMSG_AURA_UPDATE_ALL = 0x6916,
+ SMSG_AUTH_CHALLENGE = 0x4542,
+ SMSG_AUTH_RESPONSE = 0x5DB6,
+ SMSG_AVAILABLE_VOICE_CHANNEL = 0x2E16,
+ SMSG_AVERAGE_ITEM_LEVEL_INFORM = 0x5DA7,
+ SMSG_BARBER_SHOP_RESULT = 0x6125,
+ SMSG_BATTLEFIELD_LIST = 0x71B5,
+ SMSG_BATTLEFIELD_MGR_EJECTED = 0x7DB7,
+ SMSG_BATTLEFIELD_MGR_EJECT_PENDING = 0x34A2,
+ SMSG_BATTLEFIELD_MGR_ENTERED = 0x5CA0,
+ SMSG_BATTLEFIELD_MGR_ENTRY_INVITE = 0x34B3,
+ SMSG_BATTLEFIELD_MGR_EXIT_REQUEST = 0x51B1,
+ SMSG_BATTLEFIELD_MGR_QUEUE_INVITE = 0x15A6,
+ SMSG_BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE = 0x79B6,
+ SMSG_BATTLEFIELD_MGR_STATE_CHANGE = 0x35B4,
+ SMSG_BATTLEFIELD_PLAYER_POSITIONS = 0x58B4,
+ SMSG_BATTLEFIELD_PORT_DENIED = 0x35A3,
+ SMSG_BATTLEFIELD_RATED_INFO = 0x54A3,
+ SMSG_BATTLEFIELD_STATUS = 0x7DA1,
+ SMSG_BATTLEFIELD_STATUS_QUEUED = 0x35A1,
+ SMSG_BATTLEFIELD_STATUS_ACTIVE = 0x74A4,
+ SMSG_BATTLEFIELD_STATUS_NEEDCONFIRMATION = 0x59A0,
+ SMSG_BATTLEFIELD_STATUS_WAITFORGROUPS = 0x75A2,
+ SMSG_BATTLEFIELD_STATUS_FAILED = 0x71A7,
+ SMSG_BATTLEGROUND_INFO_THROTTLED = 0x34B2,
+ SMSG_BATTLEGROUND_PLAYER_JOINED = 0x50B0,
+ SMSG_BATTLEGROUND_PLAYER_LEFT = 0x59A6,
+ SMSG_BINDER_CONFIRM = 0x2835,
+ SMSG_BINDPOINTUPDATE = 0x0527,
+ SMSG_BINDZONEREPLY = 0x0000,
+ SMSG_BREAK_TARGET = 0x0105,
+ SMSG_BUY_BANK_SLOT_RESULT = 0x0000,
+ SMSG_BUY_FAILED = 0x6435,
+ SMSG_BUY_ITEM = 0x0F26,
+ SMSG_CALENDAR_ACTION_PENDING = 0x0000,
+ SMSG_CALENDAR_ARENA_TEAM = 0x0615,
+ SMSG_CALENDAR_CLEAR_PENDING_ACTION = 0x2106,
+ SMSG_CALENDAR_COMMAND_RESULT = 0x6F36,
+ SMSG_CALENDAR_EVENT_INVITE = 0x4E16,
+ SMSG_CALENDAR_EVENT_INVITE_ALERT = 0x2A05,
+ SMSG_CALENDAR_EVENT_INVITE_NOTES = 0x0E17,
+ SMSG_CALENDAR_EVENT_INVITE_NOTES_ALERT = 0x2535,
+ SMSG_CALENDAR_EVENT_INVITE_REMOVED = 0x0725,
+ SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT = 0x2617,
+ SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT = 0x6625,
+ SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT = 0x6B06,
+ SMSG_CALENDAR_EVENT_REMOVED_ALERT = 0x6D35,
+ SMSG_CALENDAR_EVENT_STATUS = 0x2A27,
+ SMSG_CALENDAR_EVENT_UPDATED_ALERT = 0x0907,
+ SMSG_CALENDAR_FILTER_GUILD = 0x4A26,
+ SMSG_CALENDAR_RAID_LOCKOUT_ADDED = 0x2305,
+ SMSG_CALENDAR_RAID_LOCKOUT_REMOVED = 0x2E25,
+ SMSG_CALENDAR_RAID_LOCKOUT_UPDATED = 0x4636,
+ SMSG_CALENDAR_SEND_CALENDAR = 0x6805,
+ SMSG_CALENDAR_SEND_EVENT = 0x0C35,
+ SMSG_CALENDAR_SEND_NUM_PENDING = 0x0C17,
+ SMSG_CALENDAR_UPDATE_INVITE_LIST = 0x0000,
+ SMSG_CAMERA_SHAKE = 0x4214,
+ SMSG_CANCEL_AUTO_REPEAT = 0x6436,
+ SMSG_CANCEL_COMBAT = 0x4F04,
+ SMSG_CAST_FAILED = 0x4D16,
+ SMSG_CHANNEL_LIST = 0x2214,
+ SMSG_CHANNEL_MEMBER_COUNT = 0x6414,
+ SMSG_CHANNEL_NOTIFY = 0x0825,
+ SMSG_CHARACTER_LOGIN_FAILED = 0x4417,
+ SMSG_CHAR_CREATE = 0x2D05,
+ SMSG_CHAR_CUSTOMIZE = 0x4F16,
+ SMSG_CHAR_DELETE = 0x0304,
+ SMSG_CHAR_ENUM = 0x10B0,
+ SMSG_CHAR_FACTION_CHANGE = 0x4C06,
+ SMSG_CHAR_RENAME = 0x2024,
+ SMSG_CHAT_IGNORED_ACCOUNT_MUTED = 0x15A4,
+ SMSG_CHAT_NOT_IN_PARTY = 0x6A14,
+ SMSG_CHAT_PLAYER_AMBIGUOUS = 0x2F34,
+ SMSG_CHAT_PLAYER_NOT_FOUND = 0x2526,
+ SMSG_CHAT_RESTRICTED = 0x6536,
+ SMSG_CHAT_SERVER_DISCONNECTED = 0x6D34,
+ SMSG_CHAT_SERVER_RECONNECTED = 0x6905,
+ SMSG_CHAT_WRONG_FACTION = 0x6724,
+ SMSG_CHECK_FOR_BOTS = 0x0000,
+ SMSG_CLEAR_BOSS_EMOTES = 0x19A3,
+ SMSG_CLEAR_COOLDOWN = 0x0627,
+ SMSG_CLEAR_COOLDOWNS = 0x59B4,
+ SMSG_CLEAR_FAR_SIGHT_IMMEDIATE = 0x2A04,
+ SMSG_CLEAR_TARGET = 0x4B26,
+ SMSG_CLIENTCACHE_VERSION = 0x2734,
+ SMSG_CLIENT_CONTROL_UPDATE = 0x2837,
+ SMSG_COMBAT_EVENT_FAILED = 0x2B07,
+ SMSG_COMBAT_LOG_MULTIPLE = 0x0000,
+ SMSG_COMMENTATOR_MAP_INFO = 0x0327,
+ SMSG_COMMENTATOR_PARTY_INFO = 0x38B0,
+ SMSG_COMMENTATOR_PLAYER_INFO = 0x2F36,
+ SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT1 = 0x2126,
+ SMSG_COMMENTATOR_SKIRMISH_QUEUE_RESULT2 = 0x6814,
+ SMSG_COMMENTATOR_STATE_CHANGED = 0x0737,
+ SMSG_COMPLAIN_RESULT = 0x6D24,
+ SMSG_COMPRESSED_MOVES = 0x0517,
+ SMSG_COMSAT_CONNECT_FAIL = 0x6317,
+ SMSG_COMSAT_DISCONNECT = 0x0316,
+ SMSG_COMSAT_RECONNECT_TRY = 0x4D35,
+ SMSG_CONTACT_LIST = 0x6017,
+ SMSG_CONVERT_RUNE = 0x4F14,
+ SMSG_COOLDOWN_CHEAT = 0x4537,
+ SMSG_COOLDOWN_EVENT = 0x4F26,
+ SMSG_CORPSE_MAP_POSITION_QUERY_RESPONSE = 0x0E35,
+ SMSG_CORPSE_NOT_IN_INSTANCE = 0x2A14,
+ SMSG_CORPSE_RECLAIM_DELAY = 0x0D34,
+ SMSG_CREATURE_QUERY_RESPONSE = 0x6024,
+ SMSG_CRITERIA_DELETED = 0x2915,
+ SMSG_CRITERIA_UPDATE = 0x6E37,
+ SMSG_CROSSED_INEBRIATION_THRESHOLD = 0x2036,
+ SMSG_CURRENCY_LOOT_REMOVED = 0x1DB4,
+ SMSG_CURRENCY_LOOT_RESTORED = 0x30A0,
+ SMSG_CUSTOM_LOAD_SCREEN = 0x1DB6,
+ SMSG_DAMAGE_CALC_LOG = 0x2436,
+ SMSG_DAMAGE_DONE_OBSOLETE = 0x0000,
+ SMSG_DANCE_QUERY_RESPONSE = 0x2F06,
+ SMSG_DB_REPLY = 0x38A4,
+ SMSG_DEATH_RELEASE_LOC = 0x2F07,
+ SMSG_DEBUG_RUNE_REGEN = 0x31B3,
+ SMSG_DEFENSE_MESSAGE = 0x0314,
+ SMSG_DESTROY_OBJECT = 0x4724,
+ SMSG_DESTRUCTIBLE_BUILDING_DAMAGE = 0x4825,
+ SMSG_DIFFERENT_INSTANCE_FROM_PARTY = 0x15B1,
+ SMSG_DISENCHANT_CREDIT = 0x55A2,
+ SMSG_DISMOUNT = 0x2135,
+ SMSG_DISMOUNTRESULT = 0x0D25,
+ SMSG_DISPEL_FAILED = 0x0307,
+ SMSG_DISPLAY_GAME_ERROR = 0x31A6,
+ SMSG_DONT_AUTO_PUSH_SPELLS_TO_ACTION_BAR = 0x38A2,
+ SMSG_DROP_NEW_CONNECTION = 0x4D40,
+ SMSG_DUEL_COMPLETE = 0x2527,
+ SMSG_DUEL_COUNTDOWN = 0x4836,
+ SMSG_DUEL_INBOUNDS = 0x0A27,
+ SMSG_DUEL_OUTOFBOUNDS = 0x0C26,
+ SMSG_DUEL_REQUESTED = 0x4504,
+ SMSG_DUEL_WINNER = 0x2D36,
+ SMSG_DUMP_RIDE_TICKETS_RESPONSE = 0x11A3,
+ SMSG_DURABILITY_DAMAGE_DEATH = 0x4C27,
+ SMSG_ECHO_PARTY_SQUELCH = 0x0814,
+ SMSG_EMOTE = 0x0A34,
+ SMSG_ENABLE_BARBER_SHOP = 0x2D16,
+ SMSG_ENCHANTMENTLOG = 0x6035,
+ SMSG_ENVIRONMENTALDAMAGELOG = 0x6C05,
+ SMSG_EQUIPMENT_SET_LIST = 0x2E04,
+ SMSG_EQUIPMENT_SET_SAVED = 0x2216,
+ SMSG_EQUIPMENT_SET_USE_RESULT = 0x2424,
+ SMSG_EXPECTED_SPAM_RECORDS = 0x4D36,
+ SMSG_EXPLORATION_EXPERIENCE = 0x6716,
+ SMSG_FAILED_PLAYER_CONDITION = 0x19A4,
+ SMSG_FEATURE_SYSTEM_STATUS = 0x3DB7,
+ SMSG_FEIGN_DEATH_RESISTED = 0x0D05,
+ SMSG_FISH_ESCAPED = 0x2205,
+ SMSG_FISH_NOT_HOOKED = 0x0A17,
+ SMSG_FLIGHT_SPLINE_SYNC = 0x0924,
+ SMSG_FLOOD_DETECTED = 0x0542,
+ SMSG_FORCEACTIONSHOW = 0x0000,
+ SMSG_FORCED_DEATH_UPDATE = 0x2606,
+ SMSG_FORCE_DISPLAY_UPDATE = 0x0000,
+ SMSG_FORCE_SEND_QUEUED_PACKETS = 0x0140,
+ SMSG_FORCE_SET_VEHICLE_REC_ID = 0x70A1,
+ SMSG_FORGE_MASTER_SET = 0x70B7,
+ SMSG_FRIEND_STATUS = 0x0717,
+ SMSG_GAMEOBJECT_CUSTOM_ANIM = 0x4936,
+ SMSG_GAMEOBJECT_DESPAWN_ANIM = 0x6735,
+ SMSG_GAMEOBJECT_PAGETEXT = 0x2925,
+ SMSG_GAMEOBJECT_QUERY_RESPONSE = 0x0915,
+ SMSG_GAMEOBJECT_RESET_STATE = 0x2A16,
+ SMSG_GAMESPEED_SET = 0x4E34,
+ SMSG_GAMETIME_SET = 0x0014,
+ SMSG_GAMETIME_UPDATE = 0x4127,
+ SMSG_GAME_EVENT_DEBUG_LOG = 0x31A7,
+ SMSG_GAME_OBJECT_ACTIVATE_ANIM_KIT = 0x14A3,
+ SMSG_GMRESPONSE_DB_ERROR = 0x0006,
+ SMSG_GMRESPONSE_RECEIVED = 0x2E34,
+ SMSG_GMRESPONSE_STATUS_UPDATE = 0x0A04,
+ SMSG_GMTICKET_CREATE = 0x2107,
+ SMSG_GMTICKET_DELETETICKET = 0x6D17,
+ SMSG_GMTICKET_GETTICKET = 0x2C15,
+ SMSG_GMTICKET_SYSTEMSTATUS = 0x0D35,
+ SMSG_GMTICKET_UPDATETEXT = 0x6535,
+ SMSG_GM_MESSAGECHAT = 0x6434,
+ SMSG_GM_PLAYER_INFO = 0x4A15,
+ SMSG_GM_TICKET_STATUS_UPDATE = 0x2C25,
+ SMSG_GODMODE = 0x0405,
+ SMSG_GOSSIP_COMPLETE = 0x0806,
+ SMSG_GOSSIP_MESSAGE = 0x2035,
+ SMSG_GOSSIP_POI = 0x4316,
+ SMSG_GROUPACTION_THROTTLED = 0x6524,
+ SMSG_GROUP_CANCEL = 0x4D25,
+ SMSG_GROUP_DECLINE = 0x6835,
+ SMSG_GROUP_DESTROYED = 0x2207,
+ SMSG_GROUP_INVITE = 0x31B2,
+ SMSG_GROUP_LIST = 0x4C24,
+ SMSG_GROUP_SET_LEADER = 0x0526,
+ SMSG_GROUP_SET_ROLE = 0x39A6,
+ SMSG_GROUP_UNINVITE = 0x0A07,
+ SMSG_GUILD_ACHIEVEMENT_DATA = 0x54B7,
+ SMSG_GUILD_ACHIEVEMENT_DELETED = 0x35A0,
+ SMSG_GUILD_ACHIEVEMENT_EARNED = 0x50B5,
+ SMSG_GUILD_ACHIEVEMENT_MEMBERS = 0x38A5,
+ SMSG_GUILD_BANK_LIST = 0x78A5,
+ SMSG_GUILD_BANK_LOG_QUERY_RESULT = 0x30B2,
+ SMSG_GUILD_BANK_MONEY_WITHDRAWN = 0x5DB4,
+ SMSG_GUILD_BANK_QUERY_TEXT_RESULT = 0x75A3,
+ SMSG_GUILD_CANCEL = 0x0000,
+ SMSG_GUILD_CHALLENGE_COMPLETED = 0x39A3,
+ SMSG_GUILD_CHALLENGE_UPDATED = 0x18B1,
+ SMSG_GUILD_CHANGE_NAME_RESULT = 0x3CB1,
+ SMSG_GUILD_COMMAND_RESULT = 0x7DB3,
+ SMSG_GUILD_COMMAND_RESULT_2 = 0x2707,
+ SMSG_GUILD_CRITERIA_DATA = 0x14B4,
+ SMSG_GUILD_CRITERIA_DELETED = 0x55B1,
+ SMSG_GUILD_DECLINE = 0x2C07,
+ SMSG_GUILD_EVENT = 0x0705,
+ SMSG_GUILD_EVENT_LOG_QUERY_RESULT = 0x10B2,
+ SMSG_GUILD_FLAGGED_FOR_RENAME = 0x30B6,
+ SMSG_GUILD_INVITE = 0x14A2,
+ SMSG_GUILD_INVITE_CANCEL = 0x0606,
+ SMSG_GUILD_KNOWN_RECIPES = 0x0000,
+ SMSG_GUILD_MAX_DAILY_XP = 0x79B5,
+ SMSG_GUILD_MEMBERS_FOR_RECIPE = 0x1CB7,
+ SMSG_GUILD_MEMBER_DAILY_RESET = 0x10A5,
+ SMSG_GUILD_MEMBER_RECIPES = 0x1CB0,
+ SMSG_GUILD_MEMBER_UPDATE_NOTE = 0x7CA0,
+ SMSG_GUILD_MOVE_COMPLETE = 0x11B2,
+ SMSG_GUILD_MOVE_STARTING = 0x70A4,
+ SMSG_GUILD_NEWS_DELETED = 0x74A7,
+ SMSG_GUILD_NEWS_UPDATE = 0x35A7,
+ SMSG_GUILD_PARTY_STATE_RESPONSE = 0x50A6,
+ SMSG_GUILD_PERMISSIONS_QUERY_RESULTS = 0x34A3,
+ SMSG_GUILD_QUERY_RESPONSE = 0x0E06,
+ SMSG_GUILD_RANK = 0x30B4,
+ SMSG_GUILD_RANKS_UPDATE = 0x5DA0,
+ SMSG_GUILD_RECIPES = 0x10B3,
+ SMSG_GUILD_RENAMED = 0x74A6,
+ SMSG_GUILD_REPUTATION_REACTION_CHANGED = 0x74B0,
+ SMSG_GUILD_REPUTATION_WEEKLY_CAP = 0x30B7,
+ SMSG_GUILD_RESET = 0x1CB5,
+ SMSG_GUILD_REWARDS_LIST = 0x1DB0,
+ SMSG_GUILD_ROSTER = 0x3DA3,
+ SMSG_GUILD_SET_NOTE = 0x0000,
+ SMSG_GUILD_TRADESKILL_UPDATE = 0x0000,
+ SMSG_GUILD_UPDATE_ROSTER = 0x18B0,
+ SMSG_GUILD_XP = 0x3DB0,
+ SMSG_GUILD_XP_GAIN = 0x14A1,
+ SMSG_GUILD_XP_UPDATE = 0x0000,
+ SMSG_HEALTH_UPDATE = 0x4734,
+ SMSG_HIGHEST_THREAT_UPDATE = 0x4104,
+ SMSG_HOTFIX_INFO = 0x19B5,
+ SMSG_HOTFIX_NOTIFY = 0x55A7,
+ SMSG_INITIALIZE_FACTIONS = 0x4634,
+ SMSG_INITIAL_SPELLS = 0x0104,
+ SMSG_INIT_CURRENCY = 0x15A5,
+ SMSG_INIT_WORLD_STATES = 0x4C15,
+ SMSG_INSPECT = 0x0000,
+ SMSG_INSPECT_HONOR_STATS = 0x79A5,
+ SMSG_INSPECT_RATED_BG_STATS = 0x19A5,
+ SMSG_INSPECT_RESULTS_UPDATE = 0x0C14,
+ SMSG_INSPECT_TALENT = 0x4014,
+ SMSG_INSTANCE_LOCK_WARNING_QUERY = 0x4F17,
+ SMSG_INSTANCE_RESET = 0x6F05,
+ SMSG_INSTANCE_RESET_FAILED = 0x4725,
+ SMSG_INSTANCE_SAVE_CREATED = 0x0124,
+ SMSG_INVALIDATE_DANCE = 0x0E27,
+ SMSG_INVALIDATE_PLAYER = 0x6325,
+ SMSG_INVALID_PROMOTION_CODE = 0x6F25,
+ SMSG_INVENTORY_CHANGE_FAILURE = 0x2236,
+ SMSG_ITEM_ADD_PASSIVE = 0x7CB4,
+ SMSG_ITEM_COOLDOWN = 0x4D14,
+ SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x0F27,
+ SMSG_ITEM_EXPIRE_PURCHASE_REFUND = 0x1CA0,
+ SMSG_ITEM_PUSH_RESULT = 0x0E15,
+ SMSG_ITEM_REFUND_INFO_RESPONSE = 0x15A3,
+ SMSG_ITEM_REFUND_RESULT = 0x5DB1,
+ SMSG_ITEM_REMOVE_PASSIVE = 0x39A1,
+ SMSG_ITEM_SEND_PASSIVE = 0x70B1,
+ SMSG_ITEM_TEXT_QUERY_RESPONSE = 0x2725,
+ SMSG_ITEM_TIME_UPDATE = 0x2407,
+ SMSG_JOINED_BATTLEGROUND_QUEUE = 0x0000,
+ SMSG_KICK_REASON = 0x0000,
+ SMSG_LEARNED_DANCE_MOVES = 0x0E05,
+ SMSG_LEARNED_SPELL = 0x58A2,
+ SMSG_LEVELUP_INFO = 0x0435,
+ SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x0F05,
+ SMSG_LFG_DISABLED = 0x0815,
+ SMSG_LFG_JOIN_RESULT = 0x38B6,
+ SMSG_LFG_OFFER_CONTINUE = 0x6B27,
+ SMSG_LFG_OPEN_FROM_GOSSIP = 0x0000,
+ SMSG_LFG_PARTY_INFO = 0x2325,
+ SMSG_LFG_PLAYER_INFO = 0x4B36,
+ SMSG_LFG_PLAYER_REWARD = 0x6834,
+ SMSG_LFG_PROPOSAL_UPDATE = 0x7DA6,
+ SMSG_LFG_QUEUE_STATUS = 0x78B4,
+ SMSG_LFG_ROLE_CHECK_UPDATE = 0x0336,
+ SMSG_LFG_ROLE_CHOSEN = 0x6A26,
+ SMSG_LFG_SLOT_INVALID = 0x54B5,
+ SMSG_LFG_TELEPORT_DENIED = 0x0E14,
+ SMSG_LFG_UPDATE_LIST = 0x0000,
+ SMSG_LFG_UPDATE_SEARCH = 0x54A1,
+ SMSG_LFG_UPDATE_STATUS = 0x31A4,
+ SMSG_LFG_UPDATE_STATUS_NONE = 0x7CA1,
+ SMSG_LF_GUILD_APPLICANT_LIST_UPDATED = 0x10A4,
+ SMSG_LF_GUILD_APPLICATIONS_LIST_CHANGED = 0x71A5,
+ SMSG_LF_GUILD_BROWSE_UPDATED = 0x1DA3,
+ SMSG_LF_GUILD_COMMAND_RESULT = 0x54A6,
+ SMSG_LF_GUILD_MEMBERSHIP_LIST_UPDATED = 0x1CA5,
+ SMSG_LF_GUILD_POST_UPDATED = 0x35B7,
+ SMSG_LF_GUILD_RECRUIT_LIST_UPDATED = 0x1CB2,
+ SMSG_LIST_INVENTORY = 0x7CB0,
+ SMSG_LOAD_CUF_PROFILES = 0x50B1,
+ SMSG_LOGIN_SETTIMESPEED = 0x4D15,
+ SMSG_LOGIN_VERIFY_WORLD = 0x2005,
+ SMSG_LOGOUT_CANCEL_ACK = 0x6514,
+ SMSG_LOGOUT_COMPLETE = 0x2137,
+ SMSG_LOGOUT_RESPONSE = 0x0524,
+ SMSG_LOG_XPGAIN = 0x4514,
+ SMSG_LOOT_ALL_PASSED = 0x6237,
+ SMSG_LOOT_CLEAR_MONEY = 0x2B37,
+ SMSG_LOOT_CONTENTS = 0x11B1,
+ SMSG_LOOT_ITEM_NOTIFY = 0x6D15,
+ SMSG_LOOT_LIST = 0x6807,
+ SMSG_LOOT_MASTER_LIST = 0x0325,
+ SMSG_LOOT_MONEY_NOTIFY = 0x2836,
+ SMSG_LOOT_RELEASE_RESPONSE = 0x6D25,
+ SMSG_LOOT_REMOVED = 0x6817,
+ SMSG_LOOT_RESPONSE = 0x4C16,
+ SMSG_LOOT_ROLL = 0x6507,
+ SMSG_LOOT_ROLL_WON = 0x6617,
+ SMSG_LOOT_SLOT_CHANGED = 0x2935,
+ SMSG_LOOT_START_ROLL = 0x2227,
+ SMSG_MAIL_LIST_RESULT = 0x4217,
+ SMSG_MAP_OBJ_EVENTS = 0x54B2,
+ SMSG_MEETINGSTONE_COMPLETE = 0x0000,
+ SMSG_MEETINGSTONE_IN_PROGRESS = 0x2D35,
+ SMSG_MEETINGSTONE_MEMBER_ADDED = 0x0000,
+ SMSG_MEETINGSTONE_SETQUEUE = 0x0000,
+ SMSG_MESSAGECHAT = 0x2026,
+ SMSG_MESSAGE_BOX = 0x30A1,
+ SMSG_MINIGAME_SETUP = 0x6727,
+ SMSG_MINIGAME_STATE = 0x2E17,
+ SMSG_MIRRORIMAGE_DATA = 0x2634,
+ SMSG_MISSILE_CANCEL = 0x3DB4,
+ SMSG_MODIFY_COOLDOWN = 0x6016,
+ SMSG_MONEY_NOTIFY = 0x55B6,
+ SMSG_MONSTER_MOVE = 0x6E17,
+ SMSG_MONSTER_MOVE_TRANSPORT = 0x2004,
+ SMSG_MOTD = 0x0A35,
+ SMSG_MOUNTRESULT = 0x2225,
+ SMSG_MOUNTSPECIAL_ANIM = 0x0217,
+ SMSG_MOVE_COLLISION_DISABLE = 0x31B0,
+ SMSG_MOVE_COLLISION_ENABLE = 0x11A7,
+ SMSG_MOVE_FEATHER_FALL = 0x79B0,
+ SMSG_MOVE_GRAVITY_DISABLE = 0x75B2,
+ SMSG_MOVE_GRAVITY_ENABLE = 0x30B3,
+ SMSG_MOVE_KNOCK_BACK = 0x5CB4,
+ SMSG_MOVE_LAND_WALK = 0x34B7,
+ SMSG_MOVE_NORMAL_FALL = 0x51B6,
+ SMSG_MOVE_ROOT = 0x7DA0,
+ SMSG_MOVE_SET_ACTIVE_MOVER = 0x11B3,
+ SMSG_MOVE_SET_CAN_FLY = 0x3DA1,
+ SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x59A2,
+ SMSG_MOVE_SET_COLLISION_HEIGHT = 0x11B0,
+ SMSG_MOVE_SET_COMPOUND_STATE = 0x75A0,
+ SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x30A2,
+ SMSG_MOVE_SET_FLIGHT_SPEED = 0x71A6,
+ SMSG_MOVE_SET_HOVER = 0x5CB3,
+ SMSG_MOVE_SET_PITCH_RATE = 0x75B0,
+ SMSG_MOVE_SET_RUN_BACK_SPEED = 0x71B1,
+ SMSG_MOVE_SET_RUN_SPEED = 0x3DB5,
+ SMSG_MOVE_SET_SWIM_BACK_SPEED = 0x5CA6,
+ SMSG_MOVE_SET_SWIM_SPEED = 0x15A7,
+ SMSG_MOVE_SET_TURN_RATE = 0x30A5,
+ SMSG_MOVE_SET_VEHICLE_REC_ID = 0x0000,
+ SMSG_MOVE_SET_WALK_IN_AIR = 0x0000,
+ SMSG_MOVE_SET_WALK_SPEED = 0x1DA4,
+ SMSG_MOVE_UNROOT = 0x7DB4,
+ SMSG_MOVE_UNSET_CAN_FLY = 0x15A2,
+ SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x7DB2,
+ SMSG_MOVE_UNSET_HOVER = 0x51B3,
+ SMSG_MOVE_UNSET_WALK_IN_AIR = 0x0000,
+ SMSG_MOVE_UPDATE_COLLISION_HEIGHT = 0x59A3,
+ SMSG_MOVE_UPDATE_FLIGHT_BACK_SPEED = 0x74A0,
+ SMSG_MOVE_UPDATE_FLIGHT_SPEED = 0x30B1,
+ SMSG_MOVE_UPDATE_KNOCK_BACK = 0x3DB2,
+ SMSG_MOVE_UPDATE_PITCH_RATE = 0x1DB5,
+ SMSG_MOVE_UPDATE_RUN_BACK_SPEED = 0x3DA6,
+ SMSG_MOVE_UPDATE_RUN_SPEED = 0x14A6,
+ SMSG_MOVE_UPDATE_SWIM_BACK_SPEED = 0x30B5,
+ SMSG_MOVE_UPDATE_SWIM_SPEED = 0x59B5,
+ SMSG_MOVE_UPDATE_TELEPORT = 0x50B2,
+ SMSG_MOVE_UPDATE_TURN_RATE = 0x5DA1,
+ SMSG_MOVE_UPDATE_WALK_SPEED = 0x54A2,
+ SMSG_MOVE_WATER_WALK = 0x75B1,
+ SMSG_MULTIPLE_PACKETS = 0x6736,
+ SMSG_NAME_QUERY_RESPONSE = 0x6E04,
+ SMSG_NEW_TAXI_PATH = 0x4B35,
+ SMSG_NEW_WORLD = 0x79B1,
+ SMSG_NEW_WORLD_ABORT = 0x14B7,
+ SMSG_NOTIFICATION = 0x14A0,
+ SMSG_NOTIFY_DANCE = 0x4904,
+ SMSG_NOTIFY_DEST_LOC_SPELL_CAST = 0x6204,
+ SMSG_NPC_TEXT_UPDATE = 0x4436,
+ SMSG_NPC_WONT_TALK = 0x0000,
+ SMSG_OFFER_PETITION_ERROR = 0x2716,
+ SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA = 0x4D34,
+ SMSG_OPEN_CONTAINER = 0x4714,
+ SMSG_OPEN_LFG_DUNGEON_FINDER = 0x2C37,
+ SMSG_OVERRIDE_LIGHT = 0x4225,
+ SMSG_PAGE_TEXT_QUERY_RESPONSE = 0x2B14,
+ SMSG_PARTYKILLLOG = 0x4937,
+ SMSG_PARTY_COMMAND_RESULT = 0x6E07,
+ SMSG_PARTY_MEMBER_STATS = 0x2104,
+ SMSG_PARTY_MEMBER_STATS_FULL = 0x0215,
+ SMSG_PAUSE_MIRROR_TIMER = 0x4015,
+ SMSG_PERIODICAURALOG = 0x0416,
+ SMSG_PETGODMODE = 0x2E36,
+ SMSG_PETITION_ALREADY_SIGNED = 0x5DA3,
+ SMSG_PETITION_QUERY_RESPONSE = 0x4B37,
+ SMSG_PETITION_SHOWLIST = 0x6405,
+ SMSG_PETITION_SHOW_SIGNATURES = 0x0716,
+ SMSG_PETITION_SIGN_RESULTS = 0x6217,
+ SMSG_PET_ACTION_FEEDBACK = 0x0807,
+ SMSG_PET_ACTION_SOUND = 0x4324,
+ SMSG_PET_ADDED = 0x3CA5,
+ SMSG_PET_BROKEN = 0x2E27,
+ SMSG_PET_CAST_FAILED = 0x2B15,
+ SMSG_PET_DISMISS_SOUND = 0x2B05,
+ SMSG_PET_GUIDS = 0x2D26,
+ SMSG_PET_LEARNED_SPELL = 0x0507,
+ SMSG_PET_MODE = 0x2235,
+ SMSG_PET_NAME_INVALID = 0x6007,
+ SMSG_PET_NAME_QUERY_RESPONSE = 0x4C37,
+ SMSG_PET_REMOVED_SPELL = 0x6A04,
+ SMSG_PET_RENAMEABLE = 0x2B27,
+ SMSG_PET_SLOT_UPDATED = 0x51A3,
+ SMSG_PET_SPELLS = 0x4114,
+ SMSG_PET_TAME_FAILURE = 0x6B24,
+ SMSG_PET_UPDATE_COMBO_POINTS = 0x4325,
+ SMSG_PLAYED_TIME = 0x6037,
+ SMSG_PLAYERBINDERROR = 0x6A24,
+ SMSG_PLAYERBOUND = 0x2516,
+ SMSG_PLAYER_DIFFICULTY_CHANGE = 0x2217,
+ SMSG_PLAYER_MOVE = 0x79A2,
+ SMSG_PLAYER_SKINNED = 0x0116,
+ SMSG_PLAYER_UNK_DEAD_ALIVE = 0x0000,
+ SMSG_PLAYER_VEHICLE_DATA = 0x4115,
+ SMSG_PLAY_DANCE = 0x4704,
+ SMSG_PLAY_MUSIC = 0x4B06,
+ SMSG_PLAY_OBJECT_SOUND = 0x2635,
+ SMSG_PLAY_ONE_SHOT_ANIM_KIT = 0x4A35,
+ SMSG_PLAY_SOUND = 0x2134,
+ SMSG_PLAY_SPELL_VISUAL = 0x10B1,
+ SMSG_PLAY_SPELL_VISUAL_KIT = 0x55A5,
+ SMSG_PLAY_TIME_WARNING = 0x4814,
+ SMSG_PONG = 0x4D42,
+ SMSG_POWER_UPDATE = 0x4A07,
+ SMSG_PRE_RESURRECT = 0x6C36,
+ SMSG_PROCRESIST = 0x0426,
+ SMSG_PROPOSE_LEVEL_GRANT = 0x6114,
+ SMSG_PUREMOUNT_CANCELLED_OBSOLETE = 0x0000,
+ SMSG_PVP_CREDIT = 0x6015,
+ SMSG_PVP_LOG_DATA = 0x5CB2,
+ SMSG_PVP_OPTIONS_ENABLED = 0x50A1,
+ SMSG_QUERY_QUESTS_COMPLETED_RESPONSE = 0x6314,
+ SMSG_QUERY_TIME_RESPONSE = 0x2124,
+ SMSG_QUESTGIVER_OFFER_REWARD = 0x2427,
+ SMSG_QUESTGIVER_QUEST_COMPLETE = 0x55A4,
+ SMSG_QUESTGIVER_QUEST_DETAILS = 0x2425,
+ SMSG_QUESTGIVER_QUEST_FAILED = 0x4236,
+ SMSG_QUESTGIVER_QUEST_INVALID = 0x4016,
+ SMSG_QUESTGIVER_QUEST_LIST = 0x0134,
+ SMSG_QUESTGIVER_REQUEST_ITEMS = 0x6236,
+ SMSG_QUESTGIVER_STATUS = 0x2115,
+ SMSG_QUESTGIVER_STATUS_MULTIPLE = 0x4F25,
+ SMSG_QUESTLOG_FULL = 0x0E36,
+ SMSG_QUESTUPDATE_ADD_ITEM = 0x0000,
+ SMSG_QUESTUPDATE_ADD_KILL = 0x0D27,
+ SMSG_QUESTUPDATE_ADD_PVP_KILL = 0x4416,
+ SMSG_QUESTUPDATE_COMPLETE = 0x2937,
+ SMSG_QUESTUPDATE_FAILED = 0x6324,
+ SMSG_QUESTUPDATE_FAILEDTIMER = 0x6427,
+ SMSG_QUEST_NPC_QUERY_RESPONSE = 0x75A1,
+ SMSG_QUEST_CONFIRM_ACCEPT = 0x6F07,
+ SMSG_QUEST_FORCE_REMOVE = 0x6605,
+ SMSG_QUEST_POI_QUERY_RESPONSE = 0x6304,
+ SMSG_QUEST_QUERY_RESPONSE = 0x6936,
+ SMSG_RAID_GROUP_ONLY = 0x0837,
+ SMSG_RAID_INSTANCE_INFO = 0x6626,
+ SMSG_RAID_INSTANCE_MESSAGE = 0x6E15,
+ SMSG_RAID_MARKERS_CHANGED = 0x10A1,
+ SMSG_RAID_READY_CHECK_THROTTLED_ERROR = 0x2607,
+ SMSG_RAID_SUMMON_FAILED = 0x18B6,
+ SMSG_RANDOMIZE_CHAR_NAME = 0x38B1,
+ SMSG_RATED_BG_RATING = 0x15A1,
+ SMSG_RATED_BG_STATS = 0x34A1,
+ SMSG_READ_ITEM_FAILED = 0x0F16,
+ SMSG_READ_ITEM_OK = 0x2605,
+ SMSG_REALM_SPLIT = 0x2714,
+ SMSG_REAL_GROUP_UPDATE = 0x0F34,
+ SMSG_RECEIVED_MAIL = 0x2924,
+ SMSG_REDIRECT_CLIENT = 0x0942,
+ SMSG_REFER_A_FRIEND_EXPIRED = 0x4934,
+ SMSG_REFER_A_FRIEND_FAILURE = 0x2037,
+ SMSG_REFORGE_RESULT = 0x58A4,
+ SMSG_REMOVED_SPELL = 0x4804,
+ SMSG_REPORT_PVP_AFK_RESULT = 0x2D06,
+ SMSG_REQUEST_CEMETERY_LIST_RESPONSE = 0x30A7,
+ SMSG_REQUEST_PVP_REWARDS_RESPONSE = 0x5DA4,
+ SMSG_RESEARCH_COMPLETE = 0x35A6,
+ SMSG_RESEARCH_SETUP_HISTORY = 0x10B6,
+ SMSG_RESET_COMPRESSION_CONTEXT = 0x0142,
+ SMSG_RESET_FAILED_NOTIFY = 0x4616,
+ SMSG_RESISTLOG = 0x0000,
+ SMSG_RESPOND_INSPECT_ACHIEVEMENTS = 0x15B0,
+ SMSG_RESURRECT_REQUEST = 0x2905,
+ SMSG_RESYNC_RUNES = 0x6224,
+ SMSG_ROLE_POLL_BEGIN = 0x70B0,
+ SMSG_RWHOIS = 0x2437,
+ SMSG_SELL_ITEM = 0x6105,
+ SMSG_SEND_MAIL_RESULT = 0x4927,
+ SMSG_SEND_UNLEARN_SPELLS = 0x4E25,
+ SMSG_SERVERTIME = 0x6327,
+ SMSG_SERVER_FIRST_ACHIEVEMENT = 0x6424,
+ SMSG_SERVER_INFO_RESPONSE = 0x74B5,
+ SMSG_SERVER_MESSAGE = 0x6C04,
+ SMSG_SERVER_PERF = 0x74B6,
+ SMSG_SET_AI_ANIM_KIT = 0x0000,
+ SMSG_SET_DF_FAST_LAUNCH_RESULT = 0x35B6,
+ SMSG_SET_FACTION_ATWAR = 0x4216,
+ SMSG_SET_FACTION_STANDING = 0x0126,
+ SMSG_SET_FACTION_VISIBLE = 0x2525,
+ SMSG_SET_FLAT_SPELL_MODIFIER = 0x2834,
+ SMSG_SET_FORCED_REACTIONS = 0x4615,
+ SMSG_SET_MELEE_ANIM_KIT = 0x0000,
+ SMSG_SET_MOVEMENT_ANIM_KIT = 0x0000,
+ SMSG_SET_PCT_SPELL_MODIFIER = 0x0224,
+ SMSG_SET_PHASE_SHIFT = 0x70A0,
+ SMSG_SET_PLAYER_DECLINED_NAMES_RESULT = 0x2B25,
+ SMSG_SET_PLAY_HOVER_ANIM = 0x30A6,
+ SMSG_SET_PROFICIENCY = 0x6207,
+ SMSG_SET_PROJECTILE_POSITION = 0x2616,
+ SMSG_SHOWTAXINODES = 0x2A36,
+ SMSG_SHOW_BANK = 0x2627,
+ SMSG_SHOW_MAILBOX = 0x2524,
+ SMSG_SHOW_RATINGS = 0x11B4,
+ SMSG_SOCKET_GEMS_RESULT = 0x6014,
+ SMSG_SOR_START_EXPERIENCE_INCOMPLETE = 0x7CA7,
+ SMSG_SPELLBREAKLOG = 0x6B17,
+ SMSG_SPELLDAMAGESHIELD = 0x2927,
+ SMSG_SPELLDISPELLOG = 0x4516,
+ SMSG_SPELLENERGIZELOG = 0x0414,
+ SMSG_SPELLHEALLOG = 0x2816,
+ SMSG_SPELLINSTAKILLLOG = 0x6216,
+ SMSG_SPELLINTERRUPTLOG = 0x1DA7,
+ SMSG_SPELLLOGEXECUTE = 0x0626,
+ SMSG_SPELLLOGMISS = 0x0625,
+ SMSG_SPELLNONMELEEDAMAGELOG = 0x4315,
+ SMSG_SPELLORDAMAGE_IMMUNE = 0x4507,
+ SMSG_SPELLSTEALLOG = 0x4E26,
+ SMSG_SPELL_CATEGORY_COOLDOWN = 0x71B6,
+ SMSG_SPELL_COOLDOWN = 0x4B16,
+ SMSG_SPELL_DELAYED = 0x0715,
+ SMSG_SPELL_FAILED_OTHER = 0x0C34,
+ SMSG_SPELL_FAILURE = 0x4535,
+ SMSG_SPELL_GO = 0x6E16,
+ SMSG_SPELL_START = 0x6415,
+ SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x6006,
+ SMSG_SPIRIT_HEALER_CONFIRM = 0x4917,
+ SMSG_SPLINE_MOVE_COLLISION_DISABLE = 0x35B1,
+ SMSG_SPLINE_MOVE_COLLISION_ENABLE = 0x3CB0,
+ SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x5DB5,
+ SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x3CA6,
+ SMSG_SPLINE_MOVE_ROOT = 0x51B4,
+ SMSG_SPLINE_MOVE_SET_ANIM = 0x4335,
+ SMSG_SPLINE_MOVE_SET_FEATHER_FALL = 0x3DA5,
+ SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED = 0x38B3,
+ SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED = 0x39A0,
+ SMSG_SPLINE_MOVE_SET_FLYING = 0x31B5,
+ SMSG_SPLINE_MOVE_SET_HOVER = 0x14B6,
+ SMSG_SPLINE_MOVE_SET_LAND_WALK = 0x3DA7,
+ SMSG_SPLINE_MOVE_SET_NORMAL_FALL = 0x38B2,
+ SMSG_SPLINE_MOVE_SET_PITCH_RATE = 0x14B0,
+ SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED = 0x3DB3,
+ SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x75A7,
+ SMSG_SPLINE_MOVE_SET_RUN_SPEED = 0x51B7,
+ SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED = 0x59A1,
+ SMSG_SPLINE_MOVE_SET_SWIM_SPEED = 0x39A4,
+ SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x78B5,
+ SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x54B6,
+ SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x34A5,
+ SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x50A2,
+ SMSG_SPLINE_MOVE_START_SWIM = 0x31A5,
+ SMSG_SPLINE_MOVE_STOP_SWIM = 0x1DA2,
+ SMSG_SPLINE_MOVE_UNROOT = 0x75B6,
+ SMSG_SPLINE_MOVE_UNSET_FLYING = 0x58A6,
+ SMSG_SPLINE_MOVE_UNSET_HOVER = 0x7DA5,
+ SMSG_SPLINE_MOVE_WATER_WALK = 0x50A2,
+ SMSG_STABLE_RESULT = 0x2204,
+ SMSG_STANDSTATE_UPDATE = 0x6F04,
+ SMSG_START_MIRROR_TIMER = 0x6824,
+ SMSG_START_TIMER = 0x59A5,
+ SMSG_STOP_DANCE = 0x4637,
+ SMSG_STOP_MIRROR_TIMER = 0x0B06,
+ SMSG_STREAMING_MOVIE = 0x15B7,
+ SMSG_SUMMON_CANCEL = 0x0B34,
+ SMSG_SUMMON_REQUEST = 0x2A07,
+ SMSG_SUPERCEDED_SPELL = 0x35B0,
+ SMSG_SUPPRESS_NPC_GREETINGS = 0x74B1,
+ SMSG_SUSPEND_COMMS = 0x4140,
+ SMSG_SUSPEND_TOKEN_RESPONSE = 0x14B1,
+ SMSG_TALENTS_ERROR = 0x0916,
+ SMSG_TALENTS_INFO = 0x6F26,
+ SMSG_TALENTS_INVOLUNTARILY_RESET = 0x2C27,
+ SMSG_TAXINODE_STATUS = 0x2936,
+ SMSG_TEST_DROP_RATE_RESULT = 0x6816,
+ SMSG_TEXT_EMOTE = 0x0B05,
+ SMSG_THREAT_CLEAR = 0x6437,
+ SMSG_THREAT_REMOVE = 0x2E05,
+ SMSG_THREAT_UPDATE = 0x4735,
+ SMSG_TIME_ADJUSTMENT = 0x79B7,
+ SMSG_TIME_SYNC_REQ = 0x3CA4,
+ SMSG_TITLE_EARNED = 0x2426,
+ SMSG_TOGGLE_XP_GAIN = 0x6704,
+ SMSG_TOTEM_CREATED = 0x2414,
+ SMSG_TRADE_STATUS = 0x5CA3,
+ SMSG_TRADE_STATUS_EXTENDED = 0x70A2,
+ SMSG_TRAINER_BUY_FAILED = 0x0004,
+ SMSG_TRAINER_BUY_SUCCEEDED = 0x6A05,
+ SMSG_TRAINER_LIST = 0x4414,
+ SMSG_TRANSFER_ABORTED = 0x0537,
+ SMSG_TRANSFER_PENDING = 0x18A6,
+ SMSG_TRIGGER_CINEMATIC = 0x6C27,
+ SMSG_TRIGGER_MOVIE = 0x4625,
+ SMSG_TURN_IN_PETITION_RESULTS = 0x0F07,
+ SMSG_TUTORIAL_FLAGS = 0x0B35,
+ SMSG_UNIT_HEALTH_FREQUENT = 0x2C26,
+ SMSG_UNIT_SPELLCAST_START = 0x2517,
+ SMSG_UPDATE_ACCOUNT_DATA = 0x6837,
+ SMSG_UPDATE_ACCOUNT_DATA_COMPLETE = 0x2015,
+ SMSG_UPDATE_COMBO_POINTS = 0x6B34,
+ SMSG_UPDATE_CURRENCY = 0x59B0,
+ SMSG_UPDATE_CURRENCY_WEEK_LIMIT = 0x70A7,
+ SMSG_UPDATE_DUNGEON_ENCOUNTER_FOR_LOOT = 0x3CB5,
+ SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT = 0x4007,
+ SMSG_UPDATE_INSTANCE_OWNERSHIP = 0x4915,
+ SMSG_UPDATE_LAST_INSTANCE = 0x0437,
+ SMSG_UPDATE_OBJECT = 0x4715,
+ SMSG_UPDATE_SERVER_PLAYER_POSITION = 0x74A3,
+ SMSG_UPDATE_WORLD_STATE = 0x4816,
+ SMSG_USERLIST_ADD = 0x0F37,
+ SMSG_USERLIST_REMOVE = 0x2006,
+ SMSG_USERLIST_UPDATE = 0x0135,
+ SMSG_VOICESESSION_FULL = 0x6225,
+ SMSG_VOICE_CHAT_STATUS = 0x0F15,
+ SMSG_VOICE_PARENTAL_CONTROLS = 0x0534,
+ SMSG_VOICE_SESSION_LEAVE = 0x2A24,
+ SMSG_VOICE_SESSION_ROSTER_UPDATE = 0x2A17,
+ SMSG_VOICE_SET_TALKER_MUTED = 0x6E35,
+ SMSG_VOID_ITEM_SWAP_RESPONSE = 0x78A2,
+ SMSG_VOID_STORAGE_CONTENTS = 0x75B4,
+ SMSG_VOID_STORAGE_FAILED = 0x18A7,
+ SMSG_VOID_STORAGE_TRANSFER_CHANGES = 0x51A6,
+ SMSG_VOID_TRANSFER_RESULT = 0x1DA6,
+ SMSG_WAIT_QUEUE_FINISH = 0x75B7,
+ SMSG_WAIT_QUEUE_UPDATE = 0x58A1,
+ SMSG_WARDEN_DATA = 0x31A0,
+ SMSG_WARGAME_CHECK_ENTRY = 0x3DA4,
+ SMSG_WARGAME_REQUEST_SENT = 0x59B2,
+ SMSG_WEATHER = 0x2904,
+ SMSG_WEEKLY_LAST_RESET = 0x50A5,
+ SMSG_WEEKLY_RESET_CURRENCY = 0x3CA1,
+ SMSG_WEEKLY_SPELL_USAGE = 0x39B7,
+ SMSG_WEEKLY_SPELL_USAGE_UPDATE = 0x11B5,
+ SMSG_WHO = 0x6907,
+ SMSG_WHOIS = 0x6917,
+ SMSG_WORLD_SERVER_INFO = 0x31A2,
+ SMSG_WORLD_STATE_UI_TIMER_UPDATE = 0x4A14,
+ SMSG_XP_GAIN_ABORTED = 0x50B4,
+ SMSG_ZONE_UNDER_ATTACK = 0x0A06,
};
/// Player state
@@ -1367,29 +1396,80 @@ enum PacketProcessing
};
class WorldPacket;
+class WorldSession;
+
+typedef void(WorldSession::*pOpcodeHandler)(WorldPacket& recvPacket);
struct OpcodeHandler
{
- char const* name;
- SessionStatus status;
- PacketProcessing packetProcessing;
- void (WorldSession::*handler)(WorldPacket& recvPacket);
-};
+ OpcodeHandler() {}
+ OpcodeHandler(char const* _name, SessionStatus _status, PacketProcessing _processing, pOpcodeHandler _handler)
+ : Handler(_handler), Name(_name), Status(_status), ProcessingPlace(_processing) {}
-extern OpcodeHandler opcodeTable[NUM_MSG_TYPES];
+ pOpcodeHandler Handler;
+ char const* Name;
+ SessionStatus Status;
+ PacketProcessing ProcessingPlace;
+};
-/// Lookup opcode name for human understandable logging
-inline const char* LookupOpcodeName(uint16 id)
+class OpcodeTable
{
- if (id >= NUM_MSG_TYPES)
- return "Received unknown opcode, it's more than max!";
- return opcodeTable[id].name;
-}
+ public:
+ OpcodeTable()
+ {
+ memset(_internalTable, 0, sizeof(_internalTable));
+ }
+
+ ~OpcodeTable()
+ {
+ for (uint16 i = 0; i < NUM_OPCODE_HANDLERS; ++i)
+ delete _internalTable[i];
+ }
+
+ void Initialize();
+
+ OpcodeHandler const* operator[](uint32 index) const
+ {
+ return _internalTable[index];
+ }
-inline std::string GetOpcodeNameForLogging(uint16 opcode)
+ private:
+ template<bool isInValidRange, bool isNonZero>
+ void ValidateAndSetOpcode(uint16 opcode, char const* name, SessionStatus status, PacketProcessing processing, pOpcodeHandler handler);
+
+ // Prevent copying this structure
+ OpcodeTable(OpcodeTable const&);
+ OpcodeTable& operator=(OpcodeTable const&);
+
+ OpcodeHandler* _internalTable[NUM_OPCODE_HANDLERS];
+};
+
+extern OpcodeTable opcodeTable;
+
+void InitOpcodes();
+
+/// Lookup opcode name for human understandable logging
+inline std::string GetOpcodeNameForLogging(Opcodes id)
{
+ uint32 opcode = uint32(id);
std::ostringstream ss;
- ss << '[' << LookupOpcodeName(opcode) << " 0x" << std::hex << std::uppercase << opcode << std::nouppercase << " (" << std::dec << opcode << ")]";
+ ss << '[';
+
+ if (id < UNKNOWN_OPCODE)
+ {
+ if (OpcodeHandler const* handler = opcodeTable[uint32(id) & 0x7FFF])
+ {
+ ss << handler->Name;
+ if (opcode & COMPRESSED_OPCODE_MASK)
+ ss << "_COMPRESSED";
+ }
+ else
+ ss << "UNKNOWN OPCODE";
+ }
+ else
+ ss << "INVALID OPCODE";
+
+ ss << " 0x" << std::hex << std::uppercase << opcode << std::nouppercase << " (" << std::dec << opcode << ")]";
return ss.str();
}
diff --git a/src/server/game/Server/WorldPacket.cpp b/src/server/game/Server/WorldPacket.cpp
new file mode 100644
index 00000000000..0658973f320
--- /dev/null
+++ b/src/server/game/Server/WorldPacket.cpp
@@ -0,0 +1,106 @@
+/*
+ * 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 <zlib.h>
+#include "WorldPacket.h"
+#include "World.h"
+
+//! Compresses packet in place
+void WorldPacket::Compress(z_stream* compressionStream)
+{
+ Opcodes uncompressedOpcode = GetOpcode();
+ if (uncompressedOpcode & COMPRESSED_OPCODE_MASK)
+ {
+ TC_LOG_ERROR("network", "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode);
+ return;
+ }
+
+ Opcodes opcode = Opcodes(uncompressedOpcode | COMPRESSED_OPCODE_MASK);
+ uint32 size = wpos();
+ uint32 destsize = compressBound(size);
+
+ std::vector<uint8> storage(destsize);
+
+ _compressionStream = compressionStream;
+ Compress(static_cast<void*>(&storage[0]), &destsize, static_cast<const void*>(contents()), size);
+ if (destsize == 0)
+ return;
+
+ clear();
+ reserve(destsize + sizeof(uint32));
+ *this << uint32(size);
+ append(&storage[0], destsize);
+ SetOpcode(opcode);
+ TC_LOG_INFO("network", "%s (len %u) successfully compressed to %04X (len %u)", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, opcode, destsize);
+}
+
+//! Compresses another packet and stores it in self (source left intact)
+void WorldPacket::Compress(z_stream* compressionStream, WorldPacket const* source)
+{
+ ASSERT(source != this);
+
+ Opcodes uncompressedOpcode = source->GetOpcode();
+ if (uncompressedOpcode & COMPRESSED_OPCODE_MASK)
+ {
+ TC_LOG_ERROR("network", "Packet with opcode 0x%04X is already compressed!", uncompressedOpcode);
+ return;
+ }
+
+ Opcodes opcode = Opcodes(uncompressedOpcode | COMPRESSED_OPCODE_MASK);
+ uint32 size = source->size();
+ uint32 destsize = compressBound(size);
+
+ size_t sizePos = 0;
+ resize(destsize + sizeof(uint32));
+
+ _compressionStream = compressionStream;
+ Compress(static_cast<void*>(&_storage[0] + sizeof(uint32)), &destsize, static_cast<const void*>(source->contents()), size);
+ if (destsize == 0)
+ return;
+
+ put<uint32>(sizePos, size);
+ resize(destsize + sizeof(uint32));
+
+ SetOpcode(opcode);
+
+ TC_LOG_INFO("network", "%s (len %u) successfully compressed to %04X (len %u)", GetOpcodeNameForLogging(uncompressedOpcode).c_str(), size, opcode, destsize);
+}
+
+void WorldPacket::Compress(void* dst, uint32 *dst_size, const void* src, int src_size)
+{
+ _compressionStream->next_out = (Bytef*)dst;
+ _compressionStream->avail_out = *dst_size;
+ _compressionStream->next_in = (Bytef*)src;
+ _compressionStream->avail_in = (uInt)src_size;
+
+ int32 z_res = deflate(_compressionStream, Z_SYNC_FLUSH);
+ if (z_res != Z_OK)
+ {
+ TC_LOG_ERROR("network", "Can't compress packet (zlib: deflate) Error code: %i (%s, msg: %s)", z_res, zError(z_res), _compressionStream->msg);
+ *dst_size = 0;
+ return;
+ }
+
+ if (_compressionStream->avail_in != 0)
+ {
+ TC_LOG_ERROR("network", "Can't compress packet (zlib: deflate not greedy)");
+ *dst_size = 0;
+ return;
+ }
+
+ *dst_size -= _compressionStream->avail_out;
+}
diff --git a/src/server/shared/Packets/WorldPacket.h b/src/server/game/Server/WorldPacket.h
index 6703c5ed2ea..e2498e64f0a 100644
--- a/src/server/shared/Packets/WorldPacket.h
+++ b/src/server/game/Server/WorldPacket.h
@@ -20,33 +20,43 @@
#define TRINITYCORE_WORLDPACKET_H
#include "Common.h"
+#include "Opcodes.h"
#include "ByteBuffer.h"
+struct z_stream_s;
+
class WorldPacket : public ByteBuffer
{
public:
// just container for later use
- WorldPacket() : ByteBuffer(0), m_opcode(0)
+ WorldPacket() : ByteBuffer(0), m_opcode(UNKNOWN_OPCODE)
+ {
+ }
+
+ WorldPacket(Opcodes opcode, size_t res = 200) : ByteBuffer(res), m_opcode(opcode)
{
}
- explicit WorldPacket(uint16 opcode, size_t res=200) : ByteBuffer(res), m_opcode(opcode) { }
// copy constructor
- WorldPacket(const WorldPacket &packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
+ WorldPacket(WorldPacket const& packet) : ByteBuffer(packet), m_opcode(packet.m_opcode)
{
}
- void Initialize(uint16 opcode, size_t newres=200)
+ void Initialize(Opcodes opcode, size_t newres = 200)
{
clear();
_storage.reserve(newres);
m_opcode = opcode;
}
- uint16 GetOpcode() const { return m_opcode; }
- void SetOpcode(uint16 opcode) { m_opcode = opcode; }
+ Opcodes GetOpcode() const { return m_opcode; }
+ void SetOpcode(Opcodes opcode) { m_opcode = opcode; }
+ void Compress(z_stream_s* compressionStream);
+ void Compress(z_stream_s* compressionStream, WorldPacket const* source);
protected:
- uint16 m_opcode;
+ Opcodes m_opcode;
+ void Compress(void* dst, uint32 *dst_size, const void* src, int src_size);
+ z_stream_s* _compressionStream;
};
#endif
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 58e7ba02f47..a99695206ad 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -21,6 +21,7 @@
*/
#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it
+#include <zlib.h>
#include "Config.h"
#include "Common.h"
#include "DatabaseEnv.h"
@@ -55,14 +56,15 @@ std::string const DefaultPlayerName = "<none>";
bool MapSessionFilter::Process(WorldPacket* packet)
{
- OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
+ Opcodes opcode = DropHighBytes(packet->GetOpcode());
+ OpcodeHandler const* opHandle = opcodeTable[opcode];
//let's check if our opcode can be really processed in Map::Update()
- if (opHandle.packetProcessing == PROCESS_INPLACE)
+ if (opHandle->ProcessingPlace == PROCESS_INPLACE)
return true;
//we do not process thread-unsafe packets
- if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
+ if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
return false;
Player* player = m_pSession->GetPlayer();
@@ -77,13 +79,14 @@ bool MapSessionFilter::Process(WorldPacket* packet)
//OR packet handler is not thread-safe!
bool WorldSessionFilter::Process(WorldPacket* packet)
{
- OpcodeHandler const& opHandle = opcodeTable[packet->GetOpcode()];
+ Opcodes opcode = DropHighBytes(packet->GetOpcode());
+ OpcodeHandler const* opHandle = opcodeTable[opcode];
//check if packet handler is supposed to be safe
- if (opHandle.packetProcessing == PROCESS_INPLACE)
+ if (opHandle->ProcessingPlace == PROCESS_INPLACE)
return true;
//thread-unsafe packets should be processed in World::UpdateSessions()
- if (opHandle.packetProcessing == PROCESS_THREADUNSAFE)
+ if (opHandle->ProcessingPlace == PROCESS_THREADUNSAFE)
return true;
//no player attached? -> our client! ^^
@@ -118,6 +121,7 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
m_latency(0),
m_clientTimeDelay(0),
m_TutorialsChanged(false),
+ _filterAddonMessages(false),
recruiterId(recruiter),
isRecruiter(isARecruiter),
timeLastWhoCommand(0),
@@ -134,6 +138,16 @@ WorldSession::WorldSession(uint32 id, WorldSocket* sock, AccountTypes sec, uint8
}
InitializeQueryCallbackParameters();
+
+ _compressionStream = new z_stream();
+ _compressionStream->zalloc = (alloc_func)NULL;
+ _compressionStream->zfree = (free_func)NULL;
+ _compressionStream->opaque = (voidpf)NULL;
+ _compressionStream->avail_in = 0;
+ _compressionStream->next_in = NULL;
+ int32 z_res = deflateInit(_compressionStream, sWorld->getIntConfig(CONFIG_COMPRESSION));
+ if (z_res != Z_OK)
+ TC_LOG_ERROR("network", "Can't initialize packet compression (zlib: deflateInit) Error code: %i (%s)", z_res, zError(z_res));
}
/// WorldSession destructor
@@ -160,6 +174,12 @@ WorldSession::~WorldSession()
delete packet;
LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); // One-time query
+
+ int32 z_res = deflateEnd(_compressionStream);
+ if (z_res != Z_OK && z_res != Z_DATA_ERROR) // Z_DATA_ERROR signals that internal state was BUSY
+ TC_LOG_ERROR("network", "Can't close packet compression stream (zlib: deflateEnd) Error code: %i (%s)", z_res, zError(z_res));
+
+ delete _compressionStream;
}
std::string const & WorldSession::GetPlayerName() const
@@ -185,11 +205,32 @@ uint32 WorldSession::GetGuidLow() const
}
/// Send a packet to the client
-void WorldSession::SendPacket(WorldPacket const* packet)
+void WorldSession::SendPacket(WorldPacket const* packet, bool forced /*= false*/)
{
if (!m_Socket)
return;
+ if (packet->GetOpcode() == NULL_OPCODE)
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending of NULL_OPCODE to %s", GetPlayerInfo().c_str());
+ return;
+ }
+ else if (packet->GetOpcode() == UNKNOWN_OPCODE)
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending of UNKNOWN_OPCODE to %s", GetPlayerInfo().c_str());
+ return;
+ }
+
+ if (!forced)
+ {
+ OpcodeHandler const* handler = opcodeTable[packet->GetOpcode()];
+ if (!handler || handler->Status == STATUS_UNHANDLED)
+ {
+ TC_LOG_ERROR("network.opcode", "Prevented sending disabled opcode %s to %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str(), GetPlayerInfo().c_str());
+ return;
+ }
+ }
+
#ifdef TRINITY_DEBUG
// Code for network use statistic
static uint64 sendPacketCount = 0;
@@ -282,107 +323,97 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
_recvQueue.next(packet, updater))
{
if (!AntiDOS.EvaluateOpcode(*packet))
- {
KickPlayer();
- }
- else if (packet->GetOpcode() >= NUM_MSG_TYPES)
- {
- TC_LOG_ERROR("network.opcode", "Received non-existed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
- , GetPlayerInfo().c_str());
- sScriptMgr->OnUnknownPacketReceive(m_Socket, WorldPacket(*packet));
- }
- else
+
+ OpcodeHandler const* opHandle = opcodeTable[packet->GetOpcode()];
+ try
{
- OpcodeHandler &opHandle = opcodeTable[packet->GetOpcode()];
- try
+ switch (opHandle->Status)
{
- switch (opHandle.status)
- {
- case STATUS_LOGGEDIN:
- if (!_player)
+ case STATUS_LOGGEDIN:
+ if (!_player)
+ {
+ // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
+ //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
+ //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
+ if (!m_playerRecentlyLogout)
{
- // skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
- //! If player didn't log out a while ago, it means packets are being sent while the server does not recognize
- //! the client to be in world yet. We will re-add the packets to the bottom of the queue and process them later.
- if (!m_playerRecentlyLogout)
- {
- //! Prevent infinite loop
- if (!firstDelayedPacket)
- firstDelayedPacket = packet;
- //! Because checking a bool is faster than reallocating memory
- deletePacket = false;
- QueuePacket(packet);
- //! Log
+ //! Prevent infinite loop
+ if (!firstDelayedPacket)
+ firstDelayedPacket = packet;
+ //! Because checking a bool is faster than reallocating memory
+ deletePacket = false;
+ QueuePacket(packet);
+ //! Log
TC_LOG_DEBUG("network", "Re-enqueueing packet with opcode %s with with status STATUS_LOGGEDIN. "
"Player is currently not in world yet.", GetOpcodeNameForLogging(packet->GetOpcode()).c_str());
- }
- }
- else if (_player->IsInWorld())
- {
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
}
- // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
- break;
- case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
- if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
- LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
- "the player has not logged in yet and not recently logout");
- else
- {
- // not expected _player or must checked in packet handler
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- break;
- case STATUS_TRANSFER:
- if (!_player)
- LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
- else if (_player->IsInWorld())
- LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
- else
- {
- sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
- (this->*opHandle.handler)(*packet);
- LogUnprocessedTail(packet);
- }
- break;
- case STATUS_AUTHED:
- // prevent cheating with skip queue wait
- if (m_inQueue)
- {
- LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
- break;
- }
-
- // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
- // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
- if (packet->GetOpcode() == CMSG_CHAR_ENUM)
- m_playerRecentlyLogout = false;
-
+ }
+ else if (_player->IsInWorld())
+ {
+ sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ (this->*opHandle->Handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ // lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
+ break;
+ case STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT:
+ if (!_player && !m_playerRecentlyLogout && !m_playerLogout) // There's a short delay between _player = null and m_playerRecentlyLogout = true during logout
+ LogUnexpectedOpcode(packet, "STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT",
+ "the player has not logged in yet and not recently logout");
+ else
+ {
+ // not expected _player or must checked in packet hanlder
+ sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ (this->*opHandle->Handler)(*packet);
+ LogUnprocessedTail(packet);
+ }
+ break;
+ case STATUS_TRANSFER:
+ if (!_player)
+ LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player has not logged in yet");
+ else if (_player->IsInWorld())
+ LogUnexpectedOpcode(packet, "STATUS_TRANSFER", "the player is still in world");
+ else
+ {
sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
- (this->*opHandle.handler)(*packet);
+ (this->*opHandle->Handler)(*packet);
LogUnprocessedTail(packet);
+ }
+ break;
+ case STATUS_AUTHED:
+ // prevent cheating with skip queue wait
+ if (m_inQueue)
+ {
+ LogUnexpectedOpcode(packet, "STATUS_AUTHED", "the player not pass queue yet");
break;
- case STATUS_NEVER:
+ }
+
+ // some auth opcodes can be recieved before STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT opcodes
+ // however when we recieve CMSG_CHAR_ENUM we are surely no longer during the logout process.
+ if (packet->GetOpcode() == CMSG_CHAR_ENUM)
+ m_playerRecentlyLogout = false;
+
+ sScriptMgr->OnPacketReceive(m_Socket, WorldPacket(*packet));
+ (this->*opHandle->Handler)(*packet);
+ LogUnprocessedTail(packet);
+ break;
+ case STATUS_NEVER:
TC_LOG_ERROR("network.opcode", "Received not allowed opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
, GetPlayerInfo().c_str());
- break;
- case STATUS_UNHANDLED:
- TC_LOG_DEBUG("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
+ break;
+ case STATUS_UNHANDLED:
+ TC_LOG_ERROR("network.opcode", "Received not handled opcode %s from %s", GetOpcodeNameForLogging(packet->GetOpcode()).c_str()
, GetPlayerInfo().c_str());
- break;
- }
- }
- catch (ByteBufferException const&)
- {
- TC_LOG_ERROR("misc", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
- packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
- packet->hexlike();
+ break;
}
}
+ catch (ByteBufferException const&)
+ {
+ TC_LOG_ERROR("network", "WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
+ packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
+ packet->hexlike();
+ }
if (deletePacket)
delete packet;
@@ -590,8 +621,11 @@ void WorldSession::SendNotification(const char *format, ...)
vsnprintf(szStr, 1024, format, ap);
va_end(ap);
- WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
- data << szStr;
+ size_t len = strlen(szStr);
+ WorldPacket data(SMSG_NOTIFICATION, 2 + len);
+ data.WriteBits(len, 13);
+ data.FlushBits();
+ data.append(szStr, len);
SendPacket(&data);
}
}
@@ -608,8 +642,11 @@ void WorldSession::SendNotification(uint32 string_id, ...)
vsnprintf(szStr, 1024, format, ap);
va_end(ap);
- WorldPacket data(SMSG_NOTIFICATION, (strlen(szStr) + 1));
- data << szStr;
+ size_t len = strlen(szStr);
+ WorldPacket data(SMSG_NOTIFICATION, 2 + len);
+ data.WriteBits(len, 13);
+ data.FlushBits();
+ data.append(szStr, len);
SendPacket(&data);
}
}
@@ -648,15 +685,21 @@ void WorldSession::SendAuthWaitQue(uint32 position)
if (position == 0)
{
WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
+ packet.WriteBit(0); // has queue info
+ packet.WriteBit(0); // has account info
+ packet.FlushBits();
packet << uint8(AUTH_OK);
SendPacket(&packet);
}
else
{
WorldPacket packet(SMSG_AUTH_RESPONSE, 6);
+ packet.WriteBit(1); // has queue info
+ packet.WriteBit(0); // unk queue bool
+ packet.WriteBit(0); // has account info
+ packet.FlushBits();
packet << uint8(AUTH_WAIT_QUEUE);
packet << uint32(position);
- packet << uint8(0); // unk
SendPacket(&packet);
}
}
@@ -782,156 +825,6 @@ void WorldSession::SaveTutorialsData(SQLTransaction &trans)
m_TutorialsChanged = false;
}
-void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi)
-{
- data >> mi->flags;
- data >> mi->flags2;
- data >> mi->time;
- data >> mi->pos.PositionXYZOStream();
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
- {
- data.readPackGUID(mi->transport.guid);
-
- data >> mi->transport.pos.PositionXYZOStream();
- data >> mi->transport.time;
- data >> mi->transport.seat;
-
- if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
- data >> mi->transport.time2;
- }
-
- if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || (mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING)))
- data >> mi->pitch;
-
- data >> mi->fallTime;
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING))
- {
- data >> mi->jump.zspeed;
- data >> mi->jump.sinAngle;
- data >> mi->jump.cosAngle;
- data >> mi->jump.xyspeed;
- }
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
- data >> mi->splineElevation;
-
- //! Anti-cheat checks. Please keep them in seperate if () blocks to maintain a clear overview.
- //! Might be subject to latency, so just remove improper flags.
- #ifdef TRINITY_DEBUG
- #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
- { \
- if (check) \
- { \
- TC_LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found (%s). " \
- "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \
- STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUIDLow(), maskToRemove); \
- mi->RemoveMovementFlag((maskToRemove)); \
- } \
- }
- #else
- #define REMOVE_VIOLATING_FLAGS(check, maskToRemove) \
- if (check) \
- mi->RemoveMovementFlag((maskToRemove));
- #endif
-
-
- /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid
- in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD.
- It will freeze clients that receive this player's movement info.
- */
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT),
- MOVEMENTFLAG_ROOT);
-
- //! Cannot hover without SPELL_AURA_HOVER
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER),
- MOVEMENTFLAG_HOVER);
-
- //! Cannot ascend and descend at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ASCENDING) && mi->HasMovementFlag(MOVEMENTFLAG_DESCENDING),
- MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING);
-
- //! Cannot move left and right at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_RIGHT),
- MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT);
-
- //! Cannot strafe left and right at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_LEFT) && mi->HasMovementFlag(MOVEMENTFLAG_STRAFE_RIGHT),
- MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT);
-
- //! Cannot pitch up and down at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_PITCH_UP) && mi->HasMovementFlag(MOVEMENTFLAG_PITCH_DOWN),
- MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN);
-
- //! Cannot move forwards and backwards at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FORWARD) && mi->HasMovementFlag(MOVEMENTFLAG_BACKWARD),
- MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD);
-
- //! Cannot walk on water without SPELL_AURA_WATER_WALK
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_WATERWALKING) && !GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK),
- MOVEMENTFLAG_WATERWALKING);
-
- //! Cannot feather fall without SPELL_AURA_FEATHER_FALL
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FALLING_SLOW) && !GetPlayer()->HasAuraType(SPELL_AURA_FEATHER_FALL),
- MOVEMENTFLAG_FALLING_SLOW);
-
- /*! Cannot fly if no fly auras present. Exception is being a GM.
- Note that we check for account level instead of Player::IsGameMaster() because in some
- situations it may be feasable to use .gm fly on as a GM without having .gm on,
- e.g. aerial combat.
- */
-
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY) && GetSecurity() == SEC_PLAYER &&
- !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_FLY) &&
- !GetPlayer()->m_mover->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED),
- MOVEMENTFLAG_FLYING | MOVEMENTFLAG_CAN_FLY);
-
- //! Cannot fly and fall at the same time
- REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY) && mi->HasMovementFlag(MOVEMENTFLAG_FALLING),
- MOVEMENTFLAG_FALLING);
-
- #undef REMOVE_VIOLATING_FLAGS
-}
-
-void WorldSession::WriteMovementInfo(WorldPacket* data, MovementInfo* mi)
-{
- data->appendPackGUID(mi->guid);
-
- *data << mi->flags;
- *data << mi->flags2;
- *data << mi->time;
- *data << mi->pos.PositionXYZOStream();
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
- {
- data->appendPackGUID(mi->transport.guid);
-
- *data << mi->transport.pos.PositionXYZOStream();
- *data << mi->transport.time;
- *data << mi->transport.seat;
-
- if (mi->HasExtraMovementFlag(MOVEMENTFLAG2_INTERPOLATED_MOVEMENT))
- *data << mi->transport.time2;
- }
-
- if (mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING)) || mi->HasExtraMovementFlag(MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING))
- *data << mi->pitch;
-
- *data << mi->fallTime;
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_FALLING))
- {
- *data << mi->jump.zspeed;
- *data << mi->jump.sinAngle;
- *data << mi->jump.cosAngle;
- *data << mi->jump.xyspeed;
- }
-
- if (mi->HasMovementFlag(MOVEMENTFLAG_SPLINE_ELEVATION))
- *data << mi->splineElevation;
-}
-
void WorldSession::ReadAddonsInfo(WorldPacket &data)
{
if (data.rpos() + 4 > data.size())
@@ -1072,6 +965,57 @@ void WorldSession::SendAddonsInfo()
SendPacket(&data);
}
+bool WorldSession::IsAddonRegistered(const std::string& prefix) const
+{
+ if (!_filterAddonMessages) // if we have hit the softcap (64) nothing should be filtered
+ return true;
+
+ if (_registeredAddonPrefixes.empty())
+ return false;
+
+ std::vector<std::string>::const_iterator itr = std::find(_registeredAddonPrefixes.begin(), _registeredAddonPrefixes.end(), prefix);
+ return itr != _registeredAddonPrefixes.end();
+}
+
+void WorldSession::HandleUnregisterAddonPrefixesOpcode(WorldPacket& /*recvPacket*/) // empty packet
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_UNREGISTER_ALL_ADDON_PREFIXES");
+
+ _registeredAddonPrefixes.clear();
+}
+
+void WorldSession::HandleAddonRegisteredPrefixesOpcode(WorldPacket& recvPacket)
+{
+ TC_LOG_DEBUG("network", "WORLD: Received CMSG_ADDON_REGISTERED_PREFIXES");
+
+ // This is always sent after CMSG_UNREGISTER_ALL_ADDON_PREFIXES
+
+ uint32 count = recvPacket.ReadBits(25);
+
+ if (count > REGISTERED_ADDON_PREFIX_SOFTCAP)
+ {
+ // if we have hit the softcap (64) nothing should be filtered
+ _filterAddonMessages = false;
+ recvPacket.rfinish();
+ return;
+ }
+
+ std::vector<uint8> lengths(count);
+ for (uint32 i = 0; i < count; ++i)
+ lengths[i] = recvPacket.ReadBits(5);
+
+ for (uint32 i = 0; i < count; ++i)
+ _registeredAddonPrefixes.push_back(recvPacket.ReadString(lengths[i]));
+
+ if (_registeredAddonPrefixes.size() > REGISTERED_ADDON_PREFIX_SOFTCAP) // shouldn't happen
+ {
+ _filterAddonMessages = false;
+ return;
+ }
+
+ _filterAddonMessages = true;
+}
+
void WorldSession::SetPlayer(Player* player)
{
_player = player;
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 904006e174d..336e28ea0fe 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -30,6 +30,7 @@
#include "World.h"
#include "WorldPacket.h"
#include "Cryptography/BigNumber.h"
+#include "Opcodes.h"
#include "AccountMgr.h"
class Creature;
@@ -84,6 +85,8 @@ enum AccountDataType
#define GLOBAL_CACHE_MASK 0x15
#define PER_CHARACTER_CACHE_MASK 0xEA
+#define REGISTERED_ADDON_PREFIX_SOFTCAP 64
+
struct AccountData
{
AccountData() : Time(0), Data("") { }
@@ -119,12 +122,15 @@ enum ChatRestrictionType
enum CharterTypes
{
- GUILD_CHARTER_TYPE = 9,
+ GUILD_CHARTER_TYPE = 4,
ARENA_TEAM_CHARTER_2v2_TYPE = 2,
ARENA_TEAM_CHARTER_3v3_TYPE = 3,
- ARENA_TEAM_CHARTER_5v5_TYPE = 5
+ ARENA_TEAM_CHARTER_5v5_TYPE = 5,
};
+#define DB2_REPLY_SPARSE 2442913102
+#define DB2_REPLY_ITEM 1344507586
+
//class to deal with packet processing
//allows to determine if next packet is safe to be processed
class PacketFilter
@@ -135,6 +141,7 @@ public:
virtual bool Process(WorldPacket* /*packet*/) { return true; }
virtual bool ProcessLogout() const { return true; }
+ static Opcodes DropHighBytes(Opcodes opcode) { return Opcodes(opcode & 0xFFFF); }
protected:
WorldSession* const m_pSession;
@@ -206,20 +213,18 @@ class WorldSession
void ReadAddonsInfo(WorldPacket& data);
void SendAddonsInfo();
+ bool IsAddonRegistered(const std::string& prefix) const;
- void ReadMovementInfo(WorldPacket& data, MovementInfo* mi);
- void WriteMovementInfo(WorldPacket* data, MovementInfo* mi);
-
- void SendPacket(WorldPacket const* packet);
+ void SendPacket(WorldPacket const* packet, bool forced = false);
void SendNotification(const char *format, ...) ATTR_PRINTF(2, 3);
void SendNotification(uint32 string_id, ...);
void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName);
void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3);
- void SendSetPhaseShift(uint32 phaseShift);
+ void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps);
void SendQueryTimeResponse();
- void SendAuthResponse(uint8 code, bool shortForm, uint32 queuePos = 0);
+ void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0);
void SendClientCacheVersion(uint32 version);
rbac::RBACData* GetRBACData();
@@ -271,12 +276,12 @@ class WorldSession
//void SendTestCreatureQueryOpcode(uint32 entry, uint64 guid, uint32 testvalue);
void SendNameQueryOpcode(uint64 guid);
+ bool CanOpenMailBox(uint64 guid);
+
void SendTrainerList(uint64 guid);
void SendTrainerList(uint64 guid, std::string const& strTitle);
void SendListInventory(uint64 guid);
void SendShowBank(uint64 guid);
- bool CanOpenMailBox(uint64 guid);
- void SendShowMailBox(uint64 guid);
void SendTabardVendorActivate(uint64 guid);
void SendSpiritResurrect();
void SendBindPoint(Creature* npc);
@@ -324,9 +329,10 @@ class WorldSession
bool SendItemInfo(uint32 itemid, WorldPacket data);
//auction
void SendAuctionHello(uint64 guid, Creature* unit);
- void SendAuctionCommandResult(uint32 auctionId, uint32 Action, uint32 ErrorCode, uint32 bidError = 0);
+ void SendAuctionCommandResult(AuctionEntry* auction, uint32 Action, uint32 ErrorCode, uint32 bidError = 0);
void SendAuctionBidderNotification(uint32 location, uint32 auctionId, uint64 bidder, uint32 bidSum, uint32 diff, uint32 item_template);
void SendAuctionOwnerNotification(AuctionEntry* auction);
+ void SendAuctionRemovedNotification(uint32 auctionId, uint32 itemEntry, int32 randomPropertyId);
//Item Enchantment
void SendEnchantmentLog(uint64 target, uint64 caster, uint32 itemId, uint32 enchantId);
@@ -369,19 +375,15 @@ class WorldSession
else
m_timeOutTime -= diff;
}
- void ResetTimeOutTime()
- {
- m_timeOutTime = sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME);
- }
- bool IsConnectionIdle() const
- {
- return (m_timeOutTime <= 0 && !m_inQueue);
- }
+ void ResetTimeOutTime() { m_timeOutTime = sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME); }
+ bool IsConnectionIdle() const { return (m_timeOutTime <= 0 && !m_inQueue); }
// Recruit-A-Friend Handling
uint32 GetRecruiterId() const { return recruiterId; }
bool IsARecruiter() const { return isRecruiter; }
+ z_stream_s* GetCompressionStream() { return _compressionStream; }
+
public: // opcodes handlers
void Handle_NULL(WorldPacket& recvPacket); // not used
@@ -394,9 +396,13 @@ class WorldSession
void HandleCharCreateOpcode(WorldPacket& recvPacket);
void HandleCharCreateCallback(PreparedQueryResult result, CharacterCreateInfo* createInfo);
void HandlePlayerLoginOpcode(WorldPacket& recvPacket);
+ void HandleLoadScreenOpcode(WorldPacket& recvPacket);
void HandleCharEnum(PreparedQueryResult result);
void HandlePlayerLogin(LoginQueryHolder * holder);
void HandleCharFactionOrRaceChange(WorldPacket& recvData);
+ void HandleRandomizeCharNameOpcode(WorldPacket& recvData);
+ void HandleReorderCharacters(WorldPacket& recvData);
+ void HandleOpeningCinematic(WorldPacket& recvData);
// played time
void HandlePlayedTime(WorldPacket& recvPacket);
@@ -405,6 +411,7 @@ class WorldSession
void HandleMoveUnRootAck(WorldPacket& recvPacket);
void HandleMoveRootAck(WorldPacket& recvPacket);
void HandleLookingForGroup(WorldPacket& recvPacket);
+ void HandleReturnToGraveyard(WorldPacket& recvPacket);
// new inspect
void HandleInspectOpcode(WorldPacket& recvPacket);
@@ -431,6 +438,7 @@ class WorldSession
void HandleMoveTeleportAck(WorldPacket& recvPacket);
void HandleForceSpeedChangeAck(WorldPacket& recvData);
+ void HandleSetCollisionHeightAck(WorldPacket& recvPacket);
void HandlePingOpcode(WorldPacket& recvPacket);
void HandleAuthSessionOpcode(WorldPacket& recvPacket);
@@ -470,8 +478,6 @@ class WorldSession
void HandleDelIgnoreOpcode(WorldPacket& recvPacket);
void HandleSetContactNotesOpcode(WorldPacket& recvPacket);
void HandleBugOpcode(WorldPacket& recvPacket);
- void HandleSetAmmoOpcode(WorldPacket& recvPacket);
- void HandleItemNameQueryOpcode(WorldPacket& recvPacket);
void HandleAreaTriggerOpcode(WorldPacket& recvPacket);
@@ -514,11 +520,11 @@ class WorldSession
void HandleGroupInviteOpcode(WorldPacket& recvPacket);
//void HandleGroupCancelOpcode(WorldPacket& recvPacket);
- void HandleGroupAcceptOpcode(WorldPacket& recvPacket);
- void HandleGroupDeclineOpcode(WorldPacket& recvPacket);
+ void HandleGroupInviteResponseOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteOpcode(WorldPacket& recvPacket);
void HandleGroupUninviteGuidOpcode(WorldPacket& recvPacket);
void HandleGroupSetLeaderOpcode(WorldPacket& recvPacket);
+ void HandleGroupSetRolesOpcode(WorldPacket& recvData);
void HandleGroupDisbandOpcode(WorldPacket& recvPacket);
void HandleOptOutOfLootOpcode(WorldPacket& recvData);
void HandleLootMethodOpcode(WorldPacket& recvPacket);
@@ -529,6 +535,7 @@ class WorldSession
void HandleRaidReadyCheckFinishedOpcode(WorldPacket& recvData);
void HandleGroupRaidConvertOpcode(WorldPacket& recvData);
void HandleGroupChangeSubGroupOpcode(WorldPacket& recvData);
+ void HandleGroupSwapSubGroupOpcode(WorldPacket& recvData);
void HandleGroupAssistantLeaderOpcode(WorldPacket& recvData);
void HandlePartyAssignmentOpcode(WorldPacket& recvData);
@@ -542,27 +549,41 @@ class WorldSession
void HandleTurnInPetitionOpcode(WorldPacket& recvData);
void HandleGuildQueryOpcode(WorldPacket& recvPacket);
- void HandleGuildCreateOpcode(WorldPacket& recvPacket);
void HandleGuildInviteOpcode(WorldPacket& recvPacket);
void HandleGuildRemoveOpcode(WorldPacket& recvPacket);
void HandleGuildAcceptOpcode(WorldPacket& recvPacket);
void HandleGuildDeclineOpcode(WorldPacket& recvPacket);
- void HandleGuildInfoOpcode(WorldPacket& recvPacket);
void HandleGuildEventLogQueryOpcode(WorldPacket& recvPacket);
void HandleGuildRosterOpcode(WorldPacket& recvPacket);
+ void HandleGuildRewardsQueryOpcode(WorldPacket& recvPacket);
void HandleGuildPromoteOpcode(WorldPacket& recvPacket);
void HandleGuildDemoteOpcode(WorldPacket& recvPacket);
+ void HandleGuildAssignRankOpcode(WorldPacket& recvPacket);
void HandleGuildLeaveOpcode(WorldPacket& recvPacket);
void HandleGuildDisbandOpcode(WorldPacket& recvPacket);
- void HandleGuildLeaderOpcode(WorldPacket& recvPacket);
+ void HandleGuildSetGuildMaster(WorldPacket& recvPacket);
void HandleGuildMOTDOpcode(WorldPacket& recvPacket);
- void HandleGuildSetPublicNoteOpcode(WorldPacket& recvPacket);
- void HandleGuildSetOfficerNoteOpcode(WorldPacket& recvPacket);
- void HandleGuildRankOpcode(WorldPacket& recvPacket);
+ void HandleGuildNewsUpdateStickyOpcode(WorldPacket& recvPacket);
+ void HandleGuildSetNoteOpcode(WorldPacket& recvPacket);
+ void HandleGuildQueryRanksOpcode(WorldPacket& recvPacket);
+ void HandleGuildQueryNewsOpcode(WorldPacket& recvPacket);
+ void HandleGuildSetRankPermissionsOpcode(WorldPacket& recvPacket);
void HandleGuildAddRankOpcode(WorldPacket& recvPacket);
void HandleGuildDelRankOpcode(WorldPacket& recvPacket);
void HandleGuildChangeInfoTextOpcode(WorldPacket& recvPacket);
void HandleSaveGuildEmblemOpcode(WorldPacket& recvPacket);
+ void HandleGuildRequestPartyState(WorldPacket& recvPacket);
+ void HandleGuildRequestMaxDailyXP(WorldPacket& recvPacket);
+ void HandleAutoDeclineGuildInvites(WorldPacket& recvPacket);
+
+ void HandleGuildFinderAddRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderBrowse(WorldPacket& recvPacket);
+ void HandleGuildFinderDeclineRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderGetApplications(WorldPacket& recvPacket);
+ void HandleGuildFinderGetRecruits(WorldPacket& recvPacket);
+ void HandleGuildFinderPostRequest(WorldPacket& recvPacket);
+ void HandleGuildFinderRemoveRecruit(WorldPacket& recvPacket);
+ void HandleGuildFinderSetGuildPost(WorldPacket& recvPacket);
void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket);
void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);
@@ -591,6 +612,7 @@ class WorldSession
void HandleStableRevivePet(WorldPacket& recvPacket);
void HandleStableSwapPet(WorldPacket& recvPacket);
void HandleStableSwapPetCallback(PreparedQueryResult result, uint32 petId);
+ void SendTrainerBuyFailed(uint64 guid, uint32 spellId, uint32 reason);
void HandleDuelAcceptedOpcode(WorldPacket& recvPacket);
void HandleDuelCancelledOpcode(WorldPacket& recvPacket);
@@ -626,13 +648,13 @@ class WorldSession
void HandleMailCreateTextItem(WorldPacket& recvData);
void HandleQueryNextMailTime(WorldPacket& recvData);
void HandleCancelChanneling(WorldPacket& recvData);
+ void SendShowMailBox(uint64 guid);
void SendItemPageInfo(ItemTemplate* itemProto);
void HandleSplitItemOpcode(WorldPacket& recvPacket);
void HandleSwapInvItemOpcode(WorldPacket& recvPacket);
void HandleDestroyItemOpcode(WorldPacket& recvPacket);
void HandleAutoEquipItemOpcode(WorldPacket& recvPacket);
- void HandleItemQuerySingleOpcode(WorldPacket& recvPacket);
void HandleSellItemOpcode(WorldPacket& recvPacket);
void HandleBuyItemInSlotOpcode(WorldPacket& recvPacket);
void HandleBuyItemOpcode(WorldPacket& recvPacket);
@@ -681,6 +703,7 @@ class WorldSession
void HandleQuestPushResult(WorldPacket& recvPacket);
void HandleMessagechatOpcode(WorldPacket& recvPacket);
+ void HandleAddonMessagechatOpcode(WorldPacket& recvPacket);
void SendPlayerNotFoundNotice(std::string const& name);
void SendPlayerAmbiguousNotice(std::string const& name);
void SendWrongFactionNotice();
@@ -688,6 +711,9 @@ class WorldSession
void HandleTextEmoteOpcode(WorldPacket& recvPacket);
void HandleChatIgnoredOpcode(WorldPacket& recvPacket);
+ void HandleUnregisterAddonPrefixesOpcode(WorldPacket& recvPacket);
+ void HandleAddonRegisteredPrefixesOpcode(WorldPacket& recvPacket);
+
void HandleReclaimCorpseOpcode(WorldPacket& recvPacket);
void HandleCorpseQueryOpcode(WorldPacket& recvPacket);
void HandleCorpseMapPositionQuery(WorldPacket& recvPacket);
@@ -718,7 +744,6 @@ class WorldSession
void HandleCompleteCinematic(WorldPacket& recvPacket);
void HandleNextCinematicCamera(WorldPacket& recvPacket);
- void HandlePageQuerySkippedOpcode(WorldPacket& recvPacket);
void HandlePageTextQueryOpcode(WorldPacket& recvPacket);
void HandleTutorialFlag (WorldPacket& recvData);
@@ -728,7 +753,7 @@ class WorldSession
//Pet
void HandlePetAction(WorldPacket& recvData);
void HandlePetStopAttack(WorldPacket& recvData);
- void HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid, uint16 flag, uint64 guid2);
+ void HandlePetActionHelper(Unit* pet, uint64 guid1, uint32 spellid, uint16 flag, uint64 guid2, float x, float y, float z);
void HandlePetNameQuery(WorldPacket& recvData);
void HandlePetSetAction(WorldPacket& recvData);
void HandlePetAbandon(WorldPacket& recvData);
@@ -758,13 +783,17 @@ class WorldSession
void HandleBattlefieldLeaveOpcode(WorldPacket& recvData);
void HandleBattlemasterJoinArena(WorldPacket& recvData);
void HandleReportPvPAFK(WorldPacket& recvData);
+ void HandleRequestRatedBgInfo(WorldPacket& recvData);
+ void HandleRequestPvpOptions(WorldPacket& recvData);
+ void HandleRequestPvpReward(WorldPacket& recvData);
+ void HandleRequestRatedBgStats(WorldPacket& recvData);
// Battlefield
- void SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 time);
- void SendBfInvitePlayerToQueue(uint32 battleId);
- void SendBfQueueInviteResponse(uint32 battleId, uint32 zoneId, bool canQueue = true, bool full = false);
- void SendBfEntered(uint32 battleId);
- void SendBfLeaveMessage(uint32 battleId, BFLeaveReason reason = BF_LEAVE_REASON_EXITED);
+ void SendBfInvitePlayerToWar(uint64 guid, uint32 zoneId, uint32 time);
+ void SendBfInvitePlayerToQueue(uint64 guid);
+ void SendBfQueueInviteResponse(uint64 guid, uint32 zoneId, bool canQueue = true, bool full = false);
+ void SendBfEntered(uint64 guid);
+ void SendBfLeaveMessage(uint64 guid, BFLeaveReason reason = BF_LEAVE_REASON_EXITED);
void HandleBfQueueInviteResponse(WorldPacket& recvData);
void HandleBfEntryInviteResponse(WorldPacket& recvData);
void HandleBfExitRequest(WorldPacket& recvData);
@@ -787,8 +816,9 @@ class WorldSession
// Looking for Dungeon/Raid
void HandleLfgSetCommentOpcode(WorldPacket& recvData);
- void HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& recvData);
- void HandleLfgPartyLockInfoRequestOpcode(WorldPacket& recvData);
+ void HandleLfgGetLockInfoOpcode(WorldPacket& recvData);
+ void SendLfgPlayerLockInfo();
+ void SendLfgPartyLockInfo();
void HandleLfgJoinOpcode(WorldPacket& recvData);
void HandleLfgLeaveOpcode(WorldPacket& recvData);
void HandleLfgSetRolesOpcode(WorldPacket& recvData);
@@ -799,8 +829,7 @@ class WorldSession
void HandleLfrLeaveOpcode(WorldPacket& recvData);
void HandleLfgGetStatus(WorldPacket& recvData);
- void SendLfgUpdatePlayer(lfg::LfgUpdateData const& updateData);
- void SendLfgUpdateParty(lfg::LfgUpdateData const& updateData);
+ void SendLfgUpdateStatus(lfg::LfgUpdateData const& updateData, bool party);
void SendLfgRoleChosen(uint64 guid, uint8 roles);
void SendLfgRoleCheckUpdate(lfg::LfgRoleCheck const& pRoleCheck);
void SendLfgLfrList(bool update);
@@ -817,6 +846,7 @@ class WorldSession
void HandleInspectArenaTeamsOpcode(WorldPacket& recvData);
void HandleArenaTeamQueryOpcode(WorldPacket& recvData);
void HandleArenaTeamRosterOpcode(WorldPacket& recvData);
+ void HandleArenaTeamCreateOpcode(WorldPacket& recvData);
void HandleArenaTeamInviteOpcode(WorldPacket& recvData);
void HandleArenaTeamAcceptOpcode(WorldPacket& recvData);
void HandleArenaTeamDeclineOpcode(WorldPacket& recvData);
@@ -859,6 +889,7 @@ class WorldSession
void HandleGuildBankBuyTab(WorldPacket& recvData);
void HandleQueryGuildBankTabText(WorldPacket& recvData);
void HandleSetGuildBankTabText(WorldPacket& recvData);
+ void HandleGuildQueryXPOpcode(WorldPacket& recvData);
// Refer-a-Friend
void HandleGrantLevel(WorldPacket& recvData);
@@ -886,12 +917,28 @@ class WorldSession
void SendCalendarRaidLockoutUpdated(InstanceSave const* save);
void HandleSetSavedInstanceExtend(WorldPacket& recvData);
+ // Void Storage
+ void HandleVoidStorageUnlock(WorldPacket& recvData);
+ void HandleVoidStorageQuery(WorldPacket& recvData);
+ void HandleVoidStorageTransfer(WorldPacket& recvData);
+ void HandleVoidSwapItem(WorldPacket& recvData);
+ void SendVoidStorageTransferResult(VoidTransferError result);
+
+ // Transmogrification
+ void HandleTransmogrifyItems(WorldPacket& recvData);
+
+ // Reforge
+ void HandleReforgeItemOpcode(WorldPacket& recvData);
+ void SendReforgeResult(bool success);
+
+ // Miscellaneous
void HandleSpellClick(WorldPacket& recvData);
void HandleMirrorImageDataRequest(WorldPacket& recvData);
void HandleAlterAppearance(WorldPacket& recvData);
void HandleRemoveGlyph(WorldPacket& recvData);
void HandleCharCustomize(WorldPacket& recvData);
void HandleQueryInspectAchievements(WorldPacket& recvData);
+ void HandleGuildAchievementProgressQuery(WorldPacket& recvData);
void HandleEquipmentSetSave(WorldPacket& recvData);
void HandleEquipmentSetDelete(WorldPacket& recvData);
void HandleEquipmentSetUse(WorldPacket& recvData);
@@ -902,7 +949,16 @@ class WorldSession
void HandleEjectPassenger(WorldPacket& data);
void HandleEnterPlayerVehicle(WorldPacket& data);
void HandleUpdateProjectilePosition(WorldPacket& recvPacket);
+ void HandleRequestHotfix(WorldPacket& recvPacket);
void HandleUpdateMissileTrajectory(WorldPacket& recvPacket);
+ void HandleViolenceLevel(WorldPacket& recvPacket);
+ void HandleObjectUpdateFailedOpcode(WorldPacket& recvPacket);
+ void HandleRequestCategoryCooldowns(WorldPacket& recvPacket);
+ int32 HandleEnableNagleAlgorithm();
+
+ // Compact Unit Frames (4.x)
+ void HandleSaveCUFProfiles(WorldPacket& recvPacket);
+ void SendLoadCUFProfiles();
private:
void InitializeQueryCallbackParameters();
@@ -999,10 +1055,13 @@ class WorldSession
uint32 m_Tutorials[MAX_ACCOUNT_TUTORIAL_VALUES];
bool m_TutorialsChanged;
AddonsList m_addonsList;
+ std::vector<std::string> _registeredAddonPrefixes;
+ bool _filterAddonMessages;
uint32 recruiterId;
bool isRecruiter;
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
time_t timeLastWhoCommand;
+ z_stream_s* _compressionStream;
rbac::RBACData* _RBACData;
};
#endif
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 605b863bfa1..161fd61796f 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -165,6 +165,13 @@ int WorldSocket::SendPacket(WorldPacket const& pct)
WorldPacket const* pkt = &pct;
+ // Empty buffer used in case packet should be compressed
+ WorldPacket buff;
+ if (m_Session && pkt->size() > 0x400)
+ {
+ buff.Compress(m_Session->GetCompressionStream(), pkt);
+ pkt = &buff;
+ }
if (m_Session)
TC_LOG_TRACE("network.opcode", "S->C: %s %s", m_Session->GetPlayerInfo().c_str(), GetOpcodeNameForLogging(pkt->GetOpcode()).c_str());
@@ -247,7 +254,12 @@ int WorldSocket::open (void *a)
m_Address = remote_addr.get_host_addr();
- if (HandleSendAuthSession() == -1)
+ // not an opcode. this packet sends raw string WORLD OF WARCRAFT CONNECTION - SERVER TO CLIENT"
+ // because of our implementation, bytes "WO" become the opcode
+ WorldPacket packet(MSG_VERIFY_CONNECTIVITY);
+ packet << "RLD OF WARCRAFT CONNECTION - SERVER TO CLIENT";
+
+ if (SendPacket(packet) == -1)
return -1;
// Register with ACE Reactor
@@ -475,7 +487,7 @@ int WorldSocket::handle_input_header (void)
EndianConvertReverse(header.size);
EndianConvert(header.cmd);
- if ((header.size < 4) || (header.size > 10240) || (header.cmd > 10240))
+ if ((header.size < 4) || (header.size > 10240) || (header.cmd > 0xFFFF && (header.cmd >> 16) != 0x4C52)) // LR (from MSG_VERIFY_CONNECTIVITY)
{
Player* _player = m_Session ? m_Session->GetPlayer() : NULL;
TC_LOG_ERROR("network", "WorldSocket::handle_input_header(): client (account: %u, char [GUID: %u, name: %s]) sent malformed packet (size: %d, cmd: %d)",
@@ -490,7 +502,7 @@ int WorldSocket::handle_input_header (void)
header.size -= 4;
- ACE_NEW_RETURN(m_RecvWPct, WorldPacket ((uint16)header.cmd, header.size), -1);
+ ACE_NEW_RETURN(m_RecvWPct, WorldPacket (PacketFilter::DropHighBytes(Opcodes(header.cmd)), header.size), -1);
if (header.size > 0)
{
@@ -663,7 +675,7 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
// manage memory ;)
ACE_Auto_Ptr<WorldPacket> aptr(new_pct);
- const ACE_UINT16 opcode = new_pct->GetOpcode();
+ Opcodes opcode = PacketFilter::DropHighBytes(new_pct->GetOpcode());
if (closing_)
return -1;
@@ -695,6 +707,29 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
return 0;
+ case CMSG_LOG_DISCONNECT:
+ new_pct->rfinish(); // contains uint32 disconnectReason;
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
+ return 0;
+ // not an opcode, client sends string "WORLD OF WARCRAFT CONNECTION - CLIENT TO SERVER" without opcode
+ // first 4 bytes become the opcode (2 dropped)
+ case MSG_VERIFY_CONNECTIVITY:
+ {
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
+ std::string str;
+ *new_pct >> str;
+ if (str != "D OF WARCRAFT CONNECTION - CLIENT TO SERVER")
+ return -1;
+ return HandleSendAuthSession();
+ }
+ case CMSG_ENABLE_NAGLE:
+ {
+ TC_LOG_DEBUG("network", "%s", opcodeName.c_str());
+ sScriptMgr->OnPacketReceive(this, WorldPacket(*new_pct));
+ return m_Session ? m_Session->HandleEnableNagleAlgorithm() : -1;
+ }
default:
{
ACE_GUARD_RETURN(LockType, Guard, m_SessionLock, -1);
@@ -704,6 +739,17 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
return -1;
}
+ // prevent invalid memory access/crash with custom opcodes
+ if (opcode >= NUM_OPCODE_HANDLERS)
+ return 0;
+
+ OpcodeHandler const* handler = opcodeTable[opcode];
+ if (!handler || handler->Status == STATUS_UNHANDLED)
+ {
+ TC_LOG_ERROR("network.opcode", "No defined handler for opcode %s sent by %s", GetOpcodeNameForLogging(new_pct->GetOpcode()).c_str(), m_Session->GetPlayerInfo().c_str());
+ return 0;
+ }
+
// Our Idle timer will reset on any non PING opcodes.
// Catches people idling on the login screen and any lingering ingame connections.
m_Session->ResetTimeOutTime();
@@ -731,9 +777,6 @@ int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
int WorldSocket::HandleSendAuthSession()
{
WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
- packet << uint32(1); // 1...31
- packet << uint32(m_Seed);
-
BigNumber seed1;
seed1.SetRand(16 * 8);
packet.append(seed1.AsByteArray(16).get(), 16); // new encryption seeds
@@ -741,6 +784,9 @@ int WorldSocket::HandleSendAuthSession()
BigNumber seed2;
seed2.SetRand(16 * 8);
packet.append(seed2.AsByteArray(16).get(), 16); // new encryption seeds
+
+ packet << m_Seed;
+ packet << uint8(1);
return SendPacket(packet);
}
@@ -749,15 +795,52 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
uint8 digest[20];
uint32 clientSeed;
uint8 security;
+ uint16 clientBuild;
uint32 id;
+ uint32 addonSize;
LocaleConstant locale;
std::string account;
SHA1Hash sha;
- uint32 clientBuild;
- uint32 unk2, unk3, unk5, unk6, unk7;
- uint64 unk4;
- WorldPacket packet, SendAddonPacked;
BigNumber k;
+ WorldPacket addonsData;
+
+ recvPacket.read_skip<uint32>();
+ recvPacket.read_skip<uint32>();
+ recvPacket.read_skip<uint8>();
+ recvPacket >> digest[10];
+ recvPacket >> digest[18];
+ recvPacket >> digest[12];
+ recvPacket >> digest[5];
+ recvPacket.read_skip<uint64>();
+ recvPacket >> digest[15];
+ recvPacket >> digest[9];
+ recvPacket >> digest[19];
+ recvPacket >> digest[4];
+ recvPacket >> digest[7];
+ recvPacket >> digest[16];
+ recvPacket >> digest[3];
+ recvPacket >> clientBuild;
+ recvPacket >> digest[8];
+ recvPacket.read_skip<uint32>();
+ recvPacket.read_skip<uint8>();
+ recvPacket >> digest[17];
+ recvPacket >> digest[6];
+ recvPacket >> digest[0];
+ recvPacket >> digest[1];
+ recvPacket >> digest[11];
+ recvPacket >> clientSeed;
+ recvPacket >> digest[2];
+ recvPacket.read_skip<uint32>();
+ recvPacket >> digest[14];
+ recvPacket >> digest[13];
+
+ recvPacket >> addonSize;
+ addonsData.resize(addonSize);
+ recvPacket.read((uint8*)addonsData.contents(), addonSize);
+
+ recvPacket.ReadBit();
+ uint32 accountNameLength = recvPacket.ReadBits(12);
+ account = recvPacket.ReadString(accountNameLength);
if (sWorld->IsClosed())
{
@@ -766,23 +849,6 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
return -1;
}
- // Read the content of the packet
- recvPacket >> clientBuild;
- recvPacket >> unk2;
- recvPacket >> account;
- recvPacket >> unk3;
- recvPacket >> clientSeed;
- recvPacket >> unk5 >> unk6 >> unk7;
- recvPacket >> unk4;
- recvPacket.read(digest, 20);
-
- TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, unk3 %u, clientseed %u",
- clientBuild,
- unk2,
- account.c_str(),
- unk3,
- clientSeed);
-
// Get the account information from the realmd database
// 0 1 2 3 4 5 6 7 8
// SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?
@@ -943,7 +1009,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
m_Session->LoadGlobalAccountData();
m_Session->LoadTutorialsData();
- m_Session->ReadAddonsInfo(recvPacket);
+ m_Session->ReadAddonsInfo(addonsData);
m_Session->LoadPermissions();
// Initialize Warden system only if it is enabled by config
@@ -964,8 +1030,8 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
uint32 latency;
// Get the ping packet content
- recvPacket >> ping;
recvPacket >> latency;
+ recvPacket >> ping;
if (m_LastPingTime == ACE_Time_Value::zero)
m_LastPingTime = ACE_OS::gettimeofday(); // for 1st ping
@@ -1026,6 +1092,8 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)
void WorldSocket::SendAuthResponseError(uint8 code)
{
WorldPacket packet(SMSG_AUTH_RESPONSE, 1);
+ packet.WriteBit(0); // has queue info
+ packet.WriteBit(0); // has account info
packet << uint8(code);
SendPacket(packet);
}
diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h
index 103d60346e8..830029c4a88 100644
--- a/src/server/game/Server/WorldSocket.h
+++ b/src/server/game/Server/WorldSocket.h
@@ -161,6 +161,7 @@ class WorldSocket : public WorldHandler
/// Called by ProcessIncoming() on CMSG_PING.
int HandlePing(WorldPacket& recvPacket);
+ /// Called by CMSG_VERIFY_CONNECTIVITY_RESPONSE
int HandleSendAuthSession();
private:
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index aa1f6a49413..268034444b0 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -200,7 +200,7 @@ enum AuraType
SPELL_AURA_MOD_MELEE_HASTE = 138,
SPELL_AURA_FORCE_REACTION = 139,
SPELL_AURA_MOD_RANGED_HASTE = 140,
- SPELL_AURA_MOD_RANGED_AMMO_HASTE = 141,
+ SPELL_AURA_141 = 141, // old SPELL_AURA_MOD_RANGED_AMMO_HASTE, unused now
SPELL_AURA_MOD_BASE_RESISTANCE_PCT = 142,
SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE = 143,
SPELL_AURA_SAFE_FALL = 144,
@@ -212,14 +212,14 @@ enum AuraType
SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT = 150,
SPELL_AURA_TRACK_STEALTHED = 151, // Track Stealthed
SPELL_AURA_MOD_DETECTED_RANGE = 152, // Mod Detected Range
- SPELL_AURA_SPLIT_DAMAGE_FLAT = 153, // Split Damage Flat
+ SPELL_AURA_153 = 153, // old SPELL_AURA_SPLIT_DAMAGE_FLAT. unused 4.3.4
SPELL_AURA_MOD_STEALTH_LEVEL = 154, // Stealth Level Modifier
SPELL_AURA_MOD_WATER_BREATHING = 155, // Mod Water Breathing
SPELL_AURA_MOD_REPUTATION_GAIN = 156, // Mod Reputation Gain
SPELL_AURA_PET_DAMAGE_MULTI = 157, // Mod Pet Damage
SPELL_AURA_MOD_SHIELD_BLOCKVALUE = 158,
SPELL_AURA_NO_PVP_CREDIT = 159,
- SPELL_AURA_MOD_AOE_AVOIDANCE = 160,
+ SPELL_AURA_160 = 160, // old SPELL_AURA_MOD_AOE_AVOIDANCE. Unused 4.3.4
SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT = 161,
SPELL_AURA_POWER_BURN = 162,
SPELL_AURA_MOD_CRIT_DAMAGE_BONUS = 163,
@@ -228,7 +228,7 @@ enum AuraType
SPELL_AURA_MOD_ATTACK_POWER_PCT = 166,
SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT = 167,
SPELL_AURA_MOD_DAMAGE_DONE_VERSUS = 168,
- SPELL_AURA_MOD_CRIT_PERCENT_VERSUS = 169,
+ SPELL_AURA_169 = 169, // old SPELL_AURA_MOD_CRIT_PERCENT_VERSUS. unused 4.3.4
SPELL_AURA_DETECT_AMORE = 170,
SPELL_AURA_MOD_SPEED_NOT_STACK = 171,
SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK = 172,
@@ -237,7 +237,7 @@ enum AuraType
SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT = 175,
SPELL_AURA_SPIRIT_OF_REDEMPTION = 176,
SPELL_AURA_AOE_CHARM = 177,
- SPELL_AURA_MOD_DEBUFF_RESISTANCE = 178,
+ SPELL_AURA_178 = 178, // old SPELL_AURA_MOD_DEBUFF_RESISTANCE, unused
SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE = 179,
SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS = 180,
SPELL_AURA_181 = 181, // old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS - possible flat spell crit damage versus
@@ -258,7 +258,7 @@ enum AuraType
SPELL_AURA_MOD_COOLDOWN = 196, // only 24818 Noxious Breath
SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197,
SPELL_AURA_198 = 198, // old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
- SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT = 199,
+ SPELL_AURA_199 = 199, // old SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT. unused 4.3.4
SPELL_AURA_MOD_XP_PCT = 200,
SPELL_AURA_FLY = 201,
SPELL_AURA_IGNORE_COMBAT_RESULT = 202,
@@ -271,12 +271,12 @@ enum AuraType
SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS = 209,
SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS = 210,
SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK = 211,
- SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT = 212,
+ SPELL_AURA_212 = 212, // old SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT. unused 4.3.4
SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT = 213,
SPELL_AURA_214 = 214,
SPELL_AURA_ARENA_PREPARATION = 215,
SPELL_AURA_HASTE_SPELLS = 216,
- SPELL_AURA_MOD_MELEE_HASTE_2 = 217, // NYI
+ SPELL_AURA_MOD_MELEE_HASTE_2 = 217,
SPELL_AURA_HASTE_RANGED = 218,
SPELL_AURA_MOD_MANA_REGEN_FROM_STAT = 219,
SPELL_AURA_MOD_RATING_FROM_STAT = 220,
@@ -289,7 +289,7 @@ enum AuraType
SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE = 227,
SPELL_AURA_DETECT_STEALTH = 228,
SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE = 229,
- SPELL_AURA_230 = 230,
+ SPELL_AURA_MOD_MAX_HEALTH = 230,
SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE = 231,
SPELL_AURA_MECHANIC_DURATION_MOD = 232,
SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS = 233, // client-side only
@@ -318,7 +318,7 @@ enum AuraType
SPELL_AURA_NO_REAGENT_USE = 256,
SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,
SPELL_AURA_258 = 258,
- SPELL_AURA_MOD_HOT_PCT = 259,
+ SPELL_AURA_259 = 259, // old SPELL_AURA_MOD_HOT_PCT, unused 4.3.4
SPELL_AURA_SCREEN_EFFECT = 260,
SPELL_AURA_PHASE = 261,
SPELL_AURA_ABILITY_IGNORE_AURASTATE = 262,
@@ -327,19 +327,19 @@ enum AuraType
SPELL_AURA_265 = 265,
SPELL_AURA_266 = 266,
SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267,
- SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268,
+ SPELL_AURA_268 = 268, // old SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT. unused 4.3.4
SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 269,
- SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive
+ SPELL_AURA_270 = 270, // old SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST, unused 4.3.4
SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271,
SPELL_AURA_IGNORE_MELEE_RESET = 272,
SPELL_AURA_X_RAY = 273,
- SPELL_AURA_ABILITY_CONSUME_NO_AMMO = 274,
+ SPELL_AURA_274 = 274, // old SPELL_AURA_ABILITY_CONSUME_NO_AMMO, unused 4.3.4
SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275,
- SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276, // NYI
- SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277,
+ SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC = 276,
+ SPELL_AURA_277 = 277, // old SPELL_AURA_MOD_MAX_AFFECTED_TARGETS. unused 4.3.4
SPELL_AURA_MOD_DISARM_RANGED = 278,
SPELL_AURA_INITIALIZE_IMAGES = 279,
- SPELL_AURA_MOD_ARMOR_PENETRATION_PCT = 280,
+ SPELL_AURA_280 = 280, // old SPELL_AURA_MOD_ARMOR_PENETRATION_PCT unused 4.3.4
SPELL_AURA_MOD_HONOR_GAIN_PCT = 281,
SPELL_AURA_MOD_BASE_HEALTH_PCT = 282,
SPELL_AURA_MOD_HEALING_RECEIVED = 283, // Possibly only for some spell family class spells
@@ -367,16 +367,70 @@ enum AuraType
SPELL_AURA_MOD_MINIMUM_SPEED = 305,
SPELL_AURA_306 = 306,
SPELL_AURA_HEAL_ABSORB_TEST = 307,
- SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308, // NYI
- SPELL_AURA_309 = 309,
+ SPELL_AURA_MOD_CRIT_CHANCE_FOR_CASTER = 308,
+ SPELL_AURA_309 = 309, // Not used in 4.3.4
SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310,
SPELL_AURA_311 = 311,
- SPELL_AURA_312 = 312,
- SPELL_AURA_313 = 313,
+ SPELL_AURA_ANIM_REPLACEMENT_SET = 312,
+ SPELL_AURA_313 = 313, // Not used in 4.3.4 - related to mounts
SPELL_AURA_PREVENT_RESURRECTION = 314,
SPELL_AURA_UNDERWATER_WALKING = 315,
- SPELL_AURA_PERIODIC_HASTE = 316,
- TOTAL_AURAS = 317
+ SPELL_AURA_PERIODIC_HASTE = 316, // Not used in 4.3.4 (name from 3.3.5a)
+ SPELL_AURA_MOD_SPELL_POWER_PCT = 317,
+ SPELL_AURA_MASTERY = 318,
+ SPELL_AURA_MOD_MELEE_HASTE_3 = 319,
+ SPELL_AURA_MOD_RANGED_HASTE_2 = 320,
+ SPELL_AURA_321 = 321,
+ SPELL_AURA_INTERFERE_TARGETTING = 322, // NYI
+ SPELL_AURA_323 = 323, // Not used in 4.3.4
+ SPELL_AURA_324 = 324, // spell critical chance (probably by school mask)
+ SPELL_AURA_325 = 325, // Not used in 4.3.4
+ SPELL_AURA_326 = 326, // phase related
+ SPELL_AURA_327 = 327, // Not used in 4.3.4
+ SPELL_AURA_PROC_ON_POWER_AMOUNT = 328,
+ SPELL_AURA_MOD_RUNE_REGEN_SPEED = 329, // NYI
+ SPELL_AURA_CAST_WHILE_WALKING = 330,
+ SPELL_AURA_FORCE_WEATHER = 331,
+ SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS = 332,
+ SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2 = 333,
+ SPELL_AURA_MOD_BLIND = 334, // NYI
+ SPELL_AURA_335 = 335,
+ SPELL_AURA_MOD_FLYING_RESTRICTIONS = 336, // NYI
+ SPELL_AURA_MOD_VENDOR_ITEMS_PRICES = 337,
+ SPELL_AURA_MOD_DURABILITY_LOSS = 338,
+ SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE = 339, // NYI
+ SPELL_AURA_MOD_RESURRECTED_HEALTH_BY_GUILD_MEMBER = 340, // Increases health gained when resurrected by a guild member by X
+ SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN = 341, // Modifies cooldown of all spells using affected category
+ SPELL_AURA_MOD_MELEE_RANGED_HASTE_2 = 342,
+ SPELL_AURA_343 = 343,
+ SPELL_AURA_MOD_AUTOATTACK_DAMAGE = 344, // NYI
+ SPELL_AURA_BYPASS_ARMOR_FOR_CASTER = 345,
+ SPELL_AURA_ENABLE_ALT_POWER = 346, // NYI
+ SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE = 347, // NYI
+ SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT = 348, // NYI
+ SPELL_AURA_MOD_CURRENCY_GAIN = 349,
+ SPELL_AURA_MOD_GATHERING_ITEMS_GAINED_PERCENT = 350, // NYI
+ SPELL_AURA_351 = 351,
+ SPELL_AURA_352 = 352,
+ SPELL_AURA_MOD_CAMOUFLAGE = 353, // NYI
+ SPELL_AURA_354 = 354, // Restoration Shaman mastery - mod healing based on target's health (less = more healing)
+ SPELL_AURA_355 = 355,
+ SPELL_AURA_356 = 356, // Arcane Mage mastery - mod damage based on current mana
+ SPELL_AURA_ENABLE_BOSS1_UNIT_FRAME = 357,
+ SPELL_AURA_WORGEN_ALTERED_FORM = 358,
+ SPELL_AURA_359 = 359,
+ SPELL_AURA_PROC_TRIGGER_SPELL_COPY = 360, // Procs the same spell that caused this proc (Dragonwrath, Tarecgosa's Rest)
+ SPELL_AURA_PROC_TRIGGER_SPELL_2 = 361,
+ SPELL_AURA_362 = 362, // Not used in 4.3.4
+ SPELL_AURA_MOD_NEXT_SPELL = 363, // Used by 101601 Throw Totem - causes the client to initialize spell cast with specified spell
+ SPELL_AURA_364 = 364, // Not used in 4.3.4
+ SPELL_AURA_MAX_FAR_CLIP_PLANE = 365, // Overrides client's View Distance setting to max("Fair", current_setting) and turns off terrain display
+ SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT = 366, // NYI - Sets spellpower equal to % of attack power, discarding all other bonuses (from gear and buffs)
+ SPELL_AURA_367 = 367,
+ 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
};
enum AuraObjectType
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c769a0b6aea..c3baf493156 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -38,6 +38,7 @@
#include "Vehicle.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
+#include "WeatherMgr.h"
#include "Pet.h"
#include "ReputationMgr.h"
@@ -120,7 +121,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
&AuraEffect::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
&AuraEffect::HandleNoImmediateEffect, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL implemented in AuraEffect::PeriodicTick
- &AuraEffect::HandleUnused, // 63 unused (3.2.0) old SPELL_AURA_PERIODIC_MANA_FUNNEL
+ &AuraEffect::HandleUnused, // 63 unused (4.3.4) old SPELL_AURA_PERIODIC_MANA_FUNNEL
&AuraEffect::HandleNoImmediateEffect, // 64 SPELL_AURA_PERIODIC_MANA_LEECH implemented in AuraEffect::PeriodicTick
&AuraEffect::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
&AuraEffect::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
@@ -147,7 +148,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
&AuraEffect::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth
&AuraEffect::HandleNoImmediateEffect, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
- &AuraEffect::HandleUnused, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
+ &AuraEffect::HandleUnused, // 90 unused (4.3.4) old SPELL_AURA_MOD_RESIST_CHANCE
&AuraEffect::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
&AuraEffect::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
&AuraEffect::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
@@ -176,7 +177,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
&AuraEffect::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
&AuraEffect::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
- &AuraEffect::HandleUnused, //119 unused (3.2.0) old SPELL_AURA_SHARE_PET_TRACKING
+ &AuraEffect::HandleUnused, //119 unused (4.3.4) old SPELL_AURA_SHARE_PET_TRACKING
&AuraEffect::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
&AuraEffect::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
&AuraEffect::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
@@ -198,7 +199,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleModMeleeSpeedPct, //138 SPELL_AURA_MOD_MELEE_HASTE
&AuraEffect::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
&AuraEffect::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
- &AuraEffect::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
+ &AuraEffect::HandleUnused, //141 SPELL_AURA_141
&AuraEffect::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
&AuraEffect::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
&AuraEffect::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
@@ -210,14 +211,14 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
&AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
&AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
- &AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
+ &AuraEffect::HandleUnused, //153 Unused (4.3.4) old SPELL_AURA_SPLIT_DAMAGE_FLAT
&AuraEffect::HandleModStealthLevel, //154 SPELL_AURA_MOD_STEALTH_LEVEL
&AuraEffect::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
&AuraEffect::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
&AuraEffect::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
&AuraEffect::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
&AuraEffect::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
- &AuraEffect::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleUnused, //160 Unused (4.3.4) old SPELL_AURA_MOD_AOE_AVOIDANCE
&AuraEffect::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
&AuraEffect::HandleNoImmediateEffect, //162 SPELL_AURA_POWER_BURN implemented in AuraEffect::PeriodicTick
&AuraEffect::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS
@@ -226,19 +227,19 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
&AuraEffect::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
&AuraEffect::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
- &AuraEffect::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
+ &AuraEffect::HandleUnused, //169 Unused (4.3.4) old SPELL_AURA_MOD_CRIT_PERCENT_VERSUS
&AuraEffect::HandleNULL, //170 SPELL_AURA_DETECT_AMORE various spells that change visual of units for aura target (clientside?)
&AuraEffect::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
&AuraEffect::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
- &AuraEffect::HandleUnused, //173 unused (3.2.0) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
+ &AuraEffect::HandleUnused, //173 unused (4.3.4) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
&AuraEffect::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
&AuraEffect::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
&AuraEffect::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
&AuraEffect::HandleCharmConvert, //177 SPELL_AURA_AOE_CHARM
- &AuraEffect::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleUnused, //178 old SPELL_AURA_MOD_DEBUFF_RESISTANCE unused 4.3.4
&AuraEffect::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
&AuraEffect::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
- &AuraEffect::HandleUnused, //181 unused (3.2.0) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
+ &AuraEffect::HandleUnused, //181 unused (4.3.4) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
&AuraEffect::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
&AuraEffect::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 - miscvalue - spell school
&AuraEffect::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
@@ -255,8 +256,8 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
&AuraEffect::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN - flat mod of spell cooldowns
&AuraEffect::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
- &AuraEffect::HandleUnused, //198 unused (3.2.0) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
- &AuraEffect::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleUnused, //198 unused (4.3.4) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
+ &AuraEffect::HandleUnused, //199 unused (4.3.4) old SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT
&AuraEffect::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::RewardPlayerAndGroupAtKill
&AuraEffect::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
&AuraEffect::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
@@ -269,19 +270,19 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
&AuraEffect::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
&AuraEffect::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
- &AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleUnused, //212 Unused (4.3.4) old SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
&AuraEffect::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
&AuraEffect::HandleNULL, //214 Tamed Pet Passive
&AuraEffect::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
&AuraEffect::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
- &AuraEffect::HandleNULL, //217 69106 - killing spree helper - unknown use
+ &AuraEffect::HandleModMeleeSpeedPct, //217 SPELL_AURA_MOD_MELEE_HASTE_2
&AuraEffect::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
&AuraEffect::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
&AuraEffect::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
&AuraEffect::HandleNULL, //221 SPELL_AURA_MOD_DETAUNT
&AuraEffect::HandleUnused, //222 unused (3.2.0) only for spell 44586 that not used in real spell cast
&AuraEffect::HandleNoImmediateEffect, //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
- &AuraEffect::HandleUnused, //224 unused (3.0.8a)
+ &AuraEffect::HandleUnused, //224 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
&AuraEffect::HandleNoImmediateEffect, //226 SPELL_AURA_PERIODIC_DUMMY implemented in AuraEffect::PeriodicTick
&AuraEffect::HandleNoImmediateEffect, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE implemented in AuraEffect::PeriodicTick
@@ -316,28 +317,28 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
&AuraEffect::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
&AuraEffect::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
- &AuraEffect::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleUnused, //259 unused (4.3.4) old SPELL_AURA_MOD_HOT_PCT
&AuraEffect::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
&AuraEffect::HandlePhase, //261 SPELL_AURA_PHASE
&AuraEffect::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
&AuraEffect::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
&AuraEffect::HandleUnused, //264 unused (3.2.0)
- &AuraEffect::HandleUnused, //265 unused (3.2.0)
- &AuraEffect::HandleUnused, //266 unused (3.2.0)
+ &AuraEffect::HandleUnused, //265 unused (4.3.4)
+ &AuraEffect::HandleUnused, //266 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
- &AuraEffect::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleUnused, //268 unused (4.3.4) old SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT.
&AuraEffect::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
- &AuraEffect::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &AuraEffect::HandleUnused, //270 unused (4.3.4) old SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST
&AuraEffect::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
&AuraEffect::HandleNoImmediateEffect, //272 SPELL_AURA_IGNORE_MELEE_RESET
&AuraEffect::HandleUnused, //273 clientside
- &AuraEffect::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
+ &AuraEffect::HandleUnused, //274 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
&AuraEffect::HandleNULL, //276 mod damage % mechanic?
- &AuraEffect::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
+ &AuraEffect::HandleUnused, //277 unused (4.3.4) old SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
&AuraEffect::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
&AuraEffect::HandleNoImmediateEffect, //279 SPELL_AURA_INITIALIZE_IMAGES
- &AuraEffect::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
+ &AuraEffect::HandleUnused, //280 unused (4.3.4) old SPELL_AURA_MOD_ARMOR_PENETRATION_PCT
&AuraEffect::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
&AuraEffect::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
&AuraEffect::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
@@ -352,28 +353,82 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraOpenStable, //292 SPELL_AURA_OPEN_STABLE
&AuraEffect::HandleAuraOverrideSpells, //293 SPELL_AURA_OVERRIDE_SPELLS auras which probably add set of abilities to their target based on it's miscvalue
&AuraEffect::HandleNoImmediateEffect, //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power)
- &AuraEffect::HandleUnused, //295 0 spells in 3.3.5
+ &AuraEffect::HandleUnused, //295 unused (4.3.4)
&AuraEffect::HandleAuraSetVehicle, //296 SPELL_AURA_SET_VEHICLE_ID sets vehicle on target
&AuraEffect::HandleNULL, //297 Spirit Burst spells
&AuraEffect::HandleNULL, //298 70569 - Strangulating, maybe prevents talk or cast
- &AuraEffect::HandleUnused, //299 unused
+ &AuraEffect::HandleUnused, //299 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //300 SPELL_AURA_SHARE_DAMAGE_PCT implemented in Unit::DealDamage
&AuraEffect::HandleNoImmediateEffect, //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb
- &AuraEffect::HandleUnused, //302 0 spells in 3.3.5
+ &AuraEffect::HandleUnused, //302 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //303 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS_AURASTATE implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
&AuraEffect::HandleAuraModFakeInebriation, //304 SPELL_AURA_MOD_DRUNK
&AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED
- &AuraEffect::HandleUnused, //306 0 spells in 3.3.5
- &AuraEffect::HandleUnused, //307 0 spells in 3.3.5
+ &AuraEffect::HandleUnused, //306 unused (4.3.4)
+ &AuraEffect::HandleUnused, //307 unused (4.3.4)
&AuraEffect::HandleNULL, //308 new aura for hunter traps
- &AuraEffect::HandleUnused, //309 0 spells in 3.3.5
+ &AuraEffect::HandleUnused, //309 unused (4.3.4)
&AuraEffect::HandleNoImmediateEffect, //310 SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE implemented in Spell::CalculateDamageDone
&AuraEffect::HandleNULL, //311 0 spells in 3.3.5
&AuraEffect::HandleNULL, //312 0 spells in 3.3.5
- &AuraEffect::HandleUnused, //313 0 spells in 3.3.5
+ &AuraEffect::HandleUnused, //313 unused (4.3.4)
&AuraEffect::HandlePreventResurrection, //314 SPELL_AURA_PREVENT_RESURRECTION todo
&AuraEffect::HandleNoImmediateEffect, //315 SPELL_AURA_UNDERWATER_WALKING todo
- &AuraEffect::HandleNoImmediateEffect, //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic
+ &AuraEffect::HandleNoImmediateEffect, //316 unused (4.3.4) old SPELL_AURA_PERIODIC_HASTE
+ &AuraEffect::HandleNULL, //317 SPELL_AURA_MOD_SPELL_POWER_PCT
+ &AuraEffect::HandleMastery, //318 SPELL_AURA_MASTERY
+ &AuraEffect::HandleModMeleeSpeedPct, //319 SPELL_AURA_MOD_MELEE_HASTE_3
+ &AuraEffect::HandleAuraModRangedHaste, //320 SPELL_AURA_MOD_RANGED_HASTE_2
+ &AuraEffect::HandleNULL, //321 SPELL_AURA_321
+ &AuraEffect::HandleNULL, //322 SPELL_AURA_INTERFERE_TARGETTING
+ &AuraEffect::HandleUnused, //323 unused (4.3.4)
+ &AuraEffect::HandleNULL, //324 SPELL_AURA_324
+ &AuraEffect::HandleUnused, //325 unused (4.3.4)
+ &AuraEffect::HandleNULL, //326 SPELL_AURA_326
+ &AuraEffect::HandleUnused, //327 unused (4.3.4)
+ &AuraEffect::HandleNoImmediateEffect, //328 SPELL_AURA_PROC_ON_POWER_AMOUNT implemented in Unit::HandleAuraProcOnPowerAmount
+ &AuraEffect::HandleNULL, //329 SPELL_AURA_MOD_RUNE_REGEN_SPEED
+ &AuraEffect::HandleNoImmediateEffect, //330 SPELL_AURA_CAST_WHILE_WALKING
+ &AuraEffect::HandleAuraForceWeather, //331 SPELL_AURA_FORCE_WEATHER
+ &AuraEffect::HandleNoImmediateEffect, //332 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS implemented in WorldSession::HandleCastSpellOpcode
+ &AuraEffect::HandleNoImmediateEffect, //333 SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2 implemented in WorldSession::HandleCastSpellOpcode
+ &AuraEffect::HandleNULL, //334 SPELL_AURA_MOD_BLIND
+ &AuraEffect::HandleNULL, //335 SPELL_AURA_335
+ &AuraEffect::HandleNULL, //336 SPELL_AURA_MOD_FLYING_RESTRICTIONS
+ &AuraEffect::HandleNoImmediateEffect, //337 SPELL_AURA_MOD_VENDOR_ITEMS_PRICES
+ &AuraEffect::HandleNoImmediateEffect, //338 SPELL_AURA_MOD_DURABILITY_LOSS
+ &AuraEffect::HandleNULL, //339 SPELL_AURA_INCREASE_SKILL_GAIN_CHANCE
+ &AuraEffect::HandleNULL, //340 SPELL_AURA_MOD_RESURRECTED_HEALTH_BY_GUILD_MEMBER
+ &AuraEffect::HandleNULL, //341 SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN
+ &AuraEffect::HandleModMeleeRangedSpeedPct, //342 SPELL_AURA_MOD_MELEE_RANGED_HASTE_2
+ &AuraEffect::HandleNULL, //343 SPELL_AURA_343
+ &AuraEffect::HandleNULL, //344 SPELL_AURA_MOD_AUTOATTACK_DAMAGE
+ &AuraEffect::HandleNoImmediateEffect, //345 SPELL_AURA_BYPASS_ARMOR_FOR_CASTER
+ &AuraEffect::HandleEnableAltPower, //346 SPELL_AURA_ENABLE_ALT_POWER
+ &AuraEffect::HandleNULL, //347 SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE
+ &AuraEffect::HandleNoImmediateEffect, //348 SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT implemented in WorldSession::HandleLootMoneyOpcode
+ &AuraEffect::HandleNoImmediateEffect, //349 SPELL_AURA_MOD_CURRENCY_GAIN implemented in Player::ModifyCurrency
+ &AuraEffect::HandleNULL, //350 SPELL_AURA_MOD_GATHERING_ITEMS_GAINED_PERCENT
+ &AuraEffect::HandleNULL, //351 SPELL_AURA_351
+ &AuraEffect::HandleNULL, //352 SPELL_AURA_352
+ &AuraEffect::HandleNULL, //353 SPELL_AURA_MOD_CAMOUFLAGE
+ &AuraEffect::HandleNULL, //354 SPELL_AURA_354
+ &AuraEffect::HandleUnused, //355 unused (4.3.4)
+ &AuraEffect::HandleNULL, //356 SPELL_AURA_356
+ &AuraEffect::HandleNULL, //357 SPELL_AURA_ENABLE_BOSS1_UNIT_FRAME
+ &AuraEffect::HandleNULL, //358 SPELL_AURA_358
+ &AuraEffect::HandleNULL, //359 SPELL_AURA_359
+ &AuraEffect::HandleNULL, //360 SPELL_AURA_PROC_TRIGGER_SPELL_COPY
+ &AuraEffect::HandleNULL, //361 SPELL_AURA_PROC_TRIGGER_SPELL_2 implemented in Unit::ProcDamageAndSpellFor
+ &AuraEffect::HandleUnused, //362 unused (4.3.4)
+ &AuraEffect::HandleNULL, //363 SPELL_AURA_MOD_NEXT_SPELL
+ &AuraEffect::HandleUnused, //364 unused (4.3.4)
+ &AuraEffect::HandleNULL, //365 SPELL_AURA_MAX_FAR_CLIP_PLANE
+ &AuraEffect::HandleNULL, //366 SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT
+ &AuraEffect::HandleNULL, //367 SPELL_AURA_367
+ &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::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* caster):
@@ -418,7 +473,12 @@ void AuraEffect::GetApplicationList(std::list<AuraApplication*> & applicationLis
int32 AuraEffect::CalculateAmount(Unit* caster)
{
// default amount calculation
- int32 amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, NULL);
+ int32 amount = 0;
+
+ if (!(m_spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) || G3D::fuzzyEq(m_spellInfo->Effects[m_effIndex].BonusMultiplier, 0.0f))
+ amount = m_spellInfo->Effects[m_effIndex].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].BonusMultiplier);
// check item enchant aura cast
if (!amount && caster)
@@ -468,9 +528,9 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
Unit::AuraEffectList const& overrideClassScripts = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (Unit::AuraEffectList::const_iterator itr = overrideClassScripts.begin(); itr != overrideClassScripts.end(); ++itr)
{
- if ((*itr)->IsAffectedOnSpell(m_spellInfo))
+ if ((*itr)->IsAffectingSpell(m_spellInfo))
{
- // Glyph of Fear, Glyph of Frost nova and similar auras
+ // Glyph of Frost nova and similar auras
if ((*itr)->GetMiscValue() == 7801)
{
AddPct(amount, (*itr)->GetAmount());
@@ -484,6 +544,45 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
case SPELL_AURA_MANA_SHIELD:
m_canBeRecalculated = false;
break;
+ case SPELL_AURA_MOUNTED:
+ if (MountCapabilityEntry const* mountCapability = GetBase()->GetUnitOwner()->GetMountCapability(uint32(GetMiscValueB())))
+ {
+ amount = mountCapability->Id;
+ m_canBeRecalculated = false;
+ }
+ break;
+ case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE:
+ {
+ if (caster)
+ {
+ // if Level <= 70 resist = player level
+ int32 resist = caster->getLevel();
+
+ if (resist > 70 && resist < 81)
+ resist += (resist - 70) * 5;
+ else if (resist > 80)
+ resist += ((resist-70) * 5 + (resist - 80) * 7);
+
+ switch (GetId())
+ {
+ case 20043: // Aspect of the Wild
+ case 8185: // Elemental Resistance
+ case 19891: // Resistance Aura
+ case 79106: // Shadow Protection
+ case 79107: // Shadow Protection
+ amount = resist;
+ break;
+ case 79060: // Mark of the Wild
+ case 79061: // Mark of the Wild
+ case 79062: // Blessing of Kings
+ case 79063: // Blessing of Kings
+ case 90363: // Embrace of the Shale Spider
+ amount = resist / 2;
+ break;
+ }
+ break;
+ }
+ }
default:
break;
}
@@ -493,7 +592,7 @@ int32 AuraEffect::CalculateAmount(Unit* caster)
return amount;
}
-void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load)
+void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= true*/, bool load /*= false*/)
{
m_amplitude = m_spellInfo->Effects[m_effIndex].Amplitude;
@@ -544,8 +643,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load)
if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
caster->ModSpellCastTime(m_spellInfo, m_amplitude);
}
- // and periodic time of auras affected by SPELL_AURA_PERIODIC_HASTE
- else if (caster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, m_spellInfo) || m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
+ else if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
m_amplitude = int32(m_amplitude * caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
}
}
@@ -563,9 +661,6 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load)
// reset periodic timer on aura create or on reapply when aura isn't dot
// possibly we should not reset periodic timers only when aura is triggered by proc
// or maybe there's a spell attribute somewhere
- bool resetPeriodicTimer = create
- || ((GetAuraType() != SPELL_AURA_PERIODIC_DAMAGE) && (GetAuraType() != SPELL_AURA_PERIODIC_DAMAGE_PERCENT));
-
if (resetPeriodicTimer)
{
m_periodicTimer = 0;
@@ -794,6 +889,16 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
case 49472: // Drink Coffee
case 57073:
case 61830:
+ case 69176:
+ case 72623:
+ case 80166:
+ case 80167:
+ case 87958:
+ case 87959:
+ case 92736:
+ case 92797:
+ case 92800:
+ case 92803:
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
return;
// Get SPELL_AURA_MOD_POWER_REGEN aura from spell
@@ -893,21 +998,10 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
bool AuraEffect::IsPeriodicTickCrit(Unit* target, Unit const* caster) const
{
ASSERT(caster);
- Unit::AuraEffectList const& mPeriodicCritAuras= caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_PERIODIC_CRIT);
- for (Unit::AuraEffectList::const_iterator itr = mPeriodicCritAuras.begin(); itr != mPeriodicCritAuras.end(); ++itr)
- {
- if ((*itr)->IsAffectedOnSpell(m_spellInfo) && caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask()))
- return true;
- }
-
- // Rupture - since 3.3.3 can crit
- if (m_spellInfo->SpellIconID == 500 && m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE)
- return caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask());
-
- return false;
+ return caster->isSpellCrit(target, m_spellInfo, m_spellInfo->GetSchoolMask());
}
-bool AuraEffect::IsAffectedOnSpell(SpellInfo const* spell) const
+bool AuraEffect::IsAffectingSpell(SpellInfo const* spell) const
{
if (!spell)
return false;
@@ -1033,14 +1127,11 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
{
uint32 spellId = 0;
uint32 spellId2 = 0;
- //uint32 spellId3 = 0;
- uint32 HotWSpellId = 0;
switch (GetMiscValue())
{
case FORM_CAT:
spellId = 3025;
- HotWSpellId = 24900;
break;
case FORM_TREE:
spellId = 34123;
@@ -1054,12 +1145,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
case FORM_BEAR:
spellId = 1178;
spellId2 = 21178;
- HotWSpellId = 24899;
- break;
- case FORM_DIREBEAR:
- spellId = 9635;
- spellId2 = 21178;
- HotWSpellId = 24899;
break;
case FORM_BATTLESTANCE:
spellId = 21156;
@@ -1072,7 +1157,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
break;
case FORM_MOONKIN:
spellId = 24905;
- spellId2 = 69366;
+ spellId2 = 24907;
break;
case FORM_FLIGHT:
spellId = 33948;
@@ -1092,7 +1177,6 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
break;
case FORM_SHADOW:
spellId = 49868;
- spellId2 = 71167;
break;
case FORM_GHOSTWOLF:
spellId = 67116;
@@ -1126,7 +1210,9 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
if (target->GetTypeId() == TYPEID_PLAYER)
{
- const PlayerSpellMap& sp_list = target->ToPlayer()->GetSpellMap();
+ Player* plrTarget = target->ToPlayer();
+
+ PlayerSpellMap const& sp_list = plrTarget->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
@@ -1139,6 +1225,9 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE)))
continue;
+ if ((spellInfo->AttributesEx8 & SPELL_ATTR8_MASTERY_SPECIALIZATION) && !plrTarget->IsCurrentSpecMasterySpell(spellInfo))
+ continue;
+
if (spellInfo->Stances & (1<<(GetMiscValue()-1)))
target->CastSpell(target, itr->first, true, NULL, this);
}
@@ -1146,49 +1235,52 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
// Also do it for Glyphs
for (uint32 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
{
- if (uint32 glyphId = target->ToPlayer()->GetGlyph(i))
+ if (uint32 glyphId = plrTarget->GetGlyph(plrTarget->GetActiveSpec(), i))
{
if (GlyphPropertiesEntry const* glyph = sGlyphPropertiesStore.LookupEntry(glyphId))
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(glyph->SpellId);
if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR0_PASSIVE | SPELL_ATTR0_HIDDEN_CLIENTSIDE)))
continue;
- if (spellInfo->Stances & (1<<(GetMiscValue()-1)))
+
+ if (spellInfo->Stances & (1 << (GetMiscValue() - 1)))
target->CastSpell(target, glyph->SpellId, true, NULL, this);
}
}
}
// Leader of the Pack
- if (target->ToPlayer()->HasSpell(17007))
+ if (plrTarget->HasSpell(17007))
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24932);
- if (spellInfo && spellInfo->Stances & (1<<(GetMiscValue()-1)))
+ if (spellInfo && spellInfo->Stances & (1 << (GetMiscValue() -1)))
target->CastSpell(target, 24932, true, NULL, this);
}
- // Improved Barkskin - apply/remove armor bonus due to shapeshift
- if (target->ToPlayer()->HasSpell(63410) || target->ToPlayer()->HasSpell(63411))
- {
- target->RemoveAurasDueToSpell(66530);
- if (GetMiscValue() == FORM_TRAVEL || GetMiscValue() == FORM_NONE) // "while in Travel Form or while not shapeshifted"
- target->CastSpell(target, 66530, true);
- }
+
// Heart of the Wild
- if (HotWSpellId)
- { // hacky, but the only way as spell family is not SPELLFAMILY_DRUID
- Unit::AuraEffectList const& mModTotalStatPct = target->GetAuraEffectsByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for (Unit::AuraEffectList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- {
- // Heart of the Wild
- if ((*i)->GetSpellInfo()->SpellIconID == 240 && (*i)->GetMiscValue() == 3)
- {
- int32 HotWMod = (*i)->GetAmount() / 2; // For each 2% Intelligence, you get 1% stamina and 1% attack power.
+ if (AuraEffect const* heartOfTheWild = target->GetAuraEffectOfRankedSpell(17003, EFFECT_0))
+ {
+ uint32 heartOfTheWildSpellId = 0;
+ int32 heartOfTheWildAmount = 0;
- target->CastCustomSpell(target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
+ 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:
@@ -1196,7 +1288,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
if (target->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_DRUID, 0, 0x10000000, 0))
target->CastSpell(target, 62071, true);
// Nurturing Instinct
- if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254, 0))
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254, EFFECT_0))
{
uint32 spellId3 = 0;
switch (aurEff->GetId())
@@ -1211,43 +1303,36 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
target->CastSpell(target, spellId3, true, NULL, this);
}
// Master Shapeshifter - Cat
- if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_HEALING_DONE_PERCENT, SPELLFAMILY_GENERIC, 2851, EFFECT_0))
{
int32 bp = aurEff->GetAmount();
target->CastCustomSpell(target, 48420, &bp, NULL, NULL, true);
}
- break;
- case FORM_DIREBEAR:
+ break;
case FORM_BEAR:
// Master Shapeshifter - Bear
- if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_HEALING_DONE_PERCENT, SPELLFAMILY_GENERIC, 2851, EFFECT_0))
{
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, 0))
+ 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();
+ int32 bp = aurEff->GetSpellInfo()->Effects[EFFECT_2].CalcValue(GetCaster());
target->CastCustomSpell(target, 62069, &bp, NULL, NULL, true, 0, this);
}
- break;
+ break;
case FORM_MOONKIN:
// Master Shapeshifter - Moonkin
- if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_AURA_MOD_HEALING_DONE_PERCENT, SPELLFAMILY_GENERIC, 2851, EFFECT_0))
{
int32 bp = aurEff->GetAmount();
target->CastCustomSpell(target, 48421, &bp, NULL, NULL, true);
}
- break;
- // Master Shapeshifter - Tree of Life
- case FORM_TREE:
- if (AuraEffect const* aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
- {
- int32 bp = aurEff->GetAmount();
- target->CastCustomSpell(target, 48422, &bp, NULL, NULL, true);
- }
- break;
+ break;
+ default:
+ break;
}
}
}
@@ -1258,17 +1343,7 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
if (spellId2)
target->RemoveOwnedAura(spellId2, target->GetGUID());
- // Improved Barkskin - apply/remove armor bonus due to shapeshift
- if (Player* player=target->ToPlayer())
- {
- if (player->HasSpell(63410) || player->HasSpell(63411))
- {
- target->RemoveAurasDueToSpell(66530);
- target->CastSpell(target, 66530, true);
- }
- }
-
- const Unit::AuraEffectList& shapeshifts = target->GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT);
+ Unit::AuraEffectList const& shapeshifts = target->GetAuraEffectsByType(SPELL_AURA_MOD_SHAPESHIFT);
AuraEffect* newAura = NULL;
// Iterate through all the shapeshift auras that the target has, if there is another aura with SPELL_AURA_MOD_SHAPESHIFT, then this aura is being removed due to that one being applied
for (Unit::AuraEffectList::const_iterator itr = shapeshifts.begin(); itr != shapeshifts.end(); ++itr)
@@ -1279,11 +1354,12 @@ void AuraEffect::HandleShapeshiftBoosts(Unit* target, bool apply) const
break;
}
}
+
Unit::AuraApplicationMap& tAuras = target->GetAppliedAuras();
for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
{
// Use the new aura to see on what stance the target will be
- uint32 newStance = (1<<((newAura ? newAura->GetMiscValue() : 0)-1));
+ uint32 newStance = (1 << ((newAura ? newAura->GetMiscValue() : 0) -1));
// If the stances are not compatible with the spell, remove it
if (itr->second->GetBase()->IsRemovedOnShapeLost(target) && !(itr->second->GetBase()->GetSpellInfo()->Stances & newStance))
@@ -1530,27 +1606,21 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
Unit* target = aurApp->GetTarget();
- // no-phase is also phase state so same code for apply and remove
- uint32 newPhase = 0;
- Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE);
- if (!phases.empty())
- for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
- newPhase |= (*itr)->GetMiscValue();
-
if (Player* player = target->ToPlayer())
{
- if (!newPhase)
- newPhase = PHASEMASK_NORMAL;
-
- // GM-mode have mask 0xFFFFFFFF
- if (player->IsGameMaster())
- newPhase = 0xFFFFFFFF;
-
- player->SetPhaseMask(newPhase, false);
- player->GetSession()->SendSetPhaseShift(newPhase);
+ if (apply)
+ player->GetPhaseMgr().RegisterPhasingAuraEffect(this);
+ else
+ player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this);
}
else
{
+ uint32 newPhase = 0;
+ Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE);
+ if (!phases.empty())
+ for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
+ newPhase |= (*itr)->GetMiscValue();
+
if (!newPhase)
{
newPhase = PHASEMASK_NORMAL;
@@ -1598,7 +1668,6 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
break;
case FORM_BEAR: // 0x05
- case FORM_DIREBEAR: // 0x08
case FORM_BATTLESTANCE: // 0x11
case FORM_DEFENSIVESTANCE: // 0x12
@@ -1648,7 +1717,6 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
case FORM_TRAVEL:
case FORM_AQUA:
case FORM_BEAR:
- case FORM_DIREBEAR:
case FORM_FLIGHT_EPIC:
case FORM_FLIGHT:
case FORM_MOONKIN:
@@ -1677,47 +1745,26 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (PowerType != POWER_MANA)
{
- uint32 oldPower = target->GetPower(PowerType);
+ int32 oldPower = target->GetPower(PowerType);
// reset power to default values only at power change
if (target->getPowerType() != PowerType)
target->setPowerType(PowerType);
- switch (form)
+ if (form == FORM_CAT || form == FORM_BEAR)
{
- case FORM_CAT:
- case FORM_BEAR:
- case FORM_DIREBEAR:
- {
- // get furor proc chance
- uint32 FurorChance = 0;
- if (AuraEffect const* dummy = target->GetDummyAuraEffect(SPELLFAMILY_DRUID, 238, 0))
- FurorChance = std::max(dummy->GetAmount(), 0);
+ // get furor proc chance
+ int32 FurorChance = 0;
+ if (AuraEffect const* dummy = target->GetDummyAuraEffect(SPELLFAMILY_DRUID, 238, 0))
+ FurorChance = std::max(dummy->GetAmount(), 0);
- switch (GetMiscValue())
- {
- case FORM_CAT:
- {
- int32 basePoints = int32(std::min(oldPower, FurorChance));
- target->SetPower(POWER_ENERGY, 0);
- target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this);
- break;
- }
- case FORM_BEAR:
- case FORM_DIREBEAR:
- if (urand(0, 99) < FurorChance)
- target->CastSpell(target, 17057, true);
- break;
- default:
- {
- uint32 newEnergy = std::min(target->GetPower(POWER_ENERGY), FurorChance);
- target->SetPower(POWER_ENERGY, newEnergy);
- break;
- }
- }
- break;
+ if (form == FORM_CAT)
+ {
+ int32 basePoints = std::min<int32>(oldPower, FurorChance);
+ target->SetPower(POWER_ENERGY, 0);
+ target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this);
}
- default:
- break;
+ else if (roll_chance_i(FurorChance))
+ target->CastSpell(target, 17057, true);
}
}
// stop handling the effect if it was removed by linked event
@@ -1748,7 +1795,6 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
{
// Nordrassil Harness - bonus
case FORM_BEAR:
- case FORM_DIREBEAR:
case FORM_CAT:
if (AuraEffect* dummy = target->GetAuraEffect(37315, 0))
target->CastSpell(target, 37316, true, NULL, dummy);
@@ -1762,7 +1808,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
case FORM_DEFENSIVESTANCE:
case FORM_BERSERKERSTANCE:
{
- uint32 Rage_val = 0;
+ int32 Rage_val = 0;
// Defensive Tactics
if (form == FORM_DEFENSIVESTANCE)
{
@@ -1811,9 +1857,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (!target->CanUseAttackType(BASE_ATTACK))
{
if (Item* pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
- {
target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetTemplate(), NULL, apply);
- }
}
}
@@ -1823,9 +1867,9 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo
if (target->GetTypeId() == TYPEID_PLAYER)
{
- SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ SpellShapeshiftFormEntry const* shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
// Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
- for (uint8 i = 0; i<MAX_SHAPESHIFT_SPELLS; ++i)
+ for (uint8 i = 0; i < MAX_SHAPESHIFT_SPELLS; ++i)
{
if (!shapeInfo->stanceSpell[i])
continue;
@@ -2112,9 +2156,7 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo
if (apply)
{
/*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data << target->GetGUID();
- data << uint8(0);
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 0);
target->SendMessageToSet(&data, true);
*/
@@ -2160,9 +2202,7 @@ void AuraEffect::HandleFeignDeath(AuraApplication const* aurApp, uint8 mode, boo
else
{
/*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data << target->GetGUID();
- data << uint8(1);
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 0);
target->SendMessageToSet(&data, true);
*/
@@ -2206,8 +2246,8 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode,
AuraType type = GetAuraType();
- //Prevent handling aura twice
- if ((apply) ? target->GetAuraEffectsByType(type).size() > 1 : target->HasAuraType(type))
+ // Prevent handling aura twice
+ if (apply ? target->GetAuraEffectsByType(type).size() > 1 : target->HasAuraType(type))
return;
uint32 field, flag, slot;
@@ -2478,17 +2518,18 @@ void AuraEffect::HandleAuraModSkill(AuraApplication const* aurApp, uint8 mode, b
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SKILL)))
return;
- Unit* target = aurApp->GetTarget();
- if (target->GetTypeId() != TYPEID_PLAYER)
+ Player* target = aurApp->GetTarget()->ToPlayer();
+ if (!target)
return;
uint32 prot = GetMiscValue();
int32 points = GetAmount();
- target->ToPlayer()->ModifySkillBonus(prot, ((apply) ? points: -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT);
if (prot == SKILL_DEFENSE)
- target->ToPlayer()->UpdateDefenseBonusesMod();
+ return;
+
+ target->ModifySkillBonus(prot, (apply ? points : -points), GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT);
}
/****************************/
@@ -2532,6 +2573,11 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
}
target->Mount(displayId, vehicleId, creatureEntry);
+
+ // cast speed aura
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(GetAmount()))
+ target->CastSpell(target, mountCapability->SpeedModSpell, true);
}
else
{
@@ -2540,7 +2586,13 @@ void AuraEffect::HandleAuraMounted(AuraApplication const* aurApp, uint8 mode, bo
// need to remove ALL arura related to mounts, this will stop client crash with broom stick
// and never endless flying after using Headless Horseman's Mount
if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
target->RemoveAurasByType(SPELL_AURA_MOUNTED);
+
+ // remove speed aura
+ if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(GetAmount()))
+ target->RemoveAurasDueToSpell(mountCapability->SpeedModSpell, target->GetGUID());
+ }
}
}
@@ -3686,19 +3738,13 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
Unit* target = aurApp->GetTarget();
- if (GetMiscValue() < -1 || GetMiscValue() > 4)
- {
- TC_LOG_ERROR("spells", "WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
- return;
- }
-
// save current health state
float healthPct = target->GetHealthPct();
bool alive = target->IsAlive();
for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
{
- if (GetMiscValue() == i || GetMiscValue() == -1)
+ if (GetMiscValueB() & 1 << i || !GetMiscValueB()) // 0 is also used for all stats
{
target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetAmount()), apply);
if (target->GetTypeId() == TYPEID_PLAYER || target->ToCreature()->IsPet())
@@ -3708,7 +3754,7 @@ void AuraEffect::HandleModTotalPercentStat(AuraApplication const* aurApp, uint8
// recalculate current HP/MP after applying aura modifications (only for spells with SPELL_ATTR0_UNK4 0x00000010 flag)
// this check is total bullshit i think
- if (GetMiscValue() == STAT_STAMINA && (m_spellInfo->Attributes & SPELL_ATTR0_ABILITY))
+ if (GetMiscValueB() & 1 << STAT_STAMINA && (m_spellInfo->Attributes & SPELL_ATTR0_ABILITY))
target->SetHealth(std::max<uint32>(uint32(healthPct * target->GetMaxHealth() * 0.01f), (alive ? 1 : 0)));
}
@@ -3764,7 +3810,7 @@ void AuraEffect::HandleModPowerRegen(AuraApplication const* aurApp, uint8 mode,
// Update manaregen value
if (GetMiscValue() == POWER_MANA)
target->ToPlayer()->UpdateManaRegen();
- else if (GetMiscValue() == POWER_RUNE)
+ else if (GetMiscValue() == POWER_RUNES)
target->ToPlayer()->UpdateRuneRegen(RuneType(GetMiscValueB()));
// other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
}
@@ -4085,6 +4131,7 @@ void AuraEffect::HandleModMeleeRangedSpeedPct(AuraApplication const* aurApp, uin
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
+ //! ToDo: Haste auras with the same handler _CAN'T_ stack together
Unit* target = aurApp->GetTarget();
target->ApplyAttackTimePercentMod(BASE_ATTACK, (float)GetAmount(), apply);
@@ -4121,6 +4168,7 @@ void AuraEffect::HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mod
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
+ //! ToDo: Haste auras with the same handler _CAN'T_ stack together
Unit* target = aurApp->GetTarget();
target->ApplyAttackTimePercentMod(BASE_ATTACK, float(GetAmount()), apply);
@@ -4132,24 +4180,12 @@ void AuraEffect::HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 m
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
return;
+ //! ToDo: Haste auras with the same handler _CAN'T_ stack together
Unit* target = aurApp->GetTarget();
target->ApplyAttackTimePercentMod(RANGED_ATTACK, (float)GetAmount(), apply);
}
-void AuraEffect::HandleRangedAmmoHaste(AuraApplication const* aurApp, uint8 mode, bool apply) const
-{
- if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
- return;
-
- Unit* target = aurApp->GetTarget();
-
- if (target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- target->ApplyAttackTimePercentMod(RANGED_ATTACK, (float)GetAmount(), apply);
-}
-
/********************************/
/*** COMBAT RATING ***/
/********************************/
@@ -4237,23 +4273,6 @@ void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const* au
target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()), apply);
}
-void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
-{
- if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
- return;
-
- Unit* target = aurApp->GetTarget();
-
- // Recalculate bonus
- if (target->GetTypeId() == TYPEID_PLAYER && !(target->getClassMask() & CLASSMASK_WAND_USERS))
- target->ToPlayer()->UpdateAttackPowerAndDamage(true);
-}
-
-void AuraEffect::HandleAuraModAttackPowerOfStatPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const
-{
- HandleAuraModAttackPowerOfArmor(aurApp, mode, apply);
-}
-
void AuraEffect::HandleAuraModAttackPowerOfArmor(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
{
if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
@@ -4523,28 +4542,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
// AT APPLY
if (apply)
{
- // Overpower
- if (caster && m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR &&
- m_spellInfo->SpellFamilyFlags[0] & 0x4)
- {
- // In addition, if you strike a player..
- if (target->GetTypeId() != TYPEID_PLAYER)
- return;
- // ..while they are casting
- if (target->IsNonMeleeSpellCast(false, false, true, false, true))
- if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARRIOR, 2775, 0))
- switch (aurEff->GetId())
- {
- // Unrelenting Assault, rank 1
- case 46859:
- target->CastSpell(target, 64849, true, NULL, aurEff);
- break;
- // Unrelenting Assault, rank 2
- case 46860:
- target->CastSpell(target, 64850, true, NULL, aurEff);
- break;
- }
- }
switch (GetId())
{
case 1515: // Tame beast
@@ -4597,22 +4594,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
}
break;
}
- case 55198: // Tidal Force
- {
- target->CastSpell(target, 55166, true, NULL, this);
- // set 3 stacks and 3 charges (to make all auras not disappear at once)
- Aura* owner_aura = target->GetAura(55166, GetCasterGUID());
- if (owner_aura)
- {
- // This aura lasts 2 sec, need this hack to properly proc spells
- /// @todo drop aura charges for ApplySpellMod in ProcDamageAndSpell
- GetBase()->SetDuration(owner_aura->GetDuration());
- // Make aura be not charged-this prevents removing charge on not crit spells
- owner_aura->SetCharges(0);
- owner_aura->SetStackAmount(owner_aura->GetSpellInfo()->StackAmount);
- }
- break;
- }
case 39850: // Rocket Blast
if (roll_chance_i(20)) // backfire stun
target->CastSpell(target, 51581, true, NULL, this);
@@ -4638,10 +4619,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (caster)
target->GetMotionMaster()->MoveFall();
break;
- case 46699: // Requires No Ammo
- if (target->GetTypeId() == TYPEID_PLAYER)
- target->ToPlayer()->RemoveAmmo(); // not use ammo and not allow use
- break;
case 52916: // Honor Among Thieves
if (target->GetTypeId() == TYPEID_PLAYER)
if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget()))
@@ -4734,8 +4711,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
case 60244: // Blood Parrot Despawn Aura
target->CastSpell((Unit*)NULL, GetAmount(), true, NULL, this);
break;
- case 58600: // Restricted Flight Area
- case 58730: // Restricted Flight Area
+ case 91604: // Restricted Flight Area
if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
target->CastSpell(target, 58601, true);
break;
@@ -4943,15 +4919,6 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod
if (!plCaster->isHonorOrXPTarget(target) ||
(target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(plCaster)))
return;
-
- // If this is Drain Soul, check for Glyph of Drain Soul
- if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000))
- {
- // Glyph of Drain Soul - chance to create an additional Soul Shard
- if (AuraEffect* aur = caster->GetAuraEffect(58070, 0))
- if (roll_chance_i(aur->GetMiscValue()))
- caster->CastSpell(caster, 58068, true, 0, aur); // We _could_ simply do ++count here, but Blizz does it this way :)
- }
}
//Adding items
@@ -5235,7 +5202,7 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode,
Unit* target = aurApp->GetTarget();
- if (target->GetTypeId() != TYPEID_PLAYER || !target->IsInWorld())
+ if (!target->IsInWorld())
return;
uint32 vehicleId = GetMiscValue();
@@ -5248,6 +5215,9 @@ void AuraEffect::HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode,
else if (target->GetVehicleKit())
target->RemoveVehicleKit();
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
WorldPacket data(SMSG_PLAYER_VEHICLE_DATA, target->GetPackGUID().size()+4);
data.appendPackGUID(target->GetGUID());
data << uint32(apply ? vehicleId : 0);
@@ -5271,6 +5241,18 @@ void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8
aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, 0, PLAYER_FIELD_BYTE_RELEASE_TIMER);
}
+void AuraEffect::HandleMastery(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Player* target = aurApp->GetTarget()->ToPlayer();
+ if (!target)
+ return;
+
+ target->UpdateMastery();
+}
+
void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
{
switch (GetSpellInfo()->SpellFamilyName)
@@ -5342,23 +5324,6 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const
}
break;
}
- case SPELLFAMILY_ROGUE:
- {
- switch (GetSpellInfo()->Id)
- {
- // Master of Subtlety
- case 31666:
- if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- target->RemoveAurasDueToSpell(31665);
- break;
- // Overkill
- case 58428:
- if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- target->RemoveAurasDueToSpell(58427);
- break;
- }
- break;
- }
case SPELLFAMILY_HUNTER:
{
// Explosive Shot
@@ -5657,13 +5622,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
case 66882:
target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000 * 2 / 3), NULL, true, NULL, this);
return;
- // Beacon of Light
- case 53563:
- {
- // area aura owner casts the spell
- GetBase()->GetUnitOwner()->CastSpell(target, triggeredSpellInfo, true, 0, this, GetBase()->GetUnitOwner()->GetGUID());
- return;
- }
// Slime Spray - temporary here until preventing default effect works again
// added on 9.10.2010
case 69508:
@@ -5814,16 +5772,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00004000))
{
if (caster->GetTypeId() == TYPEID_PLAYER && caster->ToPlayer()->isHonorOrXPTarget(target))
- {
- if (roll_chance_i(20))
- {
- caster->CastSpell(caster, 43836, true, 0, this);
- // Glyph of Drain Soul - chance to create an additional Soul Shard
- if (AuraEffect* aur = caster->GetAuraEffect(58070, 0))
- if (roll_chance_i(aur->GetMiscValue()))
- caster->CastSpell(caster, 58068, true, 0, aur);
- }
- }
+ caster->CastSpell(caster, 95810, true, 0, this);
}
if (GetSpellInfo()->SpellFamilyName == SPELLFAMILY_GENERIC)
{
@@ -5848,7 +5797,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
int32 dmg = damage;
- caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
+ caster->ApplyResilience(target, &dmg);
damage = dmg;
caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo());
@@ -5915,7 +5864,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
}
int32 dmg = damage;
- caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
+ caster->ApplyResilience(target, &dmg);
damage = dmg;
caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo);
@@ -6018,15 +5967,6 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
if (maxval)
AddPct(TakenTotalMod, maxval);
- // Healing over time taken percent
- float minval_hot = (float)target->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT);
- if (minval_hot)
- AddPct(TakenTotalMod, minval_hot);
-
- float maxval_hot = (float)target->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT);
- if (maxval_hot)
- AddPct(TakenTotalMod, maxval_hot);
-
TakenTotalMod = std::max(TakenTotalMod, 0.0f);
damage = uint32(target->CountPctFromMaxHealth(damage));
@@ -6072,7 +6012,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
// Health Funnel
// damage caster for heal amount
- if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL)
+ if (target != caster && GetSpellInfo()->AttributesEx2 & SPELL_ATTR2_HEALTH_FUNNEL && GetSpellInfo()->Id != 755)
{
uint32 funnelDamage = GetSpellInfo()->ManaPerSecond; // damage is not affected by spell power
@@ -6129,10 +6069,6 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
TC_LOG_INFO("spells", "PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), drainAmount, GetId());
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- if (powerType == POWER_MANA)
- drainAmount -= target->GetSpellCritDamageReduction(drainAmount);
-
int32 drainedAmount = -target->ModifyPower(powerType, -drainAmount);
float gainMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
@@ -6247,10 +6183,6 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
// ignore negative values (can be result apply spellmods to aura damage
int32 damage = std::max(m_amount, 0);
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- if (powerType == POWER_MANA)
- damage -= target->GetSpellCritDamageReduction(damage);
-
uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
float dmgMultiplier = GetSpellInfo()->Effects[GetEffIndex()].CalcValueMultiplier(caster);
@@ -6410,3 +6342,52 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA
TC_LOG_DEBUG("spells", "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: Triggering spell %u from aura %u proc", triggerSpellId, GetId());
target->CastCustomSpell(target, triggerSpellId, &value, NULL, NULL, true, NULL, this, GetCasterGUID());
}
+
+void AuraEffect::HandleAuraForceWeather(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Player* target = aurApp->GetTarget()->ToPlayer();
+
+ if (!target)
+ return;
+
+ if (apply)
+ {
+ WorldPacket data(SMSG_WEATHER, (4 + 4 + 1));
+
+ data << uint32(GetMiscValue()) << 1.0f << uint8(0);
+ target->GetSession()->SendPacket(&data);
+ }
+ else
+ {
+ // send weather for current zone
+ if (Weather* weather = WeatherMgr::FindWeather(target->GetZoneId()))
+ weather->SendWeatherUpdateToPlayer(target);
+ else
+ {
+ if (!WeatherMgr::AddWeather(target->GetZoneId()))
+ {
+ // send fine weather packet to remove old weather
+ WeatherMgr::SendFineWeatherUpdateToPlayer(target);
+ }
+ }
+ }
+}
+
+void AuraEffect::HandleEnableAltPower(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ uint32 altPowerId = GetMiscValue();
+ UnitPowerBarEntry const* powerEntry = sUnitPowerBarStore.LookupEntry(altPowerId);
+ if (!powerEntry)
+ return;
+
+ if (apply)
+ aurApp->GetTarget()->SetMaxPower(POWER_ALTERNATE_POWER, powerEntry->MaxPower);
+ else
+ aurApp->GetTarget()->SetMaxPower(POWER_ALTERNATE_POWER, 0);
+}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 0887ce123e2..2e849fff963 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -59,7 +59,7 @@ class AuraEffect
void SetPeriodicTimer(int32 periodicTimer) { m_periodicTimer = periodicTimer; }
int32 CalculateAmount(Unit* caster);
- void CalculatePeriodic(Unit* caster, bool create = false, bool load = false);
+ void CalculatePeriodic(Unit* caster, bool resetPeriodicTimer = true, bool load = false);
void CalculateSpellMod();
void ChangeAmount(int32 newAmount, bool mark = true, bool onStackOrReapply = false);
void RecalculateAmount() { if (!CanBeRecalculated()) return; ChangeAmount(CalculateAmount(GetCaster()), false); }
@@ -79,7 +79,7 @@ class AuraEffect
bool IsPeriodic() const { return m_isPeriodic; }
void SetPeriodic(bool isPeriodic) { m_isPeriodic = isPeriodic; }
- bool IsAffectedOnSpell(SpellInfo const* spell) const;
+ bool IsAffectingSpell(SpellInfo const* spell) const;
bool HasSpellClassMask() const { return m_spellInfo->Effects[m_effIndex].SpellClassMask; }
void SendTickImmune(Unit* target, Unit* caster) const;
@@ -242,7 +242,6 @@ class AuraEffect
void HandleModAttackSpeed(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModMeleeSpeedPct(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModRangedHaste(AuraApplication const* aurApp, uint8 mode, bool apply) const;
- void HandleRangedAmmoHaste(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// combat rating
void HandleModRating(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleModRatingFromStat(AuraApplication const* aurApp, uint8 mode, bool apply) const;
@@ -251,8 +250,6 @@ class AuraEffect
void HandleAuraModRangedAttackPower(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModRangedAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
- void HandleAuraModRangedAttackPowerOfStatPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
- void HandleAuraModAttackPowerOfStatPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraModAttackPowerOfArmor(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// damage bonus
void HandleModDamageDone(AuraApplication const* aurApp, uint8 mode, bool apply) const;
@@ -280,6 +277,9 @@ class AuraEffect
void HandleAuraOverrideSpells(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleAuraSetVehicle(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandlePreventResurrection(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleMastery(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleAuraForceWeather(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleEnableAltPower(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// aura effect periodic tick handlers
void HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const;
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 9c7fff612b7..44b2be40fec 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -147,6 +147,9 @@ void AuraApplication::_InitFlags(Unit* caster, uint8 effMask)
}
_flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
}
+
+ if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT)
+ _flags |= AFLAG_ANY_EFFECT_AMOUNT_SENT;
}
void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
@@ -192,7 +195,7 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
uint32 flags = _flags;
if (aura->GetMaxDuration() > 0 && !(aura->GetSpellInfo()->AttributesEx5 & SPELL_ATTR5_HIDE_DURATION))
flags |= AFLAG_DURATION;
- data << uint8(flags);
+ data << uint16(flags);
data << uint8(aura->GetCasterLevel());
// 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)
@@ -206,6 +209,12 @@ void AuraApplication::BuildUpdatePacket(ByteBuffer& data, bool remove) const
data << uint32(aura->GetMaxDuration());
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());
}
void AuraApplication::ClientUpdate(bool remove)
@@ -337,7 +346,7 @@ m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0),
m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1),
m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false)
{
- if (m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel)
+ if (m_spellInfo->ManaPerSecond)
m_timeCla = 1 * IN_MILLISECONDS;
m_maxDuration = CalcMaxDuration(caster);
@@ -681,7 +690,7 @@ void Aura::Update(uint32 diff, Unit* caster)
m_timeCla -= diff;
else if (caster)
{
- if (int32 manaPerSecond = m_spellInfo->ManaPerSecond + m_spellInfo->ManaPerSecondPerLevel * caster->getLevel())
+ if (int32 manaPerSecond = m_spellInfo->ManaPerSecond)
{
m_timeCla += 1000 - diff;
@@ -750,18 +759,35 @@ void Aura::RefreshDuration()
{
SetDuration(GetMaxDuration());
- if (m_spellInfo->ManaPerSecond || m_spellInfo->ManaPerSecondPerLevel)
+ if (m_spellInfo->ManaPerSecond)
m_timeCla = 1 * IN_MILLISECONDS;
}
void Aura::RefreshTimers()
{
m_maxDuration = CalcMaxDuration();
+ bool resetPeriodic = true;
+ if (m_spellInfo->AttributesEx8 & SPELL_ATTR8_DONT_RESET_PERIODIC_TIMER)
+ {
+ int32 minAmplitude = m_maxDuration;
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (AuraEffect const* eff = GetEffect(i))
+ if (int32 ampl = eff->GetAmplitude())
+ minAmplitude = std::min(ampl, minAmplitude);
+
+ // If only one tick remaining, roll it over into new duration
+ if (GetDuration() <= minAmplitude)
+ {
+ m_maxDuration += GetDuration();
+ resetPeriodic = false;
+ }
+ }
+
RefreshDuration();
Unit* caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (HasEffect(i))
- GetEffect(i)->CalculatePeriodic(caster, false, false);
+ GetEffect(i)->CalculatePeriodic(caster, resetPeriodic, false);
}
void Aura::SetCharges(uint8 charges)
@@ -782,7 +808,7 @@ uint8 Aura::CalcMaxCharges(Unit* caster) const
if (caster)
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, maxProcCharges);
- return maxProcCharges;
+ return uint8(maxProcCharges);
}
bool Aura::ModCharges(int32 num, AuraRemoveMode removeMode)
@@ -931,9 +957,12 @@ bool Aura::CanBeSaved() const
case 40075: // Fel Flak Fire
case 55849: // Power Spark
return false;
- break;
}
+ // When a druid logins, he doesnt have either eclipse power, nor the marker auras, nor the eclipse buffs. Dont save them.
+ if (GetId() == 67483 || GetId() == 67484 || GetId() == 48517 || GetId() == 48518)
+ return false;
+
// don't save auras removed by proc system
if (IsUsingCharges() && !GetCharges())
return false;
@@ -943,7 +972,7 @@ bool Aura::CanBeSaved() const
bool Aura::CanBeSentToClient() const
{
- return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect() || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect() || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING);
}
bool Aura::IsSingleTargetWith(Aura const* aura) const
@@ -1187,20 +1216,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
case SPELLFAMILY_MAGE:
if (!caster)
break;
- if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00000001 && GetSpellInfo()->SpellFamilyFlags[2] & 0x00000008)
- {
- // Glyph of Fireball
- if (caster->HasAura(56368))
- SetDuration(0);
- }
- else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00000020 && GetSpellInfo()->SpellVisual[0] == 13)
- {
- // Glyph of Frostbolt
- if (caster->HasAura(56370))
- SetDuration(0);
- }
/// @todo This should be moved to similar function in spell::hit
- else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x01000000)
+ if (GetSpellInfo()->SpellFamilyFlags[0] & 0x01000000)
{
// Polymorph Sound - Sheep && Penguin
if (GetSpellInfo()->SpellIconID == 82 && GetSpellInfo()->SpellVisual[0] == 12978)
@@ -1232,18 +1249,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
caster->CastSpell(caster, spellId, true);
}
break;
- case 44544: // Fingers of Frost
- {
- // See if we already have the indicator aura. If not, create one.
- if (Aura* aur = target->GetAura(74396))
- {
- // Aura already there. Refresh duration and set original charges
- aur->SetCharges(2);
- aur->RefreshDuration();
- }
- else
- target->AddAura(74396, target);
- }
default:
break;
}
@@ -1255,7 +1260,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (GetSpellInfo()->SpellFamilyFlags[0] & 0x02000000 && GetEffect(0))
{
// Improved Devouring Plague
- if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 1))
+ 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);
@@ -1285,49 +1290,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
if (target->HasAura(58039)) // Glyph of Blurred Speed
target->CastSpell(target, 61922, true); // Sprint (waterwalk)
break;
- case SPELLFAMILY_DEATHKNIGHT:
- if (!caster)
- break;
- // Frost Fever and Blood Plague
- if (GetSpellInfo()->SpellFamilyFlags[2] & 0x2)
- {
- // Can't proc on self
- if (GetCasterGUID() == target->GetGUID())
- break;
-
- AuraEffect* aurEff = NULL;
- // Ebon Plaguebringer / Crypt Fever
- Unit::AuraEffectList const& TalentAuras = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for (Unit::AuraEffectList::const_iterator itr = TalentAuras.begin(); itr != TalentAuras.end(); ++itr)
- {
- if ((*itr)->GetMiscValue() == 7282)
- {
- aurEff = *itr;
- // Ebon Plaguebringer - end search if found
- if ((*itr)->GetSpellInfo()->SpellIconID == 1766)
- break;
- }
- }
- if (aurEff)
- {
- uint32 spellId = 0;
- switch (aurEff->GetId())
- {
- // Ebon Plague
- case 51161: spellId = 51735; break;
- case 51160: spellId = 51734; break;
- case 51099: spellId = 51726; break;
- // Crypt Fever
- case 49632: spellId = 50510; break;
- case 49631: spellId = 50509; break;
- case 49032: spellId = 50508; break;
- default:
- TC_LOG_ERROR("spells", "Aura::HandleAuraSpecificMods: Unknown rank of Crypt Fever/Ebon Plague (%d) found", aurEff->GetId());
- }
- caster->CastSpell(target, spellId, true, 0, GetEffect(0));
- }
- }
- break;
}
}
// mods at aura remove
@@ -1366,54 +1328,9 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
target->CastSpell(target, 32612, true, NULL, GetEffect(1));
target->CombatStop();
break;
- case 74396: // Fingers of Frost
- // Remove the IGNORE_AURASTATE aura
- target->RemoveAurasDueToSpell(44544);
- break;
- case 44401: //Missile Barrage
- case 48108: //Hot Streak
- case 57761: //Fireball!
- if (removeMode != AURA_REMOVE_BY_EXPIRE || aurApp->GetBase()->IsExpired())
- break;
- if (target->HasAura(70752)) //Item - Mage T10 2P Bonus
- target->CastSpell(target, 70753, true);
- break;
default:
break;
}
- if (!caster)
- break;
- // Ice barrier - dispel/absorb remove
- if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellInfo()->SpellFamilyFlags[1] & 0x1)
- {
- // Shattered Barrier
- if (AuraEffect* dummy = caster->GetDummyAuraEffect(SPELLFAMILY_MAGE, 2945, 0))
- if (roll_chance_i(dummy->GetSpellInfo()->ProcChance))
- caster->CastSpell(target, 55080, true, NULL, GetEffect(0));
- }
- break;
- case SPELLFAMILY_WARRIOR:
- if (!caster)
- break;
- // Spell Reflection
- if (GetSpellInfo()->SpellFamilyFlags[1] & 0x2)
- {
- if (removeMode != AURA_REMOVE_BY_DEFAULT)
- {
- // Improved Spell Reflection
- if (caster->GetDummyAuraEffect(SPELLFAMILY_WARRIOR, 1935, 1))
- {
- // aura remove - remove auras from all party members
- std::list<Unit*> PartyMembers;
- target->GetPartyMembers(PartyMembers);
- for (std::list<Unit*>::iterator itr = PartyMembers.begin(); itr != PartyMembers.end(); ++itr)
- {
- if ((*itr)!= target)
- (*itr)->RemoveAurasWithFamily(SPELLFAMILY_WARRIOR, 0, 0x2, 0, GetCasterGUID());
- }
- }
- }
- }
break;
case SPELLFAMILY_WARLOCK:
if (!caster)
@@ -1439,18 +1356,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
case SPELLFAMILY_PRIEST:
if (!caster)
break;
- // Shadow word: Pain // Vampiric Touch
- if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && (GetSpellInfo()->SpellFamilyFlags[0] & 0x00008000 || GetSpellInfo()->SpellFamilyFlags[1] & 0x00000400))
- {
- // Shadow Affinity
- if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 178, 1))
- {
- int32 basepoints0 = aurEff->GetAmount() * caster->GetCreateMana() / 100;
- caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
- }
- }
// Power word: shield
- else if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellInfo()->SpellFamilyFlags[0] & 0x00000001)
+ if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellInfo()->SpellFamilyFlags[0] & 0x00000001)
{
// Rapture
if (Aura const* aura = caster->GetAuraOfRankedSpell(47535))
@@ -1472,68 +1379,12 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
// effect on caster
if (AuraEffect const* aurEff = aura->GetEffect(0))
{
- float multiplier = (float)aurEff->GetAmount();
- if (aurEff->GetId() == 47535)
- multiplier -= 0.5f;
- else if (aurEff->GetId() == 47537)
- multiplier += 0.5f;
-
+ float multiplier = float(aurEff->GetAmount());
int32 basepoints0 = int32(CalculatePct(caster->GetMaxPower(POWER_MANA), multiplier));
caster->CastCustomSpell(caster, 47755, &basepoints0, NULL, NULL, true);
}
- // effect on aura target
- if (AuraEffect const* aurEff = aura->GetEffect(1))
- {
- if (!roll_chance_i(aurEff->GetAmount()))
- break;
-
- int32 triggeredSpellId = 0;
- switch (target->getPowerType())
- {
- case POWER_MANA:
- {
- int32 basepoints0 = int32(CalculatePct(target->GetMaxPower(POWER_MANA), 2));
- caster->CastCustomSpell(target, 63654, &basepoints0, NULL, NULL, true);
- break;
- }
- case POWER_RAGE: triggeredSpellId = 63653; break;
- case POWER_ENERGY: triggeredSpellId = 63655; break;
- case POWER_RUNIC_POWER: triggeredSpellId = 63652; break;
- default:
- break;
- }
- if (triggeredSpellId)
- caster->CastSpell(target, triggeredSpellId, true);
- }
}
}
- switch (GetId())
- {
- case 47788: // Guardian Spirit
- if (removeMode != AURA_REMOVE_BY_EXPIRE)
- break;
- if (caster->GetTypeId() != TYPEID_PLAYER)
- break;
-
- Player* player = caster->ToPlayer();
- // Glyph of Guardian Spirit
- if (AuraEffect* aurEff = player->GetAuraEffect(63231, 0))
- {
- if (!player->HasSpellCooldown(47788))
- break;
-
- player->RemoveSpellCooldown(GetSpellInfo()->Id, true);
- player->AddSpellCooldown(GetSpellInfo()->Id, 0, uint32(time(NULL) + aurEff->GetAmount()));
-
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4);
- data << uint64(player->GetGUID());
- data << uint8(0x0); // flags (0x1, 0x2)
- data << uint32(GetSpellInfo()->Id);
- data << uint32(aurEff->GetAmount()*IN_MILLISECONDS);
- player->SendDirectMessage(&data);
- }
- break;
- }
break;
case SPELLFAMILY_ROGUE:
// Remove Vanish on stealth remove
@@ -1584,32 +1435,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
break;
}
break;
- case SPELLFAMILY_ROGUE:
- // Stealth
- if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00400000)
- {
- // Master of subtlety
- if (AuraEffect const* aurEff = target->GetAuraEffectOfRankedSpell(31221, 0))
- {
- if (!apply)
- target->CastSpell(target, 31666, true);
- else
- {
- int32 basepoints0 = aurEff->GetAmount();
- target->CastCustomSpell(target, 31665, &basepoints0, NULL, NULL, true);
- }
- }
- // Overkill
- if (target->HasAura(58426))
- {
- if (!apply)
- target->CastSpell(target, 58428, true);
- else
- target->CastSpell(target, 58427, true);
- }
- break;
- }
- break;
case SPELLFAMILY_HUNTER:
switch (GetId())
{
@@ -1632,7 +1457,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
case SPELLFAMILY_PALADIN:
switch (GetId())
{
- case 31842: // Divine Illumination
+ case 31842: // Divine Favor
// Item - Paladin T10 Holy 2P Bonus
if (target->HasAura(70755))
{
@@ -2487,4 +2312,3 @@ void DynObjAura::FillTargetMap(std::map<Unit*, uint8> & targets, Unit* /*caster*
}
}
}
-
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e72a1da563e..f1a58cb7e91 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -34,6 +34,7 @@
#include "Totem.h"
#include "Spell.h"
#include "DynamicObject.h"
+#include "Guild.h"
#include "Group.h"
#include "UpdateData.h"
#include "MapManager.h"
@@ -53,6 +54,7 @@
#include "SpellScript.h"
#include "InstanceScript.h"
#include "SpellInfo.h"
+#include "DB2Stores.h"
#include "Battlefield.h"
#include "BattlefieldMgr.h"
@@ -548,7 +550,7 @@ m_caster((info->AttributesEx6 & SPELL_ATTR6_CAST_BY_CHARMER && caster->GetCharme
// wand case
if ((m_caster->getClassMask() & CLASSMASK_WAND_USERS) != 0 && m_caster->GetTypeId() == TYPEID_PLAYER)
if (Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK))
- m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
+ m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->DamageType);
if (originalCasterGUID)
m_originalCasterGUID = originalCasterGUID;
@@ -823,7 +825,10 @@ void Spell::SelectSpellTargets()
else if (m_spellInfo->Speed > 0.0f)
{
float dist = m_caster->GetDistance(*m_targets.GetDstPos());
- m_delayMoment = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
+ if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
+ m_delayMoment = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
+ else
+ m_delayMoment = uint64(m_spellInfo->Speed * 1000.0f);
}
}
}
@@ -1096,14 +1101,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
{
// Other special target selection goes here
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
- {
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- maxTargets += (*j)->GetAmount();
-
Trinity::Containers::RandomResizeList(targets, maxTargets);
- }
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
@@ -1146,6 +1144,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
return;
}
+
if (!referer)
return;
@@ -1167,6 +1166,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
return;
}
+
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);
@@ -1248,14 +1248,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
{
// Other special target selection goes here
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
- {
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- maxTargets += (*j)->GetAmount();
-
Trinity::Containers::RandomResizeList(targets, maxTargets);
- }
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
@@ -1670,6 +1663,9 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
CallScriptDestinationTargetSelectHandlers(dest, effIndex);
m_targets.ModDst(dest);
}
+
+ if (Vehicle* veh = m_caster->GetVehicleKit())
+ veh->SetLastShootPos(*m_targets.GetDstPos());
}
void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
@@ -2001,8 +1997,9 @@ void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/)
(m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
-
+ {
m_procAttacker |= PROC_FLAG_DONE_TRAP_ACTIVATION;
+ }
/* Effects which are result of aura proc from triggered spell cannot proc
to prevent chain proc of these spells */
@@ -2113,7 +2110,11 @@ void Spell::AddUnitTarget(Unit* target, uint32 effectMask, bool checkIfValid /*=
if (dist < 5.0f)
dist = 5.0f;
- targetInfo.timeDelay = (uint64) floor(dist / m_spellInfo->Speed * 1000.0f);
+
+ if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
+ targetInfo.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
+ else
+ targetInfo.timeDelay = uint64(m_spellInfo->Speed * 1000.0f);
// Calculate minimum incoming time
if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
@@ -2192,7 +2193,12 @@ void Spell::AddGOTarget(GameObject* go, uint32 effectMask)
float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
if (dist < 5.0f)
dist = 5.0f;
- target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
+
+ if (!(m_spellInfo->AttributesEx9 & SPELL_ATTR9_SPECIAL_DELAY_CALCULATION))
+ target.timeDelay = uint64(floor(dist / m_spellInfo->Speed * 1000.0f));
+ else
+ target.timeDelay = uint64(m_spellInfo->Speed * 1000.0f);
+
if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
m_delayMoment = target.timeDelay;
}
@@ -2435,7 +2441,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
}
-
m_damage = damageInfo.damage;
caster->DealSpellDamage(&damageInfo, true);
@@ -2501,25 +2506,9 @@ 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);
- else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
- {
- int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
- debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
-
- if (debuff_resist_chance > 0)
- if (irand(0, 10000) <= (debuff_resist_chance * 100))
- {
- effectMask &= ~(1 << effectNumber);
- returnVal = SPELL_MISS_RESIST;
- }
- }
- }
- }
if (!effectMask)
return returnVal;
@@ -2530,14 +2519,14 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
if (Player* player = unit->ToPlayer())
{
player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET, m_spellInfo->Id);
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, m_caster);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id, 0, 0, m_caster);
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id);
}
if (Player* player = m_caster->ToPlayer())
{
player->StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER, m_spellInfo->Id);
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit);
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, 0, unit);
}
if (m_caster != unit)
@@ -2657,15 +2646,28 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
- // Haste modifies duration of channeled spells
- if (m_spellInfo->IsChanneled())
+ if (duration > 0)
{
- if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
- m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this);
+ // Haste modifies duration of channeled spells
+ if (m_spellInfo->IsChanneled())
+ {
+ if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
+ m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this);
+ }
+ else if (m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
+ {
+ int32 origDuration = duration;
+ duration = 0;
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (AuraEffect const* eff = m_spellAura->GetEffect(i))
+ if (int32 amplitude = eff->GetAmplitude()) // amplitude is hastened by UNIT_MOD_CAST_SPEED
+ duration = std::max(std::max(origDuration / amplitude, 1) * amplitude, duration);
+
+ // if there is no periodic effect
+ if (!duration)
+ duration = int32(origDuration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
+ }
}
- // and duration of auras affected by SPELL_AURA_PERIODIC_HASTE
- else if (m_originalCaster->HasAuraTypeWithAffectMask(SPELL_AURA_PERIODIC_HASTE, aurSpellInfo) || m_spellInfo->AttributesEx5 & SPELL_ATTR5_HASTE_AFFECT_DURATION)
- duration = int32(duration * m_originalCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
if (duration != m_spellAura->GetMaxDuration())
{
@@ -2721,7 +2723,7 @@ void Spell::DoTriggersOnSpellHit(Unit* unit, uint8 effMask)
{
if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
{
- m_caster->CastSpell(unit, i->triggeredSpell, true);
+ m_caster->CastSpell(unit, i->triggeredSpell, TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_TARGET_CHECK));
TC_LOG_DEBUG("spells", "Spell %d triggered spell %d by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
// SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
@@ -2924,6 +2926,10 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
m_needComboPoints = false;
SpellCastResult result = CheckCast(true);
+ // target is checked in too many locations and with different results to handle each of them
+ // handle just the general SPELL_FAILED_BAD_TARGETS result which is the default result for most DBC target checks
+ if (_triggeredCastFlags & TRIGGERED_IGNORE_TARGET_CHECK && result == SPELL_FAILED_BAD_TARGETS)
+ result = SPELL_CAST_OK;
if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
{
// Periodic auras should be interrupted when aura triggers a spell which can't be cast
@@ -2951,18 +2957,20 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered
{
player->SetSpellModTakingSpell(this, true);
// calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
- m_casttime = m_spellInfo->CalcCastTime(this);
+ m_casttime = m_spellInfo->CalcCastTime(player->getLevel(), this);
player->SetSpellModTakingSpell(this, false);
}
else
m_casttime = 0; // Set cast time to 0 if .cheat casttime is enabled.
}
else
- m_casttime = m_spellInfo->CalcCastTime(this);
+ m_casttime = m_spellInfo->CalcCastTime(m_caster->getLevel(), this);
// don't allow channeled spells / spells with cast time to be cast while moving
// (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
- if ((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT)
+ // don't cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
+ if (((m_spellInfo->IsChanneled() || m_casttime) && m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->isMoving() &&
+ m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT) && !m_caster->HasAuraTypeWithAffectMask(SPELL_AURA_CAST_WHILE_WALKING, m_spellInfo))
{
SendCastResult(SPELL_FAILED_MOVING);
finish(false);
@@ -3310,7 +3318,7 @@ void Spell::handle_immediate()
// Remove used for cast item if need (it can be already NULL after TakeReagents call
TakeCastItem();
- // handle ammo consumption for Hunter's volley spell
+ // handle ammo consumption for thrown weapons
if (m_spellInfo->IsRangedWeaponSpell() && m_spellInfo->IsChanneled())
TakeAmmo();
@@ -3440,6 +3448,9 @@ void Spell::_handle_finish_phase()
// Real add combo points from effects
if (m_comboPointGain)
m_caster->m_movedPlayer->GainSpellComboPoints(m_comboPointGain);
+
+ if (m_spellInfo->PowerType == POWER_HOLY_POWER && m_caster->m_movedPlayer->getClass() == CLASS_PALADIN)
+ HandleHolyPower(m_caster->m_movedPlayer);
}
if (m_caster->m_extraAttacks && GetSpellInfo()->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS))
@@ -3482,9 +3493,11 @@ 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
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)))
+ (m_spellInfo->Effects[0].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
if (!IsNextMeleeSwingSpell() && !IsAutoRepeat() && !IsTriggered())
@@ -3591,7 +3604,7 @@ void Spell::finish(bool ok)
Unit::AuraEffectList const& vIgnoreReset = m_caster->GetAuraEffectsByType(SPELL_AURA_IGNORE_MELEE_RESET);
for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
{
- if ((*i)->IsAffectedOnSpell(m_spellInfo))
+ if ((*i)->IsAffectingSpell(m_spellInfo))
{
found = true;
break;
@@ -3627,13 +3640,46 @@ void Spell::finish(bool ok)
m_caster->AttackStop();
}
-void Spell::WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
+void Spell::SendCastResult(SpellCastResult result)
+{
+ if (result == SPELL_CAST_OK)
+ return;
+
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
+ return;
+
+ SendCastResult(m_caster->ToPlayer(), m_spellInfo, m_cast_count, result, m_customError);
+}
+
+void Spell::SendPetCastResult(SpellCastResult result)
+{
+ if (result == SPELL_CAST_OK)
+ return;
+
+ Unit* owner = m_caster->GetCharmerOrOwner();
+ if (!owner || owner->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ SendCastResult(owner->ToPlayer(), m_spellInfo, m_cast_count, result, SPELL_CUSTOM_ERROR_NONE, SMSG_PET_CAST_FAILED);
+}
+
+void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError /*= SPELL_CUSTOM_ERROR_NONE*/, Opcodes opcode /*= SMSG_CAST_FAILED*/)
{
- data << uint8(castCount); // single cast or multi 2.3 (0/1)
+ if (result == SPELL_CAST_OK)
+ return;
+
+ WorldPacket data(opcode, (4+1+1));
+ data << uint8(cast_count);
data << uint32(spellInfo->Id);
data << uint8(result); // problem
switch (result)
{
+ case SPELL_FAILED_NOT_READY:
+ data << uint32(0); // unknown (value 1 update cooldowns on client flag)
+ break;
case SPELL_FAILED_REQUIRES_SPELL_FOCUS:
data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
break;
@@ -3686,9 +3732,29 @@ void Spell::WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo con
data << uint32(proto->ItemLimitCategory);
break;
}
+ case SPELL_FAILED_PREVENTED_BY_MECHANIC:
+ data << uint32(spellInfo->GetAllEffectsMechanicMask()); // SpellMechanic.dbc id
+ break;
+ case SPELL_FAILED_NEED_EXOTIC_AMMO:
+ data << uint32(spellInfo->EquippedItemSubClassMask); // seems correct...
+ break;
+ case SPELL_FAILED_NEED_MORE_ITEMS:
+ data << uint32(0); // Item id
+ data << uint32(0); // Item count?
+ break;
+ case SPELL_FAILED_MIN_SKILL:
+ data << uint32(0); // SkillLine.dbc id
+ data << uint32(0); // required skill value
+ break;
+ case SPELL_FAILED_FISHING_TOO_LOW:
+ data << uint32(0); // required fishing skill
+ break;
case SPELL_FAILED_CUSTOM_ERROR:
data << uint32(customError);
break;
+ case SPELL_FAILED_SILENCED:
+ data << uint32(0); // Unknown
+ break;
case SPELL_FAILED_REAGENTS:
{
uint32 missingItem = 0;
@@ -3710,72 +3776,13 @@ void Spell::WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo con
data << uint32(missingItem); // first missing item
break;
}
- case SPELL_FAILED_PREVENTED_BY_MECHANIC:
- data << uint32(spellInfo->Mechanic);
- break;
- case SPELL_FAILED_NEED_EXOTIC_AMMO:
- data << uint32(spellInfo->EquippedItemSubClassMask);
- break;
- case SPELL_FAILED_NEED_MORE_ITEMS:
- data << uint32(0); // Item entry
- data << uint32(0); // Count
- break;
- case SPELL_FAILED_MIN_SKILL:
- data << uint32(0); // SkillLine.dbc Id
- data << uint32(0); // Amount
- break;
- case SPELL_FAILED_FISHING_TOO_LOW:
- data << uint32(0); // Skill level
- break;
+ // TODO: SPELL_FAILED_NOT_STANDING
default:
break;
}
-}
-
-void Spell::SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError /*= SPELL_CUSTOM_ERROR_NONE*/)
-{
- if (result == SPELL_CAST_OK)
- return;
-
- WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
- WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
-
caster->GetSession()->SendPacket(&data);
}
-void Spell::SendCastResult(SpellCastResult result)
-{
- if (result == SPELL_CAST_OK)
- return;
-
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
- return;
-
- SendCastResult(m_caster->ToPlayer(), m_spellInfo, m_cast_count, result, m_customError);
-}
-
-void Spell::SendPetCastResult(SpellCastResult result)
-{
- if (result == SPELL_CAST_OK)
- return;
-
- Unit* owner = m_caster->GetCharmerOrOwner();
- if (!owner)
- return;
-
- Player* player = owner->ToPlayer();
- if (!player)
- return;
-
- WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
- WriteCastResultInfo(data, player, m_spellInfo, m_cast_count, result, m_customError);
-
- player->GetSession()->SendPacket(&data);
-}
-
void Spell::SendSpellStart()
{
if (!IsNeedSendToClient())
@@ -3783,19 +3790,17 @@ void Spell::SendSpellStart()
//TC_LOG_DEBUG("spells", "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
- uint32 castFlags = CAST_FLAG_UNKNOWN_2;
+ uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
- if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO)
- castFlags |= CAST_FLAG_AMMO;
if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
(m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsPet()))
&& m_spellInfo->PowerType != POWER_HEALTH)
castFlags |= CAST_FLAG_POWER_LEFT_SELF;
- if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNE)
+ if (m_spellInfo->RuneCostID && m_spellInfo->PowerType == POWER_RUNES)
castFlags |= CAST_FLAG_UNKNOWN_19;
WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
@@ -3808,22 +3813,58 @@ void Spell::SendSpellStart()
data << uint8(m_cast_count); // pending spell cast?
data << uint32(m_spellInfo->Id); // spellId
data << uint32(castFlags); // cast flags
- data << int32(m_timer); // delay?
+ data << uint32(m_timer); // delay?
+ data << uint32(m_casttime);
m_targets.Write(data);
if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
data << uint32(m_caster->GetPower((Powers)m_spellInfo->PowerType));
- if (castFlags & CAST_FLAG_AMMO)
- WriteAmmoToPacket(&data);
+ if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
+ {
+ //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())
+ {
+ data << uint8(m_runesState); // runes state before
+ data << uint8(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));
+ data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
+ }
+ }
+ else
+ {
+ data << uint8(0);
+ data << uint8(0);
+ for (uint8 i = 0; i < MAX_RUNES; ++i)
+ data << uint8(0);
+ }
+ }
- if (castFlags & CAST_FLAG_UNKNOWN_23)
+ if (castFlags & CAST_FLAG_PROJECTILE)
+ {
+ data << uint32(0); // Ammo display ID
+ data << uint32(0); // Inventory Type
+ }
+
+ if (castFlags & CAST_FLAG_IMMUNITY)
{
data << uint32(0);
data << uint32(0);
}
+ if (castFlags & CAST_FLAG_HEAL_PREDICTION)
+ {
+ data << uint32(0);
+ data << uint8(0); // unkByte
+ // if (unkByte == 2)
+ // data.append(0);
+ }
+
m_caster->SendMessageToSet(&data, true);
}
@@ -3841,9 +3882,6 @@ void Spell::SendSpellGo()
if ((IsTriggered() && !m_spellInfo->IsAutoRepeatRangedSpell()) || m_triggeredByAuraSpell)
castFlags |= CAST_FLAG_PENDING;
- if (m_spellInfo->Attributes & SPELL_ATTR0_REQ_AMMO)
- castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
-
if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
(m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsPet()))
&& m_spellInfo->PowerType != POWER_HEALTH)
@@ -3852,7 +3890,7 @@ void Spell::SendSpellGo()
if ((m_caster->GetTypeId() == TYPEID_PLAYER)
&& (m_caster->getClass() == CLASS_DEATH_KNIGHT)
&& m_spellInfo->RuneCostID
- && m_spellInfo->PowerType == POWER_RUNE)
+ && m_spellInfo->PowerType == POWER_RUNES)
{
castFlags |= CAST_FLAG_UNKNOWN_19; // same as in SMSG_SPELL_START
castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
@@ -3878,6 +3916,7 @@ void Spell::SendSpellGo()
data << uint8(m_cast_count); // pending spell cast?
data << uint32(m_spellInfo->Id); // spellId
data << uint32(castFlags); // cast flags
+ data << uint32(m_timer);
data << uint32(getMSTime()); // timestamp
WriteSpellGoTargets(&data);
@@ -3893,30 +3932,28 @@ void Spell::SendSpellGo()
//The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
if (Player* player = m_caster->ToPlayer())
{
- uint8 runeMaskInitial = m_runesState;
- uint8 runeMaskAfterCast = player->GetRunesState();
- data << uint8(runeMaskInitial); // runes state before
- data << uint8(runeMaskAfterCast); // runes state after
+ data << uint8(m_runesState); // runes state before
+ data << uint8(player->GetRunesState()); // runes state after
for (uint8 i = 0; i < MAX_RUNES; ++i)
{
- uint8 mask = (1 << i);
- if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
- {
- // float casts ensure the division is performed on floats as we need float result
- float baseCd = float(player->GetRuneBaseCooldown(i));
- data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
- }
+ // float casts ensure the division is performed on floats as we need float result
+ float baseCd = float(player->GetRuneBaseCooldown(i));
+ data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
}
}
}
+
if (castFlags & CAST_FLAG_ADJUST_MISSILE)
{
data << m_targets.GetElevation();
data << uint32(m_delayMoment);
}
- if (castFlags & CAST_FLAG_AMMO)
- WriteAmmoToPacket(&data);
+ if (castFlags & CAST_FLAG_PROJECTILE)
+ {
+ data << uint32(0); // Ammo display ID
+ data << uint32(0); // Inventory Type
+ }
if (castFlags & CAST_FLAG_VISUAL_CHAIN)
{
@@ -3929,79 +3966,21 @@ void Spell::SendSpellGo()
data << uint8(0);
}
- m_caster->SendMessageToSet(&data, true);
-}
-
-void Spell::WriteAmmoToPacket(WorldPacket* data)
-{
- uint32 ammoInventoryType = 0;
- uint32 ammoDisplayID = 0;
-
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ if (m_targets.GetTargetMask() & TARGET_FLAG_EXTRA_TARGETS)
{
- Item* pItem = m_caster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
- if (pItem)
+ data << uint32(0); // Extra targets count
+ /*
+ for (uint8 i = 0; i < count; ++i)
{
- ammoInventoryType = pItem->GetTemplate()->InventoryType;
- if (ammoInventoryType == INVTYPE_THROWN)
- ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
- else
- {
- uint32 ammoID = m_caster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID);
- if (ammoID)
- {
- ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
- if (pProto)
- {
- ammoDisplayID = pProto->DisplayInfoID;
- ammoInventoryType = pProto->InventoryType;
- }
- }
- else if (m_caster->HasAura(46699)) // Requires No Ammo
- {
- ammoDisplayID = 5996; // normal arrow
- ammoInventoryType = INVTYPE_AMMO;
- }
- }
- }
- }
- else
- {
- for (uint8 i = 0; i < 3; ++i)
- {
- if (uint32 item_id = m_caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i))
- {
- if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
- {
- if (itemEntry->Class == ITEM_CLASS_WEAPON)
- {
- switch (itemEntry->SubClass)
- {
- case ITEM_SUBCLASS_WEAPON_THROWN:
- ammoDisplayID = itemEntry->DisplayId;
- ammoInventoryType = itemEntry->InventoryType;
- break;
- case ITEM_SUBCLASS_WEAPON_BOW:
- case ITEM_SUBCLASS_WEAPON_CROSSBOW:
- ammoDisplayID = 5996; // is this need fixing?
- ammoInventoryType = INVTYPE_AMMO;
- break;
- case ITEM_SUBCLASS_WEAPON_GUN:
- ammoDisplayID = 5998; // is this need fixing?
- ammoInventoryType = INVTYPE_AMMO;
- break;
- }
-
- if (ammoDisplayID)
- break;
- }
- }
- }
+ data << float(0); // Target Position X
+ data << float(0); // Target Position Y
+ data << float(0); // Target Position Z
+ data << uint64(0); // Target Guid
}
+ */
}
- *data << uint32(ammoDisplayID);
- *data << uint32(ammoInventoryType);
+ m_caster->SendMessageToSet(&data, true);
}
/// Writes miss and hit targets for a SMSG_SPELL_GO packet
@@ -4113,11 +4092,49 @@ void Spell::ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit* victim, uint32 at
*m_effectExecuteData[effIndex] << uint32(attCount);
}
-void Spell::ExecuteLogEffectInterruptCast(uint8 effIndex, Unit* victim, uint32 spellId)
-{
- InitEffectExecuteData(effIndex);
- m_effectExecuteData[effIndex]->append(victim->GetPackGUID());
- *m_effectExecuteData[effIndex] << uint32(spellId);
+void Spell::ExecuteLogEffectInterruptCast(uint8 /*effIndex*/, Unit* victim, uint32 spellId)
+{
+ ObjectGuid casterGuid = m_caster->GetGUID();
+ ObjectGuid targetGuid = victim->GetGUID();
+
+ WorldPacket data(SMSG_SPELLINTERRUPTLOG, 8 + 8 + 4 + 4);
+ data.WriteBit(targetGuid[4]);
+ data.WriteBit(casterGuid[5]);
+ data.WriteBit(casterGuid[6]);
+ data.WriteBit(casterGuid[1]);
+ data.WriteBit(casterGuid[3]);
+ data.WriteBit(casterGuid[0]);
+ data.WriteBit(targetGuid[3]);
+ data.WriteBit(targetGuid[5]);
+ data.WriteBit(targetGuid[1]);
+ data.WriteBit(casterGuid[4]);
+ data.WriteBit(casterGuid[7]);
+ data.WriteBit(targetGuid[7]);
+ data.WriteBit(targetGuid[6]);
+ data.WriteBit(targetGuid[2]);
+ data.WriteBit(casterGuid[2]);
+ data.WriteBit(targetGuid[0]);
+
+ data.WriteByteSeq(casterGuid[7]);
+ data.WriteByteSeq(casterGuid[6]);
+ data.WriteByteSeq(casterGuid[3]);
+ data.WriteByteSeq(casterGuid[2]);
+ data.WriteByteSeq(targetGuid[3]);
+ data.WriteByteSeq(targetGuid[6]);
+ data.WriteByteSeq(targetGuid[2]);
+ data.WriteByteSeq(targetGuid[4]);
+ data.WriteByteSeq(targetGuid[7]);
+ data.WriteByteSeq(targetGuid[0]);
+ data.WriteByteSeq(casterGuid[4]);
+ data << uint32(m_spellInfo->Id);
+ data.WriteByteSeq(targetGuid[1]);
+ data.WriteByteSeq(casterGuid[0]);
+ data.WriteByteSeq(casterGuid[5]);
+ data.WriteByteSeq(casterGuid[1]);
+ data << uint32(spellId);
+ data.WriteByteSeq(targetGuid[5]);
+
+ m_caster->SendMessageToSet(&data, true);
}
void Spell::ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit* victim, int32 itemId, int32 slot)
@@ -4207,7 +4224,25 @@ void Spell::SendChannelStart(uint32 duration)
data.append(m_caster->GetPackGUID());
data << uint32(m_spellInfo->Id);
data << uint32(duration);
-
+ data << uint8(0); // immunity (castflag & 0x04000000)
+ /*
+ if (immunity)
+ {
+ data << uint32(); // CastSchoolImmunities
+ data << uint32(); // CastImmunities
+ }
+ */
+ data << uint8(0); // healPrediction (castflag & 0x40000000)
+ /*
+ if (healPrediction)
+ {
+ data.appendPackGUID(channelTarget); // target packguid
+ data << uint32(); // spellid
+ data << uint8(0); // unk3
+ if (unk3 == 2)
+ data.append(); // unk packed guid (unused ?)
+ }
+ */
m_caster->SendMessageToSet(&data, true);
m_timer = duration;
@@ -4234,8 +4269,8 @@ void Spell::SendResurrectRequest(Player* target)
data << uint8(m_caster->GetTypeId() == TYPEID_PLAYER ? 0 : 1); // "you'll be afflicted with resurrection sickness"
// override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
- if (m_spellInfo->AttributesEx3 & SPELL_ATTR3_IGNORE_RESURRECTION_TIMER)
- data << uint32(0);
+ // 4.2.2 edit : id of the spell used to resurect. (used client-side for Mass Resurect)
+ data << uint32(m_spellInfo->Id);
target->GetSession()->SendPacket(&data);
}
@@ -4321,7 +4356,7 @@ void Spell::TakePower()
bool hit = true;
if (m_caster->GetTypeId() == TYPEID_PLAYER)
{
- if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNE)
+ if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNES)
if (uint64 targetGUID = m_targets.GetUnitTargetGUID())
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if (ihit->targetGUID == targetGUID)
@@ -4337,7 +4372,7 @@ void Spell::TakePower()
}
}
- if (powerType == POWER_RUNE)
+ if (powerType == POWER_RUNES)
{
TakeRunePower(hit);
return;
@@ -4363,10 +4398,6 @@ void Spell::TakePower()
m_caster->ModifyPower(powerType, -m_powerCost);
else
m_caster->ModifyPower(powerType, -irand(0, m_powerCost/4));
-
- // Set the five second timer
- if (powerType == POWER_MANA && m_powerCost > 0)
- m_caster->SetLastManaUse(getMSTime());
}
void Spell::TakeAmmo()
@@ -4393,14 +4424,12 @@ void Spell::TakeAmmo()
m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
}
}
- else if (uint32 ammo = m_caster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID))
- m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
}
}
SpellCastResult Spell::CheckRuneCost(uint32 runeCostID)
{
- if (m_spellInfo->PowerType != POWER_RUNE || !runeCostID)
+ if (m_spellInfo->PowerType != POWER_RUNES || !runeCostID)
return SPELL_CAST_OK;
Player* player = m_caster->ToPlayer();
@@ -4607,6 +4636,41 @@ void Spell::HandleThreatSpells()
TC_LOG_DEBUG("spells", "Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, m_spellInfo->_IsPositiveSpell() ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
}
+void Spell::HandleHolyPower(Player* caster)
+{
+ if (!caster)
+ return;
+
+ bool hit = true;
+ Player* modOwner = caster->GetSpellModOwner();
+
+ m_powerCost = caster->GetPower(POWER_HOLY_POWER); // Always use all the holy power we have
+
+ if (!m_powerCost || !modOwner)
+ return;
+
+ if (uint64 targetGUID = m_targets.GetUnitTargetGUID())
+ {
+ for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ {
+ if (ihit->targetGUID == targetGUID)
+ {
+ if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS)
+ hit = false;
+
+ break;
+ }
+ }
+
+ // The spell did hit the target, apply aura cost mods if there are any.
+ if (hit)
+ {
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, m_powerCost);
+ m_caster->ModifyPower(POWER_HOLY_POWER, -m_powerCost);
+ }
+ }
+}
+
void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode)
{
effectHandleMode = mode;
@@ -4619,8 +4683,7 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff);
- // we do not need DamageMultiplier here.
- damage = CalculateDamage(i, NULL);
+ damage = CalculateDamage(i, unitTarget);
bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
@@ -4692,7 +4755,7 @@ SpellCastResult Spell::CheckCast(bool strict)
Unit::AuraEffectList const& ignore = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
{
- if (!(*i)->IsAffectedOnSpell(m_spellInfo))
+ if (!(*i)->IsAffectingSpell(m_spellInfo))
continue;
checkForm = false;
break;
@@ -4718,7 +4781,7 @@ SpellCastResult Spell::CheckCast(bool strict)
Unit::AuraEffectList const& stateAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
{
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
+ if ((*j)->IsAffectingSpell(m_spellInfo))
{
m_needComboPoints = false;
if ((*j)->GetMiscValue() == 1)
@@ -4750,7 +4813,8 @@ SpellCastResult Spell::CheckCast(bool strict)
// cancel autorepeat spells if cast start when moving
// (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->isMoving())
+ // Do not cancel spells which are affected by a SPELL_AURA_CAST_WHILE_WALKING effect
+ 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) &&
@@ -4851,14 +4915,14 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!m_caster->ToPlayer()->InBattleground())
return SPELL_FAILED_ONLY_BATTLEGROUNDS;
- // do not allow spells to be cast in arenas
- // - with greater than 10 min CD without SPELL_ATTR4_USABLE_IN_ARENA flag
- // - with SPELL_ATTR4_NOT_USABLE_IN_ARENA flag
- if ((m_spellInfo->AttributesEx4 & SPELL_ATTR4_NOT_USABLE_IN_ARENA) ||
- (m_spellInfo->GetRecoveryTime() > 10 * MINUTE * IN_MILLISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR4_USABLE_IN_ARENA)))
- if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
- if (mapEntry->IsBattleArena())
- return SPELL_FAILED_NOT_IN_ARENA;
+ // do not allow spells to be cast in arenas or rated battlegrounds
+ if (Player* player = m_caster->ToPlayer())
+ if (player->InArena()/* || player->InRatedBattleGround() NYI*/)
+ {
+ SpellCastResult castResult = CheckArenaAndRatedBattlegroundCastRules();
+ if (castResult != SPELL_CAST_OK)
+ return castResult;
+ }
// zone check
if (m_caster->GetTypeId() == TYPEID_UNIT || !m_caster->ToPlayer()->IsGameMaster())
@@ -4925,42 +4989,31 @@ SpellCastResult Spell::CheckCast(bool strict)
if (castResult != SPELL_CAST_OK)
return castResult;
- bool hasDispellableAura = false;
- bool hasNonDispelEffect = false;
- uint32 dispelMask = 0;
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
- {
- if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START)
- {
- hasDispellableAura = true;
- break;
- }
-
- dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
- }
- else if (m_spellInfo->Effects[i].IsEffect())
- {
- hasNonDispelEffect = true;
- break;
- }
-
- if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
- {
- if (Unit* target = m_targets.GetUnitTarget())
- {
- DispelChargesList dispelList;
- target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
- if (dispelList.empty())
- return SPELL_FAILED_NOTHING_TO_DISPEL;
- }
- }
-
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
// for effects of spells that have only one target
switch (m_spellInfo->Effects[i].Effect)
{
+ case SPELL_EFFECT_DUMMY:
+ {
+ if (m_spellInfo->Id == 19938) // Awaken Peon
+ {
+ Unit* unit = m_targets.GetUnitTarget();
+ if (!unit || !unit->HasAura(17743))
+ return SPELL_FAILED_BAD_TARGETS;
+ }
+ else if (m_spellInfo->Id == 31789) // Righteous Defense
+ {
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_DONT_REPORT;
+
+ Unit* target = m_targets.GetUnitTarget();
+ if (!target || !target->IsFriendlyTo(m_caster) || target->getAttackers().empty())
+ return SPELL_FAILED_BAD_TARGETS;
+
+ }
+ break;
+ }
case SPELL_EFFECT_LEARN_SPELL:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -4984,6 +5037,15 @@ SpellCastResult Spell::CheckCast(bool strict)
break;
}
+ case SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB:
+ {
+ if (m_caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_BAD_TARGETS;
+ if (Guild* guild = m_caster->ToPlayer()->GetGuild())
+ if (guild->GetLeaderGUID() != m_caster->ToPlayer()->GetGUID())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+ break;
+ }
case SPELL_EFFECT_LEARN_PET_SPELL:
{
// check target only for unit target case
@@ -5533,8 +5595,9 @@ SpellCastResult Spell::CheckCasterAuras() const
bool usableInStun = m_spellInfo->AttributesEx5 & SPELL_ATTR5_USABLE_WHILE_STUNNED;
// Glyph of Pain Suppression
+ // Allow Pain Suppression and Guardian Spirit to be cast while stunned
// there is no other way to handle it
- if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
+ if ((m_spellInfo->Id == 33206 || m_spellInfo->Id == 47788) && !m_caster->HasAura(63248))
usableInStun = false;
// Check whether the cast should be prevented by any state you might have.
@@ -5630,6 +5693,37 @@ SpellCastResult Spell::CheckCasterAuras() const
return SPELL_CAST_OK;
}
+SpellCastResult Spell::CheckArenaAndRatedBattlegroundCastRules()
+{
+ bool isRatedBattleground = false; // NYI
+ bool isArena = !isRatedBattleground;
+
+ // check USABLE attributes
+ // USABLE takes precedence over NOT_USABLE
+ if (isRatedBattleground && m_spellInfo->AttributesEx9 & SPELL_ATTR9_USABLE_IN_RATED_BATTLEGROUNDS)
+ return SPELL_CAST_OK;
+
+ if (isArena && m_spellInfo->AttributesEx4 & SPELL_ATTR4_USABLE_IN_ARENA)
+ return SPELL_CAST_OK;
+
+ // check NOT_USABLE attributes
+ if (m_spellInfo->AttributesEx4 & SPELL_ATTR4_NOT_USABLE_IN_ARENA_OR_RATED_BG)
+ return isArena ? SPELL_FAILED_NOT_IN_ARENA : SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND;
+
+ if (isArena && m_spellInfo->AttributesEx9 & SPELL_ATTR9_NOT_USABLE_IN_ARENA)
+ return SPELL_FAILED_NOT_IN_ARENA;
+
+ // check cooldowns
+ uint32 spellCooldown = m_spellInfo->GetRecoveryTime();
+ if (isArena && spellCooldown > 10 * MINUTE * IN_MILLISECONDS) // not sure if still needed
+ return SPELL_FAILED_NOT_IN_ARENA;
+
+ if (isRatedBattleground && spellCooldown > 15 * MINUTE * IN_MILLISECONDS)
+ return SPELL_FAILED_NOT_IN_RATED_BATTLEGROUND;
+
+ return SPELL_CAST_OK;
+}
+
bool Spell::CanAutoCast(Unit* target)
{
uint64 targetguid = target->GetGUID();
@@ -5750,8 +5844,8 @@ SpellCastResult Spell::CheckPower()
return SPELL_FAILED_UNKNOWN;
}
- //check rune cost only if a spell has PowerType == POWER_RUNE
- if (m_spellInfo->PowerType == POWER_RUNE)
+ //check rune cost only if a spell has PowerType == POWER_RUNES
+ if (m_spellInfo->PowerType == POWER_RUNES)
{
SpellCastResult failReason = CheckRuneCost(m_spellInfo->RuneCostID);
if (failReason != SPELL_CAST_OK)
@@ -5920,25 +6014,7 @@ SpellCastResult Spell::CheckItems()
totems -= 1;
}
if (totems != 0)
- return SPELL_FAILED_TOTEMS; //0x7C
-
- // Check items for TotemCategory (items presence in inventory)
- uint32 TotemCategory = 2;
- for (uint8 i = 0; i < 2; ++i)
- {
- if (m_spellInfo->TotemCategory[i] != 0)
- {
- if (player->HasItemTotemCategory(m_spellInfo->TotemCategory[i]))
- {
- TotemCategory -= 1;
- continue;
- }
- }
- else
- TotemCategory -= 1;
- }
- if (TotemCategory != 0)
- return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
+ return SPELL_FAILED_TOTEMS;
}
// special checks for spell effects
@@ -5978,7 +6054,7 @@ SpellCastResult Spell::CheckItems()
}
case SPELL_EFFECT_ENCHANT_ITEM:
if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
- && (m_targets.GetItemTarget()->IsWeaponVellum() || m_targets.GetItemTarget()->IsArmorVellum()))
+ && (m_targets.GetItemTarget()->IsVellum()))
{
// cannot enchant vellum for other player
if (m_targets.GetItemTarget()->GetOwner() != m_caster)
@@ -6170,47 +6246,6 @@ SpellCastResult Spell::CheckItems()
case ITEM_SUBCLASS_WEAPON_GUN:
case ITEM_SUBCLASS_WEAPON_BOW:
case ITEM_SUBCLASS_WEAPON_CROSSBOW:
- {
- uint32 ammo = player->GetUInt32Value(PLAYER_AMMO_ID);
- if (!ammo)
- {
- // Requires No Ammo
- if (m_caster->HasAura(46699))
- break; // skip other checks
-
- return SPELL_FAILED_NO_AMMO;
- }
-
- ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
- if (!ammoProto)
- return SPELL_FAILED_NO_AMMO;
-
- if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
- return SPELL_FAILED_NO_AMMO;
-
- // check ammo ws. weapon compatibility
- switch (pItem->GetTemplate()->SubClass)
- {
- case ITEM_SUBCLASS_WEAPON_BOW:
- case ITEM_SUBCLASS_WEAPON_CROSSBOW:
- if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
- return SPELL_FAILED_NO_AMMO;
- break;
- case ITEM_SUBCLASS_WEAPON_GUN:
- if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
- return SPELL_FAILED_NO_AMMO;
- break;
- default:
- return SPELL_FAILED_NO_AMMO;
- }
-
- if (!player->HasItemCount(ammo))
- {
- player->SetUInt32Value(PLAYER_AMMO_ID, 0);
- return SPELL_FAILED_NO_AMMO;
- }
- break;
- }
case ITEM_SUBCLASS_WEAPON_WAND:
break;
default:
@@ -6487,7 +6522,7 @@ bool Spell::IsAutoActionResetSpell() const
bool Spell::IsNeedSendToClient() const
{
return m_spellInfo->SpellVisual[0] || m_spellInfo->SpellVisual[1] || m_spellInfo->IsChanneled() ||
- m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered());
+ (m_spellInfo->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT) || m_spellInfo->Speed > 0.0f || (!m_triggeredByAuraSpell && !IsTriggered());
}
bool Spell::HaveTargetsForEffect(uint8 effect) const
@@ -6655,12 +6690,6 @@ void Spell::HandleLaunchPhase()
multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
bool usesAmmo = m_spellInfo->AttributesCu & SPELL_ATTR0_CU_DIRECT_DAMAGE;
- Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
- for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- {
- if ((*j)->IsAffectedOnSpell(m_spellInfo))
- usesAmmo=false;
- }
for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
{
@@ -7147,7 +7176,7 @@ void Spell::PrepareTriggersExecutedOnHit()
Unit::AuraEffectList const& targetTriggers = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER);
for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
{
- if (!(*i)->IsAffectedOnSpell(m_spellInfo))
+ if (!(*i)->IsAffectingSpell(m_spellInfo))
continue;
SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
uint32 auraSpellIdx = (*i)->GetEffIndex();
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 76be075e94d..1b415cd6cb8 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -40,11 +40,11 @@ enum SpellCastFlags
{
CAST_FLAG_NONE = 0x00000000,
CAST_FLAG_PENDING = 0x00000001, // aoe combat log?
- CAST_FLAG_UNKNOWN_2 = 0x00000002,
+ CAST_FLAG_HAS_TRAJECTORY = 0x00000002,
CAST_FLAG_UNKNOWN_3 = 0x00000004,
CAST_FLAG_UNKNOWN_4 = 0x00000008, // ignore AOE visual
CAST_FLAG_UNKNOWN_5 = 0x00000010,
- CAST_FLAG_AMMO = 0x00000020, // Projectiles visual
+ CAST_FLAG_PROJECTILE = 0x00000020,
CAST_FLAG_UNKNOWN_7 = 0x00000040,
CAST_FLAG_UNKNOWN_8 = 0x00000080,
CAST_FLAG_UNKNOWN_9 = 0x00000100,
@@ -69,7 +69,7 @@ enum SpellCastFlags
CAST_FLAG_UNKNOWN_28 = 0x08000000,
CAST_FLAG_UNKNOWN_29 = 0x10000000,
CAST_FLAG_UNKNOWN_30 = 0x20000000,
- CAST_FLAG_UNKNOWN_31 = 0x40000000,
+ CAST_FLAG_HEAL_PREDICTION = 0x40000000,
CAST_FLAG_UNKNOWN_32 = 0x80000000
};
@@ -258,7 +258,7 @@ class Spell
void EffectQuestClear(SpellEffIndex effIndex);
void EffectTeleUnitsFaceCaster(SpellEffIndex effIndex);
void EffectLearnSkill(SpellEffIndex effIndex);
- void EffectAddHonor(SpellEffIndex effIndex);
+ void EffectPlayMovie(SpellEffIndex effIndex);
void EffectTradeSkill(SpellEffIndex effIndex);
void EffectEnchantItemPerm(SpellEffIndex effIndex);
void EffectEnchantItemTmp(SpellEffIndex effIndex);
@@ -323,6 +323,7 @@ class Spell
void EffectEnergizePct(SpellEffIndex effIndex);
void EffectTriggerRitualOfSummoning(SpellEffIndex effIndex);
void EffectSummonRaFFriend(SpellEffIndex effIndex);
+ void EffectUnlockGuildVaultTab(SpellEffIndex effIndex);
void EffectKillCreditPersonal(SpellEffIndex effIndex);
void EffectKillCredit(SpellEffIndex effIndex);
void EffectQuestFail(SpellEffIndex effIndex);
@@ -341,8 +342,12 @@ class Spell
void EffectActivateSpec(SpellEffIndex effIndex);
void EffectPlaySound(SpellEffIndex effIndex);
void EffectRemoveAura(SpellEffIndex effIndex);
+ void EffectDamageFromMaxHealthPCT(SpellEffIndex effIndex);
void EffectCastButtons(SpellEffIndex effIndex);
void EffectRechargeManaGem(SpellEffIndex effIndex);
+ void EffectGiveCurrency(SpellEffIndex effIndex);
+ void EffectResurrectWithAura(SpellEffIndex effIndex);
+ void EffectCreateAreaTrigger(SpellEffIndex effIndex);
typedef std::set<Aura*> UsedSpellMods;
@@ -404,6 +409,7 @@ class Spell
SpellCastResult CheckPower();
SpellCastResult CheckRuneCost(uint32 runeCostID);
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]); }
@@ -415,15 +421,13 @@ class Spell
void DoCreateItem(uint32 i, uint32 itemtype);
void WriteSpellGoTargets(WorldPacket* data);
- void WriteAmmoToPacket(WorldPacket* data);
bool CheckEffectTarget(Unit const* target, uint32 eff) const;
bool CanAutoCast(Unit* target);
void CheckSrc() { if (!m_targets.HasSrc()) m_targets.SetSrc(*m_caster); }
void CheckDst() { if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); }
- static void WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError);
- static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE);
+ static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 cast_count, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE, Opcodes opcode = SMSG_CAST_FAILED);
void SendCastResult(SpellCastResult result);
void SendPetCastResult(SpellCastResult result);
void SendSpellStart();
@@ -445,6 +449,7 @@ class Spell
void SendChannelStart(uint32 duration);
void SendResurrectRequest(Player* target);
+ void HandleHolyPower(Player* caster);
void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
void HandleThreatSpells();
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index b2b4690f893..f152e4f5976 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -62,7 +62,10 @@
#include "AccountMgr.h"
#include "InstanceScript.h"
#include "PathGenerator.h"
+#include "Guild.h"
+#include "GuildMgr.h"
#include "ReputationMgr.h"
+#include "AreaTrigger.h"
pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
{
@@ -111,14 +114,14 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectJumpDest, // 42 SPELL_EFFECT_JUMP_DEST
&Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
&Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP
- &Spell::EffectAddHonor, // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related
+ &Spell::EffectPlayMovie, // 45 SPELL_EFFECT_PLAY_MOVIE
&Spell::EffectUnused, // 46 SPELL_EFFECT_SPAWN clientside, unit appears as if it was just spawned
&Spell::EffectTradeSkill, // 47 SPELL_EFFECT_TRADE_SKILL
&Spell::EffectUnused, // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth
&Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect
&Spell::EffectTransmitted, // 50 SPELL_EFFECT_TRANS_DOOR
&Spell::EffectUnused, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT unused
- &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT one spell: zzOLDCritical Shot
+ &Spell::EffectUnused, // 52 SPELL_EFFECT_GUARANTEE_HIT unused
&Spell::EffectEnchantItemPerm, // 53 SPELL_EFFECT_ENCHANT_ITEM
&Spell::EffectEnchantItemTmp, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
&Spell::EffectTameCreature, // 55 SPELL_EFFECT_TAMECREATURE
@@ -229,8 +232,26 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectNULL, //160 SPELL_EFFECT_160 1 spell - 45534
&Spell::EffectSpecCount, //161 SPELL_EFFECT_TALENT_SPEC_COUNT second talent spec (learn/revert)
&Spell::EffectActivateSpec, //162 SPELL_EFFECT_TALENT_SPEC_SELECT activate primary/secondary spec
- &Spell::EffectNULL, //163 unused
+ &Spell::EffectUnused, //163 SPELL_EFFECT_163 unused
&Spell::EffectRemoveAura, //164 SPELL_EFFECT_REMOVE_AURA
+ &Spell::EffectDamageFromMaxHealthPCT, //165 SPELL_EFFECT_DAMAGE_FROM_MAX_HEALTH_PCT
+ &Spell::EffectGiveCurrency, //166 SPELL_EFFECT_GIVE_CURRENCY
+ &Spell::EffectNULL, //167 SPELL_EFFECT_167
+ &Spell::EffectNULL, //168 SPELL_EFFECT_168
+ &Spell::EffectNULL, //169 SPELL_EFFECT_DESTROY_ITEM
+ &Spell::EffectNULL, //170 SPELL_EFFECT_170
+ &Spell::EffectNULL, //171 SPELL_EFFECT_171
+ &Spell::EffectResurrectWithAura, //172 SPELL_EFFECT_RESURRECT_WITH_AURA
+ &Spell::EffectUnlockGuildVaultTab, //173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
+ &Spell::EffectNULL, //174 SPELL_EFFECT_174
+ &Spell::EffectUnused, //175 SPELL_EFFECT_175 unused
+ &Spell::EffectNULL, //176 SPELL_EFFECT_176
+ &Spell::EffectNULL, //177 SPELL_EFFECT_177
+ &Spell::EffectUnused, //178 SPELL_EFFECT_178 unused
+ &Spell::EffectCreateAreaTrigger, //179 SPELL_EFFECT_CREATE_AREATRIGGER
+ &Spell::EffectUnused, //180 SPELL_EFFECT_180 unused
+ &Spell::EffectUnused, //181 SPELL_EFFECT_181 unused
+ &Spell::EffectNULL, //182 SPELL_EFFECT_182
};
void Spell::EffectNULL(SpellEffIndex /*effIndex*/)
@@ -259,13 +280,13 @@ void Spell::EffectResurrectNew(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
- if (target->isRessurectRequested()) // already have one active request
+ if (target->IsRessurectRequested()) // already have one active request
return;
uint32 health = damage;
uint32 mana = m_spellInfo->Effects[effIndex].MiscValue;
ExecuteLogEffectResurrect(effIndex, target);
- target->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
+ target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
}
@@ -368,15 +389,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
case SPELLFAMILY_WARRIOR:
{
- // Shield Slam
- if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->GetCategory() == 1209)
- {
- uint8 level = m_caster->getLevel();
- uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f));
- damage += int32(m_caster->ApplyEffectModifiers(m_spellInfo, effIndex, float(block_value)));
- }
// Victory Rush
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x100)
+ if (m_spellInfo->Id == 34428)
ApplyPct(damage, m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
// Shockwave
else if (m_spellInfo->Id == 46968)
@@ -393,73 +407,12 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
// Incinerate Rank 1 & 2
if ((m_spellInfo->SpellFamilyFlags[1] & 0x000040) && m_spellInfo->SpellIconID == 2128)
{
- // Incinerate does more dmg (dmg*0.25) if the target have Immolate debuff.
+ // Incinerate does more dmg (dmg/6) if the target have Immolate debuff.
// Check aura state for speed but aura state set not only for Immolate spell
if (unitTarget->HasAuraState(AURA_STATE_CONFLAGRATE))
{
if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x4, 0, 0))
- damage += damage/4;
- }
- }
- // Conflagrate - consumes Immolate or Shadowflame
- else if (m_spellInfo->TargetAuraState == AURA_STATE_CONFLAGRATE)
- {
- AuraEffect const* aura = NULL; // found req. aura for damage calculation
-
- Unit::AuraEffectList const &mPeriodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
- for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
- {
- // for caster applied auras only
- if ((*i)->GetSpellInfo()->SpellFamilyName != SPELLFAMILY_WARLOCK ||
- (*i)->GetCasterGUID() != m_caster->GetGUID())
- continue;
-
- // Immolate
- if ((*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x4)
- {
- aura = *i; // it selected always if exist
- break;
- }
-
- // Shadowflame
- if ((*i)->GetSpellInfo()->SpellFamilyFlags[2] & 0x00000002)
- aura = *i; // remember but wait possible Immolate as primary priority
- }
-
- // found Immolate or Shadowflame
- if (aura)
- {
- uint32 pdamage = uint32(std::max(aura->GetAmount(), 0));
- pdamage = m_caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
- pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT, aura->GetBase()->GetStackAmount());
- uint32 pct_dir = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 1));
- uint8 baseTotalTicks = uint8(m_caster->CalcSpellDuration(aura->GetSpellInfo()) / aura->GetSpellInfo()->Effects[EFFECT_0].Amplitude);
- damage += int32(CalculatePct(pdamage * baseTotalTicks, pct_dir));
-
- uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effIndex + 2)) / 3;
- m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(int32(CalculatePct(pdamage * baseTotalTicks, pct_dot)));
-
- apply_direct_bonus = false;
- // Glyph of Conflagrate
- if (!m_caster->HasAura(56235))
- unitTarget->RemoveAurasDueToSpell(aura->GetId(), m_caster->GetGUID());
-
- break;
- }
- }
- // Shadow Bite
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x400000)
- {
- if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsPet())
- {
- if (Player* owner = m_caster->GetOwner()->ToPlayer())
- {
- if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0))
- {
- int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8;
- m_caster->CastCustomSpell(m_caster, 54425, &bp0, NULL, NULL, true);
- }
- }
+ damage += damage / 6;
}
}
break;
@@ -490,20 +443,10 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
// Ferocious Bite
if (m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags[0] & 0x000800000) && m_spellInfo->SpellVisual[0] == 6587)
{
- // converts each extra point of energy into ($f1+$AP/410) additional damage
- float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
- float multiple = ap / 410 + m_spellInfo->Effects[effIndex].DamageMultiplier;
- int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -30));
- damage += int32(energy * multiple);
- damage += int32(CalculatePct(m_caster->ToPlayer()->GetComboPoints() * ap, 7));
- }
- // Wrath
- else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
- {
- // Improved Insect Swarm
- if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
- if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00200000, 0, 0))
- AddPct(damage, aurEff->GetAmount());
+ // converts each extra point of energy ( up to 25 energy ) into additional damage
+ int32 energy = -(m_caster->ModifyPower(POWER_ENERGY, -25));
+ // 25 energy = 100% more damage
+ AddPct(damage, energy * 4);
}
break;
}
@@ -575,72 +518,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
break;
}
- case SPELLFAMILY_HUNTER:
- {
- //Gore
- if (m_spellInfo->SpellIconID == 1578)
- {
- if (m_caster->HasAura(57627)) // Charge 6 sec post-affect
- damage *= 2;
- }
- // Steady Shot
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x1)
- {
- bool found = false;
- // check dazed affect
- Unit::AuraEffectList const& decSpeedList = unitTarget->GetAuraEffectsByType(SPELL_AURA_MOD_DECREASE_SPEED);
- for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
- {
- if ((*iter)->GetSpellInfo()->SpellIconID == 15 && (*iter)->GetSpellInfo()->Dispel == 0)
- {
- found = true;
- break;
- }
- }
-
- /// @todo should this be put on taken but not done?
- if (found)
- damage += m_spellInfo->Effects[EFFECT_1].CalcValue();
-
- if (Player* caster = m_caster->ToPlayer())
- {
- // Add Ammo and Weapon damage plus RAP * 0.1
- if (Item* item = caster->GetWeaponForAttack(RANGED_ATTACK))
- {
- ItemTemplate const* weaponTemplate = item->GetTemplate();
- float dmg_min = weaponTemplate->Damage[0].DamageMin;
- float dmg_max = weaponTemplate->Damage[0].DamageMax;
- if (dmg_max == 0.0f && dmg_min > dmg_max)
- damage += int32(dmg_min);
- else
- damage += irand(int32(dmg_min), int32(dmg_max));
- damage += int32(caster->GetAmmoDPS() * weaponTemplate->Delay * 0.001f);
- }
- }
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Hammer of the Righteous
- if (m_spellInfo->SpellFamilyFlags[1]&0x00040000)
- {
- // Add main hand dps * effect[2] amount
- float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2;
- int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, EFFECT_2);
- damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK);
- break;
- }
- // Shield of Righteousness
- if (m_spellInfo->SpellFamilyFlags[EFFECT_1] & 0x100000)
- {
- uint8 level = m_caster->getLevel();
- uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 29.5f), uint32(float(level) * 39.5f));
- damage += CalculatePct(block_value, m_spellInfo->Effects[EFFECT_1].CalcValue());
- break;
- }
- break;
- }
case SPELLFAMILY_DEATHKNIGHT:
{
// Blood Boil - bonus for diseased targets
@@ -813,15 +690,6 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
// special cases
switch (triggered_spell_id)
{
- // Mirror Image
- case 58832:
- {
- // Glyph of Mirror Image
- if (m_caster->HasAura(63093))
- m_caster->CastSpell(m_caster, 65047, true); // Mirror Image
-
- break;
- }
// Vanish (not exist)
case 18461:
{
@@ -854,10 +722,6 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex)
unitTarget->CastSpell(unitTarget, 7870, true);
return;
}
- // just skip
- case 23770: // Sayge's Dark Fortune of *
- // not exist, common cooldown can be implemented in scripts if need.
- return;
// Brittle Armor - (need add max stack of 24575 Brittle Armor)
case 29284:
{
@@ -1312,12 +1176,7 @@ void Spell::EffectPowerDrain(SpellEffIndex effIndex)
damage = m_caster->SpellDamageBonusDone(unitTarget, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
damage = unitTarget->SpellDamageBonusTaken(m_caster, m_spellInfo, uint32(damage), SPELL_DIRECT_DAMAGE);
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- int32 power = damage;
- if (powerType == POWER_MANA)
- power -= unitTarget->GetSpellCritDamageReduction(power);
-
- int32 newDamage = -(unitTarget->ModifyPower(powerType, -int32(power)));
+ int32 newDamage = -(unitTarget->ModifyPower(powerType, -damage));
float gainMultiplier = 0.0f;
@@ -1395,12 +1254,7 @@ void Spell::EffectPowerBurn(SpellEffIndex effIndex)
damage = std::min(damage, maxDamage);
}
- int32 power = damage;
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- if (powerType == POWER_MANA)
- power -= unitTarget->GetSpellCritDamageReduction(power);
-
- int32 newDamage = -(unitTarget->ModifyPower(powerType, -power));
+ 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);
@@ -1494,22 +1348,6 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/)
//addhealth += tickheal * tickcount;
//addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
}
- // Nourish
- else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x2000000)
- {
- addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL);
-
- // Glyph of Nourish
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(62971, 0))
- {
- Unit::AuraEffectList const& Periodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL);
- for (Unit::AuraEffectList::const_iterator i = Periodic.begin(); i != Periodic.end(); ++i)
- {
- if (m_caster->GetGUID() == (*i)->GetCasterGUID())
- AddPct(addhealth, aurEff->GetAmount());
- }
- }
- }
// 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);
@@ -1655,7 +1493,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
if (msg != EQUIP_ERR_OK)
{
// convert to possible store amount
- if (msg == EQUIP_ERR_INVENTORY_FULL || msg == EQUIP_ERR_CANT_CARRY_MORE_OF_THIS)
+ if (msg == EQUIP_ERR_INV_FULL || msg == EQUIP_ERR_ITEM_MAX_COUNT)
num_to_add -= no_space;
else
{
@@ -1684,6 +1522,11 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype)
// send info to the client
player->SendNewItem(pItem, num_to_add, true, bgType == 0);
+ if (pProto->Quality > ITEM_QUALITY_EPIC || (pProto->Quality == ITEM_QUALITY_EPIC && pProto->ItemLevel >= MinNewsItemLevel[sWorld->getIntConfig(CONFIG_EXPANSION)]))
+ if (Guild* guild = player->GetGuild())
+ guild->AddGuildNews(GUILD_NEWS_ITEM_CRAFTED, player->GetGUID(), 0, pProto->ItemId);
+
+
// we succeeded in creating at least one item, so a levelup is possible
if (bgType == 0)
player->UpdateCraftSkill(m_spellInfo->Id);
@@ -1772,7 +1615,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex)
if (!caster->IsInWorld())
return;
DynamicObject* dynObj = new DynamicObject(false);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL))
{
delete dynObj;
return;
@@ -1824,13 +1667,10 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
level_multiplier = 4;
break;
case 31930: // Judgements of the Wise
- case 63375: // Improved Stormstrike
+ case 63375: // Primal Wisdom
case 68082: // Glyph of Seal of Command
damage = int32(CalculatePct(unitTarget->GetCreateMana(), damage));
break;
- case 48542: // Revitalize
- damage = int32(CalculatePct(unitTarget->GetMaxPower(power), damage));
- break;
case 67490: // Runic Mana Injector (mana gain increased by 25% for engineers - 3.2.0 patch change)
{
if (Player* player = m_caster->ToPlayer())
@@ -1838,9 +1678,6 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
AddPct(damage, 25);
break;
}
- case 71132: // Glyph of Shadow Word: Pain
- damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
- break;
default:
break;
}
@@ -1848,7 +1685,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
if (level_diff > 0)
damage -= level_multiplier * level_diff;
- if (damage < 0)
+ if (damage < 0 && power != POWER_ECLIPSE)
return;
if (unitTarget->GetMaxPower(power) == 0)
@@ -2182,9 +2019,9 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex)
uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
- if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
+ if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CLIENT_LOCKED_OUT)
{
- if (msg == EQUIP_ERR_CANT_DO_RIGHT_NOW) dest = EQUIPMENT_SLOT_MAINHAND;
+ if (msg == EQUIP_ERR_CLIENT_LOCKED_OUT) dest = EQUIPMENT_SLOT_MAINHAND;
// prevent crash at access and unexpected charges counting with item update queue corrupt
if (m_CastItem == m_targets.GetItemTarget())
@@ -2523,7 +2360,7 @@ 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();
+ 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())
@@ -2598,7 +2435,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex)
return;
DynamicObject* dynObj = new DynamicObject(true);
- if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
+ if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS))
{
delete dynObj;
return;
@@ -2655,7 +2492,7 @@ void Spell::EffectLearnSkill(SpellEffIndex effIndex)
unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval?skillval:1, damage*75);
}
-void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/)
+void Spell::EffectPlayMovie(SpellEffIndex effIndex)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
@@ -2663,27 +2500,11 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/)
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
- // not scale value for item based reward (/10 value expected)
- if (m_CastItem)
- {
- unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage/10);
- TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(), unitTarget->ToPlayer()->GetGUIDLow());
+ uint32 movieId = GetSpellInfo()->Effects[effIndex].MiscValue;
+ if (!sMovieStore.LookupEntry(movieId))
return;
- }
- // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
- if (damage <= 50)
- {
- uint32 honor_reward = Trinity::Honor::hk_honor_at_level(unitTarget->getLevel(), float(damage));
- unitTarget->ToPlayer()->RewardHonor(NULL, 1, honor_reward);
- TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUIDLow());
- }
- else
- {
- //maybe we have correct honor_gain in damage already
- unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage);
- TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, unitTarget->ToPlayer()->GetGUIDLow());
- }
+ unitTarget->ToPlayer()->SendMovieStart(movieId);
}
void Spell::EffectTradeSkill(SpellEffIndex /*effIndex*/)
@@ -2711,7 +2532,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
return;
// Handle vellums
- if (itemTarget->IsWeaponVellum() || itemTarget->IsArmorVellum())
+ if (itemTarget->IsVellum())
{
// destroy one vellum from stack
uint32 count = 1;
@@ -2835,58 +2656,6 @@ void Spell::EffectEnchantItemTmp(SpellEffIndex effIndex)
if (!player)
return;
- // Rockbiter Weapon apply to both weapon
- if (!itemTarget)
- return;
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x400000)
- {
- uint32 spell_id = 0;
-
- // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
- // Note: damage calculated (correctly) with rounding int32(float(v)) but
- // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
- switch (damage)
- {
- // Rank 1
- case 2: spell_id = 36744; break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
- // Rank 2
- case 4: spell_id = 36753; break; // 0% [ 7% == 4, 14% == 4]
- case 5: spell_id = 36751; break; // 20%
- // Rank 3
- case 6: spell_id = 36754; break; // 0% [ 7% == 6, 14% == 6]
- case 7: spell_id = 36755; break; // 20%
- // Rank 4
- case 9: spell_id = 36761; break; // 0% [ 7% == 6]
- case 10: spell_id = 36758; break; // 14%
- case 11: spell_id = 36760; break; // 20%
- default:
- TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: Damage %u not handled in S'RW", damage);
- return;
- }
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
- if (!spellInfo)
- {
- TC_LOG_ERROR("spells", "Spell::EffectEnchantItemTmp: unknown spell id %i", spell_id);
- return;
-
- }
-
- for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
- {
- if (Item* item = player->GetWeaponForAttack(WeaponAttackType(j)))
- {
- if (item->IsFitToSpellRequirements(m_spellInfo))
- {
- Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
- SpellCastTargets targets;
- targets.SetItemTarget(item);
- spell->prepare(&targets);
- }
- }
- }
- return;
- }
if (!itemTarget)
return;
@@ -3137,9 +2906,6 @@ void Spell::EffectTaunt(SpellEffIndex /*effIndex*/)
return;
}
- if (m_spellInfo->Id == 62124)
- m_caster->CastSpell(unitTarget, 67485, true);
-
// Also use this effect to set the taunter's threat to the taunted creature's highest value
if (unitTarget->getThreatManager().getCurrentVictim())
{
@@ -3201,74 +2967,26 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
if (Aura* aur = unitTarget->GetAura(58567, m_caster->GetGUID()))
{
- // 58388 - Glyph of Devastate dummy aura.
- if (int32 num = (needCast ? 0 : 1) + (m_caster->HasAura(58388) ? 1 : 0))
+ if (int32 num = (needCast ? 0 : 1))
aur->ModStackAmount(num);
fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);
}
}
- if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow
- {
- if (unitTarget->IsImmunedToSpellEffect(m_spellInfo, EFFECT_1) || unitTarget->GetTypeId() == TYPEID_PLAYER)
- {
- m_damage = 0;
- return;
- }
- }
break;
}
case SPELLFAMILY_ROGUE:
{
- // Fan of Knives, Hemorrhage, Ghostly Strike
- if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
- || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
+ // Hemorrhage
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
{
- // Hemorrhage
- if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
- {
- if (m_caster->GetTypeId() == TYPEID_PLAYER)
- m_caster->ToPlayer()->AddComboPoints(unitTarget, 1, this);
- }
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ m_caster->ToPlayer()->AddComboPoints(unitTarget, 1, this);
// 50% more damage with daggers
if (m_caster->GetTypeId() == TYPEID_PLAYER)
if (Item* item = m_caster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
totalDamagePercentMod *= 1.5f;
}
- // Mutilate (for each hand)
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
- {
- bool found = false;
- // fast check
- if (unitTarget->HasAuraState(AURA_STATE_DEADLY_POISON, m_spellInfo, m_caster))
- found = true;
- // full aura scan
- else
- {
- Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras();
- for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- {
- if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
- {
- found = true;
- break;
- }
- }
- }
-
- if (found)
- totalDamagePercentMod *= 1.2f; // 120% if poisoned
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- {
- // Seal of Command Unleashed
- if (m_spellInfo->Id == 20467)
- {
- spell_bonus += int32(0.08f * m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
- spell_bonus += int32(0.13f * m_caster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
- }
break;
}
case SPELLFAMILY_SHAMAN:
@@ -3299,54 +3017,35 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
{
// Kill Shot - bonus damage from Ranged Attack Power
if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
- spell_bonus += int32(0.4f * m_caster->GetTotalAttackPowerValue(RANGED_ATTACK));
+ spell_bonus += int32(0.45f * m_caster->GetTotalAttackPowerValue(RANGED_ATTACK));
break;
}
case SPELLFAMILY_DEATHKNIGHT:
{
- // Plague Strike
- if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
- {
- // Glyph of Plague Strike
- if (AuraEffect const* aurEff = m_caster->GetAuraEffect(58657, EFFECT_0))
- AddPct(totalDamagePercentMod, aurEff->GetAmount());
- break;
- }
// Blood Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
{
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
+ 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);
-
- // Glyph of Blood Strike
- if (m_caster->GetAuraEffect(59332, EFFECT_0))
- if (unitTarget->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
- AddPct(totalDamagePercentMod, 20);
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>(m_caster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
+ 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)
{
- bool consumeDiseases = true;
- // Annihilation
- if (AuraEffect const* aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, EFFECT_0))
- // Do not consume diseases if roll sucesses
- if (roll_chance_i(aurEff->GetAmount()))
- consumeDiseases = false;
-
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f;
+ 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());
@@ -3362,7 +3061,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Heart Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
{
- float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID());
+ 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());
@@ -3506,7 +3205,7 @@ void Spell::EffectInterruptCast(SpellEffIndex effIndex)
// check if we can interrupt spell
if ((spell->getState() == SPELL_STATE_CASTING
|| (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
- && curSpellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE
+ && (curSpellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE || curSpellInfo->PreventionType == SPELL_PREVENTION_TYPE_UNK)
&& ((i == CURRENT_GENERIC_SPELL && curSpellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_INTERRUPT)
|| (i == CURRENT_CHANNELED_SPELL && curSpellInfo->ChannelInterruptFlags & CHANNEL_INTERRUPT_FLAG_INTERRUPT)))
{
@@ -4152,7 +3851,7 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/)
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
if (m_caster->GetTypeId() == TYPEID_PLAYER
&& m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
- && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VANISH))
+ && (m_spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_VANISH))
{
m_caster->ToPlayer()->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
// Overkill
@@ -4355,12 +4054,16 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
switch (m_glyphIndex)
{
case 0:
- case 1: minLevel = 15; break;
- case 2: minLevel = 50; break;
- case 3: minLevel = 30; break;
- case 4: minLevel = 70; break;
- case 5: minLevel = 80; break;
+ case 1:
+ case 6: minLevel = 25; break;
+ case 2:
+ case 3:
+ case 7: minLevel = 50; break;
+ case 4:
+ case 5:
+ case 8: minLevel = 75; break;
}
+
if (minLevel && m_caster->getLevel() < minLevel)
{
SendCastResult(SPELL_FAILED_GLYPH_SOCKET_LOCKED);
@@ -4368,13 +4071,13 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
}
// apply new one
- if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
+ if (uint32 newGlyph = m_spellInfo->Effects[effIndex].MiscValue)
{
- if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyph))
+ if (GlyphPropertiesEntry const* newGlyphProperties = sGlyphPropertiesStore.LookupEntry(newGlyph))
{
- if (GlyphSlotEntry const* gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
+ if (GlyphSlotEntry const* newGlyphSlot = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
{
- if (gp->TypeFlags != gs->TypeFlags)
+ if (newGlyphProperties->TypeFlags != newGlyphSlot->TypeFlags)
{
SendCastResult(SPELL_FAILED_INVALID_GLYPH);
return; // glyph slot mismatch
@@ -4382,17 +4085,26 @@ void Spell::EffectApplyGlyph(SpellEffIndex effIndex)
}
// remove old glyph
- if (uint32 oldglyph = player->GetGlyph(m_glyphIndex))
+ if (uint32 oldGlyph = player->GetGlyph(player->GetActiveSpec(), m_glyphIndex))
{
- if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
+ if (GlyphPropertiesEntry const* oldGlyphProperties = sGlyphPropertiesStore.LookupEntry(oldGlyph))
{
- player->RemoveAurasDueToSpell(old_gp->SpellId);
+ player->RemoveAurasDueToSpell(oldGlyphProperties->SpellId);
player->SetGlyph(m_glyphIndex, 0);
}
}
- player->CastSpell(m_caster, gp->SpellId, true);
- player->SetGlyph(m_glyphIndex, glyph);
+ player->CastSpell(m_caster, newGlyphProperties->SpellId, true);
+ player->SetGlyph(m_glyphIndex, newGlyph);
+ player->SendTalentsInfoData(false);
+ }
+ }
+ else if (uint32 oldGlyph = player->GetGlyph(player->GetActiveSpec(), m_glyphIndex)) // Removing the glyph, get the old one
+ {
+ if (GlyphPropertiesEntry const* oldGlyphProperties = sGlyphPropertiesStore.LookupEntry(oldGlyph))
+ {
+ player->RemoveAurasDueToSpell(oldGlyphProperties->SpellId);
+ player->SetGlyph(m_glyphIndex, 0);
player->SendTalentsInfoData(false);
}
}
@@ -4594,7 +4306,7 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
Player* target = unitTarget->ToPlayer();
- if (target->isRessurectRequested()) // already have one active request
+ if (target->IsRessurectRequested()) // already have one active request
return;
uint32 health = target->CountPctFromMaxHealth(damage);
@@ -4602,7 +4314,7 @@ void Spell::EffectResurrect(SpellEffIndex effIndex)
ExecuteLogEffectResurrect(effIndex, target);
- target->setResurrectRequestData(m_caster->GetGUID(), m_caster->GetMapId(), m_caster->GetPositionX(), m_caster->GetPositionY(), m_caster->GetPositionZ(), health, mana);
+ target->SetResurrectRequestData(m_caster, health, mana, 0);
SendResurrectRequest(target);
}
@@ -4750,6 +4462,7 @@ void Spell::EffectSelfResurrect(SpellEffIndex effIndex)
player->SetPower(POWER_MANA, mana);
player->SetPower(POWER_RAGE, 0);
player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
+ player->SetPower(POWER_FOCUS, 0);
player->SpawnCorpseBones();
}
@@ -5614,6 +5327,11 @@ void Spell::EffectCreateTamedPet(SpellEffIndex effIndex)
if (!pet)
return;
+ // relocate
+ float px, py, pz;
+ unitTarget->GetClosePoint(px, py, pz, pet->GetObjectSize(), PET_FOLLOW_DIST, pet->GetFollowAngle());
+ pet->Relocate(px, py, pz, unitTarget->GetOrientation());
+
// add to world
pet->GetMap()->AddToMap(pet->ToCreature());
@@ -5798,6 +5516,7 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex)
WorldPacket data(SMSG_PLAY_MUSIC, 4);
data << uint32(soundid);
+ data << uint64(unitTarget->GetGUID());
unitTarget->ToPlayer()->GetSession()->SendPacket(&data);
}
@@ -5833,8 +5552,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
switch (m_spellInfo->Id)
{
- case 58730: // Restricted Flight Area
- case 58600: // Restricted Flight Area
+ case 91604: // Restricted Flight Area
unitTarget->ToPlayer()->GetSession()->SendNotification(LANG_ZONE_NOFLYZONE);
break;
default:
@@ -5851,6 +5569,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(soundId);
+ data << uint64(m_caster->GetGUID());
unitTarget->ToPlayer()->GetSession()->SendPacket(&data);
}
@@ -5865,6 +5584,28 @@ void Spell::EffectRemoveAura(SpellEffIndex effIndex)
unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
}
+void Spell::EffectDamageFromMaxHealthPCT(SpellEffIndex /*effIndex*/)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ if (!unitTarget)
+ return;
+
+ m_damage += unitTarget->CountPctFromMaxHealth(damage);
+}
+
+void Spell::EffectGiveCurrency(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ unitTarget->ToPlayer()->ModifyCurrency(m_spellInfo->Effects[effIndex].MiscValue, damage);
+}
+
void Spell::EffectCastButtons(SpellEffIndex effIndex)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
@@ -5896,10 +5637,10 @@ void Spell::EffectCastButtons(SpellEffIndex effIndex)
if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
continue;
- if (!(spellInfo->AttributesEx7 & SPELL_ATTR7_SUMMON_PLAYER_TOTEM))
+ if (!(spellInfo->AttributesEx9 & SPELL_ATTR9_SUMMON_PLAYER_TOTEM))
continue;
- uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask());
+ int32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask());
if (m_caster->GetPower(POWER_MANA) < cost)
continue;
@@ -5993,3 +5734,65 @@ void Spell::EffectSummonRaFFriend(SpellEffIndex effIndex)
m_caster->CastSpell(unitTarget, m_spellInfo->Effects[effIndex].TriggerSpell, true);
}
+
+void Spell::EffectUnlockGuildVaultTab(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
+ return;
+
+ // 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
+}
+
+void Spell::EffectResurrectWithAura(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ if (!unitTarget || !unitTarget->IsInWorld())
+ return;
+
+ Player* target = unitTarget->ToPlayer();
+ if (!target)
+ return;
+
+ if (unitTarget->IsAlive())
+ return;
+
+ if (target->IsRessurectRequested()) // already have one active request
+ return;
+
+ 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 (resurrectAura && target->HasAura(resurrectAura))
+ return;
+
+ ExecuteLogEffectResurrect(effIndex, target);
+ target->SetResurrectRequestData(m_caster, health, mana, resurrectAura);
+ SendResurrectRequest(target);
+}
+
+void Spell::EffectCreateAreaTrigger(SpellEffIndex effIndex)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
+ return;
+
+ Position pos;
+ if (!m_targets.HasDst())
+ GetCaster()->GetPosition(&pos);
+ else
+ destTarget->GetPosition(&pos);
+
+ // trigger entry/miscvalue relation is currently unknown, for now use MiscValue as trigger entry
+ uint32 triggerEntry = GetSpellInfo()->Effects[effIndex].MiscValue;
+
+ AreaTrigger * areaTrigger = new AreaTrigger;
+ if (!areaTrigger->CreateAreaTrigger(sObjectMgr->GenerateLowGuid(HIGHGUID_AREATRIGGER), triggerEntry, GetCaster(), GetSpellInfo(), pos))
+ delete areaTrigger;
+}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 21c36510a32..ef9e6d5aa21 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -15,8 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "SpellAuraDefines.h"
#include "SpellInfo.h"
+#include "SpellAuraDefines.h"
#include "SpellMgr.h"
#include "Spell.h"
#include "DBCStores.h"
@@ -317,34 +317,57 @@ SpellImplicitTargetInfo::StaticData SpellImplicitTargetInfo::_data[TOTAL_SPELL_
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_DEST, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 107 TARGET_UNK_DEST_AREA_UNK_107
{TARGET_OBJECT_TYPE_GOBJ, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 108 TARGET_GAMEOBJECT_CONE
{TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 109
- {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 110 TARGET_DEST_UNK_110
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_CONE, TARGET_CHECK_DEFAULT, TARGET_DIR_FRONT}, // 110 TARGET_DEST_UNK_110
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 111
+ {TARGET_OBJECT_TYPE_DEST, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_DEFAULT, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 112
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 113
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 114
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 115
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 116
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 117
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 118
+ {TARGET_OBJECT_TYPE_UNIT, TARGET_REFERENCE_TYPE_CASTER, TARGET_SELECT_CATEGORY_AREA, TARGET_CHECK_RAID, TARGET_DIR_NONE}, // 119
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 120
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 121
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 122
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 123
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 124
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 125
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 126
+ {TARGET_OBJECT_TYPE_NONE, TARGET_REFERENCE_TYPE_NONE, TARGET_SELECT_CATEGORY_NYI, TARGET_CHECK_DEFAULT, TARGET_DIR_NONE}, // 127
};
-SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex)
+SpellEffectInfo::SpellEffectInfo(SpellEntry const* /*spellEntry*/, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* _effect)
{
+ SpellScalingEntry const* scaling = spellInfo->GetSpellScaling();
+
_spellInfo = spellInfo;
- _effIndex = effIndex;
- Effect = spellEntry->Effect[effIndex];
- ApplyAuraName = spellEntry->EffectApplyAuraName[effIndex];
- Amplitude = spellEntry->EffectAmplitude[effIndex];
- DieSides = spellEntry->EffectDieSides[effIndex];
- RealPointsPerLevel = spellEntry->EffectRealPointsPerLevel[effIndex];
- BasePoints = spellEntry->EffectBasePoints[effIndex];
- PointsPerComboPoint = spellEntry->EffectPointsPerComboPoint[effIndex];
- ValueMultiplier = spellEntry->EffectValueMultiplier[effIndex];
- DamageMultiplier = spellEntry->EffectDamageMultiplier[effIndex];
- BonusMultiplier = spellEntry->EffectBonusMultiplier[effIndex];
- MiscValue = spellEntry->EffectMiscValue[effIndex];
- MiscValueB = spellEntry->EffectMiscValueB[effIndex];
- Mechanic = Mechanics(spellEntry->EffectMechanic[effIndex]);
- TargetA = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetA[effIndex]);
- TargetB = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetB[effIndex]);
- RadiusEntry = spellEntry->EffectRadiusIndex[effIndex] ? sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[effIndex]) : NULL;
- ChainTarget = spellEntry->EffectChainTarget[effIndex];
- ItemType = spellEntry->EffectItemType[effIndex];
- TriggerSpell = spellEntry->EffectTriggerSpell[effIndex];
- SpellClassMask = spellEntry->EffectSpellClassMask[effIndex];
+ _effIndex = _effect ? _effect->EffectIndex : effIndex;
+ Effect = _effect ? _effect->Effect : 0;
+ ApplyAuraName = _effect ? _effect->EffectApplyAuraName : 0;
+ Amplitude = _effect ? _effect->EffectAmplitude : 0;
+ DieSides = _effect ? _effect->EffectDieSides : 0;
+ RealPointsPerLevel = _effect ? _effect->EffectRealPointsPerLevel : 0.0f;
+ BasePoints = _effect ? _effect->EffectBasePoints : 0;
+ PointsPerComboPoint = _effect ? _effect->EffectPointsPerComboPoint : 0.0f;
+ ValueMultiplier = _effect ? _effect->EffectValueMultiplier : 0.0f;
+ DamageMultiplier = _effect ? _effect->EffectDamageMultiplier : 0.0f;
+ BonusMultiplier = _effect ? _effect->EffectBonusMultiplier : 0.0f;
+ MiscValue = _effect ? _effect->EffectMiscValue : 0;
+ MiscValueB = _effect ? _effect->EffectMiscValueB : 0;
+ Mechanic = Mechanics(_effect ? _effect->EffectMechanic : 0);
+ TargetA = SpellImplicitTargetInfo(_effect ? _effect->EffectImplicitTargetA : 0);
+ TargetB = SpellImplicitTargetInfo(_effect ? _effect->EffectImplicitTargetB : 0);
+ RadiusEntry = _effect && _effect->EffectRadiusIndex ? sSpellRadiusStore.LookupEntry(_effect->EffectRadiusIndex) : NULL;
+ MaxRadiusEntry = _effect && _effect->EffectRadiusMaxIndex ? sSpellRadiusStore.LookupEntry(_effect->EffectRadiusMaxIndex) : NULL;
+ ChainTarget = _effect ? _effect->EffectChainTarget : 0;
+ ItemType = _effect ? _effect->EffectItemType : 0;
+ TriggerSpell = _effect ? _effect->EffectTriggerSpell : 0;
+ SpellClassMask = _effect ? _effect->EffectSpellClassMask : flag96(0);
ImplicitTargetConditions = NULL;
+ ScalingMultiplier = scaling ? scaling->Multiplier[_effIndex] : 0.0f;
+ DeltaScalingMultiplier = scaling ? scaling->RandomMultiplier[_effIndex] : 0.0f;
+ ComboScalingMultiplier = scaling ? scaling->OtherMultiplier[_effIndex] : 0.0f;
}
bool SpellEffectInfo::IsEffect() const
@@ -403,37 +426,73 @@ 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, int32 const* bp, Unit const* target) const
{
float basePointsPerLevel = RealPointsPerLevel;
int32 basePoints = bp ? *bp : BasePoints;
- int32 randomPoints = int32(DieSides);
+ float comboDamage = PointsPerComboPoint;
// base amount modification based on spell lvl vs caster lvl
- if (caster)
+ if (ScalingMultiplier != 0.0f)
{
- int32 level = int32(caster->getLevel());
- if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
- level = int32(_spellInfo->MaxLevel);
- else if (level < int32(_spellInfo->BaseLevel))
- level = int32(_spellInfo->BaseLevel);
- level -= int32(_spellInfo->SpellLevel);
- basePoints += int32(level * basePointsPerLevel);
- }
+ if (caster)
+ {
+ int32 level = caster->getLevel();
+ if (target && _spellInfo->IsPositiveEffect(_effIndex) && (Effect == SPELL_EFFECT_APPLY_AURA))
+ level = target->getLevel();
+
+ if (GtSpellScalingEntry const* gtScaling = sGtSpellScalingStore.LookupEntry((_spellInfo->ScalingClass != -1 ? _spellInfo->ScalingClass - 1 : MAX_CLASSES - 1) * 100 + level - 1))
+ {
+ 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)
+ {
+ float delta = fabs(DeltaScalingMultiplier * ScalingMultiplier * multiplier * 0.5f);
+ preciseBasePoints += frand(-delta, delta);
+ }
- // roll in a range <1;EffectDieSides> as of patch 3.3.3
- switch (randomPoints)
+ basePoints = int32(preciseBasePoints);
+
+ if (ComboScalingMultiplier)
+ comboDamage = ComboScalingMultiplier * multiplier;
+ }
+ }
+ }
+ else
{
- case 0: break;
- case 1: basePoints += 1; break; // range 1..1
- default:
- // range can have positive (1..rand) and negative (rand..1) values, so order its for irand
- int32 randvalue = (randomPoints >= 1)
- ? irand(1, randomPoints)
- : irand(randomPoints, 1);
+ if (caster)
+ {
+ int32 level = int32(caster->getLevel());
+ if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
+ level = int32(_spellInfo->MaxLevel);
+ else if (level < int32(_spellInfo->BaseLevel))
+ level = int32(_spellInfo->BaseLevel);
+ level -= int32(_spellInfo->SpellLevel);
+ basePoints += int32(level * basePointsPerLevel);
+ }
- basePoints += randvalue;
- break;
+ // roll in a range <1;EffectDieSides> as of patch 3.3.3
+ int32 randomPoints = int32(DieSides);
+ switch (randomPoints)
+ {
+ case 0: break;
+ case 1: basePoints += 1; break; // range 1..1
+ default:
+ {
+ // range can have positive (1..rand) and negative (rand..1) values, so order its for irand
+ int32 randvalue = (randomPoints >= 1)
+ ? irand(1, randomPoints)
+ : irand(randomPoints, 1);
+
+ basePoints += randvalue;
+ break;
+ }
+ }
}
float value = float(basePoints);
@@ -442,14 +501,26 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
if (caster)
{
// bonus amount from combo points
- if (caster->m_movedPlayer)
+ if (caster->m_movedPlayer && comboDamage)
if (uint8 comboPoints = caster->m_movedPlayer->GetComboPoints())
- if (float comboDamage = PointsPerComboPoint)
- value += comboDamage* comboPoints;
+ value += comboDamage * comboPoints;
value = caster->ApplyEffectModifiers(_spellInfo, _effIndex, 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))
@@ -500,6 +571,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
value *= casterScaler->ratio / spellScaler->ratio;
}
}
+// REVIEW - MERGE >>>>>>> master
}
return int32(value);
@@ -534,16 +606,25 @@ bool SpellEffectInfo::HasRadius() const
return RadiusEntry != NULL;
}
+bool SpellEffectInfo::HasMaxRadius() const
+{
+ return MaxRadiusEntry != NULL;
+}
+
float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const
{
- if (!HasRadius())
+ const SpellRadiusEntry* entry = RadiusEntry;
+ if (!HasRadius() && HasMaxRadius())
+ entry = MaxRadiusEntry;
+
+ if (!entry)
return 0.0f;
- float radius = RadiusEntry->RadiusMin;
+ float radius = entry->RadiusMin;
if (caster)
{
- radius += RadiusEntry->RadiusPerLevel * caster->getLevel();
- radius = std::min(radius, RadiusEntry->RadiusMax);
+ radius += entry->RadiusPerLevel * caster->getLevel();
+ radius = std::min(radius, entry->RadiusMax);
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_RADIUS, radius, spell);
}
@@ -590,7 +671,7 @@ SpellTargetObjectTypes SpellEffectInfo::GetUsedTargetObjectType() const
return _data[Effect].UsedTargetObjectType;
}
-SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
+SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{
// implicit target type used target object type
{EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 0
@@ -758,14 +839,29 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] =
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163
{EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 165 SPELL_EFFECT_165
+ {EFFECT_IMPLICIT_TARGET_CASTER, TARGET_OBJECT_TYPE_UNIT}, // 166 SPELL_EFFECT_GIVE_CURRENCY
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 167 SPELL_EFFECT_167
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 168 SPELL_EFFECT_168
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_ITEM}, // 169 SPELL_EFFECT_DESTROY_ITEM
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 170 SPELL_EFFECT_170
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 171 SPELL_EFFECT_171
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 172 SPELL_EFFECT_172
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 173 SPELL_EFFECT_UNLOCK_GUILD_VAULT_TAB
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 174 SPELL_EFFECT_174
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 175 SPELL_EFFECT_175
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 176 SPELL_EFFECT_176
+ {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 177 SPELL_EFFECT_177
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 178 SPELL_EFFECT_178
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 179 SPELL_EFFECT_CREATE_AREATRIGGER
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 180 SPELL_EFFECT_180
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 181 SPELL_EFFECT_181
+ {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 182 SPELL_EFFECT_182
};
-SpellInfo::SpellInfo(SpellEntry const* spellEntry)
+SpellInfo::SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects)
{
Id = spellEntry->Id;
- CategoryEntry = spellEntry->Category ? sSpellCategoryStore.LookupEntry(spellEntry->Category) : NULL;
- Dispel = spellEntry->Dispel;
- Mechanic = spellEntry->Mechanic;
Attributes = spellEntry->Attributes;
AttributesEx = spellEntry->AttributesEx;
AttributesEx2 = spellEntry->AttributesEx2;
@@ -774,82 +870,148 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry)
AttributesEx5 = spellEntry->AttributesEx5;
AttributesEx6 = spellEntry->AttributesEx6;
AttributesEx7 = spellEntry->AttributesEx7;
+ AttributesEx8 = spellEntry->AttributesEx8;
+ AttributesEx9 = spellEntry->AttributesEx9;
+ AttributesEx10 = spellEntry->AttributesEx10;
AttributesCu = 0;
- Stances = spellEntry->Stances;
- StancesNot = spellEntry->StancesNot;
- Targets = spellEntry->Targets;
- TargetCreatureType = spellEntry->TargetCreatureType;
- RequiresSpellFocus = spellEntry->RequiresSpellFocus;
- FacingCasterFlags = spellEntry->FacingCasterFlags;
- CasterAuraState = spellEntry->CasterAuraState;
- TargetAuraState = spellEntry->TargetAuraState;
- CasterAuraStateNot = spellEntry->CasterAuraStateNot;
- TargetAuraStateNot = spellEntry->TargetAuraStateNot;
- CasterAuraSpell = spellEntry->casterAuraSpell;
- TargetAuraSpell = spellEntry->targetAuraSpell;
- ExcludeCasterAuraSpell = spellEntry->excludeCasterAuraSpell;
- ExcludeTargetAuraSpell = spellEntry->excludeTargetAuraSpell;
CastTimeEntry = spellEntry->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(spellEntry->CastingTimeIndex) : NULL;
- RecoveryTime = spellEntry->RecoveryTime;
- CategoryRecoveryTime = spellEntry->CategoryRecoveryTime;
- StartRecoveryCategory = spellEntry->StartRecoveryCategory;
- StartRecoveryTime = spellEntry->StartRecoveryTime;
- InterruptFlags = spellEntry->InterruptFlags;
- AuraInterruptFlags = spellEntry->AuraInterruptFlags;
- ChannelInterruptFlags = spellEntry->ChannelInterruptFlags;
- ProcFlags = spellEntry->procFlags;
- ProcChance = spellEntry->procChance;
- ProcCharges = spellEntry->procCharges;
- MaxLevel = spellEntry->maxLevel;
- BaseLevel = spellEntry->baseLevel;
- SpellLevel = spellEntry->spellLevel;
DurationEntry = spellEntry->DurationIndex ? sSpellDurationStore.LookupEntry(spellEntry->DurationIndex) : NULL;
PowerType = spellEntry->powerType;
- ManaCost = spellEntry->manaCost;
- ManaCostPerlevel = spellEntry->manaCostPerlevel;
- ManaPerSecond = spellEntry->manaPerSecond;
- ManaPerSecondPerLevel = spellEntry->manaPerSecondPerLevel;
- ManaCostPercentage = spellEntry->ManaCostPercentage;
- RuneCostID = spellEntry->runeCostID;
RangeEntry = spellEntry->rangeIndex ? sSpellRangeStore.LookupEntry(spellEntry->rangeIndex) : NULL;
Speed = spellEntry->speed;
- StackAmount = spellEntry->StackAmount;
- for (uint8 i = 0; i < 2; ++i)
- Totem[i] = spellEntry->Totem[i];
-
- for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i)
- Reagent[i] = spellEntry->Reagent[i];
-
- for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i)
- ReagentCount[i] = spellEntry->ReagentCount[i];
-
- EquippedItemClass = spellEntry->EquippedItemClass;
- EquippedItemSubClassMask = spellEntry->EquippedItemSubClassMask;
- EquippedItemInventoryTypeMask = spellEntry->EquippedItemInventoryTypeMask;
- for (uint8 i = 0; i < 2; ++i)
- TotemCategory[i] = spellEntry->TotemCategory[i];
for (uint8 i = 0; i < 2; ++i)
SpellVisual[i] = spellEntry->SpellVisual[i];
SpellIconID = spellEntry->SpellIconID;
ActiveIconID = spellEntry->activeIconID;
- for (uint8 i = 0; i < 16; ++i)
- SpellName[i] = spellEntry->SpellName[i];
-
- for (uint8 i = 0; i < 16; ++i)
- Rank[i] = spellEntry->Rank[i];
-
- MaxTargetLevel = spellEntry->MaxTargetLevel;
- MaxAffectedTargets = spellEntry->MaxAffectedTargets;
- SpellFamilyName = spellEntry->SpellFamilyName;
- SpellFamilyFlags = spellEntry->SpellFamilyFlags;
- DmgClass = spellEntry->DmgClass;
- PreventionType = spellEntry->PreventionType;
- AreaGroupId = spellEntry->AreaGroupId;
+ SpellName = spellEntry->SpellName;
+ Rank = spellEntry->Rank;
SchoolMask = spellEntry->SchoolMask;
+ RuneCostID = spellEntry->runeCostID;
+ SpellDifficultyId = spellEntry->SpellDifficultyId;
+ SpellScalingId = spellEntry->SpellScalingId;
+ SpellAuraOptionsId = spellEntry->SpellAuraOptionsId;
+ SpellAuraRestrictionsId = spellEntry->SpellAuraRestrictionsId;
+ SpellCastingRequirementsId = spellEntry->SpellCastingRequirementsId;
+ SpellCategoriesId = spellEntry->SpellCategoriesId;
+ SpellClassOptionsId = spellEntry->SpellClassOptionsId;
+ SpellCooldownsId = spellEntry->SpellCooldownsId;
+ SpellEquippedItemsId = spellEntry->SpellEquippedItemsId;
+ SpellInterruptsId = spellEntry->SpellInterruptsId;
+ SpellLevelsId = spellEntry->SpellLevelsId;
+ SpellPowerId = spellEntry->SpellPowerId;
+ SpellReagentsId = spellEntry->SpellReagentsId;
+ SpellShapeshiftId = spellEntry->SpellShapeshiftId;
+ SpellTargetRestrictionsId = spellEntry->SpellTargetRestrictionsId;
+ SpellTotemsId = spellEntry->SpellTotemsId;
+
+ // SpellDifficultyEntry
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- Effects[i] = SpellEffectInfo(spellEntry, this, 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->CoefBase : 0;
+ CoefLevelBase = _scaling ? _scaling->CoefLevelBase : 0;
+
+ // SpellAuraOptionsEntry
+ SpellAuraOptionsEntry const* _options = GetSpellAuraOptions();
+ ProcFlags = _options ? _options->procFlags : 0;
+ ProcChance = _options ? _options->procChance : 0;
+ ProcCharges = _options ? _options->procCharges : 0;
+ StackAmount = _options ? _options->StackAmount : 0;
+
+ // SpellAuraRestrictionsEntry
+ SpellAuraRestrictionsEntry const* _aura = GetSpellAuraRestrictions();
+ CasterAuraState = _aura ? _aura->CasterAuraState : 0;
+ TargetAuraState = _aura ? _aura->TargetAuraState : 0;
+ CasterAuraStateNot = _aura ? _aura->CasterAuraStateNot : 0;
+ TargetAuraStateNot = _aura ? _aura->TargetAuraStateNot : 0;
+ CasterAuraSpell = _aura ? _aura->casterAuraSpell : 0;
+ TargetAuraSpell = _aura ? _aura->targetAuraSpell : 0;
+ ExcludeCasterAuraSpell = _aura ? _aura->excludeCasterAuraSpell : 0;
+ ExcludeTargetAuraSpell = _aura ? _aura->excludeTargetAuraSpell : 0;
+
+ // SpellCastingRequirementsEntry
+ SpellCastingRequirementsEntry const* _castreq = GetSpellCastingRequirements();
+ RequiresSpellFocus = _castreq ? _castreq->RequiresSpellFocus : 0;
+ FacingCasterFlags = _castreq ? _castreq->FacingCasterFlags : 0;
+ AreaGroupId = _castreq ? _castreq->AreaGroupId : -1;
+
+ // SpellCategoriesEntry
+ SpellCategoriesEntry const* _categorie = GetSpellCategories();
+ CategoryEntry = _categorie ? sSpellCategoryStore.LookupEntry(_categorie->Category) : NULL;
+ Dispel = _categorie ? _categorie->Dispel : 0;
+ Mechanic = _categorie ? _categorie->Mechanic : 0;
+ StartRecoveryCategory = _categorie ? _categorie->StartRecoveryCategory : 0;
+ DmgClass = _categorie ? _categorie->DmgClass : 0;
+ PreventionType = _categorie ? _categorie->PreventionType : 0;
+
+ // SpellClassOptionsEntry
+ SpellClassOptionsEntry const* _class = GetSpellClassOptions();
+ SpellFamilyName = _class ? _class->SpellFamilyName : 0;
+ SpellFamilyFlags = _class ? _class->SpellFamilyFlags : flag96(0);
+
+ // SpellCooldownsEntry
+ SpellCooldownsEntry const* _cooldowns = GetSpellCooldowns();
+ RecoveryTime = _cooldowns ? _cooldowns->RecoveryTime : 0;
+ CategoryRecoveryTime = _cooldowns ? _cooldowns->CategoryRecoveryTime : 0;
+ StartRecoveryTime = _cooldowns ? _cooldowns->StartRecoveryTime : 0;
+
+ // SpellEquippedItemsEntry
+ SpellEquippedItemsEntry const* _equipped = GetSpellEquippedItems();
+ EquippedItemClass = _equipped ? _equipped->EquippedItemClass : -1;
+ EquippedItemSubClassMask = _equipped ?_equipped->EquippedItemSubClassMask : -1;
+ EquippedItemInventoryTypeMask = _equipped ? _equipped->EquippedItemInventoryTypeMask : -1;
+
+ // SpellInterruptsEntry
+ SpellInterruptsEntry const* _interrupt = GetSpellInterrupts();
+ InterruptFlags = _interrupt ? _interrupt->InterruptFlags : 0;
+ AuraInterruptFlags = _interrupt ? _interrupt->AuraInterruptFlags : 0;
+ ChannelInterruptFlags = _interrupt ? _interrupt->ChannelInterruptFlags : 0;
+
+ // SpellLevelsEntry
+ SpellLevelsEntry const* _levels = GetSpellLevels();
+ MaxLevel = _levels ? _levels->maxLevel : 0;
+ BaseLevel = _levels ? _levels->baseLevel : 0;
+ SpellLevel = _levels ? _levels->spellLevel : 0;
+
+ // SpellPowerEntry
+ SpellPowerEntry const* _power = GetSpellPower();
+ ManaCost = _power ? _power->manaCost : 0;
+ ManaCostPerlevel = _power ? _power->manaCostPerlevel : 0;
+ ManaCostPercentage = _power ? _power->ManaCostPercentage : 0;
+ ManaPerSecond = _power ? _power->manaPerSecond : 0;
+
+ // SpellReagentsEntry
+ SpellReagentsEntry const* _reagents = GetSpellReagents();
+ for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i)
+ Reagent[i] = _reagents ? _reagents->Reagent[i] : 0;
+ for (uint8 i = 0; i < MAX_SPELL_REAGENTS; ++i)
+ ReagentCount[i] = _reagents ? _reagents->ReagentCount[i] : 0;
+
+ // SpellShapeshiftEntry
+ SpellShapeshiftEntry const* _shapeshift = GetSpellShapeshift();
+ Stances = _shapeshift ? _shapeshift->Stances : 0;
+ StancesNot = _shapeshift ? _shapeshift->StancesNot : 0;
+
+ // SpellTargetRestrictionsEntry
+ SpellTargetRestrictionsEntry const* _target = GetSpellTargetRestrictions();
+ Targets = _target ? _target->Targets : 0;
+ TargetCreatureType = _target ? _target->TargetCreatureType : 0;
+ MaxAffectedTargets = _target ? _target->MaxAffectedTargets : 0;
+
+ // SpellTotemsEntry
+ SpellTotemsEntry const* _totem = GetSpellTotems();
+ for (uint8 i = 0; i < 2; ++i)
+ TotemCategory[i] = _totem ? _totem->TotemCategory[i] : 0;
+ for (uint8 i = 0; i < 2; ++i)
+ Totem[i] = _totem ? _totem->Totem[i] : 0;
ChainEntry = NULL;
}
@@ -1292,6 +1454,7 @@ bool SpellInfo::IsAuraExclusiveBySpecificPerCasterWith(SpellInfo const* spellInf
case SPELL_SPECIFIC_AURA:
case SPELL_SPECIFIC_STING:
case SPELL_SPECIFIC_CURSE:
+ case SPELL_SPECIFIC_BANE:
case SPELL_SPECIFIC_ASPECT:
case SPELL_SPECIFIC_JUDGEMENT:
case SPELL_SPECIFIC_WARLOCK_CORRUPTION:
@@ -1318,10 +1481,10 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const
return SPELL_CAST_OK;
bool actAsShifted = false;
- SpellShapeshiftEntry const* shapeInfo = NULL;
+ SpellShapeshiftFormEntry const* shapeInfo = NULL;
if (form > 0)
{
- shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ shapeInfo = sSpellShapeshiftFormStore.LookupEntry(form);
if (!shapeInfo)
{
TC_LOG_ERROR("spells", "GetErrorAtShapeshiftedCast: unknown shapeshift %u", form);
@@ -1473,17 +1636,27 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
}
// aura limitations
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (player)
{
- if (!Effects[i].IsAura())
- continue;
- switch (Effects[i].ApplyAuraName)
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- case SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED:
- case SPELL_AURA_FLY:
+ if (!Effects[i].IsAura())
+ continue;
+
+ switch (Effects[i].ApplyAuraName)
{
- if (player && !player->IsKnowHowFlyIn(map_id, zone_id))
- return SPELL_FAILED_INCORRECT_AREA;
+ case SPELL_AURA_FLY:
+ {
+ if (!player->IsKnowHowFlyIn(map_id, zone_id))
+ return SPELL_FAILED_INCORRECT_AREA;
+ break;
+ }
+ case SPELL_AURA_MOUNTED:
+ {
+ if (Effects[i].MiscValueB && !player->GetMountCapability(Effects[i].MiscValueB))
+ return SPELL_FAILED_NOT_HERE;
+ break;
+ }
}
}
}
@@ -1683,8 +1856,8 @@ SpellCastResult SpellInfo::CheckVehicle(Unit const* caster) const
{
if (Effects[effIndex].ApplyAuraName == SPELL_AURA_MOD_SHAPESHIFT)
{
- SpellShapeshiftEntry const* shapeShiftEntry = sSpellShapeshiftStore.LookupEntry(Effects[effIndex].MiscValue);
- if (shapeShiftEntry && (shapeShiftEntry->flags1 & 1) == 0) // unk flag
+ SpellShapeshiftFormEntry const* shapeShiftFromEntry = sSpellShapeshiftFormStore.LookupEntry(Effects[effIndex].MiscValue);
+ if (shapeShiftFromEntry && (shapeShiftFromEntry->flags1 & 1) == 0) // unk flag
checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
break;
}
@@ -1950,6 +2123,10 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
}
case SPELLFAMILY_WARLOCK:
{
+ // Warlock (Bane of Doom | Bane of Agony | Bane of Havoc)
+ if (Id == 603 || Id == 980 || Id == 80240)
+ return SPELL_SPECIFIC_BANE;
+
// only warlock curses have this
if (Dispel == DISPEL_CURSE)
return SPELL_SPECIFIC_CURSE;
@@ -1986,15 +2163,14 @@ SpellSpecificType SpellInfo::GetSpellSpecific() const
case SPELLFAMILY_PALADIN:
{
// Collection of all the seal family flags. No other paladin spell has any of those.
- if (SpellFamilyFlags[1] & 0x26000C00
- || SpellFamilyFlags[0] & 0x0A000000)
+ if (SpellFamilyFlags[1] & 0xA2000800)
return SPELL_SPECIFIC_SEAL;
if (SpellFamilyFlags[0] & 0x00002190)
return SPELL_SPECIFIC_HAND;
- // Judgement of Wisdom, Judgement of Light, Judgement of Justice
- if (Id == 20184 || Id == 20185 || Id == 20186)
+ // Judgement
+ if (Id == 20271)
return SPELL_SPECIFIC_JUDGEMENT;
// only paladin auras have this (for palaldin class family)
@@ -2082,18 +2258,29 @@ int32 SpellInfo::GetMaxDuration() const
return (DurationEntry->Duration[2] == -1) ? -1 : abs(DurationEntry->Duration[2]);
}
-uint32 SpellInfo::CalcCastTime(Spell* spell /*= NULL*/) const
+uint32 SpellInfo::CalcCastTime(uint8 level, Spell* spell /*= NULL*/) const
{
+ int32 castTime = 0;
+ if (!level && spell)
+ level = spell->GetCaster()->getLevel();
+
// not all spells have cast time index and this is all is pasiive abilities
- if (!CastTimeEntry)
- return 0;
+ if (level && CastTimeMax > 0)
+ {
+ castTime = CastTimeMax;
+ if (CastTimeMaxLevel > level)
+ castTime = CastTimeMin + int32(level - 1) * (CastTimeMax - CastTimeMin) / (CastTimeMaxLevel - 1);
+ }
+ else if (CastTimeEntry)
+ castTime = CastTimeEntry->CastTime;
- int32 castTime = CastTimeEntry->CastTime;
+ if (!castTime)
+ return 0;
if (spell)
spell->GetCaster()->ModSpellCastTime(this, castTime, spell);
- if (Attributes & SPELL_ATTR0_REQ_AMMO && (!IsAutoRepeatRangedSpell()))
+ if (Attributes & SPELL_ATTR0_REQ_AMMO && (!IsAutoRepeatRangedSpell()) && !(AttributesEx9 & SPELL_ATTR9_AIMED_SHOT))
castTime += 500;
return (castTime > 0) ? uint32(castTime) : 0;
@@ -2163,10 +2350,9 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
case POWER_RAGE:
case POWER_FOCUS:
case POWER_ENERGY:
- case POWER_HAPPINESS:
powerCost += int32(CalculatePct(caster->GetMaxPower(Powers(PowerType)), ManaCostPercentage));
break;
- case POWER_RUNE:
+ case POWER_RUNES:
case POWER_RUNIC_POWER:
TC_LOG_DEBUG("spells", "CalculateManaCost: Not implemented yet!");
break;
@@ -2175,17 +2361,27 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
return 0;
}
}
- SpellSchools school = GetFirstSchoolInMask(schoolMask);
- // Flat mod from caster auras by spell school
- powerCost += caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school);
+
+ // Flat mod from caster auras by spell school and power type
+ Unit::AuraEffectList const& auras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL);
+ for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ {
+ if (!((*i)->GetMiscValue() & schoolMask))
+ continue;
+ if (!((*i)->GetMiscValueB() & (1 << PowerType)))
+ continue;
+ powerCost += (*i)->GetAmount();
+ }
// Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
if (AttributesEx4 & SPELL_ATTR4_SPELL_VS_EXTEND_COST)
{
uint32 speed = 0;
+/* REVIEW - MERGE
if (SpellShapeshiftEntry const* ss = sSpellShapeshiftStore.LookupEntry(caster->GetShapeshiftForm()))
speed = ss->attackSpeed;
else
+*/
{
WeaponAttackType slot = BASE_ATTACK;
if (AttributesEx3 & SPELL_ATTR3_REQ_OFFHAND)
@@ -2212,8 +2408,16 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) c
}
}
- // PCT mod from user auras by school
- powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school)));
+ // PCT mod from user auras by spell school and power type
+ Unit::AuraEffectList const& aurasPct = caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT);
+ for (Unit::AuraEffectList::const_iterator i = aurasPct.begin(); i != aurasPct.end(); ++i)
+ {
+ if (!((*i)->GetMiscValue() & schoolMask))
+ continue;
+ if (!((*i)->GetMiscValueB() & (1 << PowerType)))
+ continue;
+ powerCost += CalculatePct(powerCost, (*i)->GetAmount());
+ }
if (powerCost < 0)
powerCost = 0;
return powerCost;
@@ -2268,7 +2472,8 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const
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].Effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID) &&
+ !Effects[i].ScalingMultiplier)
{
needRankSelection = true;
break;
@@ -2359,8 +2564,6 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
case 29214: // Wrath of the Plaguebringer
case 34700: // Allergic Reaction
case 54836: // Wrath of the Plaguebringer
- case 61987: // Avenging Wrath Marker
- case 61988: // Divine Shield exclude aura
return false;
case 30877: // Tag Murloc
case 61716: // Rabbit Costume
@@ -2372,9 +2575,6 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
}
break;
case SPELLFAMILY_MAGE:
- // Amplify Magic, Dampen Magic
- if (SpellFamilyFlags[0] == 0x00002000)
- return true;
// Ignite
if (SpellIconID == 45)
return true;
@@ -2390,23 +2590,11 @@ bool SpellInfo::_IsPositiveEffect(uint8 effIndex, bool deep) const
break;
}
break;
- case SPELLFAMILY_HUNTER:
- // Aspect of the Viper
- if (Id == 34074)
- return true;
- break;
- case SPELLFAMILY_SHAMAN:
- if (Id == 30708)
- return false;
- break;
case SPELLFAMILY_ROGUE:
switch (Id)
{
// Envenom must be considered as a positive effect even though it deals damage
- case 32645: // Envenom (Rank 1)
- case 32684: // Envenom (Rank 2)
- case 57992: // Envenom (Rank 3)
- case 57993: // Envenom (Rank 4)
+ case 32645: // Envenom
return true;
default:
break;
@@ -2633,6 +2821,81 @@ bool SpellInfo::_IsPositiveTarget(uint32 targetA, uint32 targetB)
return true;
}
+SpellTargetRestrictionsEntry const* SpellInfo::GetSpellTargetRestrictions() const
+{
+ return SpellTargetRestrictionsId ? sSpellTargetRestrictionsStore.LookupEntry(SpellTargetRestrictionsId) : NULL;
+}
+
+SpellEquippedItemsEntry const* SpellInfo::GetSpellEquippedItems() const
+{
+ return SpellEquippedItemsId ? sSpellEquippedItemsStore.LookupEntry(SpellEquippedItemsId) : NULL;
+}
+
+SpellInterruptsEntry const* SpellInfo::GetSpellInterrupts() const
+{
+ return SpellInterruptsId ? sSpellInterruptsStore.LookupEntry(SpellInterruptsId) : NULL;
+}
+
+SpellLevelsEntry const* SpellInfo::GetSpellLevels() const
+{
+ return SpellLevelsId ? sSpellLevelsStore.LookupEntry(SpellLevelsId) : NULL;
+}
+
+SpellPowerEntry const* SpellInfo::GetSpellPower() const
+{
+ return SpellPowerId ? sSpellPowerStore.LookupEntry(SpellPowerId) : NULL;
+}
+
+SpellReagentsEntry const* SpellInfo::GetSpellReagents() const
+{
+ return SpellReagentsId ? sSpellReagentsStore.LookupEntry(SpellReagentsId) : NULL;
+}
+
+SpellScalingEntry const* SpellInfo::GetSpellScaling() const
+{
+ return SpellScalingId ? sSpellScalingStore.LookupEntry(SpellScalingId) : NULL;
+}
+
+SpellShapeshiftEntry const* SpellInfo::GetSpellShapeshift() const
+{
+ return SpellShapeshiftId ? sSpellShapeshiftStore.LookupEntry(SpellShapeshiftId) : NULL;
+}
+
+SpellTotemsEntry const* SpellInfo::GetSpellTotems() const
+{
+ return SpellTotemsId ? sSpellTotemsStore.LookupEntry(SpellTotemsId) : NULL;
+}
+
+SpellAuraOptionsEntry const* SpellInfo::GetSpellAuraOptions() const
+{
+ return SpellAuraOptionsId ? sSpellAuraOptionsStore.LookupEntry(SpellAuraOptionsId) : NULL;
+}
+
+SpellAuraRestrictionsEntry const* SpellInfo::GetSpellAuraRestrictions() const
+{
+ return SpellAuraRestrictionsId ? sSpellAuraRestrictionsStore.LookupEntry(SpellAuraRestrictionsId) : NULL;
+}
+
+SpellCastingRequirementsEntry const* SpellInfo::GetSpellCastingRequirements() const
+{
+ return SpellCastingRequirementsId ? sSpellCastingRequirementsStore.LookupEntry(SpellCastingRequirementsId) : NULL;
+}
+
+SpellCategoriesEntry const* SpellInfo::GetSpellCategories() const
+{
+ return SpellCategoriesId ? sSpellCategoriesStore.LookupEntry(SpellCategoriesId) : NULL;
+}
+
+SpellClassOptionsEntry const* SpellInfo::GetSpellClassOptions() const
+{
+ return SpellClassOptionsId ? sSpellClassOptionsStore.LookupEntry(SpellClassOptionsId) : NULL;
+}
+
+SpellCooldownsEntry const* SpellInfo::GetSpellCooldowns() const
+{
+ return SpellCooldownsId ? sSpellCooldownsStore.LookupEntry(SpellCooldownsId) : NULL;
+}
+
void SpellInfo::_UnloadImplicitTargetConditionLists()
{
// find the same instances of ConditionList and delete them.
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 562e0371fe1..ea29eb1b00f 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -29,6 +29,7 @@ class Player;
class Item;
class Spell;
class SpellInfo;
+class WorldObject;
struct SpellChainNode;
struct SpellTargetPosition;
struct SpellDurationEntry;
@@ -61,7 +62,7 @@ enum SpellCastTargetFlags
TARGET_FLAG_UNIT_MINIPET = 0x00010000, // pguid, used to validate target (if non combat pet)
TARGET_FLAG_GLYPH_SLOT = 0x00020000, // used in glyph spells
TARGET_FLAG_DEST_TARGET = 0x00040000, // sometimes appears with DEST_TARGET spells (may appear or not for a given spell)
- TARGET_FLAG_UNUSED20 = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far
+ 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_UNIT_MASK = TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY
@@ -166,7 +167,9 @@ enum SpellSpecificType
SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE = 25,
SPELL_SPECIFIC_WARRIOR_ENRAGE = 26,
SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27,
- SPELL_SPECIFIC_HAND = 28
+ SPELL_SPECIFIC_HAND = 28,
+ SPELL_SPECIFIC_PHASE = 29,
+ SPELL_SPECIFIC_BANE = 30
};
enum SpellCustomAttributes
@@ -244,17 +247,22 @@ public:
SpellImplicitTargetInfo TargetA;
SpellImplicitTargetInfo TargetB;
SpellRadiusEntry const* RadiusEntry;
+ SpellRadiusEntry const* MaxRadiusEntry;
uint32 ChainTarget;
uint32 ItemType;
uint32 TriggerSpell;
flag96 SpellClassMask;
std::list<Condition*>* ImplicitTargetConditions;
+ // SpellScalingEntry
+ float ScalingMultiplier;
+ float DeltaScalingMultiplier;
+ float ComboScalingMultiplier;
SpellEffectInfo() : _spellInfo(NULL), _effIndex(0), Effect(0), ApplyAuraName(0), Amplitude(0), DieSides(0),
RealPointsPerLevel(0), BasePoints(0), PointsPerComboPoint(0), ValueMultiplier(0), DamageMultiplier(0),
BonusMultiplier(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(NULL), ChainTarget(0),
ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) {}
- SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex);
+ SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex, SpellEffectEntry const* effect);
bool IsEffect() const;
bool IsEffect(SpellEffects effectName) const;
@@ -272,6 +280,7 @@ public:
float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const;
bool HasRadius() const;
+ bool HasMaxRadius() const;
float CalcRadius(Unit* caster = NULL, Spell* = NULL) const;
uint32 GetProvidedTargetMask() const;
@@ -304,6 +313,9 @@ public:
uint32 AttributesEx5;
uint32 AttributesEx6;
uint32 AttributesEx7;
+ uint32 AttributesEx8;
+ uint32 AttributesEx9;
+ uint32 AttributesEx10;
uint32 AttributesCu;
uint32 Stances;
uint32 StancesNot;
@@ -338,7 +350,6 @@ public:
uint32 ManaCost;
uint32 ManaCostPerlevel;
uint32 ManaPerSecond;
- uint32 ManaPerSecondPerLevel;
uint32 ManaCostPercentage;
uint32 RuneCostID;
SpellRangeEntry const* RangeEntry;
@@ -354,8 +365,8 @@ public:
uint32 SpellVisual[2];
uint32 SpellIconID;
uint32 ActiveIconID;
- char* SpellName[16];
- char* Rank[16];
+ char* SpellName;
+ char* Rank;
uint32 MaxTargetLevel;
uint32 MaxAffectedTargets;
uint32 SpellFamilyName;
@@ -364,11 +375,51 @@ public:
uint32 PreventionType;
int32 AreaGroupId;
uint32 SchoolMask;
+ uint32 SpellDifficultyId;
+ uint32 SpellScalingId;
+ uint32 SpellAuraOptionsId;
+ uint32 SpellAuraRestrictionsId;
+ uint32 SpellCastingRequirementsId;
+ uint32 SpellCategoriesId;
+ uint32 SpellClassOptionsId;
+ uint32 SpellCooldownsId;
+ uint32 SpellEquippedItemsId;
+ uint32 SpellInterruptsId;
+ uint32 SpellLevelsId;
+ uint32 SpellPowerId;
+ uint32 SpellReagentsId;
+ uint32 SpellShapeshiftId;
+ uint32 SpellTargetRestrictionsId;
+ uint32 SpellTotemsId;
+ // SpellScalingEntry
+ int32 CastTimeMin;
+ int32 CastTimeMax;
+ int32 CastTimeMaxLevel;
+ int32 ScalingClass;
+ float CoefBase;
+ int32 CoefLevelBase;
SpellEffectInfo Effects[MAX_SPELL_EFFECTS];
uint32 ExplicitTargetMask;
SpellChainNode const* ChainEntry;
- SpellInfo(SpellEntry const* spellEntry);
+ // struct access functions
+ SpellTargetRestrictionsEntry const* GetSpellTargetRestrictions() const;
+ SpellAuraOptionsEntry const* GetSpellAuraOptions() const;
+ SpellAuraRestrictionsEntry const* GetSpellAuraRestrictions() const;
+ SpellCastingRequirementsEntry const* GetSpellCastingRequirements() const;
+ SpellCategoriesEntry const* GetSpellCategories() const;
+ SpellClassOptionsEntry const* GetSpellClassOptions() const;
+ SpellCooldownsEntry const* GetSpellCooldowns() const;
+ SpellEquippedItemsEntry const* GetSpellEquippedItems() const;
+ SpellInterruptsEntry const* GetSpellInterrupts() const;
+ SpellLevelsEntry const* GetSpellLevels() const;
+ SpellPowerEntry const* GetSpellPower() const;
+ SpellReagentsEntry const* GetSpellReagents() const;
+ SpellScalingEntry const* GetSpellScaling() const;
+ SpellShapeshiftEntry const* GetSpellShapeshift() const;
+ SpellTotemsEntry const* GetSpellTotems() const;
+
+ SpellInfo(SpellEntry const* spellEntry, SpellEffectEntry const** effects);
~SpellInfo();
uint32 GetCategory() const;
@@ -448,7 +499,7 @@ public:
uint32 GetMaxTicks() const;
- uint32 CalcCastTime(Spell* spell = NULL) const;
+ uint32 CalcCastTime(uint8 level = 0, Spell* spell = NULL) const;
uint32 GetRecoveryTime() const;
int32 CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask) const;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 8b31e749c62..104d9feb5fd 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -35,13 +35,13 @@
bool IsPrimaryProfessionSkill(uint32 skill)
{
SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(skill);
- if (!pSkill)
- return false;
-
- if (pSkill->categoryId != SKILL_CATEGORY_PROFESSION)
- return false;
+ return pSkill && pSkill->categoryId == SKILL_CATEGORY_PROFESSION;
+}
- return true;
+bool IsWeaponSkill(uint32 skill)
+{
+ SkillLineEntry const* pSkill = sSkillLineStore.LookupEntry(skill);
+ return pSkill && pSkill->categoryId == SKILL_CATEGORY_WEAPON;
}
bool IsPartOfSkillLine(uint32 skillId, uint32 spellId)
@@ -127,6 +127,9 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const* spellproto,
// Seduction
else if (spellproto->SpellFamilyFlags[1] & 0x10000000)
return DIMINISHING_FEAR;
+ // Sin and Punishment (Priest spell, don't ask)
+ else if (spellproto->SpellIconID == 1869)
+ return DIMINISHING_NONE;
break;
}
case SPELLFAMILY_DRUID:
@@ -293,7 +296,7 @@ int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const
return 6 * IN_MILLISECONDS;
// Hunter's Mark
if (spellproto->SpellFamilyFlags[0] & 0x400)
- return 120 * IN_MILLISECONDS;
+ return 30 * IN_MILLISECONDS;
break;
}
case SPELLFAMILY_PALADIN:
@@ -320,7 +323,7 @@ int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const
break;
}
- return 10 * IN_MILLISECONDS;
+ return 8 * IN_MILLISECONDS;
}
bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group)
@@ -1116,19 +1119,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32
// Extra conditions
switch (spellId)
{
- case 58600: // No fly Zone - Dalaran
- {
- if (!player)
- return false;
-
- AreaTableEntry const* pArea = GetAreaEntryByAreaID(player->GetAreaId());
- if (!(pArea && pArea->flags & AREA_FLAG_NO_FLY_ZONE))
- return false;
- if (!player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY))
- return false;
- break;
- }
- case 58730: // No fly Zone - Wintergrasp
+ case 91604: // No fly Zone - Wintergrasp
{
if (!player)
return false;
@@ -1485,10 +1476,10 @@ void SpellMgr::LoadSpellLearnSpells()
{
Field* fields = result->Fetch();
- uint32 spell_id = fields[0].GetUInt16();
+ uint32 spell_id = fields[0].GetUInt32();
SpellLearnSpellNode node;
- node.spell = fields[1].GetUInt16();
+ node.spell = fields[1].GetUInt32();
node.active = fields[2].GetBool();
node.autoLearned = false;
@@ -1515,6 +1506,9 @@ void SpellMgr::LoadSpellLearnSpells()
++count;
} while (result->NextRow());
+ // copy state loaded from db
+ SpellLearnSpellMap dbSpellLearnSpells = mSpellLearnSpells;
+
// search auto-learned spells and add its to map also for use in unlearn spells/talents
uint32 dbc_count = 0;
for (uint32 spell = 0; spell < GetSpellInfoStoreSize(); ++spell)
@@ -1541,7 +1535,7 @@ void SpellMgr::LoadSpellLearnSpells()
// other required explicit dependent learning
dbc_node.autoLearned = entry->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentSpellCost(spell) > 0 || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
- SpellLearnSpellMapBounds db_node_bounds = GetSpellLearnSpellMapBounds(spell);
+ SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spell);
bool found = false;
for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
@@ -1564,7 +1558,68 @@ void SpellMgr::LoadSpellLearnSpells()
}
}
- TC_LOG_INFO("server.loading", ">> Loaded %u spell learn spells + %u found in DBC in %u ms", count, dbc_count, GetMSTimeDiffToNow(oldMSTime));
+ uint32 mastery_count = 0;
+ for (uint32 i = 0; i < sTalentTabStore.GetNumRows(); ++i)
+ {
+ TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(i);
+ if (!talentTab)
+ continue;
+
+ for (uint32 c = CLASS_WARRIOR; c < MAX_CLASSES; ++c)
+ {
+ if (!(talentTab->ClassMask & (1 << (c - 1))))
+ continue;
+
+ uint32 masteryMainSpell = MasterySpells[c];
+
+ for (uint32 m = 0; m < MAX_MASTERY_SPELLS; ++m)
+ {
+ uint32 mastery = talentTab->MasterySpellId[m];
+ if (!mastery)
+ continue;
+
+ SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(masteryMainSpell);
+ bool found = false;
+ for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
+ {
+ if (itr->second.spell == mastery)
+ {
+ TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically as mastery learned spell from TalentTab.dbc", masteryMainSpell, mastery);
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ // Check if it is already found in Spell.dbc, ignore silently if yes
+ SpellLearnSpellMapBounds dbc_node_bounds = GetSpellLearnSpellMapBounds(masteryMainSpell);
+ found = false;
+ for (SpellLearnSpellMap::const_iterator itr = dbc_node_bounds.first; itr != dbc_node_bounds.second; ++itr)
+ {
+ if (itr->second.spell == mastery)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ SpellLearnSpellNode masteryNode;
+ masteryNode.spell = mastery;
+ masteryNode.active = true;
+ masteryNode.autoLearned = false;
+
+ mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(masteryMainSpell, masteryNode));
+ ++mastery_count;
+ }
+ }
+ }
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell learn spells, %u found in Spell.dbc and %u from TalentTab.dbc in %u ms", count, dbc_count, mastery_count, GetMSTimeDiffToNow(oldMSTime));
}
void SpellMgr::LoadSpellTargetPositions()
@@ -2682,6 +2737,19 @@ 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];
+};
+
void SpellMgr::LoadSpellInfoStore()
{
uint32 oldMSTime = getMSTime();
@@ -2689,9 +2757,20 @@ void SpellMgr::LoadSpellInfoStore()
UnloadSpellInfoStore();
mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL);
+ std::map<uint32, SpellEffectArray> effectsBySpell;
+
+ for (uint32 i = 0; i < sSpellEffectStore.GetNumRows(); ++i)
+ {
+ SpellEffectEntry const* effect = sSpellEffectStore.LookupEntry(i);
+ if (!effect)
+ continue;
+
+ effectsBySpell[effect->EffectSpellId].effects[effect->EffectIndex] = effect;
+ }
+
for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i)
if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i))
- mSpellInfoMap[i] = new SpellInfo(spellEntry);
+ mSpellInfoMap[i] = new SpellInfo(spellEntry, effectsBySpell[i].effects);
TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime));
}
@@ -3020,7 +3099,7 @@ void SpellMgr::LoadSpellInfoCorrections()
SpellInfo* spellInfo = NULL;
for (uint32 i = 0; i < GetSpellInfoStoreSize(); ++i)
{
- spellInfo = mSpellInfoMap[i];
+ spellInfo = (SpellInfo*)mSpellInfoMap[i];
if (!spellInfo)
continue;
@@ -3044,16 +3123,13 @@ void SpellMgr::LoadSpellInfoCorrections()
switch (spellInfo->Id)
{
- case 53096: // Quetz'lun's Judgment
- spellInfo->MaxAffectedTargets = 1;
- break;
- case 42730:
+ case 42730: // Woe Strike
spellInfo->Effects[EFFECT_1].TriggerSpell = 42739;
break;
case 42436: // Drink! (Brewfest)
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
break;
- case 59735:
+ case 59735: // Woe Strike
spellInfo->Effects[EFFECT_1].TriggerSpell = 59736;
break;
case 52611: // Summon Skeletons
@@ -3077,7 +3153,6 @@ void SpellMgr::LoadSpellInfoCorrections()
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 2895: // Wrath of Air Totem rank 1 (Aura)
case 68933: // Wrath of Air Totem rank 2 (Aura)
case 29200: // Purify Helboar Meat
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
@@ -3106,28 +3181,13 @@ void SpellMgr::LoadSpellInfoCorrections()
case 59372: // Energize Cores
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ENEMY);
break;
- case 8494: // Mana Shield (rank 2)
- // because of bug in dbc
- spellInfo->ProcChance = 0;
- break;
- case 20335: // Heart of the Crusader
- case 20336:
- case 20337:
+ case 63320: // Glyph of Life Tap
case 53228: // Rapid Killing (Rank 1)
case 53232: // Rapid Killing (Rank 2)
- case 63320: // Glyph of Life Tap
// Entries were not updated after spell effect change, we have to do that manually :/
spellInfo->AttributesEx3 |= SPELL_ATTR3_CAN_PROC_WITH_TRIGGERED;
break;
- case 5308: // Execute (Rank 1)
- case 20658: // Execute (Rank 2)
- case 20660: // Execute (Rank 3)
- case 20661: // Execute (Rank 4)
- case 20662: // Execute (Rank 5)
- case 25234: // Execute (Rank 6)
- case 25236: // Execute (Rank 7)
- case 47470: // Execute (Rank 8)
- case 47471: // Execute (Rank 9)
+ case 5308: // Execute
spellInfo->AttributesEx3 |= SPELL_ATTR3_CANT_TRIGGER_PROC;
break;
case 59725: // Improved Spell Reflection - aoe aura
@@ -3135,47 +3195,47 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER_AREA_PARTY);
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_10_YARDS_2);
break;
- case 44978: // Wild Magic
- case 45001:
- case 45002:
- case 45004:
- case 45006:
- case 45010:
case 31347: // Doom
+ case 36327: // Shoot Arcane Explosion Arrow
+ case 39365: // Thundering Storm
+ case 41071: // Raise Dead (HACK)
+ case 42442: // Vengeance Landing Cannonfire
+ case 42611: // Shoot
+ case 44978: // Wild Magic
+ case 45001: // Wild Magic
+ case 45002: // Wild Magic
+ case 45004: // Wild Magic
+ case 45006: // Wild Magic
+ case 45010: // Wild Magic
+ case 45761: // Shoot Gun
+ case 45863: // Cosmetic - Incinerate to Random Target
+ case 48246: // Ball of Flame
case 41635: // Prayer of Mending
case 44869: // Spectral Blast
case 45027: // Revitalize
case 45976: // Muru Portal Channel
- case 39365: // Thundering Storm
- case 41071: // Raise Dead (HACK)
case 52124: // Sky Darkener Assault
- case 42442: // Vengeance Landing Cannonfire
- case 45863: // Cosmetic - Incinerate to Random Target
- case 25425: // Shoot
- case 45761: // Shoot
- case 42611: // Shoot
- case 61588: // Blazing Harpoon
+ case 53096: // Quetz'lun's Judgment
case 52479: // Gift of the Harvester
- case 48246: // Ball of Flame
- case 36327: // Shoot Arcane Explosion Arrow
+ case 61588: // Blazing Harpoon
spellInfo->MaxAffectedTargets = 1;
break;
case 36384: // Skartax Purple Beam
spellInfo->MaxAffectedTargets = 2;
break;
- case 41376: // Spite
- case 39992: // Needle Spine
+ case 28542: // Life Drain - Sapphiron
+ case 29213: // Curse of the Plaguebringer - Noth
case 29576: // Multi-Shot
- case 40816: // Saber Lash
case 37790: // Spread Shot
- case 46771: // Flame Sear
- case 45248: // Shadow Blades
+ case 39992: // Needle Spine
+ case 40816: // Saber Lash
case 41303: // Soul Drain
+ case 41376: // Spite
+ case 45248: // Shadow Blades
+ case 46771: // Flame Sear
+ case 54171: // Divine Storm
case 54172: // Divine Storm (heal)
- case 29213: // Curse of the Plaguebringer - Noth
- case 28542: // Life Drain - Sapphiron
case 66588: // Flaming Spear
- case 54171: // Divine Storm
spellInfo->MaxAffectedTargets = 3;
break;
case 38310: // Multi-Shot
@@ -3203,23 +3263,20 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->MaxAffectedTargets = 15;
break;
case 33711: // Murmur's Touch
- case 38794:
+ case 38794: // Murmur's Touch
spellInfo->MaxAffectedTargets = 1;
spellInfo->Effects[EFFECT_0].TriggerSpell = 33760;
break;
case 17941: // Shadow Trance
case 22008: // Netherwind Focus
- case 31834: // Light's Grace
- case 34754: // Clearcasting
+ case 34477: // Misdirection
case 34936: // Backlash
case 48108: // Hot Streak
case 51124: // Killing Machine
case 54741: // Firestarter
case 57761: // Fireball!
- case 39805: // Lightning Overload
case 64823: // Item - Druid T8 Balance 4P Bonus
- case 34477: // Misdirection
- case 44401: // Missile Barrage
+ case 88819: // Daybreak
spellInfo->ProcCharges = 1;
break;
case 44544: // Fingers of Frost
@@ -3232,36 +3289,34 @@ void SpellMgr::LoadSpellInfoCorrections()
case 28200: // Ascendance (Talisman of Ascendance trinket)
spellInfo->ProcCharges = 6;
break;
- case 37408: // Oscillation Field
- spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
- break;
- case 47201: // Everlasting Affliction
- case 47202:
- case 47203:
- case 47204:
- case 47205:
+ case 47201: // Everlasting Affliction (1)
+ case 47202: // Everlasting Affliction (2)
+ case 47203: // Everlasting Affliction (3)
+ case 47204: // Everlasting Affliction (4)
+ case 47205: // Everlasting Affliction (5)
// add corruption to affected spells
spellInfo->Effects[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;
break;
case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
spellInfo->Effects[EFFECT_0].Amplitude = 3000;
break;
- case 29809: // Desecration Arm - 36 instead of 37 - typo? :/
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_7_YARDS);
- 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
- case 48420:
+ case 48420: // Master Shapeshifter
+ case 24900: // Heart of the Wild - Cat Effect
spellInfo->Stances = 1 << (FORM_CAT - 1);
break;
- case 48421:
- spellInfo->Stances = 1 << (FORM_MOONKIN - 1);
+ case 24899: // Heart of the Wild - Bear Effect
+ spellInfo->Stances = 1 << (FORM_BEAR - 1);
break;
- case 48422:
- spellInfo->Stances = 1 << (FORM_TREE - 1);
+ case 48421: // Master Shapeshifter
+ spellInfo->Stances = 1 << (FORM_MOONKIN - 1);
break;
case 51466: // Elemental Oath (Rank 1)
case 51470: // Elemental Oath (Rank 2)
@@ -3277,23 +3332,9 @@ void SpellMgr::LoadSpellInfoCorrections()
case 64904: // Hymn of Hope
spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT;
break;
- case 19465: // Improved Stings (Rank 2)
- spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- break;
case 30421: // Nether Portal - Perseverence
spellInfo->Effects[EFFECT_2].BasePoints += 30000;
break;
- case 16834: // Natural shapeshifter
- case 16835:
- spellInfo->DurationEntry = sSpellDurationStore.LookupEntry(21);
- break;
- case 51735: // Ebon Plague
- case 51734:
- case 51726:
- spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
- spellInfo->SpellFamilyFlags[2] = 0x10;
- spellInfo->Effects[EFFECT_1].ApplyAuraName = SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN;
- break;
case 41913: // Parasitic Shadowfiend Passive
spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_DUMMY; // proc debuff, and summon infinite fiends
break;
@@ -3303,7 +3344,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 27915: // Anchor to Skulls
case 27931: // Anchor to Skulls
case 27937: // Anchor to Skulls
- spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(13);
+ spellInfo->RangeEntry = sSpellRangeStore.LookupEntry(EFFECT_RADIUS_10_YARDS);
break;
// target allys instead of enemies, target A is src_caster, spells with effect like that have ally target
// this is the only known exception, probably just wrong data
@@ -3312,10 +3353,6 @@ void SpellMgr::LoadSpellInfoCorrections()
spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo(TARGET_UNIT_SRC_AREA_ALLY);
break;
- case 57994: // Wind Shear - improper data for EFFECT_1 in 3.3.5 DBC, but is correct in 4.x
- spellInfo->Effects[EFFECT_1].Effect = SPELL_EFFECT_MODIFY_THREAT_PERCENT;
- spellInfo->Effects[EFFECT_1].BasePoints = -6; // -5%
- break;
case 63675: // Improved Devouring Plague
spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_DONE_BONUS;
break;
@@ -3323,26 +3360,16 @@ void SpellMgr::LoadSpellInfoCorrections()
case 6474: // Earthbind Totem (instant pulse)
spellInfo->AttributesEx5 |= SPELL_ATTR5_START_PERIODIC_AT_APPLY;
break;
- case 52109: // Flametongue Totem rank 1 (Aura)
- case 52110: // Flametongue Totem rank 2 (Aura)
- case 52111: // Flametongue Totem rank 3 (Aura)
- case 52112: // Flametongue Totem rank 4 (Aura)
- case 52113: // Flametongue Totem rank 5 (Aura)
- case 58651: // Flametongue Totem rank 6 (Aura)
- case 58654: // Flametongue Totem rank 7 (Aura)
- case 58655: // Flametongue Totem rank 8 (Aura)
- spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->Effects[EFFECT_1].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_CASTER);
- spellInfo->Effects[EFFECT_0].TargetB = SpellImplicitTargetInfo();
- spellInfo->Effects[EFFECT_1].TargetB = SpellImplicitTargetInfo();
- break;
case 53241: // Marked for Death (Rank 1)
case 53243: // Marked for Death (Rank 2)
- case 53244: // Marked for Death (Rank 3)
- case 53245: // Marked for Death (Rank 4)
- case 53246: // Marked for Death (Rank 5)
spellInfo->Effects[EFFECT_0].SpellClassMask = flag96(0x00067801, 0x10820001, 0x00000801);
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;
+ 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);
@@ -3377,26 +3404,9 @@ void SpellMgr::LoadSpellInfoCorrections()
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)"
break;
- case 64745: // Item - Death Knight T8 Tank 4P Bonus
- case 64936: // Item - Warrior T8 Protection 4P Bonus
- spellInfo->Effects[EFFECT_0].BasePoints = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit)
- break;
- case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
- case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
- case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
- case 19973: // Entangling Roots (Rank 3) -- Nature's Grasp Proc
- case 19974: // Entangling Roots (Rank 2) -- Nature's Grasp Proc
- case 19975: // Entangling Roots (Rank 1) -- Nature's Grasp Proc
- case 27010: // Entangling Roots (Rank 7) -- Nature's Grasp Proc
- case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc
- spellInfo->CastTimeEntry = sSpellCastTimesStore.LookupEntry(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;
break;
- case 70650: // Death Knight T10 Tank 2P Bonus
- spellInfo->Effects[EFFECT_0].ApplyAuraName = SPELL_AURA_ADD_PCT_MODIFIER;
- break;
case 71838: // Drain Life - Bryntroll Normal
case 71839: // Drain Life - Bryntroll Heroic
spellInfo->AttributesEx2 |= SPELL_ATTR2_CANT_CRIT;
@@ -3473,7 +3483,7 @@ void SpellMgr::LoadSpellInfoCorrections()
case 64031: // Scrapyard Teleport
case 64032: // Formation Grounds Teleport
case 65042: // Prison of Yogg-Saron Teleport
- spellInfo->Effects[0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
+ spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
// ENDOF ULDUAR SPELLS
//
@@ -3501,10 +3511,6 @@ void SpellMgr::LoadSpellInfoCorrections()
case 70861: // Sindragosa's Lair Teleport
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_DEST_DB);
break;
- case 69055: // Bone Slice (Lord Marrowgar)
- case 70814: // Bone Slice (Lord Marrowgar)
- spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_5_YARDS); // 5yd
- break;
case 69075: // Bone Storm (Lord Marrowgar)
case 70834: // Bone Storm (Lord Marrowgar)
case 70835: // Bone Storm (Lord Marrowgar)
@@ -3738,39 +3744,46 @@ void SpellMgr::LoadSpellInfoCorrections()
break;
// ENDOF EYE OF ETERNITY SPELLS
//
- // OCULUS SPELLS
- // The spells below are here because their effect 1 is giving warning due to
- // triggered spell not found in any dbc and is missing from encounter source* of data.
- // Even judged as clientside these spells can't be guessed for* now.
- case 49462: // Call Ruby Drake
- case 49461: // Call Amber Drake
- case 49345: // Call Emerald Drake
- spellInfo->Effects[EFFECT_1].Effect = 0;
- break;
- // ENDOF OCULUS SPELLS
- //
case 40055: // Introspection
case 40165: // Introspection
case 40166: // Introspection
case 40167: // Introspection
spellInfo->Attributes |= SPELL_ATTR0_NEGATIVE_1;
break;
- case 45524: // Chains of Ice
- spellInfo->Effects[EFFECT_2].TargetA = SpellImplicitTargetInfo();
- break;
case 2378: // Minor Fortitude
spellInfo->ManaCost = 0;
spellInfo->ManaPerSecond = 0;
break;
+ // Halls Of Origination spells
+ // Temple Guardian Anhuur
+ 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);
+ break;
+ case 75323: // Reverberating Hymn
+ // Aura is refreshed at 3 seconds, and the tick should happen at the fourth.
+ spellInfo->AttributesEx8 |= SPELL_ATTR8_DONT_RESET_PERIODIC_TIMER;
+ break;
case 24314: // Threatening Gaze
spellInfo->AuraInterruptFlags |= AURA_INTERRUPT_FLAG_CAST | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_JUMP;
break;
+ case 5420: // Tree of Life (Passive)
+ spellInfo->Stances = 1 << (FORM_TREE - 1);
+ break;
+ case 49376: // Feral Charge (Cat Form)
+ spellInfo->AttributesEx3 &= ~SPELL_ATTR3_CANT_TRIGGER_PROC;
+ break;
case 45257: // Using Steam Tonk Controller
case 45440: // Steam Tonk Controller
case 60256: // Collect Sample
// Crashes client on pressing ESC
spellInfo->AttributesEx4 &= ~SPELL_ATTR4_TRIGGERED;
break;
+ case 96942: // Gaze of Occu'thar
+ case 101009: // Gaze of Occu'thar
+ spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1;
+ break;
// ISLE OF CONQUEST SPELLS
//
case 66551: // Teleport
diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h
index 01fe7708db2..184b3ad0cb2 100644
--- a/src/server/game/Spells/SpellMgr.h
+++ b/src/server/game/Spells/SpellMgr.h
@@ -56,42 +56,40 @@ enum SpellFamilyFlag
// SPELLFAMILYFLAG2 = SpellFamilyFlags[2]
// Rogue
- SPELLFAMILYFLAG_ROGUE_VANISH = 0x00000800,
- SPELLFAMILYFLAG_ROGUE_VAN_EVAS_SPRINT = 0x00000860, // Vanish, Evasion, Sprint
- SPELLFAMILYFLAG1_ROGUE_COLDB_SHADOWSTEP = 0x00000240, // Cold Blood, Shadowstep
- SPELLFAMILYFLAG_ROGUE_KICK = 0x00000010, // Kick
- SPELLFAMILYFLAG1_ROGUE_DISMANTLE = 0x00100000, // Dismantle
- SPELLFAMILYFLAG_ROGUE_BLADE_FLURRY = 0x40000000, // Blade Flurry
- SPELLFAMILYFLAG1_ROGUE_BLADE_FLURRY = 0x00000800, // Blade Flurry
+ SPELLFAMILYFLAG0_ROGUE_VANISH = 0x00000800,
+ SPELLFAMILYFLAG0_ROGUE_VAN_SPRINT = 0x00000840, // Vanish, Sprint
+ SPELLFAMILYFLAG1_ROGUE_SHADOWSTEP = 0x00000200, // Shadowstep
+ SPELLFAMILYFLAG0_ROGUE_KICK = 0x00000010, // Kick
+ SPELLFAMILYFLAG1_ROGUE_DISMANTLE_SMOKE_BOMB = 0x80100000, // Dismantle, Smoke Bomb
// Warrior
- SPELLFAMILYFLAG_WARRIOR_CHARGE = 0x00000001,
- SPELLFAMILYFLAG_WARRIOR_SLAM = 0x00200000,
- SPELLFAMILYFLAG_WARRIOR_EXECUTE = 0x20000000,
- SPELLFAMILYFLAG_WARRIOR_CONCUSSION_BLOW = 0x04000000,
+ SPELLFAMILYFLAG_WARRIOR_CHARGE = 0x00000001,
+ SPELLFAMILYFLAG_WARRIOR_SLAM = 0x00200000,
+ SPELLFAMILYFLAG_WARRIOR_EXECUTE = 0x20000000,
+ SPELLFAMILYFLAG_WARRIOR_CONCUSSION_BLOW = 0x04000000,
// Warlock
- SPELLFAMILYFLAG_WARLOCK_LIFETAP = 0x00040000,
+ SPELLFAMILYFLAG_WARLOCK_LIFETAP = 0x00040000,
// Druid
- SPELLFAMILYFLAG2_DRUID_STARFALL = 0x00000100,
+ SPELLFAMILYFLAG2_DRUID_STARFALL = 0x00000100,
// Paladin
- SPELLFAMILYFLAG1_PALADIN_DIVINESTORM = 0x00020000,
+ SPELLFAMILYFLAG1_PALADIN_DIVINESTORM = 0x00020000,
// Shaman
- SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK = 0x80000000,
- SPELLFAMILYFLAG_SHAMAN_HEALING_STREAM = 0x00002000,
- SPELLFAMILYFLAG_SHAMAN_MANA_SPRING = 0x00004000,
- SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH = 0x00000004,
- SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA = 0x28000000,
+ SPELLFAMILYFLAG_SHAMAN_FROST_SHOCK = 0x80000000,
+ SPELLFAMILYFLAG_SHAMAN_HEALING_STREAM = 0x00002000,
+ SPELLFAMILYFLAG_SHAMAN_MANA_SPRING = 0x00004000,
+ SPELLFAMILYFLAG2_SHAMAN_LAVA_LASH = 0x00000004,
+ SPELLFAMILYFLAG_SHAMAN_FIRE_NOVA = 0x28000000,
// Deathknight
- SPELLFAMILYFLAG_DK_DEATH_STRIKE = 0x00000010,
- SPELLFAMILYFLAG_DK_DEATH_COIL = 0x00002000,
+ SPELLFAMILYFLAG_DK_DEATH_STRIKE = 0x00000010,
+ SPELLFAMILYFLAG_DK_DEATH_COIL = 0x00002000,
/// @todo Figure out a more accurate name for the following familyflag(s)
- SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS = 0x04000000 // Seems to be linked to most totems and some totem effects
+ SPELLFAMILYFLAG_SHAMAN_TOTEM_EFFECTS = 0x04000000 // Seems to be linked to most totems and some totem effects
};
@@ -581,6 +579,8 @@ typedef std::map<int32, std::vector<int32> > SpellLinkedMap;
bool IsPrimaryProfessionSkill(uint32 skill);
+bool IsWeaponSkill(uint32 skill);
+
inline bool IsProfessionSkill(uint32 skill)
{
return IsPrimaryProfessionSkill(skill) || skill == SKILL_FISHING || skill == SKILL_COOKING || skill == SKILL_FIRST_AID;
diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp
index 46cb7a46773..da2fbaf0ece 100644
--- a/src/server/game/Texts/CreatureTextMgr.cpp
+++ b/src/server/game/Texts/CreatureTextMgr.cpp
@@ -310,6 +310,7 @@ void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType,
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(sound);
+ data << uint64(source->GetGUID());
SendNonChatPacket(source, &data, msgType, whisperTarget, range, team, gmOnly);
}
diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h
index 12236844828..6ef983e18e5 100644
--- a/src/server/game/Texts/CreatureTextMgr.h
+++ b/src/server/game/Texts/CreatureTextMgr.h
@@ -144,7 +144,7 @@ class CreatureTextLocalizer
{
messageTemplate = new WorldPacket();
whisperGUIDpos = _builder(messageTemplate, loc_idx);
- ASSERT(messageTemplate->GetOpcode() != MSG_NULL_ACTION);
+ ASSERT(messageTemplate->GetOpcode() != NULL_OPCODE);
_packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos);
}
else
diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp
index 43c9ba80e24..e9f8748e6d9 100644
--- a/src/server/game/Tickets/TicketMgr.cpp
+++ b/src/server/game/Tickets/TicketMgr.cpp
@@ -123,6 +123,11 @@ void GmTicket::WritePacket(WorldPacket& data) const
data << uint8(std::min(_escalatedStatus, TICKET_IN_ESCALATION_QUEUE)); // escalated data
data << uint8(_viewed ? GMTICKET_OPENEDBYGM_STATUS_OPENED : GMTICKET_OPENEDBYGM_STATUS_NOT_OPENED); // whether or not it has been viewed
+
+ // TODO: implement these
+ std::string waitTimeOverrideMessage = "";
+ data << waitTimeOverrideMessage;
+ data << uint32(0); // waitTimeOverrideMinutes
}
void GmTicket::SendResponse(WorldSession* session) const
diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp
index 55d70514594..821d2c568a5 100644
--- a/src/server/game/Tools/PlayerDump.cpp
+++ b/src/server/game/Tools/PlayerDump.cpp
@@ -24,7 +24,7 @@
#include "AccountMgr.h"
#include "World.h"
-#define DUMP_TABLE_COUNT 27
+#define DUMP_TABLE_COUNT 29
struct DumpTable
{
char const* name;
@@ -39,6 +39,8 @@ static DumpTable dumpTables[DUMP_TABLE_COUNT] =
{ "character_achievement_progress", DTT_CHAR_TABLE },
{ "character_action", DTT_CHAR_TABLE },
{ "character_aura", DTT_CHAR_TABLE },
+ { "character_currency", DTT_CHAR_TABLE },
+ { "character_cuf_profiles", DTT_CHAR_TABLE },
{ "character_declinedname", DTT_CHAR_TABLE },
{ "character_equipmentsets", DTT_EQSET_TABLE},
{ "character_gifts", DTT_ITEM_GIFT },
@@ -320,10 +322,13 @@ bool PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
break;
case DTT_CHARACTER:
{
- if (result->GetFieldCount() <= 68) // avoid crashes on next check
+ if (result->GetFieldCount() <= 64) // avoid crashes on next check
+ {
TC_LOG_FATAL("misc", "PlayerDumpWriter::DumpTable - Trying to access non-existing or wrong positioned field (`deleteInfos_Account`) in `characters` table.");
+ return false;
+ }
- if (result->Fetch()[68].GetUInt32()) // characters.deleteInfos_Account - if filled error
+ if (result->Fetch()[64].GetUInt32()) // characters.deleteInfos_Account - if filled error
return false;
break;
}
@@ -543,18 +548,18 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s
PreparedQueryResult result = CharacterDatabase.Query(stmt);
if (result)
- if (!changenth(line, 37, "1")) // characters.at_login set to "rename on login"
+ if (!changenth(line, 38, "1")) // characters.at_login set to "rename on login"
ROLLBACK(DUMP_FILE_BROKEN);
}
else if (!changenth(line, 3, name.c_str())) // characters.name
ROLLBACK(DUMP_FILE_BROKEN);
const char null[5] = "NULL";
- if (!changenth(line, 69, null)) // characters.deleteInfos_Account
+ if (!changenth(line, 63, null)) // characters.deleteInfos_Account
ROLLBACK(DUMP_FILE_BROKEN);
- if (!changenth(line, 70, null)) // characters.deleteInfos_Name
+ if (!changenth(line, 64, null)) // characters.deleteInfos_Name
ROLLBACK(DUMP_FILE_BROKEN);
- if (!changenth(line, 71, null)) // characters.deleteDate
+ if (!changenth(line, 65, null)) // characters.deleteDate
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
diff --git a/src/server/game/Tools/PlayerDump.h b/src/server/game/Tools/PlayerDump.h
index ece2c0693e2..8be71f1a819 100644
--- a/src/server/game/Tools/PlayerDump.h
+++ b/src/server/game/Tools/PlayerDump.h
@@ -30,7 +30,8 @@ enum DumpTableType
DTT_CHAR_TABLE, // // character_achievement, character_achievement_progress,
// character_action, character_aura, character_homebind,
// character_queststatus, character_queststatus_rewarded, character_reputation,
- // character_spell, character_spell_cooldown, character_ticket, character_talent
+ // character_spell, character_spell_cooldown, character_ticket, character_talent.
+ // character_cuf_profiles, character_currency
DTT_EQSET_TABLE, // <- guid // character_equipmentsets
diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp
index cb332df9a41..79b4fbd8c69 100644
--- a/src/server/game/Weather/Weather.cpp
+++ b/src/server/game/Weather/Weather.cpp
@@ -29,6 +29,7 @@
#include "Util.h"
#include "ScriptMgr.h"
#include "Opcodes.h"
+#include "WorldSession.h"
/// Create the Weather object
Weather::Weather(uint32 zone, WeatherData const* weatherChances)
diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h
index 0bdd6af6dc5..ae83fa67a84 100644
--- a/src/server/game/Weather/Weather.h
+++ b/src/server/game/Weather/Weather.h
@@ -46,7 +46,7 @@ struct WeatherData
enum WeatherState
{
WEATHER_STATE_FINE = 0,
- WEATHER_STATE_FOG = 1,
+ WEATHER_STATE_FOG = 1, // Used in some instance encounters.
WEATHER_STATE_LIGHT_RAIN = 3,
WEATHER_STATE_MEDIUM_RAIN = 4,
WEATHER_STATE_HEAVY_RAIN = 5,
diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp
index 886a910becc..9faecdf7c99 100644
--- a/src/server/game/Weather/WeatherMgr.cpp
+++ b/src/server/game/Weather/WeatherMgr.cpp
@@ -28,6 +28,7 @@
#include "Player.h"
#include "WorldPacket.h"
#include "Opcodes.h"
+#include "WorldSession.h"
namespace WeatherMgr
{
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 3fde3ad4a11..5f6fb683e8f 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -40,11 +40,13 @@
#include "ObjectMgr.h"
#include "ArenaTeamMgr.h"
#include "GuildMgr.h"
+#include "GuildFinderMgr.h"
#include "TicketMgr.h"
#include "SpellMgr.h"
#include "GroupMgr.h"
#include "Chat.h"
#include "DBCStores.h"
+#include "DB2Stores.h"
#include "LootMgr.h"
#include "ItemEnchantmentMgr.h"
#include "MapManager.h"
@@ -112,6 +114,7 @@ World::World()
m_NextMonthlyQuestReset = 0;
m_NextRandomBGReset = 0;
m_NextGuildReset = 0;
+ m_NextCurrencyReset = 0;
m_defaultDbcLocale = LOCALE_enUS;
m_availableDbcLocaleMask = 0;
@@ -284,7 +287,7 @@ void World::AddSession_(WorldSession* s)
return;
}
- s->SendAuthResponse(AUTH_OK, true);
+ s->SendAuthResponse(AUTH_OK, false);
s->SendAddonsInfo();
s->SendClientCacheVersion(sWorld->getIntConfig(CONFIG_CLIENTCACHE_VERSION));
s->SendTutorialsData();
@@ -340,7 +343,7 @@ void World::AddQueuedPlayer(WorldSession* sess)
m_QueuedPlayer.push_back(sess);
// The 1st SMSG_AUTH_RESPONSE needs to contain other info too.
- sess->SendAuthResponse(AUTH_WAIT_QUEUE, false, GetQueuePos(sess));
+ sess->SendAuthResponse(AUTH_WAIT_QUEUE, true, GetQueuePos(sess));
}
bool World::RemoveQueuedPlayer(WorldSession* sess)
@@ -414,6 +417,16 @@ void World::LoadConfigSettings(bool reload)
sLog->LoadFromConfig();
}
+ m_defaultDbcLocale = LocaleConstant(sConfigMgr->GetIntDefault("DBC.Locale", 0));
+
+ if (m_defaultDbcLocale >= TOTAL_LOCALES)
+ {
+ TC_LOG_ERROR("server.loading", "Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)", TOTAL_LOCALES);
+ m_defaultDbcLocale = LOCALE_enUS;
+ }
+
+ TC_LOG_INFO("server.loading", "Using %s DBC Locale", localeNames[m_defaultDbcLocale]);
+
///- Read the player limit and the Message of the day from the config file
SetPlayerAmountLimit(sConfigMgr->GetIntDefault("PlayerLimit", 100));
SetMotd(sConfigMgr->GetStringDefault("Motd", "Welcome to a Trinity Core Server."));
@@ -775,57 +788,84 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_START_PLAYER_MONEY] = sConfigMgr->GetIntDefault("StartPlayerMoney", 0);
if (int32(m_int_configs[CONFIG_START_PLAYER_MONEY]) < 0)
{
- TC_LOG_ERROR("server.loading", "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.", m_int_configs[CONFIG_START_PLAYER_MONEY], MAX_MONEY_AMOUNT, 0);
+ TC_LOG_ERROR("server.loading", "StartPlayerMoney (%i) must be in range 0.." UI64FMTD ". Set to %u.", m_int_configs[CONFIG_START_PLAYER_MONEY], uint64(MAX_MONEY_AMOUNT), 0);
m_int_configs[CONFIG_START_PLAYER_MONEY] = 0;
}
- else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > MAX_MONEY_AMOUNT)
+ else if (m_int_configs[CONFIG_START_PLAYER_MONEY] > 0x7FFFFFFF-1) // TODO: (See MAX_MONEY_AMOUNT)
{
TC_LOG_ERROR("server.loading", "StartPlayerMoney (%i) must be in range 0..%u. Set to %u.",
- m_int_configs[CONFIG_START_PLAYER_MONEY], MAX_MONEY_AMOUNT, MAX_MONEY_AMOUNT);
- m_int_configs[CONFIG_START_PLAYER_MONEY] = MAX_MONEY_AMOUNT;
+ m_int_configs[CONFIG_START_PLAYER_MONEY], 0x7FFFFFFF-1, 0x7FFFFFFF-1);
+ m_int_configs[CONFIG_START_PLAYER_MONEY] = 0x7FFFFFFF-1;
}
- m_int_configs[CONFIG_MAX_HONOR_POINTS] = sConfigMgr->GetIntDefault("MaxHonorPoints", 75000);
- if (int32(m_int_configs[CONFIG_MAX_HONOR_POINTS]) < 0)
+ m_int_configs[CONFIG_CURRENCY_RESET_HOUR] = sConfigMgr->GetIntDefault("Currency.ResetHour", 3);
+ if (m_int_configs[CONFIG_CURRENCY_RESET_HOUR] > 23)
{
- TC_LOG_ERROR("server.loading", "MaxHonorPoints (%i) can't be negative. Set to 0.", m_int_configs[CONFIG_MAX_HONOR_POINTS]);
- m_int_configs[CONFIG_MAX_HONOR_POINTS] = 0;
+ TC_LOG_ERROR("server.loading", "Currency.ResetHour (%i) can't be load. Set to 6.", m_int_configs[CONFIG_CURRENCY_RESET_HOUR]);
+ m_int_configs[CONFIG_CURRENCY_RESET_HOUR] = 3;
+ }
+ m_int_configs[CONFIG_CURRENCY_RESET_DAY] = sConfigMgr->GetIntDefault("Currency.ResetDay", 3);
+ if (m_int_configs[CONFIG_CURRENCY_RESET_DAY] > 6)
+ {
+ TC_LOG_ERROR("server.loading", "Currency.ResetDay (%i) can't be load. Set to 3.", m_int_configs[CONFIG_CURRENCY_RESET_DAY]);
+ m_int_configs[CONFIG_CURRENCY_RESET_DAY] = 3;
+ }
+ m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL] = sConfigMgr->GetIntDefault("Currency.ResetInterval", 7);
+ if (int32(m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL]) <= 0)
+ {
+ TC_LOG_ERROR("server.loading", "Currency.ResetInterval (%i) must be > 0, set to default 7.", m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL]);
+ m_int_configs[CONFIG_CURRENCY_RESET_INTERVAL] = 7;
}
- m_int_configs[CONFIG_START_HONOR_POINTS] = sConfigMgr->GetIntDefault("StartHonorPoints", 0);
- if (int32(m_int_configs[CONFIG_START_HONOR_POINTS]) < 0)
+ m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS] = sConfigMgr->GetIntDefault("Currency.StartHonorPoints", 0);
+ if (int32(m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS]) < 0)
{
- TC_LOG_ERROR("server.loading", "StartHonorPoints (%i) must be in range 0..MaxHonorPoints(%u). Set to %u.",
- m_int_configs[CONFIG_START_HONOR_POINTS], m_int_configs[CONFIG_MAX_HONOR_POINTS], 0);
- m_int_configs[CONFIG_START_HONOR_POINTS] = 0;
+ TC_LOG_ERROR("server.loading", "Currency.StartHonorPoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS]);
+ m_int_configs[CONFIG_CURRENCY_START_HONOR_POINTS] = 0;
}
- else if (m_int_configs[CONFIG_START_HONOR_POINTS] > m_int_configs[CONFIG_MAX_HONOR_POINTS])
+ m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] = sConfigMgr->GetIntDefault("Currency.MaxHonorPoints", 4000);
+ if (int32(m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS]) < 0)
{
- TC_LOG_ERROR("server.loading", "StartHonorPoints (%i) must be in range 0..MaxHonorPoints(%u). Set to %u.",
- m_int_configs[CONFIG_START_HONOR_POINTS], m_int_configs[CONFIG_MAX_HONOR_POINTS], m_int_configs[CONFIG_MAX_HONOR_POINTS]);
- m_int_configs[CONFIG_START_HONOR_POINTS] = m_int_configs[CONFIG_MAX_HONOR_POINTS];
+ TC_LOG_ERROR("server.loading", "Currency.MaxHonorPoints (%i) can't be negative. Set to default 4000.", m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS]);
+ m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] = 4000;
}
+ m_int_configs[CONFIG_CURRENCY_MAX_HONOR_POINTS] *= 100; //precision mod
- m_int_configs[CONFIG_MAX_ARENA_POINTS] = sConfigMgr->GetIntDefault("MaxArenaPoints", 10000);
- if (int32(m_int_configs[CONFIG_MAX_ARENA_POINTS]) < 0)
+ m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS] = sConfigMgr->GetIntDefault("Currency.StartJusticePoints", 0);
+ if (int32(m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS]) < 0)
+ {
+ TC_LOG_ERROR("server.loading", "Currency.StartJusticePoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS]);
+ m_int_configs[CONFIG_CURRENCY_START_JUSTICE_POINTS] = 0;
+ }
+ m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] = sConfigMgr->GetIntDefault("Currency.MaxJusticePoints", 4000);
+ if (int32(m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS]) < 0)
{
- TC_LOG_ERROR("server.loading", "MaxArenaPoints (%i) can't be negative. Set to 0.", m_int_configs[CONFIG_MAX_ARENA_POINTS]);
- m_int_configs[CONFIG_MAX_ARENA_POINTS] = 0;
+ TC_LOG_ERROR("server.loading", "Currency.MaxJusticePoints (%i) can't be negative. Set to default 4000.", m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS]);
+ m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] = 4000;
}
+ m_int_configs[CONFIG_CURRENCY_MAX_JUSTICE_POINTS] *= 100; //precision mod
- m_int_configs[CONFIG_START_ARENA_POINTS] = sConfigMgr->GetIntDefault("StartArenaPoints", 0);
- if (int32(m_int_configs[CONFIG_START_ARENA_POINTS]) < 0)
+ m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS] = sConfigMgr->GetIntDefault("Currency.StartConquestPoints", 0);
+ if (int32(m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS]) < 0)
{
- TC_LOG_ERROR("server.loading", "StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.",
- m_int_configs[CONFIG_START_ARENA_POINTS], m_int_configs[CONFIG_MAX_ARENA_POINTS], 0);
- m_int_configs[CONFIG_START_ARENA_POINTS] = 0;
+ TC_LOG_ERROR("server.loading", "Currency.StartConquestPoints (%i) must be >= 0, set to default 0.", m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS]);
+ m_int_configs[CONFIG_CURRENCY_START_CONQUEST_POINTS] = 0;
}
- else if (m_int_configs[CONFIG_START_ARENA_POINTS] > m_int_configs[CONFIG_MAX_ARENA_POINTS])
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] = sConfigMgr->GetIntDefault("Currency.ConquestPointsWeekCap", 1650);
+ if (int32(m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP]) <= 0)
{
- TC_LOG_ERROR("server.loading", "StartArenaPoints (%i) must be in range 0..MaxArenaPoints(%u). Set to %u.",
- m_int_configs[CONFIG_START_ARENA_POINTS], m_int_configs[CONFIG_MAX_ARENA_POINTS], m_int_configs[CONFIG_MAX_ARENA_POINTS]);
- m_int_configs[CONFIG_START_ARENA_POINTS] = m_int_configs[CONFIG_MAX_ARENA_POINTS];
+ TC_LOG_ERROR("server.loading", "Currency.ConquestPointsWeekCap (%i) must be > 0, set to default 1650.", m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP]);
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] = 1650;
}
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP] *= 100; //precision mod
+
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] = sConfigMgr->GetIntDefault("Currency.ConquestPointsArenaReward", 180);
+ if (int32(m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD]) <= 0)
+ {
+ TC_LOG_ERROR("server.loading", "Currency.ConquestPointsArenaReward (%i) must be > 0, set to default 180.", m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD]);
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] = 180;
+ }
+ m_int_configs[CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD] *= 100; //precision mod
m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] = sConfigMgr->GetIntDefault("RecruitAFriend.MaxLevel", 60);
if (m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
@@ -922,13 +962,10 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_SKILL_GAIN_CRAFTING] = sConfigMgr->GetIntDefault("SkillGain.Crafting", 1);
- m_int_configs[CONFIG_SKILL_GAIN_DEFENSE] = sConfigMgr->GetIntDefault("SkillGain.Defense", 1);
-
m_int_configs[CONFIG_SKILL_GAIN_GATHERING] = sConfigMgr->GetIntDefault("SkillGain.Gathering", 1);
- m_int_configs[CONFIG_SKILL_GAIN_WEAPON] = sConfigMgr->GetIntDefault("SkillGain.Weapon", 1);
-
m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] = sConfigMgr->GetIntDefault("MaxOverspeedPings", 2);
+
if (m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] != 0 && m_int_configs[CONFIG_MAX_OVERSPEED_PINGS] < 2)
{
TC_LOG_ERROR("server.loading", "MaxOverspeedPings (%i) must be in range 2..infinity (or 0 to disable check). Set to 2.", m_int_configs[CONFIG_MAX_OVERSPEED_PINGS]);
@@ -940,8 +977,6 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_DISABLE_BREATHING] = sConfigMgr->GetIntDefault("DisableWaterBreath", SEC_CONSOLE);
- m_bool_configs[CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL] = sConfigMgr->GetBoolDefault("AlwaysMaxSkillForLevel", false);
-
if (reload)
{
uint32 val = sConfigMgr->GetIntDefault("Expansion", 2);
@@ -1015,6 +1050,7 @@ void World::LoadConfigSettings(bool reload)
// always use declined names in the russian client
m_bool_configs[CONFIG_DECLINED_NAMES_USED] =
+
(m_int_configs[CONFIG_REALM_ZONE] == REALM_ZONE_RUSSIAN) ? true : sConfigMgr->GetBoolDefault("DeclinedNames", false);
m_float_configs[CONFIG_LISTEN_RANGE_SAY] = sConfigMgr->GetFloatDefault("ListenRange.Say", 25.0f);
@@ -1031,8 +1067,6 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfigMgr->GetIntDefault ("Arena.MaxRatingDifference", 150);
m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfigMgr->GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS);
m_int_configs[CONFIG_ARENA_RATED_UPDATE_TIMER] = sConfigMgr->GetIntDefault ("Arena.RatedUpdateTimer", 5 * IN_MILLISECONDS);
- m_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfigMgr->GetBoolDefault("Arena.AutoDistributePoints", false);
- m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfigMgr->GetIntDefault ("Arena.AutoDistributeInterval", 7);
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfigMgr->GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY] = sConfigMgr->GetBoolDefault("Arena.QueueAnnouncer.PlayerOnly", false);
m_int_configs[CONFIG_ARENA_SEASON_ID] = sConfigMgr->GetIntDefault ("Arena.ArenaSeason.ID", 1);
@@ -1056,6 +1090,9 @@ void World::LoadConfigSettings(bool reload)
TC_LOG_ERROR("server.loading", "ClientCacheVersion can't be negative %d, ignored.", clientCacheId);
}
+ m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = sConfigMgr->GetIntDefault("Guild.NewsLogRecordsCount", GUILD_NEWSLOG_MAX_RECORDS);
+ if (m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] > GUILD_NEWSLOG_MAX_RECORDS)
+ m_int_configs[CONFIG_GUILD_NEWS_LOG_COUNT] = GUILD_NEWSLOG_MAX_RECORDS;
m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = sConfigMgr->GetIntDefault("Guild.EventLogRecordsCount", GUILD_EVENTLOG_MAX_RECORDS);
if (m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] > GUILD_EVENTLOG_MAX_RECORDS)
m_int_configs[CONFIG_GUILD_EVENT_LOG_COUNT] = GUILD_EVENTLOG_MAX_RECORDS;
@@ -1207,12 +1244,12 @@ void World::LoadConfigSettings(bool reload)
m_int_configs[CONFIG_ACC_PASSCHANGESEC] = sConfigMgr->GetIntDefault("Account.PasswordChangeSecurity", 0);
// Random Battleground Rewards
- m_int_configs[CONFIG_BG_REWARD_WINNER_HONOR_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerHonorFirst", 30);
- m_int_configs[CONFIG_BG_REWARD_WINNER_ARENA_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerArenaFirst", 25);
- m_int_configs[CONFIG_BG_REWARD_WINNER_HONOR_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerHonorLast", 15);
- m_int_configs[CONFIG_BG_REWARD_WINNER_ARENA_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerArenaLast", 0);
- m_int_configs[CONFIG_BG_REWARD_LOSER_HONOR_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardLoserHonorFirst", 5);
- m_int_configs[CONFIG_BG_REWARD_LOSER_HONOR_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardLoserHonorLast", 5);
+ m_int_configs[CONFIG_BG_REWARD_WINNER_HONOR_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerHonorFirst", 27000);
+ m_int_configs[CONFIG_BG_REWARD_WINNER_CONQUEST_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerConquestFirst", 10000);
+ m_int_configs[CONFIG_BG_REWARD_WINNER_HONOR_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerHonorLast", 13500);
+ m_int_configs[CONFIG_BG_REWARD_WINNER_CONQUEST_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardWinnerConquestLast", 5000);
+ m_int_configs[CONFIG_BG_REWARD_LOSER_HONOR_FIRST] = sConfigMgr->GetIntDefault("Battleground.RewardLoserHonorFirst", 4500);
+ m_int_configs[CONFIG_BG_REWARD_LOSER_HONOR_LAST] = sConfigMgr->GetIntDefault("Battleground.RewardLoserHonorLast", 3500);
// Max instances per hour
m_int_configs[CONFIG_MAX_INSTANCES_PER_HOUR] = sConfigMgr->GetIntDefault("AccountInstancesPerHour", 5);
@@ -1233,6 +1270,15 @@ void World::LoadConfigSettings(bool reload)
// MySQL ping time interval
m_int_configs[CONFIG_DB_PING_INTERVAL] = sConfigMgr->GetIntDefault("MaxPingTime", 30);
+ // Guild save interval
+ m_bool_configs[CONFIG_GUILD_LEVELING_ENABLED] = sConfigMgr->GetBoolDefault("Guild.LevelingEnabled", true);
+ m_int_configs[CONFIG_GUILD_SAVE_INTERVAL] = sConfigMgr->GetIntDefault("Guild.SaveInterval", 15);
+ m_int_configs[CONFIG_GUILD_MAX_LEVEL] = sConfigMgr->GetIntDefault("Guild.MaxLevel", 25);
+ m_int_configs[CONFIG_GUILD_UNDELETABLE_LEVEL] = sConfigMgr->GetIntDefault("Guild.UndeletableLevel", 4);
+ rate_values[RATE_XP_GUILD_MODIFIER] = sConfigMgr->GetFloatDefault("Guild.XPModifier", 0.25f);
+ m_int_configs[CONFIG_GUILD_DAILY_XP_CAP] = sConfigMgr->GetIntDefault("Guild.DailyXPCap", 7807500);
+ m_int_configs[CONFIG_GUILD_WEEKLY_REP_CAP] = sConfigMgr->GetIntDefault("Guild.WeeklyReputationCap", 4375);
+
// misc
m_bool_configs[CONFIG_PDUMP_NO_PATHS] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowPaths", true);
m_bool_configs[CONFIG_PDUMP_NO_OVERWRITE] = sConfigMgr->GetBoolDefault("PlayerDump.DisallowOverwrite", true);
@@ -1334,7 +1380,7 @@ void World::SetInitialWorldSettings()
///- Load the DBC files
TC_LOG_INFO("server.loading", "Initialize data stores...");
LoadDBCStores(m_dataPath);
- DetectDBCLang();
+ LoadDB2Stores(m_dataPath);
TC_LOG_INFO("server.loading", "Loading SpellInfo store...");
sSpellMgr->LoadSpellInfoStore();
@@ -1366,7 +1412,6 @@ void World::SetInitialWorldSettings()
sObjectMgr->LoadCreatureLocales();
sObjectMgr->LoadGameObjectLocales();
sObjectMgr->LoadItemLocales();
- sObjectMgr->LoadItemSetNameLocales();
sObjectMgr->LoadQuestLocales();
sObjectMgr->LoadNpcTextLocales();
sObjectMgr->LoadPageTextLocales();
@@ -1418,6 +1463,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Spell Group Stack Rules...");
sSpellMgr->LoadSpellGroupStackRules();
+ TC_LOG_INFO("server.loading", "Loading Spell Phase Dbc Info...");
+ sObjectMgr->LoadSpellPhaseInfo();
+
TC_LOG_INFO("server.loading", "Loading NPC Texts...");
sObjectMgr->LoadGossipText();
@@ -1434,7 +1482,10 @@ void World::SetInitialWorldSettings()
sObjectMgr->LoadItemTemplates();
TC_LOG_INFO("server.loading", "Loading Item set names..."); // must be after LoadItemPrototypes
- sObjectMgr->LoadItemSetNames();
+ sObjectMgr->LoadItemTemplateAddon();
+
+ TC_LOG_INFO("misc", "Loading Item Scripts..."); // must be after LoadItemPrototypes
+ sObjectMgr->LoadItemScriptNames();
TC_LOG_INFO("server.loading", "Loading Creature Model Based Info Data...");
sObjectMgr->LoadCreatureModelInfo();
@@ -1544,6 +1595,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Graveyard-zone links...");
sObjectMgr->LoadGraveyardZones();
+ TC_LOG_INFO("server.loading", "Loading Graveyard Orientations...");
+ sObjectMgr->LoadGraveyardOrientations();
+
TC_LOG_INFO("server.loading", "Loading spell pet auras...");
sSpellMgr->LoadSpellPetAuras();
@@ -1615,9 +1669,17 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Auctions...");
sAuctionMgr->LoadAuctions();
+ TC_LOG_INFO("server.loading", "Loading Guild XP for level...");
+ sGuildMgr->LoadGuildXpForLevel();
+
+ TC_LOG_INFO("server.loading", "Loading Guild rewards...");
+ sGuildMgr->LoadGuildRewards();
+
TC_LOG_INFO("server.loading", "Loading Guilds...");
sGuildMgr->LoadGuilds();
+ sGuildFinderMgr->LoadFromDB();
+
TC_LOG_INFO("server.loading", "Loading ArenaTeams...");
sArenaTeamMgr->LoadArenaTeams();
@@ -1660,6 +1722,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions
LoadWorldStates();
+ TC_LOG_INFO("server.loading", "Loading Phase definitions...");
+ sObjectMgr->LoadPhaseDefinitions();
+
TC_LOG_INFO("server.loading", "Loading Conditions...");
sConditionMgr->LoadConditions();
@@ -1745,6 +1810,8 @@ void World::SetInitialWorldSettings()
m_timers[WUPDATE_PINGDB].SetInterval(getIntConfig(CONFIG_DB_PING_INTERVAL)*MINUTE*IN_MILLISECONDS); // Mysql ping time in minutes
+ m_timers[WUPDATE_GUILDSAVE].SetInterval(getIntConfig(CONFIG_GUILD_SAVE_INTERVAL) * MINUTE * IN_MILLISECONDS);
+
//to set mailtimer to return mails every day between 4 and 5 am
//mailtimer is increased when updating auctions
//one second is 1000 -(tested on win system)
@@ -1781,7 +1848,6 @@ void World::SetInitialWorldSettings()
///- Initialize Battlegrounds
TC_LOG_INFO("server.loading", "Starting Battleground System");
sBattlegroundMgr->CreateInitialBattlegrounds();
- sBattlegroundMgr->InitAutomaticArenaPointDistribution();
///- Initialize outdoor pvp
TC_LOG_INFO("server.loading", "Starting Outdoor PvP System");
@@ -1819,8 +1885,20 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Calculate guild limitation(s) reset time...");
InitGuildResetTime();
+ TC_LOG_INFO("server.loading", "Calculate next currency reset time...");
+ InitCurrencyResetTime();
+
LoadCharacterNameData();
+ TC_LOG_INFO("misc", "Initializing Opcodes...");
+ opcodeTable.Initialize();
+
+ TC_LOG_INFO("misc", "Loading hotfix info...");
+ sObjectMgr->LoadHotfixData();
+
+ TC_LOG_INFO("server.loading", "Loading missing KeyChains...");
+ sObjectMgr->LoadMissingKeyChains();
+
uint32 startupDuration = GetMSTimeDiffToNow(startupBegin);
TC_LOG_INFO("server.worldserver", "World initialized in %u minutes %u seconds", (startupDuration / 60000), ((startupDuration % 60000) / 1000));
@@ -1829,49 +1907,6 @@ void World::SetInitialWorldSettings()
sLog->SetRealmId(realmId);
}
-void World::DetectDBCLang()
-{
- uint8 m_lang_confid = sConfigMgr->GetIntDefault("DBC.Locale", 255);
-
- if (m_lang_confid != 255 && m_lang_confid >= TOTAL_LOCALES)
- {
- TC_LOG_ERROR("server.loading", "Incorrect DBC.Locale! Must be >= 0 and < %d (set to 0)", TOTAL_LOCALES);
- m_lang_confid = LOCALE_enUS;
- }
-
- ChrRacesEntry const* race = sChrRacesStore.LookupEntry(1);
-
- std::string availableLocalsStr;
-
- uint8 default_locale = TOTAL_LOCALES;
- for (uint8 i = default_locale-1; i < TOTAL_LOCALES; --i) // -1 will be 255 due to uint8
- {
- if (race->name[i][0] != '\0') // check by race names
- {
- default_locale = i;
- m_availableDbcLocaleMask |= (1 << i);
- availableLocalsStr += localeNames[i];
- availableLocalsStr += " ";
- }
- }
-
- if (default_locale != m_lang_confid && m_lang_confid < TOTAL_LOCALES &&
- (m_availableDbcLocaleMask & (1 << m_lang_confid)))
- {
- default_locale = m_lang_confid;
- }
-
- if (default_locale >= TOTAL_LOCALES)
- {
- TC_LOG_ERROR("server.loading", "Unable to determine your DBC Locale! (corrupt DBC?)");
- exit(1);
- }
-
- m_defaultDbcLocale = LocaleConstant(default_locale);
-
- TC_LOG_INFO("server.loading", "Using %s DBC Locale as default. All available DBC locales: %s", localeNames[m_defaultDbcLocale], availableLocalsStr.empty() ? "<none>" : availableLocalsStr.c_str());
-}
-
void World::RecordTimeDiff(const char *text, ...)
{
if (m_updateTimeCount != 1)
@@ -1985,6 +2020,9 @@ void World::Update(uint32 diff)
if (m_gameTime > m_NextGuildReset)
ResetGuildCap();
+ if (m_gameTime > m_NextCurrencyReset)
+ ResetCurrencyWeekCap();
+
/// <ul><li> Handle auctions when the timer has passed
if (m_timers[WUPDATE_AUCTIONS].Passed())
{
@@ -2112,6 +2150,12 @@ void World::Update(uint32 diff)
WorldDatabase.KeepAlive();
}
+ if (m_timers[WUPDATE_GUILDSAVE].Passed())
+ {
+ m_timers[WUPDATE_GUILDSAVE].Reset();
+ sGuildMgr->SaveGuilds();
+ }
+
// update the instance reset times
sInstanceSaveMgr->Update();
@@ -2711,16 +2755,20 @@ void World::SendAutoBroadcast()
sWorld->SendWorldText(LANG_AUTO_BROADCAST, msg.c_str());
else if (abcenter == 1)
{
- WorldPacket data(SMSG_NOTIFICATION, (msg.size()+1));
- data << msg;
+ WorldPacket data(SMSG_NOTIFICATION, 2 + msg.length());
+ data.WriteBits(msg.length(), 13);
+ data.FlushBits();
+ data.WriteString(msg);
sWorld->SendGlobalMessage(&data);
}
else if (abcenter == 2)
{
sWorld->SendWorldText(LANG_AUTO_BROADCAST, msg.c_str());
- WorldPacket data(SMSG_NOTIFICATION, (msg.size()+1));
- data << msg;
+ WorldPacket data(SMSG_NOTIFICATION, 2 + msg.length());
+ data.WriteBits(msg.length(), 13);
+ data.FlushBits();
+ data.WriteString(msg);
sWorld->SendGlobalMessage(&data);
}
@@ -2861,6 +2909,35 @@ void World::InitGuildResetTime()
sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(m_NextGuildReset));
}
+void World::InitCurrencyResetTime()
+{
+ time_t currencytime = uint64(sWorld->getWorldState(WS_CURRENCY_RESET_TIME));
+ if (!currencytime)
+ m_NextCurrencyReset = time_t(time(NULL)); // game time not yet init
+
+ // generate time by config
+ time_t curTime = time(NULL);
+ tm localTm = *localtime(&curTime);
+
+ localTm.tm_wday = getIntConfig(CONFIG_CURRENCY_RESET_DAY);
+ localTm.tm_hour = getIntConfig(CONFIG_CURRENCY_RESET_HOUR);
+ localTm.tm_min = 0;
+ localTm.tm_sec = 0;
+
+ // current week reset time
+ time_t nextWeekResetTime = mktime(&localTm);
+
+ // next reset time before current moment
+ if (curTime >= nextWeekResetTime)
+ nextWeekResetTime += getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL) * DAY;
+
+ // normalize reset time
+ m_NextCurrencyReset = currencytime < curTime ? nextWeekResetTime - getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL) * DAY : nextWeekResetTime;
+
+ if (!currencytime)
+ sWorld->setWorldState(WS_CURRENCY_RESET_TIME, uint64(m_NextCurrencyReset));
+}
+
void World::ResetDailyQuests()
{
TC_LOG_INFO("misc", "Daily quests reset for all characters.");
@@ -2876,6 +2953,18 @@ void World::ResetDailyQuests()
sPoolMgr->ChangeDailyQuests();
}
+void World::ResetCurrencyWeekCap()
+{
+ CharacterDatabase.Execute("UPDATE `character_currency` SET `week_count` = 0");
+
+ for (SessionMap::const_iterator itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ if (itr->second->GetPlayer())
+ itr->second->GetPlayer()->ResetCurrencyWeekCap();
+
+ m_NextCurrencyReset = time_t(m_NextCurrencyReset + DAY * getIntConfig(CONFIG_CURRENCY_RESET_INTERVAL));
+ sWorld->setWorldState(WS_CURRENCY_RESET_TIME, uint64(m_NextCurrencyReset));
+}
+
void World::LoadDBAllowedSecurityLevel()
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_REALMLIST_SECURITY_LEVEL);
@@ -2985,11 +3074,14 @@ void World::ResetRandomBG()
void World::ResetGuildCap()
{
- TC_LOG_INFO("misc", "Guild Daily Cap reset.");
-
m_NextGuildReset = time_t(m_NextGuildReset + DAY);
sWorld->setWorldState(WS_GUILD_DAILY_RESET_TIME, uint64(m_NextGuildReset));
- sGuildMgr->ResetTimes();
+ uint32 week = getWorldState(WS_GUILD_WEEKLY_RESET_TIME);
+ week = week < 7 ? week + 1 : 1;
+
+ TC_LOG_INFO("misc", "Guild Daily Cap reset. Week: %u", week == 1);
+ sWorld->setWorldState(WS_GUILD_WEEKLY_RESET_TIME, week);
+ sGuildMgr->ResetTimes(week == 1);
}
void World::UpdateMaxSessionCounters()
@@ -3195,6 +3287,14 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const
return NULL;
}
+void World::UpdatePhaseDefinitions()
+{
+ SessionMap::const_iterator itr;
+ for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
+ if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld())
+ itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded();
+}
+
void World::ReloadRBAC()
{
// Passive reload, we mark the data as invalidated and next time a permission is checked it will be reloaded
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index a320933e181..c8937a062b6 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -45,11 +45,19 @@ class SystemMgr;
// ServerMessages.dbc
enum ServerMessageType
{
- SERVER_MSG_SHUTDOWN_TIME = 1,
- SERVER_MSG_RESTART_TIME = 2,
- SERVER_MSG_STRING = 3,
- SERVER_MSG_SHUTDOWN_CANCELLED = 4,
- SERVER_MSG_RESTART_CANCELLED = 5
+ SERVER_MSG_SHUTDOWN_TIME = 1,
+ SERVER_MSG_RESTART_TIME = 2,
+ SERVER_MSG_STRING = 3,
+ SERVER_MSG_SHUTDOWN_CANCELLED = 4,
+ SERVER_MSG_RESTART_CANCELLED = 5,
+ SERVER_MSG_BG_SHUTDOWN_TIME = 6,
+ SERVER_MSG_BG_RESTART_TIME = 7,
+ SERVER_MSG_INSTANCE_SHUTDOWN_TIME = 8,
+ SERVER_MSG_INSTANCE_RESTART_TIME = 9,
+ SERVER_MSG_CONTENT_READY = 10,
+ SERVER_MSG_TICKET_SERVICED_SOON = 11,
+ SERVER_MSG_WAIT_TIME_UNAVAILABLE = 12,
+ SERVER_MSG_TICKET_WAIT_TIME = 13,
};
enum ShutdownMask
@@ -78,6 +86,7 @@ enum WorldTimers
WUPDATE_MAILBOXQUEUE,
WUPDATE_DELETECHARS,
WUPDATE_PINGDB,
+ WUPDATE_GUILDSAVE,
WUPDATE_COUNT
};
@@ -107,7 +116,6 @@ enum WorldBoolConfigs
CONFIG_SKILL_MILLING,
CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY,
CONFIG_WEATHER,
- CONFIG_ALWAYS_MAX_SKILL_FOR_LEVEL,
CONFIG_QUEST_IGNORE_RAID,
CONFIG_DETECT_POS_COLLISION,
CONFIG_RESTRICTED_LFG_CHANNEL,
@@ -123,7 +131,6 @@ enum WorldBoolConfigs
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE,
CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_BG_XP_FOR_KILL,
- CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,
CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,
CONFIG_ARENA_QUEUE_ANNOUNCER_PLAYERONLY,
CONFIG_ARENA_SEASON_IN_PROGRESS,
@@ -159,6 +166,7 @@ enum WorldBoolConfigs
CONFIG_WARDEN_ENABLED,
CONFIG_ENABLE_MMAPS,
CONFIG_WINTERGRASP_ENABLE,
+ CONFIG_GUILD_LEVELING_ENABLED,
CONFIG_UI_QUESTLEVELS_IN_DIALOGS, // Should we add quest levels to the title in the NPC dialogs?
CONFIG_EVENT_ANNOUNCE,
CONFIG_STATS_LIMITS_ENABLE,
@@ -218,10 +226,16 @@ enum WorldIntConfigs
CONFIG_START_PLAYER_LEVEL,
CONFIG_START_HEROIC_PLAYER_LEVEL,
CONFIG_START_PLAYER_MONEY,
- CONFIG_MAX_HONOR_POINTS,
- CONFIG_START_HONOR_POINTS,
- CONFIG_MAX_ARENA_POINTS,
- CONFIG_START_ARENA_POINTS,
+ CONFIG_CURRENCY_START_JUSTICE_POINTS,
+ CONFIG_CURRENCY_MAX_JUSTICE_POINTS,
+ CONFIG_CURRENCY_START_HONOR_POINTS,
+ CONFIG_CURRENCY_MAX_HONOR_POINTS,
+ CONFIG_CURRENCY_START_CONQUEST_POINTS,
+ CONFIG_CURRENCY_CONQUEST_POINTS_WEEK_CAP,
+ CONFIG_CURRENCY_CONQUEST_POINTS_ARENA_REWARD,
+ CONFIG_CURRENCY_RESET_HOUR,
+ CONFIG_CURRENCY_RESET_DAY,
+ CONFIG_CURRENCY_RESET_INTERVAL,
CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL,
CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL_DIFFERENCE,
CONFIG_INSTANCE_RESET_TIME_HOUR,
@@ -246,9 +260,7 @@ enum WorldIntConfigs
CONFIG_SKILL_CHANCE_MINING_STEPS,
CONFIG_SKILL_CHANCE_SKINNING_STEPS,
CONFIG_SKILL_GAIN_CRAFTING,
- CONFIG_SKILL_GAIN_DEFENSE,
CONFIG_SKILL_GAIN_GATHERING,
- CONFIG_SKILL_GAIN_WEAPON,
CONFIG_MAX_OVERSPEED_PINGS,
CONFIG_EXPANSION,
CONFIG_CHATFLOOD_MESSAGE_COUNT,
@@ -282,7 +294,6 @@ enum WorldIntConfigs
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
CONFIG_ARENA_RATING_DISCARD_TIMER,
CONFIG_ARENA_RATED_UPDATE_TIMER,
- CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
CONFIG_ARENA_SEASON_ID,
CONFIG_ARENA_START_RATING,
CONFIG_ARENA_START_PERSONAL_RATING,
@@ -300,6 +311,7 @@ enum WorldIntConfigs
CONFIG_LOGDB_CLEARINTERVAL,
CONFIG_LOGDB_CLEARTIME,
CONFIG_CLIENTCACHE_VERSION,
+ CONFIG_GUILD_NEWS_LOG_COUNT,
CONFIG_GUILD_EVENT_LOG_COUNT,
CONFIG_GUILD_BANK_EVENT_LOG_COUNT,
CONFIG_MIN_LEVEL_STAT_SAVE,
@@ -329,16 +341,21 @@ enum WorldIntConfigs
CONFIG_WINTERGRASP_BATTLETIME,
CONFIG_WINTERGRASP_NOBATTLETIME,
CONFIG_WINTERGRASP_RESTART_AFTER_CRASH,
+ CONFIG_GUILD_SAVE_INTERVAL,
+ CONFIG_GUILD_MAX_LEVEL,
+ CONFIG_GUILD_UNDELETABLE_LEVEL,
+ CONFIG_GUILD_DAILY_XP_CAP,
+ CONFIG_GUILD_WEEKLY_REP_CAP,
CONFIG_PACKET_SPOOF_POLICY,
CONFIG_PACKET_SPOOF_BANMODE,
CONFIG_PACKET_SPOOF_BANDURATION,
CONFIG_ACC_PASSCHANGESEC,
CONFIG_BG_REWARD_WINNER_HONOR_FIRST,
- CONFIG_BG_REWARD_WINNER_ARENA_FIRST,
CONFIG_BG_REWARD_WINNER_HONOR_LAST,
- CONFIG_BG_REWARD_WINNER_ARENA_LAST,
CONFIG_BG_REWARD_LOSER_HONOR_FIRST,
CONFIG_BG_REWARD_LOSER_HONOR_LAST,
+ CONFIG_BG_REWARD_WINNER_CONQUEST_FIRST,
+ CONFIG_BG_REWARD_WINNER_CONQUEST_LAST,
INT_CONFIG_VALUE_COUNT
};
@@ -366,6 +383,7 @@ enum Rates
RATE_DROP_MONEY,
RATE_XP_KILL,
RATE_XP_QUEST,
+ RATE_XP_GUILD_MODIFIER,
RATE_XP_EXPLORE,
RATE_REPAIRCOST,
RATE_REPUTATION_GAIN,
@@ -484,6 +502,8 @@ enum WorldStates
WS_CLEANING_FLAGS = 20004, // Cleaning Flags
WS_GUILD_DAILY_RESET_TIME = 20006, // Next guild cap reset time
WS_MONTHLY_QUEST_RESET_TIME = 20007, // Next monthly reset time
+ // Cata specific custom worldstates
+ WS_GUILD_WEEKLY_RESET_TIME = 20050, // Next guild week reset time
};
/// Storage class for commands issued for delayed execution
@@ -616,7 +636,7 @@ class World
/// Get the maximum skill level a player can reach
uint16 GetConfigMaxSkillValue() const
{
- uint16 lvl = uint16(getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
+ uint8 lvl = uint8(getIntConfig(CONFIG_MAX_PLAYER_LEVEL));
return lvl > 60 ? 300 + ((lvl - 60) * 75) / 10 : lvl * 5;
}
@@ -744,6 +764,7 @@ class World
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
void ResetEventSeasonalQuests(uint16 event_id);
+ void UpdatePhaseDefinitions();
void ReloadRBAC();
protected:
@@ -756,11 +777,13 @@ class World
void InitMonthlyQuestResetTime();
void InitRandomBGResetTime();
void InitGuildResetTime();
+ void InitCurrencyResetTime();
void ResetDailyQuests();
void ResetWeeklyQuests();
void ResetMonthlyQuests();
void ResetRandomBG();
void ResetGuildCap();
+ void ResetCurrencyWeekCap();
private:
static ACE_Atomic_Op<ACE_Thread_Mutex, bool> m_stopEvent;
static uint8 m_ExitCode;
@@ -800,7 +823,6 @@ class World
AccountTypes m_allowedSecurityLevel;
LocaleConstant m_defaultDbcLocale; // from config for one from loaded DBC locales
uint32 m_availableDbcLocaleMask; // by loaded DBC
- void DetectDBCLang();
bool m_allowMovement;
std::string m_motd;
std::string m_dataPath;
@@ -817,12 +839,13 @@ class World
// CLI command holder to be thread safe
ACE_Based::LockedQueue<CliCommandHolder*, ACE_Thread_Mutex> cliCmdQueue;
- // next daily quests and random bg reset time
+ // scheduled reset times
time_t m_NextDailyQuestReset;
time_t m_NextWeeklyQuestReset;
time_t m_NextMonthlyQuestReset;
time_t m_NextRandomBGReset;
time_t m_NextGuildReset;
+ time_t m_NextCurrencyReset;
//Player Queue
Queue m_QueuedPlayer;
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index c1a9435de52..4ffa9925e0f 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -37,6 +37,7 @@ if(SCRIPTS)
include(Kalimdor/CMakeLists.txt)
include(Outland/CMakeLists.txt)
include(Northrend/CMakeLists.txt)
+ include(Maelstrom/CMakeLists.txt)
include(Events/CMakeLists.txt)
include(Pet/CMakeLists.txt)
endif()
@@ -88,6 +89,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Combat
${CMAKE_SOURCE_DIR}/src/server/game/DataStores
${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding
+ ${CMAKE_SOURCE_DIR}/src/server/game/Entities/AreaTrigger
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature
${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index f9ef827e8c3..2a127175648 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -277,7 +277,7 @@ public:
if (titleInfo && target->HasTitle(titleInfo))
{
- std::string name = titleInfo->name[loc];
+ std::string name = titleInfo->name;
if (name.empty())
continue;
@@ -566,7 +566,7 @@ public:
{
FactionState const& faction = itr->second;
FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID);
- char const* factionName = factionEntry ? factionEntry->name[loc] : "#Not found#";
+ char const* factionName = factionEntry ? factionEntry->name : "#Not found#";
ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]);
std::ostringstream ss;
diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp
index bf51141ba4f..ee35b16c061 100644
--- a/src/server/scripts/Commands/cs_cheat.cpp
+++ b/src/server/scripts/Commands/cs_cheat.cpp
@@ -185,10 +185,11 @@ public:
std::string argstr = (char*)args;
+ Player* target = handler->GetSession()->GetPlayer();
if (!*args)
{
- argstr = (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on";
- if (handler->GetSession()->GetPlayer()->GetCommandStatus(CHEAT_WATERWALK))
+ argstr = (target->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on";
+ if (target->GetCommandStatus(CHEAT_WATERWALK))
argstr = "off";
else
argstr = "on";
@@ -196,15 +197,15 @@ public:
if (argstr == "off")
{
- handler->GetSession()->GetPlayer()->SetCommandStatusOff(CHEAT_WATERWALK);
- handler->GetSession()->GetPlayer()->SetMovement(MOVE_LAND_WALK); // OFF
+ target->SetCommandStatusOff(CHEAT_WATERWALK);
+ target->SetWaterWalking(false);
handler->SendSysMessage("Waterwalking is OFF. You can't walk on water.");
return true;
}
else if (argstr == "on")
{
- handler->GetSession()->GetPlayer()->SetCommandStatusOn(CHEAT_WATERWALK);
- handler->GetSession()->GetPlayer()->SetMovement(MOVE_WATER_WALK); // ON
+ target->SetCommandStatusOn(CHEAT_WATERWALK);
+ target->SetWaterWalking(true);
handler->SendSysMessage("Waterwalking is ON. You can walk on water.");
return true;
}
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index 597823abc13..6186e0d3ddc 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -93,6 +93,7 @@ public:
{ "los", rbac::RBAC_PERM_COMMAND_DEBUG_LOS, false, &HandleDebugLoSCommand, "", NULL },
{ "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "", NULL },
{ "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "", NULL },
+ { "phase", rbac::RBAC_PERM_COMMAND_DEBUG_PHASE, false, &HandleDebugPhaseCommand, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
@@ -239,7 +240,7 @@ public:
return false;
SellResult msg = SellResult(atoi(args));
- handler->GetSession()->GetPlayer()->SendSellError(msg, 0, 0, 0);
+ handler->GetSession()->GetPlayer()->SendSellError(msg, 0, 0);
return true;
}
@@ -313,7 +314,7 @@ public:
uint32 opcode;
parsedStream >> opcode;
- WorldPacket data(opcode, 0);
+ WorldPacket data(Opcodes(opcode), 0);
while (!parsedStream.eof())
{
@@ -419,7 +420,7 @@ public:
}
TC_LOG_DEBUG("network", "Sending opcode %u", data.GetOpcode());
data.hexlike();
- player->GetSession()->SendPacket(&data);
+ player->GetSession()->SendPacket(&data, true);
handler->PSendSysMessage(LANG_COMMAND_OPCODESENT, data.GetOpcode(), unit->GetName().c_str());
return true;
}
@@ -953,8 +954,21 @@ public:
if (!*args)
return false;
- uint32 PhaseShift = atoi(args);
- handler->GetSession()->SendSetPhaseShift(PhaseShift);
+ char* t = strtok((char*)args, " ");
+ char* p = strtok(NULL, " ");
+
+ if (!t)
+ return false;
+
+ std::set<uint32> terrainswap;
+ std::set<uint32> phaseId;
+
+ terrainswap.insert((uint32)atoi(t));
+
+ if (p)
+ phaseId.insert((uint32)atoi(p));
+
+ handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap);
return true;
}
@@ -1311,35 +1325,9 @@ public:
char* mask2 = strtok(NULL, " \n");
uint32 moveFlags = (uint32)atoi(mask1);
+ target->SetUnitMovementFlags(moveFlags);
- static uint32 const FlagsWithHandlers = MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE |
- MOVEMENTFLAG_WALKING | MOVEMENTFLAG_SWIMMING |
- MOVEMENTFLAG_SPLINE_ENABLED;
-
- bool unhandledFlag = (moveFlags ^ target->GetUnitMovementFlags()) & ~FlagsWithHandlers;
-
- target->SetWalk(moveFlags & MOVEMENTFLAG_WALKING);
- target->SetDisableGravity(moveFlags & MOVEMENTFLAG_DISABLE_GRAVITY);
- target->SetSwim(moveFlags & MOVEMENTFLAG_SWIMMING);
- target->SetCanFly(moveFlags & MOVEMENTFLAG_CAN_FLY);
- target->SetWaterWalking(moveFlags & MOVEMENTFLAG_WATERWALKING);
- target->SetFeatherFall(moveFlags & MOVEMENTFLAG_FALLING_SLOW);
- target->SetHover(moveFlags & MOVEMENTFLAG_HOVER);
-
- if (moveFlags & (MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_CAN_FLY))
- moveFlags &= ~MOVEMENTFLAG_FALLING;
-
- if (moveFlags & MOVEMENTFLAG_ROOT)
- {
- target->SetControlled(true, UNIT_STATE_ROOT);
- moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
- }
-
- if (target->HasUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED) && !(moveFlags & MOVEMENTFLAG_SPLINE_ENABLED))
- target->StopMoving();
-
- if (unhandledFlag)
- target->SetUnitMovementFlags(moveFlags);
+ /// @fixme: port master's HandleDebugMoveflagsCommand; flags need different handling
if (mask2)
{
@@ -1347,8 +1335,14 @@ public:
target->SetExtraUnitMovementFlags(moveFlagsExtra);
}
- if (mask2 || unhandledFlag)
- target->SendMovementFlagUpdate();
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ target->DestroyForNearbyPlayers(); // Force new SMSG_UPDATE_OBJECT:CreateObject
+ else
+ {
+ WorldPacket data(SMSG_PLAYER_MOVE);
+ target->WriteMovementInfo(data);
+ target->SendMessageToSet(&data, true);
+ }
handler->PSendSysMessage(LANG_MOVEFLAGS_SET, target->GetUnitMovementFlags(), target->GetExtraUnitMovementFlags());
}
@@ -1392,6 +1386,17 @@ public:
handler->PSendSysMessage("Transport %s %s", transport->GetName().c_str(), start ? "started" : "stopped");
return true;
}
+
+ static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ Unit* unit = handler->getSelectedUnit();
+ Player* player = handler->GetSession()->GetPlayer();
+ if (unit && unit->GetTypeId() == TYPEID_PLAYER)
+ player = unit->ToPlayer();
+
+ player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer());
+ return true;
+ }
};
void AddSC_debug_commandscript()
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 498ee68ba11..5b58ccf6474 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -101,19 +101,16 @@ public:
if (!target)
target = handler->GetSession()->GetPlayer();
- WorldPacket data(12);
+ WorldPacket data;
if (strncmp(args, "on", 3) == 0)
- data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);
+ target->SetCanFly(true);
else if (strncmp(args, "off", 4) == 0)
- data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);
+ target->SetCanFly(false);
else
{
handler->SendSysMessage(LANG_USE_BOL);
return false;
}
- data.append(target->GetPackGUID());
- data << uint32(0); // unknown
- target->SendMessageToSet(&data, true);
handler->PSendSysMessage(LANG_COMMAND_FLYMODE_STATUS, handler->GetNameLink(target).c_str(), args);
return true;
}
diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp
index fecb4edf968..691055d536d 100644
--- a/src/server/scripts/Commands/cs_go.cpp
+++ b/src/server/scripts/Commands/cs_go.cpp
@@ -446,7 +446,7 @@ public:
if (map->Instanceable())
{
- handler->PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name[handler->GetSessionDbcLocale()], map->GetId(), map->GetMapName());
+ handler->PSendSysMessage(LANG_INVALID_ZONE_MAP, areaEntry->ID, areaEntry->area_name, map->GetId(), map->GetMapName());
handler->SetSentErrorMessage(true);
return false;
}
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 423a47eb3c8..2aa78964ffd 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -152,7 +152,7 @@ public:
GameObject* object = new GameObject;
uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
- if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
+ if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
{
delete object;
return false;
@@ -165,7 +165,7 @@ public:
}
// fill the gameobject data and save to the db
- object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
+ object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn());
// this will generate a new guid if the object is in an instance
if (!object->LoadGameObjectFromDB(guidLow, map))
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index 4627f6b022e..928e110e9a1 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -22,6 +22,7 @@ Comment: All guild related commands
Category: commandscripts
EndScriptData */
+#include "AchievementMgr.h"
#include "Chat.h"
#include "Language.h"
#include "Guild.h"
diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp
index 113f6da2e31..722c863ac6c 100644
--- a/src/server/scripts/Commands/cs_learn.cpp
+++ b/src/server/scripts/Commands/cs_learn.cpp
@@ -399,33 +399,14 @@ public:
!skillInfo->canLink) // only prof with recipes have set
continue;
- int locale = handler->GetSessionDbcLocale();
- name = skillInfo->name[locale];
+ name = skillInfo->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, namePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = skillInfo->name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, namePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
- {
- targetSkillInfo = skillInfo;
- break;
- }
+ targetSkillInfo = skillInfo;
}
if (!targetSkillInfo)
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 1ee92625735..0021f96c7a2 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -439,7 +439,7 @@ public:
AuraApplication const* aurApp = itr->second;
Aura const* aura = aurApp->GetBase();
- char const* name = aura->GetSpellInfo()->SpellName[handler->GetSessionDbcLocale()];
+ char const* name = aura->GetSpellInfo()->SpellName;
std::ostringstream ss_name;
ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index f2b4f54363b..0a382b794e5 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -106,48 +106,30 @@ public:
AreaTableEntry const* areaEntry = sAreaStore.LookupEntry(areaflag);
if (areaEntry)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = areaEntry->area_name[locale];
+ std::string name = areaEntry->area_name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = areaEntry->area_name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
+ if (maxResults && count++ == maxResults)
{
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- // send area in "id - [name]" format
- std::ostringstream ss;
- if (handler->GetSession())
- ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << ' ' << localeNames[locale]<< "]|h|r";
- else
- ss << areaEntry->ID << " - " << name << ' ' << localeNames[locale];
+ // send area in "id - [name]" format
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name<< "]|h|r";
+ else
+ ss << areaEntry->ID << " - " << name;
- handler->SendSysMessage(ss.str().c_str());
+ handler->SendSysMessage(ss.str().c_str());
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
@@ -313,77 +295,58 @@ public:
for (uint32 id = 0; id < sFactionStore.GetNumRows(); ++id)
{
- FactionEntry const* factionEntry = sFactionStore.LookupEntry(id);
- if (factionEntry)
+ if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(id))
{
FactionState const* factionState = target ? target->GetReputationMgr().GetState(factionEntry) : NULL;
- int locale = handler->GetSessionDbcLocale();
- std::string name = factionEntry->name[locale];
+ std::string name = factionEntry->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = factionEntry->name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
+ if (maxResults && count++ == maxResults)
{
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
- // or "id - [faction] [no reputation]" format
- std::ostringstream ss;
- if (handler->GetSession())
- ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << ' ' << localeNames[locale] << "]|h|r";
- else
- ss << id << " - " << name << ' ' << localeNames[locale];
+ // send faction in "id - [faction] rank reputation [visible] [at war] [own team] [unknown] [invisible] [inactive]" format
+ // or "id - [faction] [no reputation]" format
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << id << " - |cffffffff|Hfaction:" << id << "|h[" << name << "]|h|r";
+ else
+ ss << id << " - " << name;
- if (factionState) // and then target != NULL also
- {
- uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry);
- std::string rankName = handler->GetTrinityString(index);
-
- ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
-
- if (factionState->Flags & FACTION_FLAG_VISIBLE)
- ss << handler->GetTrinityString(LANG_FACTION_VISIBLE);
- if (factionState->Flags & FACTION_FLAG_AT_WAR)
- ss << handler->GetTrinityString(LANG_FACTION_ATWAR);
- if (factionState->Flags & FACTION_FLAG_PEACE_FORCED)
- ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED);
- if (factionState->Flags & FACTION_FLAG_HIDDEN)
- ss << handler->GetTrinityString(LANG_FACTION_HIDDEN);
- if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
- ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
- if (factionState->Flags & FACTION_FLAG_INACTIVE)
- ss << handler->GetTrinityString(LANG_FACTION_INACTIVE);
- }
- else
- ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION);
+ if (factionState) // and then target != NULL also
+ {
+ uint32 index = target->GetReputationMgr().GetReputationRankStrIndex(factionEntry);
+ std::string rankName = handler->GetTrinityString(index);
+
+ ss << ' ' << rankName << "|h|r (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
+
+ if (factionState->Flags & FACTION_FLAG_VISIBLE)
+ ss << handler->GetTrinityString(LANG_FACTION_VISIBLE);
+ if (factionState->Flags & FACTION_FLAG_AT_WAR)
+ ss << handler->GetTrinityString(LANG_FACTION_ATWAR);
+ if (factionState->Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if (factionState->Flags & FACTION_FLAG_HIDDEN)
+ ss << handler->GetTrinityString(LANG_FACTION_HIDDEN);
+ if (factionState->Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if (factionState->Flags & FACTION_FLAG_INACTIVE)
+ ss << handler->GetTrinityString(LANG_FACTION_INACTIVE);
+ }
+ else
+ ss << handler->GetTrinityString(LANG_FACTION_NOREPUTATION);
- handler->SendSysMessage(ss.str().c_str());
+ handler->SendSysMessage(ss.str().c_str());
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
@@ -498,45 +461,27 @@ public:
ItemSetEntry const* set = sItemSetStore.LookupEntry(id);
if (set)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = set->name[locale];
+ std::string name = set->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = set->name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
+ if (maxResults && count++ == maxResults)
{
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- // send item set in "id - [namedlink locale]" format
- if (handler->GetSession())
- handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), localeNames[locale]);
- else
- handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), localeNames[locale]);
+ // send item set in "id - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_ITEMSET_LIST_CHAT, id, id, name.c_str(), "");
+ else
+ handler->PSendSysMessage(LANG_ITEMSET_LIST_CONSOLE, id, name.c_str(), "");
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
if (!found)
@@ -779,59 +724,41 @@ public:
SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id);
if (skillInfo)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = skillInfo->name[locale];
+ std::string name = skillInfo->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = skillInfo->name[locale];
- if (name.empty())
- continue;
+ continue;
- if (Utf8FitTo(name, wNamePart))
- break;
- }
+ if (maxResults && count++ == maxResults)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
}
- if (locale < TOTAL_LOCALES)
+ char valStr[50] = "";
+ char const* knownStr = "";
+ if (target && target->HasSkill(id))
{
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
-
- char valStr[50] = "";
- char const* knownStr = "";
- if (target && target->HasSkill(id))
- {
- knownStr = handler->GetTrinityString(LANG_KNOWN);
- uint32 curValue = target->GetPureSkillValue(id);
- uint32 maxValue = target->GetPureMaxSkillValue(id);
- uint32 permValue = target->GetSkillPermBonusValue(id);
- uint32 tempValue = target->GetSkillTempBonusValue(id);
-
- char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES);
- snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue);
- }
+ knownStr = handler->GetTrinityString(LANG_KNOWN);
+ uint32 curValue = target->GetPureSkillValue(id);
+ uint32 maxValue = target->GetPureMaxSkillValue(id);
+ uint32 permValue = target->GetSkillPermBonusValue(id);
+ uint32 tempValue = target->GetSkillTempBonusValue(id);
+
+ char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES);
+ snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue);
+ }
- // send skill in "id - [namedlink locale]" format
- if (handler->GetSession())
- handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), localeNames[locale], knownStr, valStr);
- else
- handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), localeNames[locale], knownStr, valStr);
+ // send skill in "id - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), "", knownStr, valStr);
+ else
+ handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), "", knownStr, valStr);
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
if (!found)
@@ -867,83 +794,63 @@ public:
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id);
if (spellInfo)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = spellInfo->SpellName[locale];
+ std::string name = spellInfo->SpellName;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
+ continue;
+
+ if (maxResults && count++ == maxResults)
{
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- name = spellInfo->SpellName[locale];
- if (name.empty())
- continue;
+ bool known = target && target->HasSpell(id);
+ bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
- if (locale < TOTAL_LOCALES)
- {
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ uint32 talentCost = GetTalentSpellCost(id);
- bool known = target && target->HasSpell(id);
- bool learn = (spellInfo->Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL);
+ bool talent = (talentCost > 0);
+ bool passive = spellInfo->IsPassive();
+ bool active = target && target->HasAura(id);
- SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
+ // unit32 used to prevent interpreting uint8 as char at output
+ // find rank of learned spell for learning spell, or talent rank
+ uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
- uint32 talentCost = GetTalentSpellCost(id);
+ // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
+ else
+ ss << id << " - " << name;
- bool talent = (talentCost > 0);
- bool passive = spellInfo->IsPassive();
- bool active = target && target->HasAura(id);
+ // include rank in link name
+ if (rank)
+ ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
- // unit32 used to prevent interpreting uint8 as char at output
- // find rank of learned spell for learning spell, or talent rank
- uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
+ if (handler->GetSession())
+ ss << "]|h|r";
- // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
- std::ostringstream ss;
- if (handler->GetSession())
- ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
- else
- ss << id << " - " << name;
-
- // include rank in link name
- if (rank)
- ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
-
- if (handler->GetSession())
- ss << ' ' << localeNames[locale] << "]|h|r";
- else
- ss << ' ' << localeNames[locale];
-
- if (talent)
- ss << handler->GetTrinityString(LANG_TALENT);
- if (passive)
- ss << handler->GetTrinityString(LANG_PASSIVE);
- if (learn)
- ss << handler->GetTrinityString(LANG_LEARN);
- if (known)
- ss << handler->GetTrinityString(LANG_KNOWN);
- if (active)
- ss << handler->GetTrinityString(LANG_ACTIVE);
+ if (talent)
+ ss << handler->GetTrinityString(LANG_TALENT);
+ if (passive)
+ ss << handler->GetTrinityString(LANG_PASSIVE);
+ if (learn)
+ ss << handler->GetTrinityString(LANG_LEARN);
+ if (known)
+ ss << handler->GetTrinityString(LANG_KNOWN);
+ if (active)
+ ss << handler->GetTrinityString(LANG_ACTIVE);
- handler->SendSysMessage(ss.str().c_str());
+ handler->SendSysMessage(ss.str().c_str());
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
if (!found)
@@ -965,7 +872,7 @@ public:
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id))
{
int locale = handler->GetSessionDbcLocale();
- std::string name = spellInfo->SpellName[locale];
+ std::string name = spellInfo->SpellName;
if (name.empty())
{
handler->SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
@@ -1046,47 +953,29 @@ public:
TaxiNodesEntry const* nodeEntry = sTaxiNodesStore.LookupEntry(id);
if (nodeEntry)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = nodeEntry->name[locale];
+ std::string name = nodeEntry->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = nodeEntry->name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
+ if (maxResults && count++ == maxResults)
{
- if (maxResults && count++ == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
- if (handler->GetSession())
- handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), localeNames[locale],
- nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
- else
- handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), localeNames[locale],
- nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
+ // send taxinode in "id - [name] (Map:m X:x Y:y Z:z)" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CHAT, id, id, name.c_str(), "",
+ nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
+ else
+ handler->PSendSysMessage(LANG_TAXINODE_ENTRY_LIST_CONSOLE, id, name.c_str(), "",
+ nodeEntry->map_id, nodeEntry->x, nodeEntry->y, nodeEntry->z);
- if (!found)
- found = true;
- }
+ if (!found)
+ found = true;
}
}
if (!found)
@@ -1183,53 +1072,35 @@ public:
CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
if (titleInfo)
{
- int locale = handler->GetSessionDbcLocale();
- std::string name = titleInfo->name[locale];
+ std::string name = titleInfo->name;
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- {
- locale = 0;
- for (; locale < TOTAL_LOCALES; ++locale)
- {
- if (locale == handler->GetSessionDbcLocale())
- continue;
-
- name = titleInfo->name[locale];
- if (name.empty())
- continue;
-
- if (Utf8FitTo(name, wNamePart))
- break;
- }
- }
+ continue;
- if (locale < TOTAL_LOCALES)
+ if (maxResults && counter == maxResults)
{
- if (maxResults && counter == maxResults)
- {
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
- }
+ 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->bit_index
- ? handler->GetTrinityString(LANG_ACTIVE)
- : "";
+ char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
+ ? 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->bit_index, id, titleNameStr, localeNames[locale], knownStr, activeStr);
- else
- handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, localeNames[locale], knownStr, activeStr);
+ // send title in "id (idx:idx) - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, "", knownStr, activeStr);
+ else
+ handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, titleNameStr, "", knownStr, activeStr);
- ++counter;
- }
+ ++counter;
}
}
if (counter == 0) // if counter == 0 then we found nth
@@ -1260,7 +1131,7 @@ public:
{
if (MapEntry const* mapInfo = sMapStore.LookupEntry(id))
{
- std::string name = mapInfo->name[locale];
+ std::string name = mapInfo->name;
if (name.empty())
continue;
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 6de8a155d01..2be40b03a3d 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -61,7 +61,6 @@ public:
{ "die", rbac::RBAC_PERM_COMMAND_DIE, false, &HandleDieCommand, "", NULL },
{ "dismount", rbac::RBAC_PERM_COMMAND_DISMOUNT, false, &HandleDismountCommand, "", NULL },
{ "distance", rbac::RBAC_PERM_COMMAND_DISTANCE, false, &HandleGetDistanceCommand, "", NULL },
- { "flusharenapoints", rbac::RBAC_PERM_COMMAND_FLUSHARENAPOINTS, false, &HandleFlushArenaPointsCommand, "", NULL },
{ "freeze", rbac::RBAC_PERM_COMMAND_FREEZE, false, &HandleFreezeCommand, "", NULL },
{ "gps", rbac::RBAC_PERM_COMMAND_GPS, false, &HandleGPSCommand, "", NULL },
{ "guid", rbac::RBAC_PERM_COMMAND_GUID, false, &HandleGUIDCommand, "", NULL },
@@ -201,9 +200,9 @@ public:
handler->PSendSysMessage("no VMAP available for area info");
handler->PSendSysMessage(LANG_MAP_POSITION,
- mapId, (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
- zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
- areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ mapId, (mapEntry ? mapEntry->name : "<unknown>"),
+ zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
+ areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
@@ -1343,7 +1342,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 ? atol(maxPureSkill) : targetHasSkill ? target->GetPureMaxSkillValue(skill) : uint16(level);
if (level <= 0 || level > max || max <= 0)
return false;
@@ -1352,7 +1351,7 @@ public:
// add the skill to the player's book with step 1 (which is the first rank, in most cases something
// like 'Apprentice <skill>'.
target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max);
- handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max);
+ handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->name, handler->GetNameLink(target).c_str(), level, max);
return true;
}
@@ -1708,15 +1707,15 @@ public:
AreaTableEntry const* area = GetAreaEntryByAreaID(areaId);
if (area)
{
- areaName = area->area_name[locale];
+ areaName = area->area_name;
AreaTableEntry const* zone = GetAreaEntryByAreaID(area->zone);
if (zone)
- zoneName = zone->area_name[locale];
+ zoneName = zone->area_name;
}
if (target)
- handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name[locale], (!zoneName.empty() ? zoneName.c_str() : "<Unknown>"), (!areaName.empty() ? areaName.c_str() : "<Unknown>"));
+ handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name, (!zoneName.empty() ? zoneName.c_str() : "<Unknown>"), (!areaName.empty() ? areaName.c_str() : "<Unknown>"));
// Output XVII. - XVIX. if they are not empty
if (!guildName.empty())
@@ -2228,12 +2227,6 @@ public:
return true;
}
- static bool HandleFlushArenaPointsCommand(ChatHandler* /*handler*/, char const* /*args*/)
- {
- sArenaTeamMgr->DistributeArenaPoints();
- return true;
- }
-
static bool HandleRepairitemsCommand(ChatHandler* handler, char const* args)
{
Player* target;
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index 61598bf0945..37e7177cbc6 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -1,19 +1,19 @@
/*
- * 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/>.
- */
+* 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/>.
+*/
/**
* @file cs_mmaps.cpp
@@ -46,17 +46,17 @@ public:
static ChatCommand mmapCommandTable[] =
{
{ "loadedtiles", rbac::RBAC_PERM_COMMAND_MMAP_LOADEDTILES, false, &HandleMmapLoadedTilesCommand, "", NULL },
- { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL },
- { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL },
- { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL },
- { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL },
+ { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL },
+ { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL },
+ { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
- { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable },
- { NULL, 0, false, NULL, "", NULL }
+ { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -142,8 +142,8 @@ public:
float const* min = navmesh->getParams()->orig;
float x, y, z;
player->GetPosition(x, y, z);
- float location[VERTEX_SIZE] = {y, z, x};
- float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f};
+ float location[VERTEX_SIZE] = { y, z, x };
+ float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f };
int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index c2d6bf47154..98b1f688867 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -23,6 +23,7 @@ Category: commandscripts
EndScriptData */
#include "Chat.h"
+#include <stdlib.h>
#include "ObjectMgr.h"
#include "Opcodes.h"
#include "Pet.h"
@@ -50,7 +51,6 @@ public:
};
static ChatCommand modifyCommandTable[] =
{
- { "arenapoints", rbac::RBAC_PERM_COMMAND_MODIFY_ARENAPOINTS, false, &HandleModifyArenaCommand, "", NULL },
{ "bit", rbac::RBAC_PERM_COMMAND_MODIFY_BIT, false, &HandleModifyBitCommand, "", NULL },
{ "drunk", rbac::RBAC_PERM_COMMAND_MODIFY_DRUNK, false, &HandleModifyDrunkCommand, "", NULL },
{ "energy", rbac::RBAC_PERM_COMMAND_MODIFY_ENERGY, false, &HandleModifyEnergyCommand, "", NULL },
@@ -963,14 +963,14 @@ public:
target->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP);
target->Mount(mId);
- WorldPacket data(SMSG_FORCE_RUN_SPEED_CHANGE, (8+4+1+4));
+ WorldPacket data(SMSG_MOVE_SET_RUN_SPEED, (8+4+1+4));
data.append(target->GetPackGUID());
data << (uint32)0;
data << (uint8)0; //new 2.1.0
data << float(speed);
target->SendMessageToSet(&data, true);
- data.Initialize(SMSG_FORCE_SWIM_SPEED_CHANGE, (8+4+4));
+ data.Initialize(SMSG_MOVE_SET_SWIM_SPEED, (8+4+4));
data.append(target->GetPackGUID());
data << (uint32)0;
data << float(speed);
@@ -997,19 +997,19 @@ public:
if (handler->HasLowerSecurity(target, 0))
return false;
- int32 moneyToAdd = 0;
+ int64 moneyToAdd = 0;
if (strchr(args, 'g') || strchr(args, 's') || strchr(args, 'c'))
moneyToAdd = MoneyStringToMoney(std::string(args));
else
- moneyToAdd = atoi(args);
+ moneyToAdd = atol(args);
- uint32 targetMoney = target->GetMoney();
+ uint64 targetMoney = target->GetMoney();
if (moneyToAdd < 0)
{
- int32 newmoney = int32(targetMoney) + moneyToAdd;
+ int64 newmoney = int64(targetMoney) + moneyToAdd;
- TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), targetMoney, moneyToAdd, newmoney);
+ TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_CURRENT_MONEY), uint32(targetMoney), int32(moneyToAdd), uint32(newmoney));
if (newmoney <= 0)
{
handler->PSendSysMessage(LANG_YOU_TAKE_ALL_MONEY, handler->GetNameLink(target).c_str());
@@ -1020,31 +1020,32 @@ public:
}
else
{
- if (newmoney > MAX_MONEY_AMOUNT)
+ uint32 moneyToAddMsg = moneyToAdd * -1;
+ if (newmoney > int64(MAX_MONEY_AMOUNT))
newmoney = MAX_MONEY_AMOUNT;
- handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, abs(moneyToAdd), handler->GetNameLink(target).c_str());
+ handler->PSendSysMessage(LANG_YOU_TAKE_MONEY, moneyToAddMsg, handler->GetNameLink(target).c_str());
if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), abs(moneyToAdd));
+ ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_TAKEN, handler->GetNameLink().c_str(), moneyToAddMsg);
target->SetMoney(newmoney);
}
}
else
{
- handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, moneyToAdd, handler->GetNameLink(target).c_str());
+ handler->PSendSysMessage(LANG_YOU_GIVE_MONEY, uint32(moneyToAdd), handler->GetNameLink(target).c_str());
if (handler->needReportToTarget(target))
- ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), moneyToAdd);
+ ChatHandler(target->GetSession()).PSendSysMessage(LANG_YOURS_MONEY_GIVEN, handler->GetNameLink().c_str(), uint32(moneyToAdd));
- if (moneyToAdd >= MAX_MONEY_AMOUNT)
+ if (moneyToAdd >= int64(MAX_MONEY_AMOUNT))
moneyToAdd = MAX_MONEY_AMOUNT;
- if (targetMoney >= uint32(MAX_MONEY_AMOUNT) - moneyToAdd)
+ if (targetMoney >= uint64(MAX_MONEY_AMOUNT) - moneyToAdd)
moneyToAdd -= targetMoney;
target->ModifyMoney(moneyToAdd);
}
- TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_NEW_MONEY), targetMoney, moneyToAdd, target->GetMoney());
+ TC_LOG_DEBUG("misc", handler->GetTrinityString(LANG_NEW_MONEY), uint32(targetMoney), int32(moneyToAdd), uint32(target->GetMoney()));
return true;
}
@@ -1104,7 +1105,7 @@ public:
return true;
}
- static bool HandleModifyHonorCommand (ChatHandler* handler, const char* args)
+ static bool HandleModifyHonorCommand(ChatHandler* handler, const char* args)
{
if (!*args)
return false;
@@ -1123,9 +1124,9 @@ public:
int32 amount = (uint32)atoi(args);
- target->ModifyHonorPoints(amount);
+ target->ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, amount, true, true);
- handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetHonorPoints());
+ handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_HONOR_POINTS, false));
return true;
}
@@ -1233,14 +1234,14 @@ public:
if (factionEntry->reputationListID < 0)
{
- handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name[handler->GetSessionDbcLocale()], factionId);
+ handler->PSendSysMessage(LANG_COMMAND_FACTION_NOREP_ERROR, factionEntry->name, factionId);
handler->SetSentErrorMessage(true);
return false;
}
target->GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false);
target->GetReputationMgr().SendState(target->GetReputationMgr().GetState(factionEntry));
- handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name[handler->GetSessionDbcLocale()], factionId,
+ handler->PSendSysMessage(LANG_COMMAND_MODIFY_REP, factionEntry->name, factionId,
handler->GetNameLink(target).c_str(), target->GetReputationMgr().GetReputation(factionEntry));
return true;
}
@@ -1275,14 +1276,15 @@ public:
uint32 phasemask = (uint32)atoi((char*)args);
Unit* target = handler->getSelectedUnit();
- if (!target)
- target = handler->GetSession()->GetPlayer();
-
- // check online security
- else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0))
- return false;
-
- target->SetPhaseMask(phasemask, true);
+ if (target)
+ {
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask);
+ else
+ target->SetPhaseMask(phasemask, true);
+ }
+ else
+ handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask);
return true;
}
@@ -1299,28 +1301,6 @@ public:
return true;
}
- static bool HandleModifyArenaCommand(ChatHandler* handler, const char* args)
- {
- if (!*args)
- return false;
-
- Player* target = handler->getSelectedPlayer();
- if (!target)
- {
- handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- int32 amount = (uint32)atoi(args);
-
- target->ModifyArenaPoints(amount);
-
- handler->PSendSysMessage(LANG_COMMAND_MODIFY_ARENA, handler->GetNameLink(target).c_str(), target->GetArenaPoints());
-
- return true;
- }
-
static bool HandleModifyGenderCommand(ChatHandler* handler, const char* args)
{
if (!*args)
@@ -1396,6 +1376,33 @@ public:
return true;
}
+
+ static bool HandleModifyCurrencyCommand(ChatHandler* handler, const char* args)
+ {
+ if (!*args)
+ return false;
+
+ Player* target = handler->getSelectedPlayer();
+ if (!target)
+ {
+ handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ uint32 currencyId = atoi(strtok((char*)args, " "));
+ const CurrencyTypesEntry* currencyType = sCurrencyTypesStore.LookupEntry(currencyId);
+ if (!currencyType)
+ return false;
+
+ uint32 amount = atoi(strtok(NULL, " "));
+ if (!amount)
+ return false;
+
+ target->ModifyCurrency(currencyId, amount, true, true);
+
+ return true;
+ }
};
void AddSC_modify_commandscript()
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index a5b13301403..9bfa4f0334f 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -105,7 +105,8 @@ EnumName<Mechanics> const mechanicImmunes[MAX_MECHANIC] =
CREATE_NAMED_ENUM(MECHANIC_DISCOVERY),
CREATE_NAMED_ENUM(MECHANIC_IMMUNE_SHIELD),
CREATE_NAMED_ENUM(MECHANIC_SAPPED),
- CREATE_NAMED_ENUM(MECHANIC_ENRAGED)
+ CREATE_NAMED_ENUM(MECHANIC_ENRAGED),
+ CREATE_NAMED_ENUM(MECHANIC_WOUNDED)
};
EnumName<UnitFlags> const unitFlags[MAX_UNIT_FLAGS] =
@@ -250,7 +251,7 @@ public:
uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT);
CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid);
data.id = id;
- data.phaseMask = chr->GetPhaseMaskForSpawn();
+ data.phaseMask = chr->GetPhaseMgr().GetPhaseMaskForSpawn();
data.posX = chr->GetTransOffsetX();
data.posY = chr->GetTransOffsetY();
data.posZ = chr->GetTransOffsetZ();
@@ -258,20 +259,20 @@ public:
Creature* creature = trans->CreateNPCPassenger(guid, &data);
- creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMaskForSpawn());
+ creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
sObjectMgr->AddCreatureToGrid(guid, &data);
return true;
}
Creature* creature = new Creature();
- if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
+ if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
{
delete creature;
return false;
}
- creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
uint32 db_guid = creature->GetDBTableGUIDLow();
@@ -296,6 +297,8 @@ public:
if (!*args)
return false;
+ const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
+
char* pitem = handler->extractKeyFromLink((char*)args, "Hitem");
if (!pitem)
{
@@ -332,13 +335,13 @@ public:
uint32 vendor_entry = vendor->GetEntry();
- if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, handler->GetSession()->GetPlayer()))
+ if (!sObjectMgr->IsVendorItemValid(vendor_entry, itemId, maxcount, incrtime, extendedcost, type, handler->GetSession()->GetPlayer()))
{
handler->SetSentErrorMessage(true);
return false;
}
- sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost);
+ sObjectMgr->AddVendorItem(vendor_entry, itemId, maxcount, incrtime, extendedcost, type);
ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
@@ -553,7 +556,9 @@ public:
}
uint32 itemId = atol(pitem);
- if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId))
+ const uint8 type = 1; // FIXME: make type (1 item, 2 currency) an argument
+
+ if (!sObjectMgr->RemoveVendorItem(vendor->GetEntry(), itemId, type))
{
handler->PSendSysMessage(LANG_ITEM_NOT_IN_LIST, itemId);
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 7e759a788f5..4b2b0480a72 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -100,7 +100,6 @@ public:
{ "gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION, true, &HandleReloadGossipMenuOptionCommand, "", NULL },
{ "item_enchantment_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_ENCHANTMENT_TEMPLATE, true, &HandleReloadItemEnchantementsCommand, "", NULL },
{ "item_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesItemCommand, "", NULL },
- { "item_set_names", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_SET_NAMES, true, &HandleReloadItemSetNamesCommand, "", NULL },
{ "lfg_dungeon_rewards", rbac::RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS, true, &HandleReloadLfgRewardsCommand, "", NULL },
{ "locales_achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD, true, &HandleReloadLocalesAchievementRewardCommand, "", NULL },
{ "locales_creature", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE, true, &HandleReloadLocalesCreatureCommand, "", NULL },
@@ -108,7 +107,6 @@ public:
{ "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "", NULL },
{ "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "", NULL },
{ "locales_item", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM, true, &HandleReloadLocalesItemCommand, "", NULL },
- { "locales_item_set_name", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ITEM_SET_NAME, true, &HandleReloadLocalesItemSetNameCommand, "", NULL },
{ "locales_npc_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_NPC_TEXT, true, &HandleReloadLocalesNpcTextCommand, "", NULL },
{ "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "", NULL },
{ "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "", NULL },
@@ -430,11 +428,12 @@ public:
Field* fields = result->Fetch();
- cInfo->DifficultyEntry[0] = fields[0].GetUInt32();
- cInfo->DifficultyEntry[1] = fields[1].GetUInt32();
- cInfo->DifficultyEntry[2] = fields[2].GetUInt32();
- cInfo->KillCredit[0] = fields[3].GetUInt32();
- cInfo->KillCredit[1] = fields[4].GetUInt32();
+ for (uint8 i = 0; i < MAX_DIFFICULTY - 1; ++i)
+ cInfo->DifficultyEntry[i] = fields[0 + i].GetUInt32();
+
+ for (uint8 i = 0; i < MAX_KILL_CREDIT; ++i)
+ cInfo->KillCredit[i] = fields[3 + i].GetUInt32();
+
cInfo->Modelid1 = fields[5].GetUInt32();
cInfo->Modelid2 = fields[6].GetUInt32();
cInfo->Modelid3 = fields[7].GetUInt32();
@@ -446,27 +445,27 @@ public:
cInfo->minlevel = fields[13].GetUInt8();
cInfo->maxlevel = fields[14].GetUInt8();
cInfo->expansion = fields[15].GetUInt16();
- cInfo->faction_A = fields[16].GetUInt16();
- cInfo->faction_H = fields[17].GetUInt16();
- cInfo->npcflag = fields[18].GetUInt32();
- cInfo->speed_walk = fields[19].GetFloat();
- cInfo->speed_run = fields[20].GetFloat();
- cInfo->scale = fields[21].GetFloat();
- cInfo->rank = fields[22].GetUInt8();
- cInfo->mindmg = fields[23].GetFloat();
- cInfo->maxdmg = fields[24].GetFloat();
- cInfo->dmgschool = fields[25].GetUInt8();
- cInfo->attackpower = fields[26].GetUInt32();
- cInfo->dmg_multiplier = fields[27].GetFloat();
- cInfo->baseattacktime = fields[28].GetUInt32();
- cInfo->rangeattacktime = fields[29].GetUInt32();
- cInfo->unit_class = fields[30].GetUInt8();
- cInfo->unit_flags = fields[31].GetUInt32();
- cInfo->unit_flags2 = fields[32].GetUInt32();
- cInfo->dynamicflags = fields[33].GetUInt32();
- cInfo->family = fields[34].GetUInt8();
- cInfo->trainer_type = fields[35].GetUInt8();
- cInfo->trainer_spell = fields[36].GetUInt32();
+ cInfo->expansionUnknown = fields[16].GetUInt16();
+ cInfo->faction_A = fields[17].GetUInt16();
+ cInfo->faction_H = fields[18].GetUInt16();
+ cInfo->npcflag = fields[19].GetUInt32();
+ cInfo->speed_walk = fields[20].GetFloat();
+ cInfo->speed_run = fields[21].GetFloat();
+ cInfo->scale = fields[22].GetFloat();
+ cInfo->rank = fields[23].GetUInt8();
+ cInfo->mindmg = fields[24].GetFloat();
+ cInfo->maxdmg = fields[25].GetFloat();
+ cInfo->dmgschool = fields[26].GetUInt8();
+ cInfo->attackpower = fields[27].GetUInt32();
+ cInfo->dmg_multiplier = fields[28].GetFloat();
+ cInfo->baseattacktime = fields[29].GetUInt32();
+ cInfo->rangeattacktime = fields[30].GetUInt32();
+ cInfo->unit_class = fields[31].GetUInt8();
+ cInfo->unit_flags = fields[32].GetUInt32();
+ cInfo->unit_flags2 = fields[33].GetUInt32();
+ cInfo->dynamicflags = fields[34].GetUInt32();
+ cInfo->family = fields[35].GetUInt8();
+ cInfo->trainer_type = fields[36].GetUInt8();
cInfo->trainer_class = fields[37].GetUInt8();
cInfo->trainer_race = fields[38].GetUInt8();
cInfo->minrangedmg = fields[39].GetFloat();
@@ -474,44 +473,39 @@ public:
cInfo->rangedattackpower = fields[41].GetUInt16();
cInfo->type = fields[42].GetUInt8();
cInfo->type_flags = fields[43].GetUInt32();
- cInfo->lootid = fields[44].GetUInt32();
- cInfo->pickpocketLootId = fields[45].GetUInt32();
- cInfo->SkinLootId = fields[46].GetUInt32();
+ cInfo->type_flags2 = fields[44].GetUInt32();
+ cInfo->lootid = fields[45].GetUInt32();
+ cInfo->pickpocketLootId = fields[46].GetUInt32();
+ cInfo->SkinLootId = fields[47].GetUInt32();
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- cInfo->resistance[i] = fields[47 + i -1].GetUInt16();
-
- cInfo->spells[0] = fields[53].GetUInt32();
- cInfo->spells[1] = fields[54].GetUInt32();
- cInfo->spells[2] = fields[55].GetUInt32();
- cInfo->spells[3] = fields[56].GetUInt32();
- cInfo->spells[4] = fields[57].GetUInt32();
- cInfo->spells[5] = fields[58].GetUInt32();
- cInfo->spells[6] = fields[59].GetUInt32();
- cInfo->spells[7] = fields[60].GetUInt32();
- cInfo->PetSpellDataId = fields[61].GetUInt32();
- cInfo->VehicleId = fields[62].GetUInt32();
- cInfo->mingold = fields[63].GetUInt32();
- cInfo->maxgold = fields[64].GetUInt32();
- cInfo->AIName = fields[65].GetString();
- cInfo->MovementType = fields[66].GetUInt8();
- cInfo->InhabitType = fields[67].GetUInt8();
- cInfo->HoverHeight = fields[68].GetFloat();
- cInfo->ModHealth = fields[69].GetFloat();
- cInfo->ModMana = fields[70].GetFloat();
- cInfo->ModArmor = fields[71].GetFloat();
- cInfo->RacialLeader = fields[72].GetBool();
- cInfo->questItems[0] = fields[73].GetUInt32();
- cInfo->questItems[1] = fields[74].GetUInt32();
- cInfo->questItems[2] = fields[75].GetUInt32();
- cInfo->questItems[3] = fields[76].GetUInt32();
- cInfo->questItems[4] = fields[77].GetUInt32();
- cInfo->questItems[5] = fields[78].GetUInt32();
- cInfo->movementId = fields[79].GetUInt32();
- cInfo->RegenHealth = fields[80].GetBool();
- cInfo->MechanicImmuneMask = fields[81].GetUInt32();
- cInfo->flags_extra = fields[82].GetUInt32();
- cInfo->ScriptID = sObjectMgr->GetScriptId(fields[83].GetCString());
+ cInfo->resistance[i] = fields[48 + i -1].GetUInt16();
+
+ for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ cInfo->spells[i] = fields[54 + i].GetUInt32();
+
+ cInfo->PetSpellDataId = fields[62].GetUInt32();
+ cInfo->VehicleId = fields[63].GetUInt32();
+ cInfo->mingold = fields[64].GetUInt32();
+ cInfo->maxgold = fields[65].GetUInt32();
+ cInfo->AIName = fields[66].GetString();
+ cInfo->MovementType = fields[67].GetUInt8();
+ cInfo->InhabitType = fields[68].GetUInt8();
+ cInfo->HoverHeight = fields[69].GetFloat();
+ cInfo->ModHealth = fields[70].GetFloat();
+ cInfo->ModMana = fields[71].GetFloat();
+ cInfo->ModManaExtra = fields[72].GetFloat();
+ cInfo->ModArmor = fields[73].GetFloat();
+ cInfo->RacialLeader = fields[74].GetBool();
+
+ for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i)
+ cInfo->questItems[i] = fields[75 + i].GetUInt32();
+
+ cInfo->movementId = fields[81].GetUInt32();
+ cInfo->RegenHealth = fields[82].GetBool();
+ cInfo->MechanicImmuneMask = fields[83].GetUInt32();
+ cInfo->flags_extra = fields[84].GetUInt32();
+ cInfo->ScriptID = sObjectMgr->GetScriptId(fields[85].GetCString());
sObjectMgr->CheckCreatureTemplate(cInfo);
}
@@ -941,14 +935,6 @@ public:
return true;
}
- static bool HandleReloadItemSetNamesCommand(ChatHandler* handler, const char* /*args*/)
- {
- TC_LOG_INFO("misc", "Re-Loading Item set names...");
- sObjectMgr->LoadItemSetNames();
- handler->SendGlobalGMSysMessage("DB table `item_set_names` reloaded.");
- return true;
- }
-
static bool HandleReloadEventScriptsCommand(ChatHandler* handler, const char* args)
{
if (sScriptMgr->IsScriptScheduled())
@@ -1118,14 +1104,6 @@ public:
return true;
}
- static bool HandleReloadLocalesItemSetNameCommand(ChatHandler* handler, const char* /*args*/)
- {
- TC_LOG_INFO("misc", "Re-Loading Locales Item set name... ");
- sObjectMgr->LoadItemSetNameLocales();
- handler->SendGlobalGMSysMessage("DB table `locales_item_set_name` reloaded.");
- return true;
- }
-
static bool HandleReloadLocalesNpcTextCommand(ChatHandler* handler, const char* /*args*/)
{
TC_LOG_INFO("misc", "Re-Loading Locales NPC Text ... ");
@@ -1216,6 +1194,16 @@ public:
return true;
}
+
+ static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/)
+ {
+ TC_LOG_INFO("misc", "Reloading phase_definitions table...");
+ sObjectMgr->LoadPhaseDefinitions();
+ sWorld->UpdatePhaseDefinitions();
+ handler->SendGlobalGMSysMessage("Phase Definitions reloaded.");
+ return true;
+ }
+
static bool HandleReloadRBACCommand(ChatHandler* handler, const char* /*args*/)
{
TC_LOG_INFO("misc", "Reloading RBAC tables...");
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index 4299e690989..2251677bd57 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -66,7 +66,7 @@ public:
if (target)
target->ResetAchievements();
else
- AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid));
+ AchievementMgr<Player>::DeleteFromDB(GUID_LOPART(targetGuid));
return true;
}
@@ -77,11 +77,8 @@ public:
if (!handler->extractPlayerTarget((char*)args, &target))
return false;
- target->SetHonorPoints(0);
target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
- target->SetUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, 0);
- target->SetUInt32Value(PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0);
target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
return true;
@@ -233,7 +230,7 @@ public:
if (target)
{
- target->resetTalents(true);
+ target->ResetTalents(true);
target->SendTalentsInfoData(false);
ChatHandler(target->GetSession()).SendSysMessage(LANG_RESET_TALENTS);
if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)
diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp
index 20bffdbb792..bed09cf3c22 100644
--- a/src/server/scripts/Commands/cs_titles.cpp
+++ b/src/server/scripts/Commands/cs_titles.cpp
@@ -96,7 +96,7 @@ public:
target->SetTitle(titleInfo); // to be sure that title now known
target->SetUInt32Value(PLAYER_CHOSEN_TITLE, titleInfo->bit_index);
- handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, titleInfo->name[handler->GetSessionDbcLocale()], tNameLink.c_str());
+ handler->PSendSysMessage(LANG_TITLE_CURRENT_RES, id, titleInfo->name, tNameLink.c_str());
return true;
}
@@ -139,7 +139,7 @@ public:
std::string tNameLink = handler->GetNameLink(target);
char titleNameStr[80];
- snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], target->GetName().c_str());
+ snprintf(titleNameStr, 80, titleInfo->name, target->GetName().c_str());
target->SetTitle(titleInfo);
handler->PSendSysMessage(LANG_TITLE_ADD_RES, id, titleNameStr, tNameLink.c_str());
@@ -187,7 +187,7 @@ public:
std::string tNameLink = handler->GetNameLink(target);
char titleNameStr[80];
- snprintf(titleNameStr, 80, titleInfo->name[handler->GetSessionDbcLocale()], target->GetName().c_str());
+ snprintf(titleNameStr, 80, titleInfo->name, target->GetName().c_str());
handler->PSendSysMessage(LANG_TITLE_REMOVE_RES, id, titleNameStr, tNameLink.c_str());
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index 9b20383e94a..041823896ba 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -241,40 +241,44 @@ public:
if (!target)
{
- handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select target.");
+ handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select a target.");
return true;
}
- uint32 guildLow = target->GetDBTableGUIDLow();
+ uint32 guidLow = target->GetDBTableGUIDLow();
+ if (guidLow == 0)
+ {
+ handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target is not saved to DB.");
+ return true;
+ }
- if (target->GetCreatureAddon())
+ CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(guidLow);
+ if (!addon || addon->path_id == 0)
{
- if (target->GetCreatureAddon()->path_id != 0)
- {
- PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
+ handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target does not have a loaded path.");
+ return true;
+ }
- stmt->setUInt32(0, guildLow);
+ PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
- WorldDatabase.Execute(stmt);
+ stmt->setUInt32(0, guidLow);
+
+ WorldDatabase.Execute(stmt);
- target->UpdateWaypointID(0);
+ target->UpdateWaypointID(0);
- stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
+ stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
- stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE));
- stmt->setUInt32(1, guildLow);
+ stmt->setUInt8(0, uint8(IDLE_MOTION_TYPE));
+ stmt->setUInt32(1, guidLow);
- WorldDatabase.Execute(stmt);
+ WorldDatabase.Execute(stmt);
- target->LoadPath(0);
- target->SetDefaultMovementType(IDLE_MOTION_TYPE);
- target->GetMotionMaster()->MoveTargetedHome();
- target->GetMotionMaster()->Initialize();
- target->MonsterSay("Path unloaded.", LANG_UNIVERSAL, NULL);
- return true;
- }
- handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target have no loaded path.");
- }
+ target->LoadPath(0);
+ target->SetDefaultMovementType(IDLE_MOTION_TYPE);
+ target->GetMotionMaster()->MoveTargetedHome();
+ target->GetMotionMaster()->Initialize();
+ target->MonsterSay("Path unloaded.", LANG_UNIVERSAL, NULL);
return true;
}
@@ -690,7 +694,7 @@ public:
}
// re-create
Creature* wpCreature2 = new Creature();
- if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
+ if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
@@ -698,7 +702,7 @@ public:
return false;
}
- wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
/// @todo Should we first use "Create" then use "LoadFromDB"?
if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map))
@@ -914,7 +918,7 @@ public:
float o = chr->GetOrientation();
Creature* wpCreature = new Creature();
- if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete wpCreature;
@@ -930,7 +934,7 @@ public:
WorldDatabase.Execute(stmt);
- wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map))
{
@@ -978,14 +982,14 @@ public:
Map* map = chr->GetMap();
Creature* creature = new Creature();
- if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete creature;
return false;
}
- creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
@@ -1027,14 +1031,14 @@ public:
Map* map = chr->GetMap();
Creature* creature = new Creature();
- if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
+ if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
delete creature;
return false;
}
- creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
+ creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h b/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h
new file mode 100644
index 00000000000..22df3858c43
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/baradin_hold.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2008-2013 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 3 of the License, or (at your
+* option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License along
+* with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef DEF_BARADIN_HOLD_H_
+#define DEF_BARADIN_HOLD_H_
+
+#include "Map.h"
+#include "Creature.h"
+#include "ObjectMgr.h"
+
+#define BHScriptName "instance_baradin_hold"
+
+uint32 const EncounterCount = 3;
+
+enum DataTypes
+{
+ DATA_ARGALOTH = 0,
+ DATA_OCCUTHAR = 1,
+ DATA_ALIZABAL = 2
+};
+
+enum CreatureIds
+{
+ BOSS_ARGALOTH = 47120,
+ BOSS_OCCUTHAR = 52363,
+ BOSS_ALIZABAL = 55869,
+
+ NPC_EYE_OF_OCCUTHAR = 52389,
+ NPC_FOCUS_FIRE_DUMMY = 52369,
+ NPC_OCCUTHAR_EYE = 52368
+};
+
+enum GameObjectIds
+{
+ GO_ARGALOTH_DOOR = 207619,
+ GO_OCCUTHAR_DOOR = 208953,
+ GO_ALIZABAL_DOOR = 209849
+};
+
+template<class AI>
+CreatureAI* GetBaradinHoldAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(BHScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
+#endif
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp
new file mode 100644
index 00000000000..e80a1e37bb0
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_alizabal.cpp
@@ -0,0 +1,270 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "Player.h"
+#include "ObjectAccessor.h"
+#include "baradin_hold.h"
+
+enum Texts
+{
+ SAY_INTRO = 1,
+ SAY_AGGRO = 2,
+ SAY_HATE = 3,
+ SAY_SKEWER = 4,
+ SAY_SKEWER_ANNOUNCE = 5,
+ SAY_BLADE_STORM = 6,
+ SAY_SLAY = 10,
+ SAY_DEATH = 12
+};
+
+enum Spells
+{
+ SPELL_BLADE_DANCE = 105784,
+ SPELL_BLADE_DANCE_DUMMY = 105828,
+ SPELL_SEETHING_HATE = 105067,
+ SPELL_SKEWER = 104936,
+ SPELL_BERSERK = 47008
+};
+
+enum Actions
+{
+ ACTION_INTRO = 1
+};
+
+ enum Points
+{
+ POINT_STORM = 1
+};
+
+enum Events
+{
+ EVENT_RANDOM_CAST = 1,
+ EVENT_STOP_STORM = 2,
+ EVENT_MOVE_STORM = 3,
+ EVENT_CAST_STORM = 4
+};
+
+class at_alizabal_intro : public AreaTriggerScript
+{
+ public:
+ at_alizabal_intro() : AreaTriggerScript("at_alizabal_intro") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/)
+ {
+ if (InstanceScript* instance = player->GetInstanceScript())
+ if (Creature* alizabal = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_ALIZABAL)))
+ alizabal->AI()->DoAction(ACTION_INTRO);
+ return true;
+ }
+};
+
+class boss_alizabal : public CreatureScript
+{
+ public:
+ boss_alizabal() : CreatureScript("boss_alizabal") { }
+
+ struct boss_alizabalAI : public BossAI
+ {
+ boss_alizabalAI(Creature* creature) : BossAI(creature, DATA_ALIZABAL)
+ {
+ _intro = false;
+ }
+
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ _hate = false;
+ _skewer = false;
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
+ events.ScheduleEvent(EVENT_RANDOM_CAST, 10000);
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
+
+ void KilledUnit(Unit* who) OVERRIDE
+ {
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ me->GetMotionMaster()->MoveTargetedHome();
+ _DespawnAtEvade();
+ }
+
+ void DoAction(int32 action) OVERRIDE
+ {
+ switch (action)
+ {
+ case ACTION_INTRO:
+ if (!_intro)
+ {
+ Talk(SAY_INTRO);
+ _intro = true;
+ }
+ break;
+ }
+ }
+
+ void MovementInform(uint32 /*type*/, uint32 pointId) OVERRIDE
+ {
+ switch (pointId)
+ {
+ case POINT_STORM:
+ events.ScheduleEvent(EVENT_CAST_STORM, 1);
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RANDOM_CAST:
+ switch (urand(0, 1))
+ {
+ case 0:
+ if (!_skewer)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0))
+ {
+ DoCast(target, SPELL_SKEWER, true);
+ Talk(SAY_SKEWER);
+ Talk(SAY_SKEWER_ANNOUNCE, target);
+ }
+ _skewer = true;
+ events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000));
+ }
+ else if (!_hate)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ {
+ DoCast(target, SPELL_SEETHING_HATE, true);
+ Talk(SAY_HATE);
+ }
+ _hate = true;
+ events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000));
+ }
+ else if (_hate && _skewer)
+ {
+ Talk(SAY_BLADE_STORM);
+ DoCastAOE(SPELL_BLADE_DANCE_DUMMY);
+ DoCastAOE(SPELL_BLADE_DANCE);
+ events.ScheduleEvent(EVENT_RANDOM_CAST, 21000);
+ events.ScheduleEvent(EVENT_MOVE_STORM, 4050);
+ events.ScheduleEvent(EVENT_STOP_STORM, 13000);
+ }
+ break;
+ case 1:
+ if (!_hate)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ {
+ DoCast(target, SPELL_SEETHING_HATE, true);
+ Talk(SAY_HATE);
+ }
+ _hate = true;
+ events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000));
+ }
+ else if (!_skewer)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0))
+ {
+ DoCast(target, SPELL_SKEWER, true);
+ Talk(SAY_SKEWER);
+ Talk(SAY_SKEWER_ANNOUNCE, target);
+ }
+ _skewer = true;
+ events.ScheduleEvent(EVENT_RANDOM_CAST, urand(7000, 10000));
+ }
+ else if (_hate && _skewer)
+ {
+ Talk(SAY_BLADE_STORM);
+ DoCastAOE(SPELL_BLADE_DANCE_DUMMY);
+ DoCastAOE(SPELL_BLADE_DANCE);
+ events.ScheduleEvent(EVENT_RANDOM_CAST, 21000);
+ events.ScheduleEvent(EVENT_MOVE_STORM, 4050);
+ events.ScheduleEvent(EVENT_STOP_STORM, 13000);
+ }
+ break;
+ }
+ break;
+ case EVENT_MOVE_STORM:
+ me->SetSpeed(MOVE_RUN, 4.0f);
+ me->SetSpeed(MOVE_WALK, 4.0f);
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me)))
+ me->GetMotionMaster()->MovePoint(POINT_STORM, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
+ events.ScheduleEvent(EVENT_MOVE_STORM, 4050);
+ break;
+ case EVENT_STOP_STORM:
+ me->RemoveAura(SPELL_BLADE_DANCE);
+ me->RemoveAura(SPELL_BLADE_DANCE_DUMMY);
+ me->SetSpeed(MOVE_WALK, 1.0f);
+ me->SetSpeed(MOVE_RUN, 1.14f);
+ me->GetMotionMaster()->MoveChase(me->GetVictim());
+ _hate = false;
+ _skewer = false;
+ break;
+ case EVENT_CAST_STORM:
+ DoCastAOE(SPELL_BLADE_DANCE);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ bool _intro;
+ bool _hate;
+ bool _skewer;
+
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetBaradinHoldAI<boss_alizabalAI>(creature);
+ }
+};
+
+void AddSC_boss_alizabal()
+{
+ new boss_alizabal();
+ new at_alizabal_intro();
+}
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp
new file mode 100644
index 00000000000..fbd7ec6bc6e
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_occuthar.cpp
@@ -0,0 +1,393 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "Vehicle.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "baradin_hold.h"
+
+enum Spells
+{
+ SPELL_SEARING_SHADOWS = 96913,
+ SPELL_FOCUSED_FIRE_FIRST_DAMAGE = 97212,
+ SPELL_FOCUSED_FIRE_TRIGGER = 96872,
+ SPELL_FOCUSED_FIRE_VISUAL = 96886,
+ SPELL_FOCUSED_FIRE = 96884,
+ SPELL_EYES_OF_OCCUTHAR = 96920,
+ SPELL_GAZE_OF_OCCUTHAR = 96942,
+ SPELL_OCCUTHARS_DESTUCTION = 96968,
+ SPELL_BERSERK = 47008
+};
+
+enum Events
+{
+ EVENT_SEARING_SHADOWS = 1,
+ EVENT_FOCUSED_FIRE = 2,
+ EVENT_EYES_OF_OCCUTHAR = 3,
+ EVENT_BERSERK = 4,
+
+ EVENT_FOCUSED_FIRE_FIRST_DAMAGE = 1
+};
+
+enum Misc
+{
+ MAX_OCCUTHAR_VEHICLE_SEATS = 7
+};
+
+class boss_occuthar : public CreatureScript
+{
+ public:
+ boss_occuthar() : CreatureScript("boss_occuthar") { }
+
+ struct boss_occutharAI : public BossAI
+ {
+ boss_occutharAI(Creature* creature) : BossAI(creature, DATA_OCCUTHAR),
+ _vehicle(me->GetVehicleKit())
+ {
+ ASSERT(_vehicle);
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
+ events.ScheduleEvent(EVENT_SEARING_SHADOWS, 8 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 30 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_BERSERK, 5 * MINUTE * IN_MILLISECONDS);
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ BossAI::EnterEvadeMode();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _DespawnAtEvade();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
+
+ void JustSummoned(Creature* summon) OVERRIDE
+ {
+ summons.Summon(summon);
+
+ if (summon->GetEntry() == NPC_FOCUS_FIRE_DUMMY)
+ {
+ DoCast(summon, SPELL_FOCUSED_FIRE);
+
+ for (uint8 i = 0; i < MAX_OCCUTHAR_VEHICLE_SEATS; ++i)
+ {
+ if (Unit* vehicle = _vehicle->GetPassenger(i))
+ vehicle->CastSpell(summon, SPELL_FOCUSED_FIRE_VISUAL);
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SEARING_SHADOWS:
+ DoCastAOE(SPELL_SEARING_SHADOWS);
+ events.ScheduleEvent(EVENT_SEARING_SHADOWS, 25 * IN_MILLISECONDS);
+ break;
+ case EVENT_FOCUSED_FIRE:
+ DoCastAOE(SPELL_FOCUSED_FIRE_TRIGGER, true);
+ events.ScheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS);
+ break;
+ case EVENT_EYES_OF_OCCUTHAR:
+ DoCastAOE(SPELL_EYES_OF_OCCUTHAR);
+ events.RescheduleEvent(EVENT_FOCUSED_FIRE, 15 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_EYES_OF_OCCUTHAR, 60 * IN_MILLISECONDS);
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK, true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ Vehicle* _vehicle;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetBaradinHoldAI<boss_occutharAI>(creature);
+ }
+};
+
+class npc_eyestalk : public CreatureScript
+{
+ public:
+ npc_eyestalk() : CreatureScript("npc_eyestalk") { }
+
+ struct npc_eyestalkAI : public ScriptedAI
+ {
+ npc_eyestalkAI(Creature* creature) : ScriptedAI(creature),
+ _instance(creature->GetInstanceScript())
+ {
+ _damageCount = 0;
+ }
+
+ void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
+ {
+ // player is the spellcaster so register summon manually
+ if (Creature* occuthar = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_OCCUTHAR)))
+ occuthar->AI()->JustSummoned(me);
+ }
+
+ void Reset() OVERRIDE
+ {
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 0);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ _events.Update(diff);
+
+ if (_events.ExecuteEvent() == EVENT_FOCUSED_FIRE_FIRST_DAMAGE)
+ {
+ DoCastAOE(SPELL_FOCUSED_FIRE_FIRST_DAMAGE);
+ if (++_damageCount < 2)
+ _events.ScheduleEvent(EVENT_FOCUSED_FIRE_FIRST_DAMAGE, 1 * IN_MILLISECONDS);
+ }
+ }
+
+ void EnterEvadeMode() OVERRIDE { } // Never evade
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ uint8 _damageCount;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetBaradinHoldAI<npc_eyestalkAI>(creature);
+ }
+};
+
+class FocusedFireTargetSelector : public std::unary_function<Unit *, bool>
+{
+ public:
+ FocusedFireTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) { }
+
+ bool operator() (WorldObject* target)
+ {
+ if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)
+ return true;
+
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return true;
+
+ return false;
+ }
+
+ Creature* _me;
+ Unit const* _victim;
+};
+
+// 96872 - Focused Fire
+class spell_occuthar_focused_fire : public SpellScriptLoader
+{
+ public:
+ spell_occuthar_focused_fire() : SpellScriptLoader("spell_occuthar_focused_fire") { }
+
+ class spell_occuthar_focused_fire_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_occuthar_focused_fire_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ targets.remove_if(FocusedFireTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_focused_fire_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_occuthar_focused_fire_SpellScript();
+ }
+};
+
+// ID - 96931 Eyes of Occu'thar
+class spell_occuthar_eyes_of_occuthar : public SpellScriptLoader
+{
+ public:
+ spell_occuthar_eyes_of_occuthar() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar") { }
+
+ class spell_occuthar_eyes_of_occuthar_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_occuthar_eyes_of_occuthar_SpellScript);
+
+ bool Validate(SpellInfo const* spellInfo) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->CastSpell(GetCaster(), GetEffectValue(), true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_occuthar_eyes_of_occuthar_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_occuthar_eyes_of_occuthar_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_occuthar_eyes_of_occuthar_SpellScript();
+ }
+};
+
+// ID - 96932 Eyes of Occu'thar
+class spell_occuthar_eyes_of_occuthar_vehicle : public SpellScriptLoader
+{
+ public:
+ spell_occuthar_eyes_of_occuthar_vehicle() : SpellScriptLoader("spell_occuthar_eyes_of_occuthar_vehicle") { }
+
+ class spell_occuthar_eyes_of_occuthar_vehicle_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript);
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetInstanceScript() != NULL;
+ }
+
+ void HandleScript()
+ {
+ Position pos;
+ GetHitUnit()->GetPosition(&pos);
+
+ if (Creature* occuthar = ObjectAccessor::GetCreature(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_OCCUTHAR)))
+ {
+ if (Creature* creature = occuthar->SummonCreature(NPC_EYE_OF_OCCUTHAR, pos))
+ creature->CastSpell(GetHitUnit(), SPELL_GAZE_OF_OCCUTHAR, false);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterHit += SpellHitFn(spell_occuthar_eyes_of_occuthar_vehicle_SpellScript::HandleScript);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_occuthar_eyes_of_occuthar_vehicle_SpellScript();
+ }
+};
+
+// 96942 / 101009 - Gaze of Occu'thar
+class spell_occuthar_occuthars_destruction : public SpellScriptLoader
+{
+ public:
+ spell_occuthar_occuthars_destruction() : SpellScriptLoader("spell_occuthar_occuthars_destruction") { }
+
+ class spell_occuthar_occuthars_destruction_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_occuthar_occuthars_destruction_AuraScript);
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster() && GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ if (IsExpired())
+ caster->CastSpell((Unit*)NULL, SPELL_OCCUTHARS_DESTUCTION, true, NULL, aurEff);
+
+ caster->ToCreature()->DespawnOrUnsummon(500);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_occuthar_occuthars_destruction_AuraScript::OnRemove, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_occuthar_occuthars_destruction_AuraScript();
+ }
+};
+
+void AddSC_boss_occuthar()
+{
+ new boss_occuthar();
+ new npc_eyestalk();
+ new spell_occuthar_focused_fire();
+ new spell_occuthar_eyes_of_occuthar();
+ new spell_occuthar_eyes_of_occuthar_vehicle();
+ new spell_occuthar_occuthars_destruction();
+}
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
new file mode 100644
index 00000000000..1be012590b5
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
@@ -0,0 +1,200 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "baradin_hold.h"
+
+/* TODO:
+- Fel Firestorm need completion
+- Need Correct timer
+*/
+
+enum Spells
+{
+ SPELL_METEOR_SLASH = 88942,
+ SPELL_CONSUMING_DARKNESS = 88954,
+ SPELL_FEL_FIRESTORM = 88972,
+ SPELL_BERSERK = 47008
+};
+
+enum Events
+{
+ EVENT_METEOR_SLASH = 1,
+ EVENT_CONSUMING_DARKNESS = 2,
+ EVENT_BERSERK = 3
+};
+
+class boss_pit_lord_argaloth : public CreatureScript
+{
+ public:
+ boss_pit_lord_argaloth() : CreatureScript("boss_pit_lord_argaloth") { }
+
+ struct boss_pit_lord_argalothAI : public BossAI
+ {
+ boss_pit_lord_argalothAI(Creature* creature) : BossAI(creature, DATA_ARGALOTH) { }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
+ events.ScheduleEvent(EVENT_METEOR_SLASH, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_BERSERK, 5 * MINUTE * IN_MILLISECONDS);
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ me->GetMotionMaster()->MoveTargetedHome();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _DespawnAtEvade();
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
+ {
+ if (me->HealthBelowPctDamaged(33, damage) ||
+ me->HealthBelowPctDamaged(66, damage))
+ {
+ DoCastAOE(SPELL_FEL_FIRESTORM);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_METEOR_SLASH:
+ DoCastAOE(SPELL_METEOR_SLASH);
+ events.ScheduleEvent(EVENT_METEOR_SLASH, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
+ break;
+ case EVENT_CONSUMING_DARKNESS:
+ DoCastAOE(SPELL_CONSUMING_DARKNESS, true);
+ events.ScheduleEvent(EVENT_CONSUMING_DARKNESS, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
+ break;
+ case EVENT_BERSERK:
+ DoCast(me, SPELL_BERSERK, true);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetBaradinHoldAI<boss_pit_lord_argalothAI>(creature);
+ }
+};
+
+// 88954 / 95173 - Consuming Darkness
+class spell_argaloth_consuming_darkness : public SpellScriptLoader
+{
+ public:
+ spell_argaloth_consuming_darkness() : SpellScriptLoader("spell_argaloth_consuming_darkness") { }
+
+ class spell_argaloth_consuming_darkness_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_argaloth_consuming_darkness_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ Trinity::Containers::RandomResizeList(targets, GetCaster()->GetMap()->Is25ManRaid() ? 8 : 3);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_argaloth_consuming_darkness_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_argaloth_consuming_darkness_SpellScript();
+ }
+};
+
+// 88942 / 95172 - Meteor Slash
+class spell_argaloth_meteor_slash : public SpellScriptLoader
+{
+ public:
+ spell_argaloth_meteor_slash() : SpellScriptLoader("spell_argaloth_meteor_slash") { }
+
+ class spell_argaloth_meteor_slash_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_argaloth_meteor_slash_SpellScript);
+
+ bool Load() OVERRIDE
+ {
+ _targetCount = 0;
+ return true;
+ }
+
+ void CountTargets(std::list<WorldObject*>& targets)
+ {
+ _targetCount = targets.size();
+ }
+
+ void SplitDamage()
+ {
+ if (!_targetCount)
+ return;
+
+ SetHitDamage(GetHitDamage() / _targetCount);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_argaloth_meteor_slash_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CONE_ENEMY_104);
+ OnHit += SpellHitFn(spell_argaloth_meteor_slash_SpellScript::SplitDamage);
+ }
+
+ private:
+ uint32 _targetCount;
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_argaloth_meteor_slash_SpellScript();
+ }
+};
+
+void AddSC_boss_pit_lord_argaloth()
+{
+ new boss_pit_lord_argaloth();
+ new spell_argaloth_consuming_darkness();
+ new spell_argaloth_meteor_slash();
+}
diff --git a/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp b/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp
new file mode 100644
index 00000000000..2030cca170b
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/BaradinHold/instance_baradin_hold.cpp
@@ -0,0 +1,164 @@
+/*
+ * 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 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "InstanceScript.h"
+#include "baradin_hold.h"
+
+DoorData const doorData[] =
+{
+ { GO_ARGALOTH_DOOR, DATA_ARGALOTH, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_OCCUTHAR_DOOR, DATA_OCCUTHAR, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_ALIZABAL_DOOR, DATA_ALIZABAL, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+};
+
+class instance_baradin_hold: public InstanceMapScript
+{
+ public:
+ instance_baradin_hold() : InstanceMapScript(BHScriptName, 757) { }
+
+ struct instance_baradin_hold_InstanceMapScript: public InstanceScript
+ {
+ instance_baradin_hold_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
+ {
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
+
+ ArgalothGUID = 0;
+ OccutharGUID = 0;
+ AlizabalGUID = 0;
+ }
+
+ void OnCreatureCreate(Creature* creature) OVERRIDE
+ {
+ switch(creature->GetEntry())
+ {
+ case BOSS_ARGALOTH:
+ ArgalothGUID = creature->GetGUID();
+ break;
+ case BOSS_OCCUTHAR:
+ OccutharGUID = creature->GetGUID();
+ break;
+ case BOSS_ALIZABAL:
+ AlizabalGUID = creature->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectCreate(GameObject* go) OVERRIDE
+ {
+ switch(go->GetEntry())
+ {
+ case GO_ARGALOTH_DOOR:
+ case GO_OCCUTHAR_DOOR:
+ case GO_ALIZABAL_DOOR:
+ AddDoor(go, true);
+ break;
+ }
+ }
+
+ uint64 GetData64(uint32 data) const OVERRIDE
+ {
+ switch (data)
+ {
+ case DATA_ARGALOTH:
+ return ArgalothGUID;
+ case DATA_OCCUTHAR:
+ return OccutharGUID;
+ case DATA_ALIZABAL:
+ return AlizabalGUID;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ void OnGameObjectRemove(GameObject* go) OVERRIDE
+ {
+ switch(go->GetEntry())
+ {
+ case GO_ARGALOTH_DOOR:
+ case GO_OCCUTHAR_DOOR:
+ case GO_ALIZABAL_DOOR:
+ AddDoor(go, false);
+ break;
+ }
+ }
+
+ std::string GetSaveData() OVERRIDE
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "B H " << GetBossSaveData();
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* in) OVERRIDE
+ {
+ if (!in)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(in);
+
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(in);
+ loadStream >> dataHead1 >> dataHead2;
+
+ if (dataHead1 == 'B' && dataHead2 == 'H')
+ {
+ for (uint8 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+
+ SetBossState(i, EncounterState(tmpState));
+ }
+
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ protected:
+ uint64 ArgalothGUID;
+ uint64 OccutharGUID;
+ uint64 AlizabalGUID;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const
+ {
+ return new instance_baradin_hold_InstanceMapScript(map);
+ }
+};
+
+void AddSC_instance_baradin_hold()
+{
+ new instance_baradin_hold();
+}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
index 02662cd235c..f3bcbb2526a 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
@@ -262,7 +262,7 @@ public:
case EVENT_SUCCESS_1:
if (Unit* player = me->SelectNearestPlayer(60.0f))
{
- me->SetInFront(player);
+ me->SetFacingToObject(player);
Talk(SAY_SUCCESS);
if (GameObject* portcullis1 = me->FindNearestGameObject(GO_PORTCULLIS_ACTIVE, 65.0f))
portcullis1->SetGoState(GO_STATE_ACTIVE);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
index f8e00e4ed74..71c4a7469d9 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
@@ -147,7 +147,7 @@ public:
case EVENT_SPEECH_4:
me->setFaction(103);
if (PlayerGUID && Unit::GetUnit(*me, PlayerGUID))
- AttackStart(Unit::GetUnit(*me, PlayerGUID));;
+ AttackStart(Unit::GetUnit(*me, PlayerGUID));
break;
}
}
diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt
index 4adb087921b..1e0e05840c4 100644
--- a/src/server/scripts/EasternKingdoms/CMakeLists.txt
+++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt
@@ -17,6 +17,10 @@ set(scripts_STAT_SRCS
EasternKingdoms/AlteracValley/boss_drekthar.cpp
EasternKingdoms/AlteracValley/boss_vanndar.cpp
EasternKingdoms/AlteracValley/alterac_valley.cpp
+ EasternKingdoms/BaradinHold/boss_alizabal.cpp
+ EasternKingdoms/BaradinHold/boss_occuthar.cpp
+ EasternKingdoms/BaradinHold/boss_pit_lord_argaloth.cpp
+ EasternKingdoms/BaradinHold/instance_baradin_hold.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
@@ -85,22 +89,17 @@ set(scripts_STAT_SRCS
EasternKingdoms/Scholomance/boss_ras_frostwhisper.cpp
EasternKingdoms/Scholomance/boss_kirtonos_the_herald.cpp
EasternKingdoms/zone_isle_of_queldanas.cpp
- EasternKingdoms/boss_kruul.cpp
- EasternKingdoms/ZulGurub/boss_hakkar.cpp
- EasternKingdoms/ZulGurub/boss_mandokir.cpp
- EasternKingdoms/ZulGurub/boss_marli.cpp
- EasternKingdoms/ZulGurub/boss_hazzarah.cpp
- EasternKingdoms/ZulGurub/boss_jeklik.cpp
EasternKingdoms/ZulGurub/boss_grilek.cpp
- EasternKingdoms/ZulGurub/zulgurub.h
+ EasternKingdoms/ZulGurub/boss_hazzarah.cpp
+ EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp
+ EasternKingdoms/ZulGurub/boss_kilnara.cpp
+ EasternKingdoms/ZulGurub/boss_mandokir.cpp
EasternKingdoms/ZulGurub/boss_renataki.cpp
- EasternKingdoms/ZulGurub/boss_arlokk.cpp
- EasternKingdoms/ZulGurub/boss_gahzranka.cpp
EasternKingdoms/ZulGurub/boss_venoxis.cpp
- EasternKingdoms/ZulGurub/instance_zulgurub.cpp
- EasternKingdoms/ZulGurub/boss_jindo.cpp
EasternKingdoms/ZulGurub/boss_wushoolay.cpp
- EasternKingdoms/ZulGurub/boss_thekal.cpp
+ EasternKingdoms/ZulGurub/boss_zanzil.cpp
+ EasternKingdoms/ZulGurub/instance_zulgurub.cpp
+ EasternKingdoms/ZulGurub/zulgurub.h
EasternKingdoms/zone_wetlands.cpp
EasternKingdoms/zone_arathi_highlands.cpp
EasternKingdoms/Gnomeregan/instance_gnomeregan.cpp
@@ -181,7 +180,7 @@ set(scripts_STAT_SRCS
EasternKingdoms/zone_stormwind_city.cpp
EasternKingdoms/ZulAman/boss_halazzi.cpp
EasternKingdoms/ZulAman/boss_hexlord.cpp
- EasternKingdoms/ZulAman/boss_zuljin.cpp
+ EasternKingdoms/ZulAman/boss_daakara.cpp
EasternKingdoms/ZulAman/boss_akilzon.cpp
EasternKingdoms/ZulAman/instance_zulaman.cpp
EasternKingdoms/ZulAman/boss_janalai.cpp
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp
index f48314ea220..59610b20015 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp
+++ b/src/server/scripts/EasternKingdoms/Deadmines/deadmines.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Deadmines
-SD%Complete: 0
-SDComment: Placeholder
-SDCategory: Deadmines
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "deadmines.h"
@@ -30,37 +22,6 @@ EndScriptData */
#include "Player.h"
#include "WorldSession.h"
-/*#####
-# item_Defias_Gunpowder
-#####*/
-
-class item_defias_gunpowder : public ItemScript
-{
-public:
- item_defias_gunpowder() : ItemScript("item_defias_gunpowder") { }
-
- bool OnUse(Player* player, Item* item, SpellCastTargets const& targets) OVERRIDE
- {
- InstanceScript* instance = player->GetInstanceScript();
-
- if (!instance)
- {
- player->GetSession()->SendNotification("Instance script not initialized");
- return true;
- }
-
- if (instance->GetData(EVENT_STATE) != CANNON_NOT_USED)
- return false;
-
- if (targets.GetGOTarget() && targets.GetGOTarget()->GetEntry() == GO_DEFIAS_CANNON)
- instance->SetData(EVENT_STATE, CANNON_GUNPOWDER_USED);
-
- player->DestroyItemCount(item->GetEntry(), 1, true);
- return true;
- }
-};
-
void AddSC_deadmines()
{
- new item_defias_gunpowder();
}
diff --git a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
index a2369f290f1..30dc2d89142 100644
--- a/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
+++ b/src/server/scripts/EasternKingdoms/Deadmines/instance_deadmines.cpp
@@ -242,6 +242,7 @@ class instance_deadmines : public InstanceMapScript
{
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(sound);
+ data << uint64(unit->GetGUID());
unit->SendMessageToSet(&data, false);
}
};
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
index 22398314a41..12a8cfc69ae 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_terestian_illhoof.cpp
@@ -64,7 +64,6 @@ enum Creatures
NPC_KILREK = 17229
};
-
class npc_kilrek : public CreatureScript
{
public:
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index a3d4d6669a3..96386462c44 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -1030,6 +1030,8 @@ class npc_scarlet_miner : public CreatureScript
if (Unit* car = ObjectAccessor::GetCreature(*me, carGUID))
{
me->SetFacingToObject(car);
+ car->Relocate(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1);
+ car->StopMoving();
car->RemoveAura(SPELL_CART_DRAG);
}
Talk(SAY_SCARLET_MINER_1);
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
index cdc37b40521..4fbcfac08ee 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/zone_the_scarlet_enclave.cpp
@@ -99,7 +99,7 @@ public:
FlyBackTimer = 4500;
break;
case 2:
- if (!player->isRessurectRequested())
+ if (!player->IsRessurectRequested())
{
me->HandleEmoteCommand(EMOTE_ONESHOT_CUSTOM_SPELL_01);
DoCast(player, SPELL_REVIVE, true);
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
index eca840dbeb2..41dd499f5c3 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,67 +15,19 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: boss_Akilzon
-SD%Complete: 75%
-SDComment: Missing timer for Call Lightning and Sound ID's
-SQLUpdate:
-#Temporary fix for Soaring Eagles
-
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "GridNotifiers.h"
-#include "GridNotifiersImpl.h"
-#include "Cell.h"
-#include "CellImpl.h"
#include "zulaman.h"
-#include "Weather.h"
-
-enum Spells
-{
- SPELL_STATIC_DISRUPTION = 43622,
- SPELL_STATIC_VISUAL = 45265,
- SPELL_CALL_LIGHTNING = 43661, // Missing timer
- SPELL_GUST_OF_WIND = 43621,
- SPELL_ELECTRICAL_STORM = 43648,
- SPELL_BERSERK = 45078,
- SPELL_ELECTRICAL_OVERLOAD = 43658,
- SPELL_EAGLE_SWOOP = 44732,
- SPELL_ZAP = 43137,
- SPELL_SAND_STORM = 25160
-};
enum Says
{
- SAY_AGGRO = 0,
- SAY_SUMMON = 1,
- SAY_INTRO = 2, // Not used in script
- SAY_ENRAGE = 3,
- SAY_KILL = 4,
- SAY_DEATH = 5
-};
-
-enum Misc
-{
- NPC_SOARING_EAGLE = 24858,
- SE_LOC_X_MAX = 400,
- SE_LOC_X_MIN = 335,
- SE_LOC_Y_MAX = 1435,
- SE_LOC_Y_MIN = 1370
-};
-
-enum Events
-{
- EVENT_STATIC_DISRUPTION = 1,
- EVENT_GUST_OF_WIND = 2,
- EVENT_CALL_LIGHTNING = 3,
- EVENT_ELECTRICAL_STORM = 4,
- EVENT_RAIN = 5,
- EVENT_SUMMON_EAGLES = 6,
- EVENT_STORM_SEQUENCE = 7,
- EVENT_ENRAGE = 8
+ SAY_AGGRO = 0,
+ SAY_PLAYER_KILL = 1,
+ EMOTE_ELECTRICAL_STORM = 2,
+ SAY_SUMMON_EAGLE = 3,
+ SAY_SUMMON_BIRDS = 4,
+ SAY_BERSERK = 5,
+ SAY_DEATH = 6
};
class boss_akilzon : public CreatureScript
@@ -86,37 +37,17 @@ class boss_akilzon : public CreatureScript
struct boss_akilzonAI : public BossAI
{
- boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZONEVENT)
- {
- memset(BirdGUIDs, 0, sizeof(BirdGUIDs));
- }
+ boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { }
void Reset() OVERRIDE
{
_Reset();
-
- TargetGUID = 0;
- CloudGUID = 0;
- CycloneGUID = 0;
- memset(BirdGUIDs, 0, sizeof(BirdGUIDs));
- StormCount = 0;
- isRaining = false;
-
- SetWeather(WEATHER_STATE_FINE, 0.0f);
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 20000)); // 10 to 20 seconds (bosskillers)
- events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000)); // 20 to 30 seconds(bosskillers)
- events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(10000, 20000)); // totaly random timer. can't find any info on this
- events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
- events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
- events.ScheduleEvent(EVENT_ENRAGE, 10*MINUTE*IN_MILLISECONDS); // 10 minutes till enrage(bosskillers)
-
Talk(SAY_AGGRO);
- //DoZoneInCombat();
- instance->SetData(DATA_AKILZONEVENT, IN_PROGRESS);
+ _EnterCombat();
}
void JustDied(Unit* /*killer*/) OVERRIDE
@@ -128,90 +59,7 @@ class boss_akilzon : public CreatureScript
void KilledUnit(Unit* who) OVERRIDE
{
if (who->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_KILL);
- }
-
- void SetWeather(uint32 weather, float grade)
- {
- Map* map = me->GetMap();
- if (!map->IsDungeon())
- return;
-
- WorldPacket data(SMSG_WEATHER, (4+4+4));
- data << uint32(weather) << float(grade) << uint8(0);
-
- map->SendToPlayers(&data);
- }
-
- void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end
- {
- if (StormCount < 10 && StormCount > 1)
- {
- // deal damage
- int32 bp0 = 800;
- for (uint8 i = 2; i < StormCount; ++i)
- bp0 *= 2;
-
- CellCoord p(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY()));
- Cell cell(p);
- cell.SetNoCreate();
-
- std::list<Unit*> tempUnitMap;
-
- {
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(me, me, SIZE_OF_GRIDS);
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(me, tempUnitMap, u_check);
-
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
-
- cell.Visit(p, world_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS);
- cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS);
- }
-
- // deal damage
- for (std::list<Unit*>::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i)
- {
- if (Unit* target = (*i))
- {
- if (Cloud && !Cloud->IsWithinDist(target, 6, false))
- Cloud->CastCustomSpell(target, SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, me->GetGUID());
- }
- }
-
- // visual
- float x, y, z;
- z = me->GetPositionZ();
- for (uint8 i = 0; i < 5+rand()%5; ++i)
- {
- x = 343.0f+rand()%60;
- y = 1380.0f+rand()%60;
- if (Unit* trigger = me->SummonTrigger(x, y, z, 0, 2000))
- {
- trigger->setFaction(35);
- trigger->SetMaxHealth(100000);
- trigger->SetHealth(100000);
- trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- if (Cloud)
- Cloud->CastCustomSpell(trigger, /*43661*/SPELL_ZAP, &bp0, NULL, NULL, true, 0, 0, Cloud->GetGUID());
- }
- }
- }
-
- ++StormCount;
-
- if (StormCount > 10)
- {
- StormCount = 0; // finish
- events.ScheduleEvent(EVENT_SUMMON_EAGLES, 5000);
- me->InterruptNonMeleeSpells(false);
- CloudGUID = 0;
- if (Cloud)
- Cloud->DealDamage(Cloud, Cloud->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- SetWeather(WEATHER_STATE_FINE, 0.0f);
- isRaining = false;
- }
- events.ScheduleEvent(EVENT_STORM_SEQUENCE, 1000);
+ Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -221,149 +69,21 @@ class boss_akilzon : public CreatureScript
events.Update(diff);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_STATIC_DISRUPTION:
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
- if (!target)
- target = me->GetVictim();
- if (target)
- {
- TargetGUID = target->GetGUID();
- DoCast(target, SPELL_STATIC_DISRUPTION, false);
- me->SetInFront(me->GetVictim());
- }
- /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f;
- SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/
- events.ScheduleEvent(EVENT_STATIC_DISRUPTION, urand(10000, 18000));
- break;
- }
- case EVENT_GUST_OF_WIND:
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
- if (!target)
- target = me->GetVictim();
- if (target)
- DoCast(target, SPELL_GUST_OF_WIND);
- events.ScheduleEvent(EVENT_GUST_OF_WIND, urand(20000, 30000));
- break;
- }
- case EVENT_CALL_LIGHTNING:
- DoCastVictim(SPELL_CALL_LIGHTNING);
- events.ScheduleEvent(EVENT_CALL_LIGHTNING, urand(12000, 17000)); // totaly random timer. can't find any info on this
- break;
- case EVENT_ELECTRICAL_STORM:
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
- if (!target)
- {
- EnterEvadeMode();
- return;
- }
- target->CastSpell(target, 44007, true); // cloud visual
- DoCast(target, SPELL_ELECTRICAL_STORM, false); // storm cyclon + visual
- float x, y, z;
- target->GetPosition(x, y, z);
- /// @todo: fix it in correct way, that causes player to can fly until logout
- /*
- if (target)
- {
- target->SetDisableGravity(true);
- target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0);
- }
- */
-
- Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000);
- if (Cloud)
- {
- CloudGUID = Cloud->GetGUID();
- Cloud->SetDisableGravity(true);
- Cloud->StopMoving();
- Cloud->SetObjectScale(1.0f);
- Cloud->setFaction(35);
- Cloud->SetMaxHealth(9999999);
- Cloud->SetHealth(9999999);
- Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
- StormCount = 1;
- events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 60000); // 60 seconds(bosskillers)
- events.ScheduleEvent(EVENT_RAIN, urand(47000, 52000));
- break;
- }
- case EVENT_RAIN:
- if (!isRaining)
- {
- SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
- isRaining = true;
- }
- else
- events.ScheduleEvent(EVENT_RAIN, 1000);
- break;
- case EVENT_STORM_SEQUENCE:
- {
- Unit* target = Unit::GetUnit(*me, CloudGUID);
- if (!target || !target->IsAlive())
- {
- EnterEvadeMode();
- return;
- }
- else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID))
- Cyclone->CastSpell(target, SPELL_SAND_STORM, true); // keep casting or...
- HandleStormSequence(target);
- break;
- }
- case EVENT_SUMMON_EAGLES:
- Talk(SAY_SUMMON);
-
- float x, y, z;
- me->GetPosition(x, y, z);
-
- for (uint8 i = 0; i < 8; ++i)
- {
- Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]);
- if (!bird) //they despawned on die
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- x = target->GetPositionX() + irand(-10, 10);
- y = target->GetPositionY() + irand(-10, 10);
- z = target->GetPositionZ() + urand(16, 20);
- if (z > 95)
- z = 95.0f - urand(0, 5);
- }
- Creature* creature = me->SummonCreature(NPC_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- if (creature)
- {
- creature->AddThreat(me->GetVictim(), 1.0f);
- creature->AI()->AttackStart(me->GetVictim());
- BirdGUIDs[i] = creature->GetGUID();
- }
- }
- }
- break;
- case EVENT_ENRAGE:
- Talk(SAY_ENRAGE);
- DoCast(me, SPELL_BERSERK, true);
- events.ScheduleEvent(EVENT_ENRAGE, 600000);
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
-
- private:
- uint64 BirdGUIDs[8];
- uint64 TargetGUID;
- uint64 CycloneGUID;
- uint64 CloudGUID;
- uint8 StormCount;
- bool isRaining;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
@@ -372,91 +92,7 @@ class boss_akilzon : public CreatureScript
}
};
-class npc_akilzon_eagle : public CreatureScript
-{
- public:
- npc_akilzon_eagle() : CreatureScript("npc_akilzon_eagle") { }
-
- struct npc_akilzon_eagleAI : public ScriptedAI
- {
- npc_akilzon_eagleAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 EagleSwoop_Timer;
- bool arrived;
- uint64 TargetGUID;
-
- void Reset() OVERRIDE
- {
- EagleSwoop_Timer = urand(5000, 10000);
- arrived = true;
- TargetGUID = 0;
- me->SetDisableGravity(true);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- DoZoneInCombat();
- }
-
- void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
-
-
- void MovementInform(uint32, uint32) OVERRIDE
- {
- arrived = true;
- if (TargetGUID)
- {
- if (Unit* target = Unit::GetUnit(*me, TargetGUID))
- DoCast(target, SPELL_EAGLE_SWOOP, true);
- TargetGUID = 0;
- me->SetSpeed(MOVE_RUN, 1.2f);
- EagleSwoop_Timer = urand(5000, 10000);
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (EagleSwoop_Timer <= diff)
- EagleSwoop_Timer = 0;
- else
- EagleSwoop_Timer -= diff;
-
- if (arrived)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- float x, y, z;
- if (EagleSwoop_Timer)
- {
- x = target->GetPositionX() + irand(-10, 10);
- y = target->GetPositionY() + irand(-10, 10);
- z = target->GetPositionZ() + urand(10, 15);
- if (z > 95)
- z = 95.0f - urand(0, 5);
- }
- else
- {
- target->GetContactPoint(me, x, y, z);
- z += 2;
- me->SetSpeed(MOVE_RUN, 5.0f);
- TargetGUID = target->GetGUID();
- }
- me->GetMotionMaster()->MovePoint(0, x, y, z);
- arrived = false;
- }
- }
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_akilzon_eagleAI(creature);
- }
-};
-
void AddSC_boss_akilzon()
{
new boss_akilzon();
- new npc_akilzon_eagle();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp
new file mode 100644
index 00000000000..63d2abe8c92
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp
@@ -0,0 +1,113 @@
+/*
+ * 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 "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "zulaman.h"
+
+enum Says
+{
+ SAY_INTRO = 0,
+ SAY_AGGRO = 1,
+ SAY_PLAYER_KILL = 2,
+ SAY_FIRE_BREATH = 3,
+ SAY_TRANSFORMS_BEAR = 4,
+ SAY_TRANSFORMS_EAGLE = 5,
+ SAY_TRANSFORMS_LYNX = 6,
+ SAY_TRANSFORMS_DRAGONHAWK = 7,
+ SAY_ABSORBS_BEAR_SPIRIT = 8,
+ SAY_ABSORBS_EAGLE_SPIRIT = 9,
+ SAY_ABSORBS_LYNX_SPIRIT = 10,
+ SAY_ABSORBS_DRAGONHAWK_SPIRIT = 11,
+ SAY_DEATH = 12
+};
+
+enum Spells
+{
+};
+
+enum Events
+{
+};
+
+class boss_daakara : public CreatureScript
+{
+ public:
+
+ boss_daakara() : CreatureScript("boss_daakara") { }
+
+ struct boss_daakaraAI : public BossAI
+ {
+ boss_daakaraAI(Creature* creature) : BossAI(creature, DATA_DAAKARA) { }
+
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ Talk(SAY_AGGRO);
+ _EnterCombat();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ Talk(SAY_DEATH);
+ _JustDied();
+ }
+
+ void KilledUnit(Unit* victim) OVERRIDE
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ default:
+ break;
+ }
+ }
+ */
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetZulAmanAI<boss_daakaraAI>(creature);
+ }
+};
+
+void AddSC_boss_daakara()
+{
+ new boss_daakara();
+}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
index 4e354b47be5..07a6f249a5f 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,403 +15,92 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: boss_Halazzi
-SD%Complete: 80
-SDComment:
-SDCategory: Zul'Aman
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
-#include "SpellInfo.h"
-
-#define YELL_AGGRO "Get on your knees and bow to da fang and claw!"
-#define SOUND_AGGRO 12020
-#define YELL_SABER_ONE "You gonna leave in pieces!"
-#define YELL_SABER_TWO "Me gonna carve ya now!"
-#define YELL_SPLIT "Me gonna carve ya now!"
-#define SOUND_SPLIT 12021
-#define YELL_MERGE "Spirit, come back to me!"
-#define SOUND_MERGE 12022
-#define YELL_KILL_ONE "You cant fight the power!"
-#define SOUND_KILL_ONE 12026
-#define YELL_KILL_TWO "You gonna fail!"
-#define SOUND_KILL_TWO 12027
-#define YELL_DEATH "Chaga... choka'jinn."
-#define SOUND_DEATH 12028
-#define YELL_BERSERK "Whatch you be doing? Pissin' yourselves..."
-#define SOUND_BERSERK 12025
-enum Spells
+enum Says
{
- SPELL_DUAL_WIELD = 29651,
- SPELL_SABER_LASH = 43267,
- SPELL_FRENZY = 43139,
- SPELL_FLAMESHOCK = 43303,
- SPELL_EARTHSHOCK = 43305,
- SPELL_TRANSFORM_SPLIT = 43142,
- SPELL_TRANSFORM_SPLIT2 = 43573,
- SPELL_TRANSFORM_MERGE = 43271,
- SPELL_SUMMON_LYNX = 43143,
- SPELL_SUMMON_TOTEM = 43302,
- SPELL_BERSERK = 45078,
- SPELL_LYNX_FRENZY = 43290, // Used by Spirit Lynx
- SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx
+ SAY_AGGRO = 0,
+ SAY_PLAYER_KILL = 1,
+ SAY_MELEE = 2,
+ SAY_SPLIT = 3,
+ SAY_COMBINE = 4,
+ SAY_DEATH = 5
};
-enum Hal_CreatureIds
+enum Spells
{
- NPC_SPIRIT_LYNX = 24143,
- NPC_TOTEM = 24224
};
-enum PhaseHalazzi
+enum Events
{
- PHASE_NONE = 0,
- PHASE_LYNX = 1,
- PHASE_SPLIT = 2,
- PHASE_HUMAN = 3,
- PHASE_MERGE = 4,
- PHASE_ENRAGE = 5
};
class boss_halazzi : public CreatureScript
{
public:
- boss_halazzi()
- : CreatureScript("boss_halazzi")
- {
- }
+ boss_halazzi() : CreatureScript("boss_halazzi") { }
- struct boss_halazziAI : public ScriptedAI
+ struct boss_halazziAI : public BossAI
{
- boss_halazziAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 FrenzyTimer;
- uint32 SaberlashTimer;
- uint32 ShockTimer;
- uint32 TotemTimer;
- uint32 CheckTimer;
- uint32 BerserkTimer;
-
- uint32 TransformCount;
-
- PhaseHalazzi Phase;
-
- uint64 LynxGUID;
+ boss_halazziAI(Creature* creature) : BossAI(creature, DATA_HALAZZI) { }
void Reset() OVERRIDE
{
- instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED);
-
- LynxGUID = 0;
- TransformCount = 0;
- BerserkTimer = 600000;
- CheckTimer = 1000;
-
- DoCast(me, SPELL_DUAL_WIELD, true);
-
- Phase = PHASE_NONE;
- EnterPhase(PHASE_LYNX);
+ _Reset();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS);
-
- me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_AGGRO);
-
- EnterPhase(PHASE_LYNX);
- }
-
- void JustSummoned(Creature* summon) OVERRIDE
- {
- summon->AI()->AttackStart(me->GetVictim());
- if (summon->GetEntry() == NPC_SPIRIT_LYNX)
- LynxGUID = summon->GetGUID();
- }
-
- void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
- {
- if (damage >= me->GetHealth() && Phase != PHASE_ENRAGE)
- damage = 0;
- }
-
- void SpellHit(Unit*, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_TRANSFORM_SPLIT2)
- EnterPhase(PHASE_HUMAN);
+ Talk(SAY_AGGRO);
+ _EnterCombat();
}
- void AttackStart(Unit* who) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (Phase != PHASE_MERGE) ScriptedAI::AttackStart(who);
+ Talk(SAY_DEATH);
+ _JustDied();
}
- void EnterPhase(PhaseHalazzi NextPhase)
+ void KilledUnit(Unit* victim) OVERRIDE
{
- switch (NextPhase)
- {
- case PHASE_LYNX:
- case PHASE_ENRAGE:
- if (Phase == PHASE_MERGE)
- {
- DoCast(me, SPELL_TRANSFORM_MERGE, true);
- me->Attack(me->GetVictim(), true);
- me->GetMotionMaster()->MoveChase(me->GetVictim());
- }
- if (Creature* Lynx = Unit::GetCreature(*me, LynxGUID))
- Lynx->DisappearAndDie();
- me->SetMaxHealth(600000);
- me->SetHealth(600000 - 150000 * TransformCount);
- FrenzyTimer = 16000;
- SaberlashTimer = 20000;
- ShockTimer = 10000;
- TotemTimer = 12000;
- break;
- case PHASE_SPLIT:
- me->MonsterYell(YELL_SPLIT, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_SPLIT);
- DoCast(me, SPELL_TRANSFORM_SPLIT, true);
- break;
- case PHASE_HUMAN:
- //DoCast(me, SPELL_SUMMON_LYNX, true);
- DoSpawnCreature(NPC_SPIRIT_LYNX, 5, 5, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- me->SetMaxHealth(400000);
- me->SetHealth(400000);
- ShockTimer = 10000;
- TotemTimer = 12000;
- break;
- case PHASE_MERGE:
- if (Unit* pLynx = Unit::GetUnit(*me, LynxGUID))
- {
- me->MonsterYell(YELL_MERGE, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_MERGE);
- pLynx->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- pLynx->GetMotionMaster()->Clear();
- pLynx->GetMotionMaster()->MoveFollow(me, 0, 0);
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveFollow(pLynx, 0, 0);
- ++TransformCount;
- }
- break;
- default:
- break;
- }
- Phase = NextPhase;
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
- void UpdateAI(uint32 diff) OVERRIDE
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
- if (BerserkTimer <= diff)
- {
- me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_BERSERK);
- DoCast(me, SPELL_BERSERK, true);
- BerserkTimer = 60000;
- } else BerserkTimer -= diff;
-
- if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE)
- {
- if (SaberlashTimer <= diff)
- {
- // A tank with more than 490 defense skills should receive no critical hit
- //DoCast(me, 41296, true);
- DoCastVictim(SPELL_SABER_LASH, true);
- //me->RemoveAurasDueToSpell(41296);
- SaberlashTimer = 30000;
- } else SaberlashTimer -= diff;
-
- if (FrenzyTimer <= diff)
- {
- DoCast(me, SPELL_FRENZY);
- FrenzyTimer = urand(10000, 15000);
- } else FrenzyTimer -= diff;
+ events.Update(diff);
- if (Phase == PHASE_LYNX)
- {
- if (CheckTimer <= diff)
- {
- if (HealthBelowPct(25 * (3 - TransformCount)))
- EnterPhase(PHASE_SPLIT);
- CheckTimer = 1000;
- } else CheckTimer -= diff;
- }
- }
-
- if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (TotemTimer <= diff)
+ switch (eventId)
{
- DoCast(me, SPELL_SUMMON_TOTEM);
- TotemTimer = 20000;
- } else TotemTimer -= diff;
-
- if (ShockTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- if (target->IsNonMeleeSpellCast(false))
- DoCast(target, SPELL_EARTHSHOCK);
- else
- DoCast(target, SPELL_FLAMESHOCK);
- ShockTimer = urand(10000, 15000);
- }
- } else ShockTimer -= diff;
-
- if (Phase == PHASE_HUMAN)
- {
- if (CheckTimer <= diff)
- {
- if (!HealthAbovePct(20) /*HealthBelowPct(10)*/)
- EnterPhase(PHASE_MERGE);
- else
- {
- Unit* Lynx = Unit::GetUnit(*me, LynxGUID);
- if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/)
- EnterPhase(PHASE_MERGE);
- }
- CheckTimer = 1000;
- } else CheckTimer -= diff;
+ default:
+ break;
}
}
-
- if (Phase == PHASE_MERGE)
- {
- if (CheckTimer <= diff)
- {
- Unit* Lynx = Unit::GetUnit(*me, LynxGUID);
- if (Lynx)
- {
- Lynx->GetMotionMaster()->MoveFollow(me, 0, 0);
- me->GetMotionMaster()->MoveFollow(Lynx, 0, 0);
- if (me->IsWithinDistInMap(Lynx, 6.0f))
- {
- if (TransformCount < 3)
- EnterPhase(PHASE_LYNX);
- else
- EnterPhase(PHASE_ENRAGE);
- }
- }
- CheckTimer = 1000;
- } else CheckTimer -= diff;
- }
+ */
DoMeleeAttackIfReady();
}
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- switch (urand(0, 1))
- {
- case 0:
- me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_KILL_ONE);
- break;
-
- case 1:
- me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_KILL_TWO);
- break;
- }
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- instance->SetData(DATA_HALAZZIEVENT, DONE);
-
- me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_DEATH);
- }
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetInstanceAI<boss_halazziAI>(creature);
- }
-};
-
-// Spirits Lynx AI
-class npc_halazzi_lynx : public CreatureScript
-{
- public:
-
- npc_halazzi_lynx()
- : CreatureScript("npc_halazzi_lynx")
- {
- }
-
- struct npc_halazzi_lynxAI : public ScriptedAI
- {
- npc_halazzi_lynxAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 FrenzyTimer;
- uint32 shredder_timer;
-
- void Reset() OVERRIDE
- {
- FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
- shredder_timer = 4000;
- }
-
- void DamageTaken(Unit* /*done_by*/, uint32 &damage) OVERRIDE
- {
- if (damage >= me->GetHealth())
- damage = 0;
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- ScriptedAI::AttackStart(who);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE {/*DoZoneInCombat();*/ }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (FrenzyTimer <= diff)
- {
- DoCast(me, SPELL_LYNX_FRENZY);
- FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds
- } else FrenzyTimer -= diff;
-
- if (shredder_timer <= diff)
- {
- DoCastVictim(SPELL_SHRED_ARMOR);
- shredder_timer = 4000;
- } else shredder_timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_halazzi_lynxAI(creature);
+ return GetZulAmanAI<boss_halazziAI>(creature);
}
};
void AddSC_boss_halazzi()
{
new boss_halazzi();
- new npc_halazzi_lynx();
}
-
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
index d6657ac0986..93a0e4e6f05 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,938 +15,92 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Hex_Lord_Malacrass
-SD%Complete:
-SDComment:
-SDCategory: Zul'Aman
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "zulaman.h"
-#define YELL_AGGRO "Da shadow gonna fall on you... "
-#define SOUND_YELL_AGGRO 12041
-#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!"
-#define SOUND_YELL_SPIRIT_BOLTS 12047
-#define YELL_DRAIN_POWER "Darkness comin\' for you"
-#define SOUND_YELL_DRAIN_POWER 12046
-#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!"
-#define SOUND_YELL_KILL_ONE 12043
-#define YELL_KILL_TWO "Azzaga choogo zinn!"
-#define SOUND_YELL_KILL_TWO 12044
-#define YELL_DEATH "Dis not... da end of me..."
-#define SOUND_YELL_DEATH 12051
-
-
-enum Creatures
+enum Says
{
- NPC_TEMP_TRIGGER = 23920
+ SAY_AGGRO = 0,
+ SAY_PLAYER_KILL = 1,
+ SAY_SPIRIT_BOLTS = 2,
+ SAY_SIPHON_SOUL = 3,
+ SAY_PET_DEATH = 4,
+ SAY_DEATH = 5
};
enum Spells
{
- SPELL_SPIRIT_BOLTS = 43383,
- SPELL_DRAIN_POWER = 44131,
- SPELL_SIPHON_SOUL = 43501,
-
- // Druid
- SPELL_DR_THORNS = 43420,
- SPELL_DR_LIFEBLOOM = 43421,
- SPELL_DR_MOONFIRE = 43545,
-
- // Hunter
- SPELL_HU_EXPLOSIVE_TRAP = 43444,
- SPELL_HU_FREEZING_TRAP = 43447,
- SPELL_HU_SNAKE_TRAP = 43449,
-
- // Mage
- SPELL_MG_FIREBALL = 41383,
- SPELL_MG_FROST_NOVA = 43426,
- SPELL_MG_ICE_LANCE = 43427,
- SPELL_MG_FROSTBOLT = 43428,
-
- // Paladin
- SPELL_PA_CONSECRATION = 43429,
- SPELL_PA_AVENGING_WRATH = 43430,
- SPELL_PA_HOLY_LIGHT = 43451,
-
- // Priest
- SPELL_PR_HEAL = 41372,
- SPELL_PR_MIND_BLAST = 41374,
- SPELL_PR_SW_DEATH = 41375,
- SPELL_PR_PSYCHIC_SCREAM = 43432,
- SPELL_PR_MIND_CONTROL = 43550,
- SPELL_PR_PAIN_SUPP = 44416,
-
- // Rogue
- SPELL_RO_BLIND = 43433,
- SPELL_RO_SLICE_DICE = 43457,
- SPELL_RO_WOUND_POISON = 43461,
-
- // Shaman
- SPELL_SH_CHAIN_LIGHT = 43435,
- SPELL_SH_FIRE_NOVA = 43436,
- SPELL_SH_HEALING_WAVE = 43548,
-
- // Warlock
- SPELL_WL_CURSE_OF_DOOM = 43439,
- SPELL_WL_RAIN_OF_FIRE = 43440,
SPELL_WL_UNSTABLE_AFFL = 43522,
SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
-
- // Warrior
- SPELL_WR_MORTAL_STRIKE = 43441,
- SPELL_WR_WHIRLWIND = 43442,
- SPELL_WR_SPELL_REFLECT = 43443,
-
- // Thurg
- SPELL_BLOODLUST = 43578,
- SPELL_CLEAVE = 15496,
-
- // Gazakroth
- SPELL_FIREBOLT = 43584,
-
- // Alyson Antille
- SPELL_FLASH_HEAL = 43575,
- SPELL_DISPEL_MAGIC = 43577,
-
- // Lord Raadan
- SPELL_FLAME_BREATH = 43582,
- SPELL_THUNDERCLAP = 43583,
-
- // Darkheart
- SPELL_PSYCHIC_WAIL = 43590,
-
- // Slither
- SPELL_VENOM_SPIT = 43579,
-
- // Fenstalker
- SPELL_VOLATILE_INFECTION = 43586,
-
- // Koragg
- SPELL_COLD_STARE = 43593,
- SPELL_MIGHTY_BLOW = 43592
-
-};
-
-#define ORIENT 1.5696f
-#define POS_Y 921.2795f
-#define POS_Z 33.8883f
-
-static float Pos_X[4] = {112.8827f, 107.8827f, 122.8827f, 127.8827f};
-
-static uint32 AddEntryList[8]=
-{
- 24240, //Alyson Antille
- 24241, //Thurg
- 24242, //Slither
- 24243, //Lord Raadan
- 24244, //Gazakroth
- 24245, //Fenstalker
- 24246, //Darkheart
- 24247 //Koragg
-};
-
-enum AbilityTarget
-{
- ABILITY_TARGET_SELF = 0,
- ABILITY_TARGET_VICTIM = 1,
- ABILITY_TARGET_ENEMY = 2,
- ABILITY_TARGET_HEAL = 3,
- ABILITY_TARGET_BUFF = 4,
- ABILITY_TARGET_SPECIAL = 5
};
-struct PlayerAbilityStruct
+enum Events
{
- uint32 spell;
- AbilityTarget target;
- uint32 cooldown; //FIXME - it's never used
-};
-
-static PlayerAbilityStruct PlayerAbility[][3] =
-{
- // 1 warrior
- {{SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000},
- {SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000},
- {SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000}},
- // 2 paladin
- {{SPELL_PA_CONSECRATION, ABILITY_TARGET_SELF, 10000},
- {SPELL_PA_HOLY_LIGHT, ABILITY_TARGET_HEAL, 10000},
- {SPELL_PA_AVENGING_WRATH, ABILITY_TARGET_SELF, 10000}},
- // 3 hunter
- {{SPELL_HU_EXPLOSIVE_TRAP, ABILITY_TARGET_SELF, 10000},
- {SPELL_HU_FREEZING_TRAP, ABILITY_TARGET_SELF, 10000},
- {SPELL_HU_SNAKE_TRAP, ABILITY_TARGET_SELF, 10000}},
- // 4 rogue
- {{SPELL_RO_WOUND_POISON, ABILITY_TARGET_VICTIM, 3000},
- {SPELL_RO_SLICE_DICE, ABILITY_TARGET_SELF, 10000},
- {SPELL_RO_BLIND, ABILITY_TARGET_ENEMY, 10000}},
- // 5 priest
- {{SPELL_PR_PAIN_SUPP, ABILITY_TARGET_HEAL, 10000},
- {SPELL_PR_HEAL, ABILITY_TARGET_HEAL, 10000},
- {SPELL_PR_PSYCHIC_SCREAM, ABILITY_TARGET_SELF, 10000}},
- // 5* shadow priest
- {{SPELL_PR_MIND_CONTROL, ABILITY_TARGET_ENEMY, 15000},
- {SPELL_PR_MIND_BLAST, ABILITY_TARGET_ENEMY, 5000},
- {SPELL_PR_SW_DEATH, ABILITY_TARGET_ENEMY, 10000}},
- // 7 shaman
- {{SPELL_SH_FIRE_NOVA, ABILITY_TARGET_SELF, 10000},
- {SPELL_SH_HEALING_WAVE, ABILITY_TARGET_HEAL, 10000},
- {SPELL_SH_CHAIN_LIGHT, ABILITY_TARGET_ENEMY, 8000}},
- // 8 mage
- {{SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000},
- {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000},
- {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000}},
- // 9 warlock
- {{SPELL_WL_CURSE_OF_DOOM, ABILITY_TARGET_ENEMY, 10000},
- {SPELL_WL_RAIN_OF_FIRE, ABILITY_TARGET_ENEMY, 10000},
- {SPELL_WL_UNSTABLE_AFFL, ABILITY_TARGET_ENEMY, 10000}},
- // 11 druid
- {{SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000},
- {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000},
- {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000}}
-};
-
-struct boss_hexlord_addAI : public ScriptedAI
-{
- InstanceScript* instance;
-
- boss_hexlord_addAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- DoZoneInCombat();
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS)
- {
- EnterEvadeMode();
- return;
- }
-
- DoMeleeAttackIfReady();
- }
};
class boss_hexlord_malacrass : public CreatureScript
{
public:
- boss_hexlord_malacrass()
- : CreatureScript("boss_hexlord_malacrass")
- {
- }
+ boss_hexlord_malacrass() : CreatureScript("boss_hexlord_malacrass") { }
- struct boss_hex_lord_malacrassAI : public ScriptedAI
+ struct boss_hex_lord_malacrassAI : public BossAI
{
- boss_hex_lord_malacrassAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- SelectAddEntry();
- for (uint8 i = 0; i < 4; ++i)
- AddGUID[i] = 0;
- }
-
- InstanceScript* instance;
-
- uint64 AddGUID[4];
- uint32 AddEntry[4];
-
- uint64 PlayerGUID;
-
- uint32 SpiritBolts_Timer;
- uint32 DrainPower_Timer;
- uint32 SiphonSoul_Timer;
- uint32 PlayerAbility_Timer;
- uint32 CheckAddState_Timer;
- uint32 ResetTimer;
-
- uint32 PlayerClass;
+ boss_hex_lord_malacrassAI(Creature* creature) : BossAI(creature, DATA_HEXLORD) { }
void Reset() OVERRIDE
{
- instance->SetData(DATA_HEXLORDEVENT, NOT_STARTED);
-
- SpiritBolts_Timer = 20000;
- DrainPower_Timer = 60000;
- SiphonSoul_Timer = 100000;
- PlayerAbility_Timer = 99999;
- CheckAddState_Timer = 5000;
- ResetTimer = 5000;
-
- SpawnAdds();
-
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916);
- me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
+ _Reset();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS);
-
- DoZoneInCombat();
- me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
-
- for (uint8 i = 0; i < 4; ++i)
- {
- Creature* creature = Unit::GetCreature(*me, AddGUID[i]);
- if (creature && creature->IsAlive())
- creature->AI()->AttackStart(me->GetVictim());
- else
- {
- EnterEvadeMode();
- break;
- }
- }
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- switch (urand(0, 1))
- {
- case 0:
- me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
- break;
- case 1:
- me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO);
- break;
- }
+ Talk(SAY_AGGRO);
+ _EnterCombat();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
- instance->SetData(DATA_HEXLORDEVENT, DONE);
-
- me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_DEATH);
-
- for (uint8 i = 0; i < 4; ++i)
- {
- Unit* Temp = Unit::GetUnit(*me, AddGUID[i]);
- if (Temp && Temp->IsAlive())
- Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
- }
-
- void SelectAddEntry()
- {
- std::vector<uint32> AddList;
-
- for (uint8 i = 0; i < 8; ++i)
- AddList.push_back(AddEntryList[i]);
-
- while (AddList.size() > 4)
- AddList.erase(AddList.begin()+rand()%AddList.size());
-
- uint8 i = 0;
- for (std::vector<uint32>::const_iterator itr = AddList.begin(); itr != AddList.end(); ++itr, ++i)
- AddEntry[i] = *itr;
- }
-
- void SpawnAdds()
- {
- for (uint8 i = 0; i < 4; ++i)
- {
- Creature* creature = (Unit::GetCreature((*me), AddGUID[i]));
- if (!creature || !creature->IsAlive())
- {
- if (creature) creature->setDeathState(DEAD);
- creature = me->SummonCreature(AddEntry[i], Pos_X[i], POS_Y, POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0);
- if (creature) AddGUID[i] = creature->GetGUID();
- }
- else
- {
- creature->AI()->EnterEvadeMode();
- creature->SetPosition(Pos_X[i], POS_Y, POS_Z, ORIENT);
- creature->StopMoving();
- }
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (ResetTimer <= diff)
- {
- if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10))
- {
- EnterEvadeMode();
- return;
- }
- ResetTimer = 5000;
- } else ResetTimer -= diff;
-
- if (CheckAddState_Timer <= diff)
- {
- for (uint8 i = 0; i < 4; ++i)
- if (Creature* temp = Unit::GetCreature(*me, AddGUID[i]))
- if (temp->IsAlive() && !temp->GetVictim())
- temp->AI()->AttackStart(me->GetVictim());
-
- CheckAddState_Timer = 5000;
- } else CheckAddState_Timer -= diff;
-
- if (DrainPower_Timer <= diff)
- {
- DoCast(me, SPELL_DRAIN_POWER, true);
- me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER);
- DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear
- } else DrainPower_Timer -= diff;
-
- if (SpiritBolts_Timer <= diff)
- {
- if (DrainPower_Timer < 12000) // channel 10 sec
- SpiritBolts_Timer = 13000; // cast drain power first
- else
- {
- DoCast(me, SPELL_SPIRIT_BOLTS, false);
- me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS);
- SpiritBolts_Timer = 40000;
- SiphonSoul_Timer = 10000; // ready to drain
- PlayerAbility_Timer = 99999;
- }
- } else SpiritBolts_Timer -= diff;
-
- if (SiphonSoul_Timer <= diff)
- {
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true);
- Unit* trigger = DoSpawnCreature(NPC_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000);
- if (!target || !trigger)
- {
- EnterEvadeMode();
- return;
- }
- else
- {
- trigger->SetDisplayId(11686);
- trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- trigger->CastSpell(target, SPELL_SIPHON_SOUL, true);
- trigger->GetMotionMaster()->MoveChase(me);
-
- //DoCast(target, SPELL_SIPHON_SOUL, true);
- //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID());
- //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL);
-
- PlayerGUID = target->GetGUID();
- PlayerAbility_Timer = urand(8000, 10000);
- PlayerClass = target->getClass() - 1;
-
- if (PlayerClass == CLASS_DRUID-1)
- PlayerClass = CLASS_DRUID;
- else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473))
- PlayerClass = CLASS_PRIEST; // shadow priest
-
- SiphonSoul_Timer = 99999; // buff lasts 30 sec
- }
- } else SiphonSoul_Timer -= diff;
-
- if (PlayerAbility_Timer <= diff)
- {
- //Unit* target = Unit::GetUnit(*me, PlayerGUID);
- //if (target && target->IsAlive())
- //{
- UseAbility();
- PlayerAbility_Timer = urand(8000, 10000);
- //}
- } else PlayerAbility_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- void UseAbility()
- {
- uint8 random = urand(0, 2);
- Unit* target = NULL;
- switch (PlayerAbility[PlayerClass][random].target)
- {
- case ABILITY_TARGET_SELF:
- target = me;
- break;
- case ABILITY_TARGET_VICTIM:
- target = me->GetVictim();
- break;
- case ABILITY_TARGET_ENEMY:
- default:
- target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
- break;
- case ABILITY_TARGET_HEAL:
- target = DoSelectLowestHpFriendly(50, 0);
- break;
- case ABILITY_TARGET_BUFF:
- {
- std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, PlayerAbility[PlayerClass][random].spell);
- if (!templist.empty())
- target = *(templist.begin());
- }
- break;
- }
- if (target)
- DoCast(target, PlayerAbility[PlayerClass][random].spell, false);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_hex_lord_malacrassAI>(creature);
- }
-};
-
-class boss_thurg : public CreatureScript
-{
- public:
-
- boss_thurg()
- : CreatureScript("boss_thurg")
- {
- }
-
- struct boss_thurgAI : public boss_hexlord_addAI
- {
-
- boss_thurgAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 bloodlust_timer;
- uint32 cleave_timer;
-
- void Reset() OVERRIDE
- {
- bloodlust_timer = 15000;
- cleave_timer = 10000;
-
- boss_hexlord_addAI::Reset();
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (bloodlust_timer <= diff)
- {
- std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, SPELL_BLOODLUST);
- if (!templist.empty())
- {
- if (Unit* target = *(templist.begin()))
- DoCast(target, SPELL_BLOODLUST, false);
- }
- bloodlust_timer = 12000;
- } else bloodlust_timer -= diff;
-
- if (cleave_timer <= diff)
- {
- DoCastVictim(SPELL_CLEAVE, false);
- cleave_timer = 12000; //3 sec cast
- } else cleave_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_thurgAI>(creature);
- }
-};
-
-class boss_alyson_antille : public CreatureScript
-{
- public:
-
- boss_alyson_antille()
- : CreatureScript("boss_alyson_antille")
- {
- }
-
- struct boss_alyson_antilleAI : public boss_hexlord_addAI
- {
- //Holy Priest
- boss_alyson_antilleAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 flashheal_timer;
- uint32 dispelmagic_timer;
-
- void Reset() OVERRIDE
- {
- flashheal_timer = 2500;
- dispelmagic_timer = 10000;
-
- //AcquireGUID();
-
- boss_hexlord_addAI::Reset();
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who)
- return;
-
- if (who->isTargetableForAttack())
- {
- if (me->Attack(who, false))
- {
- me->GetMotionMaster()->MoveChase(who, 20);
- me->AddThreat(who, 0.0f);
- }
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (flashheal_timer <= diff)
- {
- Unit* target = DoSelectLowestHpFriendly(99, 30000);
- if (target)
- {
- if (target->IsWithinDistInMap(me, 50))
- DoCast(target, SPELL_FLASH_HEAL, false);
- else
- {
- // bugged
- //me->GetMotionMaster()->Clear();
- //me->GetMotionMaster()->MoveChase(target, 20);
- }
- }
- else
- {
- if (urand(0, 1))
- target = DoSelectLowestHpFriendly(50, 0);
- else
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- DoCast(target, SPELL_DISPEL_MAGIC, false);
- }
- flashheal_timer = 2500;
- } else flashheal_timer -= diff;
-
- /*if (dispelmagic_timer <= diff)
- {
- if (urand(0, 1))
- {
- Unit* target = SelectTarget();
-
- DoCast(target, SPELL_DISPEL_MAGIC, false);
- }
- else
- me->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DISPEL_MAGIC, false);
-
- dispelmagic_timer = 12000;
- } else dispelmagic_timer -= diff;*/
-
- boss_hexlord_addAI::UpdateAI(diff);
+ Talk(SAY_DEATH);
+ _JustDied();
}
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_alyson_antilleAI>(creature);
- }
-};
-
-struct boss_gazakrothAI : public boss_hexlord_addAI
-{
- boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 firebolt_timer;
-
- void Reset() OVERRIDE
- {
- firebolt_timer = 2000;
- boss_hexlord_addAI::Reset();
- }
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who)
- return;
-
- if (who->isTargetableForAttack())
- {
- if (me->Attack(who, false))
+ void KilledUnit(Unit* victim) OVERRIDE
{
- me->GetMotionMaster()->MoveChase(who, 20);
- me->AddThreat(who, 0.0f);
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (firebolt_timer <= diff)
- {
- DoCastVictim(SPELL_FIREBOLT, false);
- firebolt_timer = 700;
- } else firebolt_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
-};
-
-class boss_lord_raadan : public CreatureScript
-{
- public:
- boss_lord_raadan()
- : CreatureScript("boss_lord_raadan")
- {
- }
-
- struct boss_lord_raadanAI : public boss_hexlord_addAI
- {
- boss_lord_raadanAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 flamebreath_timer;
- uint32 thunderclap_timer;
-
- void Reset() OVERRIDE
- {
- flamebreath_timer = 8000;
- thunderclap_timer = 13000;
-
- boss_hexlord_addAI::Reset();
-
- }
void UpdateAI(uint32 diff) OVERRIDE
{
if (!UpdateVictim())
return;
- if (thunderclap_timer <= diff)
- {
- DoCastVictim(SPELL_THUNDERCLAP, false);
- thunderclap_timer = 12000;
- } else thunderclap_timer -= diff;
+ events.Update(diff);
- if (flamebreath_timer <= diff)
- {
- DoCastVictim(SPELL_FLAME_BREATH, false);
- flamebreath_timer = 12000;
- } else flamebreath_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_lord_raadanAI>(creature);
- }
-};
-
-class boss_darkheart : public CreatureScript
-{
- public:
-
- boss_darkheart()
- : CreatureScript("boss_darkheart")
- {
- }
-
- struct boss_darkheartAI : public boss_hexlord_addAI
- {
- boss_darkheartAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 psychicwail_timer;
-
- void Reset() OVERRIDE
- {
- psychicwail_timer = 8000;
- boss_hexlord_addAI::Reset();
- }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
- if (psychicwail_timer <= diff)
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCastVictim(SPELL_PSYCHIC_WAIL, false);
- psychicwail_timer = 12000;
- } else psychicwail_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_darkheartAI>(creature);
- }
-};
-
-
-class boss_slither : public CreatureScript
-{
- public:
-
- boss_slither()
- : CreatureScript("boss_slither")
- {
- }
-
- struct boss_slitherAI : public boss_hexlord_addAI
- {
- boss_slitherAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 venomspit_timer;
-
- void Reset() OVERRIDE
- {
- venomspit_timer = 5000;
- boss_hexlord_addAI::Reset();
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who)
- return;
-
- if (who->isTargetableForAttack())
- {
- if (me->Attack(who, false))
+ switch (eventId)
{
- me->GetMotionMaster()->MoveChase(who, 20);
- me->AddThreat(who, 0.0f);
+ default:
+ break;
}
}
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (venomspit_timer <= diff)
- {
- if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(victim, SPELL_VENOM_SPIT, false);
- venomspit_timer = 2500;
- } else venomspit_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_slitherAI>(creature);
- }
-};
-
-class boss_fenstalker : public CreatureScript
-{
- public:
-
- boss_fenstalker()
- : CreatureScript("boss_fenstalker")
- {
- }
-
- struct boss_fenstalkerAI : public boss_hexlord_addAI
- {
- boss_fenstalkerAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 volatileinf_timer;
-
- void Reset() OVERRIDE
- {
- volatileinf_timer = 15000;
- boss_hexlord_addAI::Reset();
-
- }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (volatileinf_timer <= diff)
- {
- // core bug
- me->GetVictim()->CastSpell(me->GetVictim(), SPELL_VOLATILE_INFECTION, false);
- volatileinf_timer = 12000;
- } else volatileinf_timer -= diff;
-
- boss_hexlord_addAI::UpdateAI(diff);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_fenstalkerAI>(creature);
- }
-};
-
-class boss_koragg : public CreatureScript
-{
- public:
-
- boss_koragg()
- : CreatureScript("boss_koragg")
- {
- }
-
- struct boss_koraggAI : public boss_hexlord_addAI
- {
- boss_koraggAI(Creature* creature) : boss_hexlord_addAI(creature) { }
-
- uint32 coldstare_timer;
- uint32 mightyblow_timer;
-
- void Reset() OVERRIDE
- {
- coldstare_timer = 15000;
- mightyblow_timer = 10000;
- boss_hexlord_addAI::Reset();
-
- }
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (mightyblow_timer <= diff)
- {
- DoCastVictim(SPELL_MIGHTY_BLOW, false);
- mightyblow_timer = 12000;
- }
- if (coldstare_timer <= diff)
- {
- if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(victim, SPELL_COLD_STARE, false);
- coldstare_timer = 12000;
- }
+ */
- boss_hexlord_addAI::UpdateAI(diff);
+ DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetInstanceAI<boss_koraggAI>(creature);
+ return GetInstanceAI<boss_hex_lord_malacrassAI>(creature);
}
};
@@ -988,14 +141,5 @@ class spell_hexlord_unstable_affliction : public SpellScriptLoader
void AddSC_boss_hex_lord_malacrass()
{
new boss_hexlord_malacrass();
- new boss_thurg();
- // new boss_gazakroth();
- new boss_lord_raadan();
- new boss_darkheart();
- new boss_slither();
- new boss_fenstalker();
- new boss_koragg();
- new boss_alyson_antille();
new spell_hexlord_unstable_affliction();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
index caf54313fe7..b0c008d897a 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,424 +15,83 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Janalai
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Aman
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
-#include "GridNotifiers.h"
-#include "CellImpl.h"
-enum Yells
+enum Says
{
- SAY_AGGRO = 0,
- SAY_FIRE_BOMBS = 1,
- SAY_SUMMON_HATCHER = 2,
- SAY_ALL_EGGS = 3,
- SAY_BERSERK = 4,
- SAY_SLAY = 5,
- SAY_DEATH = 6,
- SAY_EVENT_STRANGERS = 7,
- SAY_EVENT_FRIENDS = 8
+ SAY_AGGRO = 0,
+ SAY_PLAYER_KILL = 1,
+ SAY_SUMMON_HATCHER = 2,
+ SAY_FIRE_BOMB = 3,
+ SAY_HATCH_ALL_EGGS = 4,
+ EMOTE_FRENZY = 5,
+ SAY_DEATH = 6
};
enum Spells
{
- // Jan'alai
- SPELL_FLAME_BREATH = 43140,
- SPELL_FIRE_WALL = 43113,
- SPELL_ENRAGE = 44779,
- SPELL_SUMMON_PLAYERS = 43097,
- SPELL_TELE_TO_CENTER = 43098, // coord
- SPELL_HATCH_ALL = 43144,
- SPELL_BERSERK = 45078,
-
- // Fire Bob Spells
- SPELL_FIRE_BOMB_CHANNEL = 42621, // last forever
- SPELL_FIRE_BOMB_THROW = 42628, // throw visual
- SPELL_FIRE_BOMB_DUMMY = 42629, // bomb visual
- SPELL_FIRE_BOMB_DAMAGE = 42630,
-
- // Hatcher Spells
- SPELL_HATCH_EGG = 42471, // 43734
- SPELL_SUMMON_HATCHLING = 42493,
-
- // Hatchling Spells
- SPELL_FLAMEBUFFET = 43299
-};
-
-enum Creatures
-{
- NPC_AMANI_HATCHER = 23818,
- NPC_HATCHLING = 23598, // 42493
- NPC_EGG = 23817,
- NPC_FIRE_BOMB = 23920
-};
-
-const int area_dx = 44;
-const int area_dy = 51;
-
-float JanalainPos[1][3] =
-{
- {-33.93f, 1149.27f, 19}
};
-float FireWallCoords[4][4] =
+enum Events
{
- {-10.13f, 1149.27f, 19, 3.1415f},
- {-33.93f, 1123.90f, 19, 0.5f*3.1415f},
- {-54.80f, 1150.08f, 19, 0},
- {-33.93f, 1175.68f, 19, 1.5f*3.1415f}
};
-float hatcherway[2][5][3] =
-{
- {
- {-87.46f, 1170.09f, 6},
- {-74.41f, 1154.75f, 6},
- {-52.74f, 1153.32f, 19},
- {-33.37f, 1172.46f, 19},
- {-33.09f, 1203.87f, 19}
- },
- {
- {-86.57f, 1132.85f, 6},
- {-73.94f, 1146.00f, 6},
- {-52.29f, 1146.51f, 19},
- {-33.57f, 1125.72f, 19},
- {-34.29f, 1095.22f, 19}
- }
-};
class boss_janalai : public CreatureScript
{
public:
- boss_janalai()
- : CreatureScript("boss_janalai")
- {
- }
+ boss_janalai() : CreatureScript("boss_janalai") { }
- struct boss_janalaiAI : public ScriptedAI
+ struct boss_janalaiAI : public BossAI
{
- boss_janalaiAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 FireBreathTimer;
- uint32 BombTimer;
- uint32 BombSequenceTimer;
- uint32 BombCount;
- uint32 HatcherTimer;
- uint32 EnrageTimer;
-
- bool noeggs;
- bool enraged;
- bool isBombing;
-
- bool isFlameBreathing;
-
- uint64 FireBombGUIDs[40];
+ boss_janalaiAI(Creature* creature) : BossAI(creature, DATA_JANALAI) { }
void Reset() OVERRIDE
{
- instance->SetData(DATA_JANALAIEVENT, NOT_STARTED);
-
- FireBreathTimer = 8000;
- BombTimer = 30000;
- BombSequenceTimer = 1000;
- BombCount = 0;
- HatcherTimer = 10000;
- EnrageTimer = MINUTE*5*IN_MILLISECONDS;
-
- noeggs = false;
- isBombing =false;
- enraged = false;
-
- isFlameBreathing = false;
-
- for (uint8 i = 0; i < 40; ++i)
- FireBombGUIDs[i] = 0;
-
- HatchAllEggs(1);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- Talk(SAY_DEATH);
-
- instance->SetData(DATA_JANALAIEVENT, DONE);
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- Talk(SAY_SLAY);
+ _Reset();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- instance->SetData(DATA_JANALAIEVENT, IN_PROGRESS);
-
Talk(SAY_AGGRO);
- // DoZoneInCombat();
- }
-
- void DamageDealt(Unit* target, uint32 &damage, DamageEffectType /*damagetype*/) OVERRIDE
- {
- if (isFlameBreathing)
- {
- if (!me->HasInArc(M_PI/6, target))
- damage = 0;
- }
+ _EnterCombat();
}
- void FireWall()
- {
- uint8 WallNum;
- Creature* wall = NULL;
- for (uint8 i = 0; i < 4; ++i)
- {
- if (i == 0 || i == 2)
- WallNum = 3;
- else
- WallNum = 2;
-
- for (uint8 j = 0; j < WallNum; j++)
- {
- if (WallNum == 3)
- wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0], FireWallCoords[i][1]+5*(j-1), FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000);
- else
- wall = me->SummonCreature(NPC_FIRE_BOMB, FireWallCoords[i][0]-2+4*j, FireWallCoords[i][1], FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000);
- if (wall) wall->CastSpell(wall, SPELL_FIRE_WALL, true);
- }
- }
- }
-
- void SpawnBombs()
- {
- float dx, dy;
- for (int i(0); i < 40; ++i)
- {
- dx = float(irand(-area_dx/2, area_dx/2));
- dy = float(irand(-area_dy/2, area_dy/2));
-
- Creature* bomb = DoSpawnCreature(NPC_FIRE_BOMB, dx, dy, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000);
- if (bomb)
- FireBombGUIDs[i] = bomb->GetGUID();
- }
- BombCount = 0;
- }
-
- bool HatchAllEggs(uint32 action) //1: reset, 2: isHatching all
- {
- std::list<Creature*> templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- {
- CellCoord pair(Trinity::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Trinity::AllCreaturesOfEntryInRange check(me, NPC_EGG, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check);
-
- TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange());
- }
-
- //TC_LOG_ERROR("scripts", "Eggs %d at middle", templist.size());
- if (templist.empty())
- return false;
-
- for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
- {
- if (action == 1)
- (*i)->SetDisplayId(10056);
- else if (action == 2 &&(*i)->GetDisplayId() != 11686)
- (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
- }
- return true;
- }
-
- void Boom()
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- std::list<Creature*> templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- {
- CellCoord pair(Trinity::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Trinity::AllCreaturesOfEntryInRange check(me, NPC_FIRE_BOMB, 100);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check);
-
- TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange());
- }
- for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
- {
- (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true);
- (*i)->RemoveAllAuras();
- }
+ Talk(SAY_DEATH);
+ _JustDied();
}
- void HandleBombSequence()
+ void KilledUnit(Unit* victim) OVERRIDE
{
- if (BombCount < 40)
- {
- if (Unit* FireBomb = Unit::GetUnit(*me, FireBombGUIDs[BombCount]))
- {
- FireBomb->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- DoCast(FireBomb, SPELL_FIRE_BOMB_THROW, true);
- FireBomb->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
- ++BombCount;
- if (BombCount == 40)
- {
- BombSequenceTimer = 5000;
- } else BombSequenceTimer = 100;
- }
- else
- {
- Boom();
- isBombing = false;
- BombTimer = urand(20000, 40000);
- me->RemoveAurasDueToSpell(SPELL_FIRE_BOMB_CHANNEL);
- if (EnrageTimer <= 10000)
- EnrageTimer = 0;
- else
- EnrageTimer -= 10000;
- }
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 diff) OVERRIDE
{
- if (isFlameBreathing)
- {
- if (!me->IsNonMeleeSpellCast(false))
- isFlameBreathing = false;
- else
- return;
- }
-
- if (isBombing)
- {
- if (BombSequenceTimer <= diff)
- HandleBombSequence();
- else
- BombSequenceTimer -= diff;
- return;
- }
-
if (!UpdateVictim())
return;
- //enrage if under 25% hp before 5 min.
- if (!enraged && HealthBelowPct(25))
- EnrageTimer = 0;
+ events.Update(diff);
- if (EnrageTimer <= diff)
- {
- if (!enraged)
- {
- DoCast(me, SPELL_ENRAGE, true);
- enraged = true;
- EnrageTimer = 300000;
- }
- else
- {
- Talk(SAY_BERSERK);
- DoCast(me, SPELL_BERSERK, true);
- EnrageTimer = 300000;
- }
- } else EnrageTimer -= diff;
-
- if (BombTimer <= diff)
- {
- Talk(SAY_FIRE_BOMBS);
-
- me->AttackStop();
- me->GetMotionMaster()->Clear();
- DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
- me->StopMoving();
- DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false);
- //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0);
- //DoCast(me, SPELL_TELE_TO_CENTER, true);
-
- FireWall();
- SpawnBombs();
- isBombing = true;
- BombSequenceTimer = 100;
-
- //Teleport every Player into the middle
- Map* map = me->GetMap();
- if (!map->IsDungeon())
- return;
-
- Map::PlayerList const &PlayerList = map->GetPlayers();
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* i_pl = i->GetSource())
- if (i_pl->IsAlive())
- DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0);
- //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far
+ if (me->HasUnitState(UNIT_STATE_CASTING))
return;
- } else BombTimer -= diff;
-
- if (!noeggs)
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (HealthBelowPct(35))
+ switch (eventId)
{
- Talk(SAY_ALL_EGGS);
-
- me->AttackStop();
- me->GetMotionMaster()->Clear();
- DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]);
- me->StopMoving();
- DoCast(me, SPELL_HATCH_ALL, false);
- HatchAllEggs(2);
- noeggs = true;
+ default:
+ break;
}
- else if (HatcherTimer <= diff)
- {
- if (HatchAllEggs(0))
- {
- Talk(SAY_SUMMON_HATCHER);
- me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[0][0][0], hatcherway[0][0][1], hatcherway[0][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_AMANI_HATCHER, hatcherway[1][0][0], hatcherway[1][0][1], hatcherway[1][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- HatcherTimer = 90000;
- }
- else
- noeggs = true;
- } else HatcherTimer -= diff;
}
-
- EnterEvadeIfOutOfCombatArea(diff);
+ */
DoMeleeAttackIfReady();
-
- if (FireBreathTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- me->AttackStop();
- me->GetMotionMaster()->Clear();
- DoCast(target, SPELL_FLAME_BREATH, false);
- me->StopMoving();
- isFlameBreathing = true;
- }
- FireBreathTimer = 8000;
- } else FireBreathTimer -= diff;
}
};
@@ -443,270 +101,7 @@ class boss_janalai : public CreatureScript
}
};
-class npc_janalai_firebomb : public CreatureScript
-{
- public:
-
- npc_janalai_firebomb()
- : CreatureScript("npc_janalai_firebomb")
- {
- }
-
- struct npc_janalai_firebombAI : public ScriptedAI
- {
- npc_janalai_firebombAI(Creature* creature) : ScriptedAI(creature){ }
-
- void Reset() OVERRIDE { }
-
- void SpellHit(Unit* /*caster*/, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_FIRE_BOMB_THROW)
- DoCast(me, SPELL_FIRE_BOMB_DUMMY, true);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void AttackStart(Unit* /*who*/) OVERRIDE { }
-
- void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
-
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE { }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_janalai_firebombAI(creature);
- }
-};
-
-class npc_janalai_hatcher : public CreatureScript
-{
- public:
-
- npc_janalai_hatcher()
- : CreatureScript("npc_janalai_hatcher")
- {
- }
-
- struct npc_janalai_hatcherAI : public ScriptedAI
- {
- npc_janalai_hatcherAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 waypoint;
- uint32 HatchNum;
- uint32 WaitTimer;
-
- bool side;
- bool hasChangedSide;
- bool isHatching;
-
- void Reset() OVERRIDE
- {
- me->SetWalk(true);
- side =(me->GetPositionY() < 1150);
- waypoint = 0;
- isHatching = false;
- hasChangedSide = false;
- WaitTimer = 1;
- HatchNum = 0;
- }
-
- bool HatchEggs(uint32 num)
- {
- std::list<Creature*> templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- {
- CellCoord pair(Trinity::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Trinity::AllCreaturesOfEntryInRange check(me, 23817, 50);
- Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check);
-
- TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
- }
-
- //TC_LOG_ERROR("scripts", "Eggs %d at %d", templist.size(), side);
-
- for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end() && num > 0; ++i)
- if ((*i)->GetDisplayId() != 11686)
- {
- (*i)->CastSpell(*i, SPELL_HATCH_EGG, false);
- num--;
- }
-
- return num == 0; // if num == 0, no more templist
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
- void AttackStart(Unit* /*who*/) OVERRIDE { }
- void MoveInLineOfSight(Unit* /*who*/) OVERRIDE { }
-
- void MovementInform(uint32, uint32) OVERRIDE
- {
- if (waypoint == 5)
- {
- isHatching = true;
- HatchNum = 1;
- WaitTimer = 5000;
- }
- else
- WaitTimer = 1;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS))
- {
- me->DisappearAndDie();
- return;
- }
-
- if (!isHatching)
- {
- if (WaitTimer)
- {
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MovePoint(0, hatcherway[side][waypoint][0], hatcherway[side][waypoint][1], hatcherway[side][waypoint][2]);
- ++waypoint;
- WaitTimer = 0;
- }
- }
- else
- {
- if (WaitTimer <= diff)
- {
- if (HatchEggs(HatchNum))
- {
- ++HatchNum;
- WaitTimer = 10000;
- }
- else if (!hasChangedSide)
- {
- side = side ? 0 : 1;
- isHatching = false;
- waypoint = 3;
- WaitTimer = 1;
- hasChangedSide = true;
- }
- else
- me->DisappearAndDie();
-
- } else WaitTimer -= diff;
- }
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_janalai_hatcherAI>(creature);
- }
-};
-
-class npc_janalai_hatchling : public CreatureScript
-{
- public:
-
- npc_janalai_hatchling()
- : CreatureScript("npc_janalai_hatchling")
- {
- }
-
- struct npc_janalai_hatchlingAI : public ScriptedAI
- {
- npc_janalai_hatchlingAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 BuffetTimer;
-
- void Reset() OVERRIDE
- {
- BuffetTimer = 7000;
- if (me->GetPositionY() > 1150)
- me->GetMotionMaster()->MovePoint(0, hatcherway[0][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[0][3][2]);
- else
- me->GetMotionMaster()->MovePoint(0, hatcherway[1][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[1][3][2]);
-
- me->SetDisableGravity(true);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE {/*DoZoneInCombat();*/ }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS))
- {
- me->DisappearAndDie();
- return;
- }
-
- if (!UpdateVictim())
- return;
-
- if (BuffetTimer <= diff)
- {
- DoCastVictim(SPELL_FLAMEBUFFET, false);
- BuffetTimer = 10000;
- } else BuffetTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_janalai_hatchlingAI>(creature);
- }
-};
-
-class npc_janalai_egg : public CreatureScript
-{
-public:
- npc_janalai_egg(): CreatureScript("npc_janalai_egg") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_janalai_eggAI(creature);
- }
-
- struct npc_janalai_eggAI : public ScriptedAI
- {
- npc_janalai_eggAI(Creature* creature) : ScriptedAI(creature){ }
-
- void Reset() OVERRIDE { }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE { }
-
- void SpellHit(Unit* /*caster*/, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_HATCH_EGG)
- {
- DoCast(SPELL_SUMMON_HATCHLING);
- }
- }
- };
-
-};
-
void AddSC_boss_janalai()
{
new boss_janalai();
- new npc_janalai_firebomb();
- new npc_janalai_hatcher();
- new npc_janalai_hatchling();
- new npc_janalai_egg();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
index 5bd78006f95..ea97f44b829 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,433 +15,86 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Nalorakk
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Aman
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulaman.h"
-#include "GridNotifiers.h"
-#include "GridNotifiersImpl.h"
-#include "CellImpl.h"
-enum Spells
+enum Says
{
- SPELL_BERSERK = 45078,
-
- // Troll form
- SPELL_BRUTALSWIPE = 42384,
- SPELL_MANGLE = 42389,
- SPELL_MANGLEEFFECT = 44955,
- SPELL_SURGE = 42402,
- SPELL_BEARFORM = 42377,
-
- // Bear form
- SPELL_LACERATINGSLASH = 42395,
- SPELL_RENDFLESH = 42397,
- SPELL_DEAFENINGROAR = 42398
+ SAY_WAVE_1 = 0,
+ SAY_WAVE_2 = 1,
+ SAY_WAVE_3 = 2,
+ SAY_WAVE_4 = 3,
+ SAY_AGGRO = 4,
+ SAY_PLAYER_KILL = 5,
+ SAY_SURGE = 6,
+ EMOTE_SURGE = 7,
+ EMOTE_BEAR = 8,
+ SAY_BEAR = 9,
+ SAY_TROLL = 10,
+ SAY_DEATH = 11
};
-// Trash Waves
-float NalorakkWay[8][3] =
+enum Spells
{
- { 18.569f, 1414.512f, 11.42f}, // waypoint 1
- {-17.264f, 1419.551f, 12.62f},
- {-52.642f, 1419.357f, 27.31f}, // waypoint 2
- {-69.908f, 1419.721f, 27.31f},
- {-79.929f, 1395.958f, 27.31f},
- {-80.072f, 1374.555f, 40.87f}, // waypoint 3
- {-80.072f, 1314.398f, 40.87f},
- {-80.072f, 1295.775f, 48.60f} // waypoint 4
};
-#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!"
-#define SOUND_NALORAKK_WAVE1 12066
-#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?"
-#define SOUND_NALORAKK_WAVE2 12067
-#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!"
-#define SOUND_NALORAKK_WAVE3 12068
-#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!"
-#define SOUND_NALORAKK_WAVE4 12069
-
-//Unimplemented SoundIDs
-/*
-#define SOUND_NALORAKK_EVENT1 12078
-#define SOUND_NALORAKK_EVENT2 12079
-*/
-
-//General defines
-#define YELL_AGGRO "You be dead soon enough!"
-#define SOUND_YELL_AGGRO 12070
-#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?"
-#define SOUND_YELL_KILL_ONE 12075
-#define YELL_KILL_TWO "Da Amani gonna rule again!"
-#define SOUND_YELL_KILL_TWO 12076
-#define YELL_DEATH "I... be waitin' on da udda side...."
-#define SOUND_YELL_DEATH 12077
-#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear.
-#define SOUND_YELL_BERSERK 12074
-#define YELL_SURGE "I bring da pain!"
-#define SOUND_YELL_SURGE 12071
-
-#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!"
-#define SOUND_YELL_TOTROLL 12073
-
-
-#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!"
-#define SOUND_YELL_TOBEAR 12072
+enum Events
+{
+};
class boss_nalorakk : public CreatureScript
{
public:
- boss_nalorakk()
- : CreatureScript("boss_nalorakk")
- {
- }
+ boss_nalorakk() : CreatureScript("boss_nalorakk") { }
- struct boss_nalorakkAI : public ScriptedAI
+ struct boss_nalorakkAI : public BossAI
{
- boss_nalorakkAI(Creature* creature) : ScriptedAI(creature)
- {
- MoveEvent = true;
- MovePhase = 0;
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- uint32 BrutalSwipe_Timer;
- uint32 Mangle_Timer;
- uint32 Surge_Timer;
-
- uint32 LaceratingSlash_Timer;
- uint32 RendFlesh_Timer;
- uint32 DeafeningRoar_Timer;
-
- uint32 ShapeShift_Timer;
- uint32 Berserk_Timer;
-
- bool inBearForm;
- bool MoveEvent;
- bool inMove;
- uint32 MovePhase;
- uint32 waitTimer;
+ boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK) { }
void Reset() OVERRIDE
{
- if (MoveEvent)
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- inMove = false;
- waitTimer = 0;
- me->SetSpeed(MOVE_RUN, 2);
- me->SetWalk(false);
- }else
- {
- (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]);
- }
-
- instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED);
-
- Surge_Timer = urand(15000, 20000);
- BrutalSwipe_Timer = urand(7000, 12000);
- Mangle_Timer = urand(10000, 15000);
- ShapeShift_Timer = urand(45000, 50000);
- Berserk_Timer = 600000;
-
- inBearForm = false;
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id
- }
-
- void SendAttacker(Unit* target)
- {
- std::list<Creature*> templist;
- float x, y, z;
- me->GetPosition(x, y, z);
-
- {
- CellCoord pair(Trinity::ComputeCellCoord(x, y));
- Cell cell(pair);
- cell.SetNoCreate();
-
- Trinity::AllFriendlyCreaturesInGrid check(me);
- Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(me, templist, check);
-
- TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher);
-
- cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange());
- }
-
- if (templist.empty())
- return;
-
- for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i)
- {
- if ((*i) && me->IsWithinDistInMap((*i), 25))
- {
- (*i)->SetNoCallAssistance(true);
- (*i)->AI()->AttackStart(target);
- }
- }
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!MoveEvent)
- ScriptedAI::AttackStart(who);
- }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
- {
- if (!MoveEvent)
- {
- ScriptedAI::MoveInLineOfSight(who);
- }
- else
- {
- if (me->IsHostileTo(who))
- {
- if (!inMove)
- {
- switch (MovePhase)
- {
- case 0:
- if (me->IsWithinDistInMap(who, 50))
- {
- me->MonsterYell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE1);
-
- (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 2:
- if (me->IsWithinDistInMap(who, 40))
- {
- me->MonsterYell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE2);
-
- (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 5:
- if (me->IsWithinDistInMap(who, 40))
- {
- me->MonsterYell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE3);
-
- (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]);
- MovePhase ++;
- inMove = true;
-
- SendAttacker(who);
- }
- break;
- case 7:
- if (me->IsWithinDistInMap(who, 50))
- {
- SendAttacker(who);
-
- me->MonsterYell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4);
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
-
- MoveEvent = false;
- }
- break;
- }
- }
- }
- }
+ _Reset();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
- instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS);
-
- me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_AGGRO);
- DoZoneInCombat();
+ Talk(SAY_AGGRO);
+ _EnterCombat();
}
void JustDied(Unit* /*killer*/) OVERRIDE
{
- instance->SetData(DATA_NALORAKKEVENT, DONE);
-
- me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_DEATH);
+ Talk(SAY_DEATH);
+ _JustDied();
}
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ void KilledUnit(Unit* victim) OVERRIDE
{
- switch (urand(0, 1))
- {
- case 0:
- me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE);
- break;
- case 1:
- me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO);
- break;
- }
- }
-
- void MovementInform(uint32 type, uint32 id) OVERRIDE
- {
- if (MoveEvent)
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (!inMove)
- return;
-
- if (MovePhase != id)
- return;
-
- switch (MovePhase)
- {
- case 2:
- me->SetOrientation(3.1415f*2);
- inMove = false;
- return;
- case 1:
- case 3:
- case 4:
- case 6:
- MovePhase ++;
- waitTimer = 1;
- inMove = true;
- return;
- case 5:
- me->SetOrientation(3.1415f*0.5f);
- inMove = false;
- return;
- case 7:
- me->SetOrientation(3.1415f*0.5f);
- inMove = false;
- return;
- }
-
- }
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 diff) OVERRIDE
{
- if (waitTimer && inMove)
- {
- if (waitTimer <= diff)
- {
- (*me).GetMotionMaster()->MovementExpired();
- (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]);
- waitTimer = 0;
- } else waitTimer -= diff;
- }
-
if (!UpdateVictim())
return;
- if (Berserk_Timer <= diff)
- {
- DoCast(me, SPELL_BERSERK, true);
- me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_BERSERK);
- Berserk_Timer = 600000;
- } else Berserk_Timer -= diff;
+ events.Update(diff);
- if (ShapeShift_Timer <= diff)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (inBearForm)
- {
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);
- me->MonsterYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_TOTROLL);
- me->RemoveAurasDueToSpell(SPELL_BEARFORM);
- Surge_Timer = urand(15000, 20000);
- BrutalSwipe_Timer = urand(7000, 12000);
- Mangle_Timer = urand(10000, 15000);
- ShapeShift_Timer = urand(45000, 50000);
- inBearForm = false;
- }
- else
+ switch (eventId)
{
- // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);
- me->MonsterYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_TOBEAR);
- DoCast(me, SPELL_BEARFORM, true);
- LaceratingSlash_Timer = 2000; // dur 18s
- RendFlesh_Timer = 3000; // dur 5s
- DeafeningRoar_Timer = urand(5000, 10000); // dur 2s
- ShapeShift_Timer = urand(20000, 25000); // dur 30s
- inBearForm = true;
+ default:
+ break;
}
- } else ShapeShift_Timer -= diff;
-
- if (!inBearForm)
- {
- if (BrutalSwipe_Timer <= diff)
- {
- DoCastVictim(SPELL_BRUTALSWIPE);
- BrutalSwipe_Timer = urand(7000, 12000);
- } else BrutalSwipe_Timer -= diff;
-
- if (Mangle_Timer <= diff)
- {
- if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT))
- {
- DoCastVictim(SPELL_MANGLE);
- Mangle_Timer = 1000;
- }
- else Mangle_Timer = urand(10000, 15000);
- } else Mangle_Timer -= diff;
-
- if (Surge_Timer <= diff)
- {
- me->MonsterYell(YELL_SURGE, LANG_UNIVERSAL, NULL);
- DoPlaySoundToSet(me, SOUND_YELL_SURGE);
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true);
- if (target)
- DoCast(target, SPELL_SURGE);
- Surge_Timer = urand(15000, 20000);
- } else Surge_Timer -= diff;
- }
- else
- {
- if (LaceratingSlash_Timer <= diff)
- {
- DoCastVictim(SPELL_LACERATINGSLASH);
- LaceratingSlash_Timer = urand(18000, 23000);
- } else LaceratingSlash_Timer -= diff;
-
- if (RendFlesh_Timer <= diff)
- {
- DoCastVictim(SPELL_RENDFLESH);
- RendFlesh_Timer = urand(5000, 10000);
- } else RendFlesh_Timer -= diff;
-
- if (DeafeningRoar_Timer <= diff)
- {
- DoCastVictim(SPELL_DEAFENINGROAR);
- DeafeningRoar_Timer = urand(15000, 20000);
- } else DeafeningRoar_Timer -= diff;
}
+ */
DoMeleeAttackIfReady();
}
@@ -458,4 +110,3 @@ void AddSC_boss_nalorakk()
{
new boss_nalorakk();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp
deleted file mode 100644
index dbdc0b8e5c7..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Boss_ZulJin
-SD%Complete: 85%
-SDComment:
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulaman.h"
-#include "SpellInfo.h"
-
-enum Says
-{
- YELL_INTRO = 0,
- YELL_AGGRO = 1,
- YELL_TRANSFORM_TO_BEAR = 2,
- YELL_TRANSFORM_TO_EAGLE = 3,
- YELL_TRANSFORM_TO_LYNX = 4,
- YELL_TRANSFORM_TO_DRAGONHAWK = 5,
- YELL_FIRE_BREATH = 6,
- YELL_BERSERK = 7,
- YELL_KILL = 8,
- YELL_DEATH = 9
-};
-
-enum Spells
-{
- // Troll Form
- SPELL_WHIRLWIND = 17207,
- SPELL_GRIEVOUS_THROW = 43093, // remove debuff after full healed
- // Bear Form
- SPELL_CREEPING_PARALYSIS = 43095, // should cast on the whole raid
- SPELL_OVERPOWER = 43456, // use after melee attack dodged
- // Eagle Form
- SPELL_ENERGY_STORM = 43983, // enemy area aura, trigger 42577
- SPELL_ZAP_INFORM = 42577,
- SPELL_ZAP_DAMAGE = 43137, // 1250 damage
- SPELL_SUMMON_CYCLONE = 43112, // summon four feather vortex
- CREATURE_FEATHER_VORTEX = 24136,
- SPELL_CYCLONE_VISUAL = 43119, // trigger 43147 visual
- SPELL_CYCLONE_PASSIVE = 43120, // trigger 43121 (4y aoe) every second
- // Lynx Form
- SPELL_CLAW_RAGE_HASTE = 42583,
- SPELL_CLAW_RAGE_TRIGGER = 43149,
- SPELL_CLAW_RAGE_DAMAGE = 43150,
- SPELL_LYNX_RUSH_HASTE = 43152,
- SPELL_LYNX_RUSH_DAMAGE = 43153,
- // Dragonhawk Form
- SPELL_FLAME_WHIRL = 43213, // trigger two spells
- SPELL_FLAME_BREATH = 43215,
- SPELL_SUMMON_PILLAR = 43216, // summon 24187
- CREATURE_COLUMN_OF_FIRE = 24187,
- SPELL_PILLAR_TRIGGER = 43218, // trigger 43217
- // Cosmetic
- SPELL_SPIRIT_AURA = 42466,
- SPELL_SIPHON_SOUL = 43501,
- // Transforms:
- SPELL_SHAPE_OF_THE_BEAR = 42594, // 15% dmg
- SPELL_SHAPE_OF_THE_EAGLE = 42606,
- SPELL_SHAPE_OF_THE_LYNX = 42607, // haste melee 30%
- SPELL_SHAPE_OF_THE_DRAGONHAWK = 42608,
-
- SPELL_BERSERK = 45078
-};
-
-enum Phase
-{
- PHASE_BEAR = 0,
- PHASE_EAGLE = 1,
- PHASE_LYNX = 2,
- PHASE_DRAGONHAWK = 3,
- PHASE_TROLL = 4
-};
-
-//coords for going for changing form
-#define CENTER_X 120.148811f
-#define CENTER_Y 703.713684f
-#define CENTER_Z 45.111477f
-
-struct SpiritInfoStruct
-{
- uint32 entry;
- float x, y, z, orient;
-};
-
-static SpiritInfoStruct SpiritInfo[4] =
-{
- {23878, 147.87f, 706.51f, 45.11f, 3.04f},
- {23880, 88.95f, 705.49f, 45.11f, 6.11f},
- {23877, 137.23f, 725.98f, 45.11f, 3.71f},
- {23879, 104.29f, 726.43f, 45.11f, 5.43f}
-};
-
-struct TransformStruct
-{
- uint8 text;
- uint32 spell, unaura;
-};
-
-static TransformStruct Transform[4] =
-{
- {YELL_TRANSFORM_TO_BEAR, SPELL_SHAPE_OF_THE_BEAR, SPELL_WHIRLWIND},
- {YELL_TRANSFORM_TO_EAGLE, SPELL_SHAPE_OF_THE_EAGLE, SPELL_SHAPE_OF_THE_BEAR},
- {YELL_TRANSFORM_TO_LYNX, SPELL_SHAPE_OF_THE_LYNX, SPELL_SHAPE_OF_THE_EAGLE},
- {YELL_TRANSFORM_TO_DRAGONHAWK, SPELL_SHAPE_OF_THE_DRAGONHAWK, SPELL_SHAPE_OF_THE_LYNX}
-};
-
-class boss_zuljin : public CreatureScript
-{
- public:
-
- boss_zuljin()
- : CreatureScript("boss_zuljin")
- {
- }
-
- struct boss_zuljinAI : public ScriptedAI
- {
- boss_zuljinAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- instance = creature->GetInstanceScript();
- }
- InstanceScript* instance;
-
- uint64 SpiritGUID[4];
- uint64 ClawTargetGUID;
- uint64 TankGUID;
-
- uint32 Phase;
- uint32 health_20;
-
- uint32 Intro_Timer;
- uint32 Berserk_Timer;
-
- uint32 Whirlwind_Timer;
- uint32 Grievous_Throw_Timer;
-
- uint32 Creeping_Paralysis_Timer;
- uint32 Overpower_Timer;
-
- uint32 Claw_Rage_Timer;
- uint32 Lynx_Rush_Timer;
- uint32 Claw_Counter;
- uint32 Claw_Loop_Timer;
-
- uint32 Flame_Whirl_Timer;
- uint32 Flame_Breath_Timer;
- uint32 Pillar_Of_Fire_Timer;
-
- SummonList Summons;
-
- void Reset() OVERRIDE
- {
- instance->SetData(DATA_ZULJINEVENT, NOT_STARTED);
-
- Phase = 0;
-
- health_20 = me->CountPctFromMaxHealth(20);
-
- Intro_Timer = 37000;
- Berserk_Timer = 600000;
-
- Whirlwind_Timer = 7000;
- Grievous_Throw_Timer = 8000;
-
- Creeping_Paralysis_Timer = 7000;
- Overpower_Timer = 0;
-
- Claw_Rage_Timer = 5000;
- Lynx_Rush_Timer = 14000;
- Claw_Loop_Timer = 0;
- Claw_Counter = 0;
-
- Flame_Whirl_Timer = 5000;
- Flame_Breath_Timer = 6000;
- Pillar_Of_Fire_Timer = 7000;
-
- ClawTargetGUID = 0;
- TankGUID = 0;
-
- Summons.DespawnAll();
-
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 33975);
- //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674);
- //me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- instance->SetData(DATA_ZULJINEVENT, IN_PROGRESS);
-
- DoZoneInCombat();
-
- Talk(YELL_INTRO);
- SpawnAdds();
- EnterPhase(0);
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- if (Intro_Timer)
- return;
-
- Talk(YELL_KILL);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- instance->SetData(DATA_ZULJINEVENT, DONE);
-
- Talk(YELL_DEATH);
- Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE);
-
- if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[3]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
- }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (Phase == 2)
- AttackStartNoMove(who);
- else
- ScriptedAI::AttackStart(who);
- }
-
- void DoMeleeAttackIfReady()
- {
- if (!me->IsNonMeleeSpellCast(false))
- {
- if (me->isAttackReady() && me->IsWithinMeleeRange(me->GetVictim()))
- {
- if (Phase == 1 && !Overpower_Timer)
- {
- uint32 health = me->GetVictim()->GetHealth();
- me->AttackerStateUpdate(me->GetVictim());
- if (me->GetVictim() && health == me->GetVictim()->GetHealth())
- {
- DoCastVictim(SPELL_OVERPOWER, false);
- Overpower_Timer = 5000;
- }
- } else me->AttackerStateUpdate(me->GetVictim());
- me->resetAttackTimer();
- }
- }
- }
-
- void SpawnAdds()
- {
- Creature* creature = NULL;
- for (uint8 i = 0; i < 4; ++i)
- {
- creature = me->SummonCreature(SpiritInfo[i].entry, SpiritInfo[i].x, SpiritInfo[i].y, SpiritInfo[i].z, SpiritInfo[i].orient, TEMPSUMMON_DEAD_DESPAWN, 0);
- if (creature)
- {
- creature->CastSpell(creature, SPELL_SPIRIT_AURA, true);
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- SpiritGUID[i] = creature->GetGUID();
- }
- }
- }
-
- void DespawnAdds()
- {
- for (uint8 i = 0; i < 4; ++i)
- {
- if (SpiritGUID[i])
- {
- if (Unit* temp = Unit::GetUnit(*me, SpiritGUID[i]))
- {
- temp->SetVisible(false);
- temp->setDeathState(DEAD);
- }
- }
- SpiritGUID[i] = 0;
- }
- }
-
- void JustSummoned(Creature* summon) OVERRIDE
- {
- Summons.Summon(summon);
- }
-
- void SummonedCreatureDespawn(Creature* summon) OVERRIDE
- {
- Summons.Despawn(summon);
- }
-
- void EnterPhase(uint32 NextPhase)
- {
- switch (NextPhase)
- {
- case 0:
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- DoTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, 100);
- DoResetThreat();
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
- me->RemoveAurasDueToSpell(Transform[Phase].unaura);
- DoCast(me, Transform[Phase].spell);
- Talk(Transform[Phase].text);
- if (Phase > 0)
- {
- if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[Phase - 1]))
- Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
- }
- if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[NextPhase - 1]))
- Temp->CastSpell(me, SPELL_SIPHON_SOUL, false); // should m cast on temp
- if (NextPhase == 2)
- {
- me->GetMotionMaster()->Clear();
- DoCast(me, SPELL_ENERGY_STORM, true); // enemy aura
- for (uint8 i = 0; i < 4; ++i)
- {
- Creature* Vortex = DoSpawnCreature(CREATURE_FEATHER_VORTEX, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
- if (Vortex)
- {
- Vortex->CastSpell(Vortex, SPELL_CYCLONE_PASSIVE, true);
- Vortex->CastSpell(Vortex, SPELL_CYCLONE_VISUAL, true);
- Vortex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Vortex->SetSpeed(MOVE_RUN, 1.0f);
- Vortex->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0));
- DoZoneInCombat(Vortex);
- }
- }
- }
- else
- me->AI()->AttackStart(me->GetVictim());
- if (NextPhase == 3)
- {
- me->RemoveAurasDueToSpell(SPELL_ENERGY_STORM);
- Summons.DespawnEntry(CREATURE_FEATHER_VORTEX);
- me->GetMotionMaster()->MoveChase(me->GetVictim());
- }
- break;
- default:
- break;
- }
- Phase = NextPhase;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!TankGUID)
- {
- if (!UpdateVictim())
- return;
-
- if (me->GetHealth() < health_20 * (4 - Phase))
- EnterPhase(Phase + 1);
- }
-
- if (Berserk_Timer <= diff)
- {
- DoCast(me, SPELL_BERSERK, true);
- Talk(YELL_BERSERK);
- Berserk_Timer = 60000;
- } else Berserk_Timer -= diff;
-
- switch (Phase)
- {
- case 0:
- if (Intro_Timer)
- {
- if (Intro_Timer <= diff)
- {
- Talk(YELL_AGGRO);
- Intro_Timer = 0;
- } else Intro_Timer -= diff;
- }
-
- if (Whirlwind_Timer <= diff)
- {
- DoCast(me, SPELL_WHIRLWIND);
- Whirlwind_Timer = urand(15000, 20000);
- } else Whirlwind_Timer -= diff;
-
- if (Grievous_Throw_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_GRIEVOUS_THROW, false);
- Grievous_Throw_Timer = 10000;
- } else Grievous_Throw_Timer -= diff;
- break;
-
- case 1:
- if (Creeping_Paralysis_Timer <= diff)
- {
- DoCast(me, SPELL_CREEPING_PARALYSIS);
- Creeping_Paralysis_Timer = 20000;
- } else Creeping_Paralysis_Timer -= diff;
-
- if (Overpower_Timer <= diff)
- {
- // implemented in DoMeleeAttackIfReady()
- Overpower_Timer = 0;
- } else Overpower_Timer -= diff;
- break;
-
- case 2:
- return;
-
- case 3:
- if (Claw_Rage_Timer <= diff)
- {
- if (!TankGUID)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- TankGUID = me->GetVictim()->GetGUID();
- me->SetSpeed(MOVE_RUN, 5.0f);
- AttackStart(target); // change victim
- Claw_Rage_Timer = 0;
- Claw_Loop_Timer = 500;
- Claw_Counter = 0;
- }
- }
- else if (!Claw_Rage_Timer) // do not do this when Lynx_Rush
- {
- if (Claw_Loop_Timer <= diff)
- {
- Unit* target = me->GetVictim();
- if (!target || !target->isTargetableForAttack()) target = Unit::GetUnit(*me, TankGUID);
- if (!target || !target->isTargetableForAttack()) target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- {
- AttackStart(target);
- if (me->IsWithinMeleeRange(target))
- {
- DoCast(target, SPELL_CLAW_RAGE_DAMAGE, true);
- ++Claw_Counter;
- if (Claw_Counter == 12)
- {
- Claw_Rage_Timer = urand(15000, 20000);
- me->SetSpeed(MOVE_RUN, 1.2f);
- AttackStart(Unit::GetUnit(*me, TankGUID));
- TankGUID = 0;
- return;
- }
- else
- Claw_Loop_Timer = 500;
- }
- }
- else
- {
- EnterEvadeMode(); // if (target)
- return;
- }
- } else Claw_Loop_Timer -= diff;
- } //if (TankGUID)
- } else Claw_Rage_Timer -= diff;
-
- if (Lynx_Rush_Timer <= diff)
- {
- if (!TankGUID)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- TankGUID = me->GetVictim()->GetGUID();
- me->SetSpeed(MOVE_RUN, 5.0f);
- AttackStart(target); // change victim
- Lynx_Rush_Timer = 0;
- Claw_Counter = 0;
- }
- }
- else if (!Lynx_Rush_Timer)
- {
- Unit* target = me->GetVictim();
- if (!target || !target->isTargetableForAttack())
- {
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- AttackStart(target);
- }
- if (target)
- {
- if (me->IsWithinMeleeRange(target))
- {
- DoCast(target, SPELL_LYNX_RUSH_DAMAGE, true);
- ++Claw_Counter;
- if (Claw_Counter == 9)
- {
- Lynx_Rush_Timer = urand(15000, 20000);
- me->SetSpeed(MOVE_RUN, 1.2f);
- AttackStart(Unit::GetUnit(*me, TankGUID));
- TankGUID = 0;
- }
- else
- AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0));
- }
- }
- else
- {
- EnterEvadeMode(); // if (target)
- return;
- }
- } //if (TankGUID)
- } else Lynx_Rush_Timer -= diff;
-
- break;
- case 4:
- if (Flame_Whirl_Timer <= diff)
- {
- DoCast(me, SPELL_FLAME_WHIRL);
- Flame_Whirl_Timer = 12000;
- }Flame_Whirl_Timer -= diff;
-
- if (Pillar_Of_Fire_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_SUMMON_PILLAR);
- Pillar_Of_Fire_Timer = 10000;
- } else Pillar_Of_Fire_Timer -= diff;
-
- if (Flame_Breath_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- me->SetInFront(target);
- DoCast(me, SPELL_FLAME_BREATH);
- Flame_Breath_Timer = 10000;
- } else Flame_Breath_Timer -= diff;
- break;
-
- default:
- break;
- }
-
- if (!TankGUID)
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_zuljinAI>(creature);
- }
-};
-
-class npc_zuljin_vortex : public CreatureScript
-{
- public:
-
- npc_zuljin_vortex()
- : CreatureScript("npc_zuljin_vortex")
- {
- }
-
- struct npc_zuljin_vortexAI : public ScriptedAI
- {
- npc_zuljin_vortexAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* /*target*/) OVERRIDE { }
-
- void SpellHit(Unit* caster, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_ZAP_INFORM)
- DoCast(caster, SPELL_ZAP_DAMAGE, true);
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- //if the vortex reach the target, it change his target to another player
- if (me->IsWithinMeleeRange(me->GetVictim()))
- AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0));
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_zuljin_vortexAI(creature);
- }
-};
-
-void AddSC_boss_zuljin()
-{
- new boss_zuljin();
- new npc_zuljin_vortex();
-}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
index 2347de4fa66..351596300d7 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp
@@ -1,6 +1,5 @@
- /*
+/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,136 +15,69 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: instance_zulaman
-SD%Complete: 80
-SDComment:
-SDCategory: Zul'Aman
-EndScriptData */
-
#include "ScriptMgr.h"
#include "InstanceScript.h"
+#include "ScriptedCreature.h"
#include "zulaman.h"
-#include "Player.h"
-#include "TemporarySummon.h"
-
-enum Misc
-{
- MAX_ENCOUNTER = 7,
- RAND_VENDOR = 2,
- WORLDSTATE_SHOW_TIMER = 3104,
- WORLDSTATE_TIME_TO_SACRIFICE = 3106
-};
-
-// Chests spawn at bear/eagle/dragonhawk/lynx bosses
-// The loots depend on how many bosses have been killed, but not the entries of the chests
-// But we cannot add loots to gameobject, so we have to use the fixed loot_template
-struct SHostageInfo
-{
- uint32 npc, go; // FIXME go Not used
- float x, y, z, o;
-};
-
-static SHostageInfo HostageInfo[] =
-{
- {23790, 186648, -57, 1343, 40.77f, 3.2f}, // bear
- {23999, 187021, 400, 1414, 74.36f, 3.3f}, // eagle
- {24001, 186672, -35, 1134, 18.71f, 1.9f}, // dragonhawk
- {24024, 186667, 413, 1117, 6.32f, 3.1f} // lynx
-};
-
-Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f};
class instance_zulaman : public InstanceMapScript
{
public:
- instance_zulaman()
- : InstanceMapScript("instance_zulaman", 568)
- {
- }
+ instance_zulaman() : InstanceMapScript(ZulAmanScriptName, 568) { }
- struct instance_zulaman_InstanceMapScript : public InstanceScript
+ struct instance_zulaman_InstanceScript : public InstanceScript
{
- instance_zulaman_InstanceMapScript(Map* map) : InstanceScript(map) { }
-
- uint64 HarkorsSatchelGUID;
- uint64 TanzarsTrunkGUID;
- uint64 AshlisBagGUID;
- uint64 KrazsPackageGUID;
- uint64 StrangeGongGUID;
- uint64 HarrisonJonesGUID;
-
- uint64 HexLordGateGUID;
- uint64 ZulJinGateGUID;
- uint64 MassiveGateGUID;
- uint64 AkilzonDoorGUID;
- uint64 ZulJinDoorGUID;
- uint64 HalazziDoorGUID;
-
- uint32 QuestTimer;
- uint16 BossKilled;
- uint16 QuestMinute;
- uint16 ChestLooted;
-
- uint32 m_auiEncounter[MAX_ENCOUNTER];
- uint32 RandVendor[RAND_VENDOR];
-
- void Initialize() OVERRIDE
+ instance_zulaman_InstanceScript(InstanceMap* map) : InstanceScript(map)
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
-
- HarkorsSatchelGUID = 0;
- TanzarsTrunkGUID = 0;
- AshlisBagGUID = 0;
- KrazsPackageGUID = 0;
- StrangeGongGUID = 0;
- HexLordGateGUID = 0;
- ZulJinGateGUID = 0;
- MassiveGateGUID = 0;
- AkilzonDoorGUID = 0;
- HalazziDoorGUID = 0;
- ZulJinDoorGUID = 0;
-
- HarrisonJonesGUID = 0;
-
- QuestTimer = 0;
- QuestMinute = 0;
- BossKilled = 0;
- ChestLooted = 0;
-
- for (uint8 i = 0; i < RAND_VENDOR; ++i)
- RandVendor[i] = NOT_STARTED;
-
- m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED;
- }
-
- bool IsEncounterInProgress() const OVERRIDE
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (m_auiEncounter[i] == IN_PROGRESS)
- return true;
-
- return false;
+ SetBossNumber(EncounterCount);
+
+ AkilzonGUID = 0;
+ NalorakkGUID = 0;
+ JanalaiGUID = 0;
+ HalazziGUID = 0;
+ HexLordMalacrassGUID = 0;
+ DaakaraGUID = 0;
+ VoljinGUID = 0;
+ HexLordTriggerGUID = 0;
+ SpeedRunTimer = 16;
+ ZulAmanState = NOT_STARTED;
+ ZulAmanBossCount = 0;
}
- void OnPlayerEnter(Player* /*player*/)
+ void FillInitialWorldStates(WorldPacket& packet) OVERRIDE
{
- if (!HarrisonJonesGUID)
- instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc);
+ packet << uint32(WORLD_STATE_ZULAMAN_TIMER_ENABLED) << uint32(ZulAmanState ? 1 : 0);
+ packet << uint32(WORLD_STATE_ZULAMAN_TIMER) << uint32(SpeedRunTimer);
}
void OnCreatureCreate(Creature* creature) OVERRIDE
{
switch (creature->GetEntry())
{
- case NPC_HARRISON_JONES:
- HarrisonJonesGUID = creature->GetGUID();
+ case NPC_AKILZON:
+ AkilzonGUID = creature->GetGUID();
+ break;
+ case NPC_NALORAKK:
+ NalorakkGUID = creature->GetGUID();
break;
case NPC_JANALAI:
- case NPC_ZULJIN:
- case NPC_HEXLORD:
+ JanalaiGUID = creature->GetGUID();
+ break;
case NPC_HALAZZI:
- case NPC_NALORAKK:
+ HalazziGUID = creature->GetGUID();
+ break;
+ case NPC_HEXLORD:
+ HexLordMalacrassGUID = creature->GetGUID();
+ break;
+ case NPC_DAAKARA:
+ DaakaraGUID = creature->GetGUID();
+ break;
+ case NPC_VOLJIN:
+ VoljinGUID = creature->GetGUID();
+ break;
+ case NPC_HEXLORD_TRIGGER:
+ HexLordTriggerGUID = creature->GetGUID();
+ break;
default:
break;
}
@@ -155,219 +87,261 @@ class instance_zulaman : public InstanceMapScript
{
switch (go->GetEntry())
{
- case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break;
- case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break;
- case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break;
- case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break;
- case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break;
- case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break;
-
- case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break;
- case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break;
- case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break;
- case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break;
- case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break;
- default: break;
+ case GO_STRANGE_GONG:
+ StrangeGongGUID = go->GetGUID();
+ break;
+ case GO_MASSIVE_GATE:
+ MasiveGateGUID = go->GetGUID();
+ AddDoor(go, true);
+ if (ZulAmanState != NOT_STARTED)
+ go->SetGoState(GO_STATE_ACTIVE);
+ break;
+ default:
+ break;
}
- CheckInstanceStatus();
}
- void SummonHostage(uint8 num)
+ void OnGameObjectRemove(GameObject* go) OVERRIDE
{
- if (!QuestMinute)
- return;
-
- Map::PlayerList const &PlayerList = instance->GetPlayers();
- if (PlayerList.isEmpty())
- return;
-
- Map::PlayerList::const_iterator i = PlayerList.begin();
- if (Player* i_pl = i->GetSource())
+ switch (go->GetEntry())
{
- if (Unit* Hostage = i_pl->SummonCreature(HostageInfo[num].npc, HostageInfo[num].x, HostageInfo[num].y, HostageInfo[num].z, HostageInfo[num].o, TEMPSUMMON_DEAD_DESPAWN, 0))
- {
- Hostage->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- Hostage->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
+ case GO_MASSIVE_GATE:
+ AddDoor(go, false);
+ break;
+ default:
+ break;
}
}
- void CheckInstanceStatus()
+ uint64 GetData64(uint32 type) const OVERRIDE
{
- if (BossKilled >= DATA_HALAZZIEVENT)
- HandleGameObject(HexLordGateGUID, true);
+ switch (type)
+ {
+ case DATA_AKILZON:
+ return AkilzonGUID;
+ case DATA_NALORAKK:
+ return NalorakkGUID;
+ case DATA_JANALAI:
+ return JanalaiGUID;
+ case DATA_HALAZZI:
+ return HalazziGUID;
+ case DATA_HEXLORD:
+ return HexLordMalacrassGUID;
+ case DATA_DAAKARA:
+ return DaakaraGUID;
+ case DATA_HEXLORD_TRIGGER:
+ return HexLordTriggerGUID;
+ case DATA_STRANGE_GONG:
+ return StrangeGongGUID;
+ case DATA_MASSIVE_GATE:
+ return MasiveGateGUID;
+ default:
+ break;
+ }
- if (BossKilled >= DATA_HEXLORDEVENT)
- HandleGameObject(ZulJinGateGUID, true);
+ return 0;
}
- std::string GetSaveData() OVERRIDE
+ void SetData(uint32 type, uint32 data) OVERRIDE
{
- OUT_SAVE_INST_DATA;
-
- std::ostringstream ss;
- ss << "S " << BossKilled << ' ' << ChestLooted << ' ' << QuestMinute;
-
- OUT_SAVE_INST_DATA_COMPLETE;
- return ss.str();
+ switch (type)
+ {
+ case DATA_ZULAMAN_STATE:
+ {
+ if (data == IN_PROGRESS)
+ {
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1);
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, 15);
+ events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000);
+ SpeedRunTimer = 15;
+ ZulAmanState = data;
+ SaveToDB();
+ }
+ break;
+ }
+ default:
+ break;
+ }
}
- void Load(const char* load)
+ uint32 GetData(uint32 type) const OVERRIDE
{
- if (!load)
- return;
-
- std::istringstream ss(load);
- //TC_LOG_ERROR("scripts", "Zul'aman loaded, %s.", ss.str().c_str());
- char dataHead; // S
- uint16 data1, data2, data3;
- ss >> dataHead >> data1 >> data2 >> data3;
- //TC_LOG_ERROR("scripts", "Zul'aman loaded, %d %d %d.", data1, data2, data3);
- if (dataHead == 'S')
+ switch (type)
{
- BossKilled = data1;
- ChestLooted = data2;
- QuestMinute = data3;
- } else TC_LOG_ERROR("scripts", "Zul'aman: corrupted save data.");
+ case DATA_ZULAMAN_STATE:
+ return ZulAmanState;
+ default:
+ break;
+ }
+
+ return 0;
}
- void SetData(uint32 type, uint32 data) OVERRIDE
+ bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
- switch (type)
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ if (state == DONE)
{
- case DATA_GONGEVENT:
- m_auiEncounter[DATA_GONGEVENT] = data;
- if (data == IN_PROGRESS)
- SaveToDB();
- else if (data == DONE)
- QuestMinute = 21;
- break;
- case DATA_NALORAKKEVENT:
- m_auiEncounter[DATA_NALORAKKEVENT] = data;
- if (data == DONE)
+ if (ZulAmanState == IN_PROGRESS && SpeedRunTimer)
{
- if (QuestMinute)
+ ++ZulAmanBossCount;
+
+ if (ZulAmanBossCount < 2)
{
- QuestMinute += 15;
- DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
+ SpeedRunTimer = SpeedRunTimer + 5;
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer);
}
- SummonHostage(0);
- }
- break;
- case DATA_AKILZONEVENT:
- m_auiEncounter[DATA_AKILZONEVENT] = data;
- HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS);
- if (data == DONE)
- {
- if (QuestMinute)
+ else if (ZulAmanBossCount == 4)
{
- QuestMinute += 10;
- DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0);
+ events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER);
+ ZulAmanState = DONE;
}
- SummonHostage(1);
}
- break;
- case DATA_JANALAIEVENT:
- m_auiEncounter[DATA_JANALAIEVENT] = data;
- if (data == DONE)
- SummonHostage(2);
- break;
- case DATA_HALAZZIEVENT:
- m_auiEncounter[DATA_HALAZZIEVENT] = data;
- HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS);
- if (data == DONE) SummonHostage(3);
- break;
- case DATA_HEXLORDEVENT:
- m_auiEncounter[DATA_HEXLORDEVENT] = data;
- if (data == IN_PROGRESS)
- HandleGameObject(HexLordGateGUID, false);
- else if (data == NOT_STARTED)
- CheckInstanceStatus();
- break;
- case DATA_ZULJINEVENT:
- m_auiEncounter[DATA_ZULJINEVENT] = data;
- HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS);
- break;
- case DATA_CHESTLOOTED:
- ++ChestLooted;
- SaveToDB();
- break;
- case TYPE_RAND_VENDOR_1:
- RandVendor[0] = data;
- break;
- case TYPE_RAND_VENDOR_2:
- RandVendor[1] = data;
- break;
}
- if (data == DONE)
+ switch (type)
{
- ++BossKilled;
- if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT)
- {
- QuestMinute = 0;
- DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0);
- }
- CheckInstanceStatus();
- SaveToDB();
+ case DATA_AKILZON:
+ break;
+ case DATA_NALORAKK:
+ break;
+ case DATA_JANALAI:
+ break;
+ case DATA_HALAZZI:
+ case DATA_HEXLORD:
+ case DATA_DAAKARA:
+ break;
+ default:
+ break;
}
+
+ return true;
}
- uint32 GetData(uint32 type) const OVERRIDE
+ void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) OVERRIDE
{
- switch (type)
+ switch (eventId)
{
- case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT];
- case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT];
- case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT];
- case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT];
- case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT];
- case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT];
- case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT];
- case DATA_CHESTLOOTED: return ChestLooted;
- case TYPE_RAND_VENDOR_1: return RandVendor[0];
- case TYPE_RAND_VENDOR_2: return RandVendor[1];
- default: return 0;
+ case EVENT_START_ZULAMAN:
+ if (Creature* voljin = instance->GetCreature(VoljinGUID))
+ {
+ if (voljin->IsAIEnabled)
+ voljin->AI()->DoAction(ACTION_START_ZULAMAN);
+ }
+ break;
+ default:
+ break;
}
}
- void Update(uint32 diff) OVERRIDE
+ void Update(uint32 diff)
{
- if (QuestMinute)
+ if (events.Empty())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (QuestTimer <= diff)
+ switch (eventId)
{
- QuestMinute--;
- SaveToDB();
- QuestTimer += 60000;
- if (QuestMinute)
- {
- DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1);
- DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute);
- } else DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0);
+ case EVENT_UPDATE_ZULAMAN_TIMER:
+ SaveToDB();
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, --SpeedRunTimer);
+ if (SpeedRunTimer)
+ events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000);
+ else
+ {
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0);
+ events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER);
+ ZulAmanState = FAIL;
+ }
+ break;
+ default:
+ break;
}
- QuestTimer -= diff;
}
}
- uint64 GetData64(uint32 type) const OVERRIDE
+ std::string GetSaveData() OVERRIDE
{
- switch (type)
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "Z A " << GetBossSaveData() << ZulAmanState
+ << ' ' << SpeedRunTimer << ' ' << ZulAmanBossCount;
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(char const* str) OVERRIDE
+ {
+ if (!str)
{
- case GO_STRANGE_GONG:
- return StrangeGongGUID;
- case GO_MASSIVE_GATE:
- return MassiveGateGUID;
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
}
- return 0;
+ OUT_LOAD_INST_DATA(str);
+
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
+
+ if (dataHead1 == 'Z' && dataHead2 == 'A')
+ {
+ for (uint8 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+
+ SetBossState(i, EncounterState(tmpState));
+ }
+
+ loadStream >> ZulAmanState;
+ loadStream >> SpeedRunTimer;
+ loadStream >> ZulAmanBossCount;
+
+ if (ZulAmanState == IN_PROGRESS && SpeedRunTimer && SpeedRunTimer <= 15)
+ {
+ events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000);
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1);
+ DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer);
+ }
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
}
+ protected:
+ EventMap events;
+ uint64 AkilzonGUID;
+ uint64 NalorakkGUID;
+ uint64 JanalaiGUID;
+ uint64 HalazziGUID;
+ uint64 HexLordMalacrassGUID;
+ uint64 DaakaraGUID;
+ uint64 VoljinGUID;
+ uint64 HexLordTriggerGUID;
+ uint64 StrangeGongGUID;
+ uint64 MasiveGateGUID;
+ uint32 SpeedRunTimer;
+ uint32 ZulAmanState;
+ uint32 ZulAmanBossCount;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
{
- return new instance_zulaman_InstanceMapScript(map);
+ return new instance_zulaman_InstanceScript(map);
}
};
@@ -375,4 +349,3 @@ void AddSC_instance_zulaman()
{
new instance_zulaman();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
index e51bcfc70ba..4f15efb5ea3 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,447 +15,209 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Zulaman
-SD%Complete: 90
-SDComment: Forest Frog will turn into different NPC's. Workaround to prevent new entry from running this script
-SDCategory: Zul'Aman
-EndScriptData */
-
-/* ContentData
-npc_forest_frog
-EndContentData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
-#include "zulaman.h"
#include "Player.h"
-#include "SpellInfo.h"
+#include "CreatureTextMgr.h"
#include "SpellScript.h"
-
-/*######
-## npc_forest_frog
-######*/
-
-enum ForestFrog
-{
- // Spells
- SPELL_REMOVE_AMANI_CURSE = 43732,
- SPELL_PUSH_MOJO = 43923,
-
- // Creatures
- NPC_FOREST_FROG = 24396
-
-};
-
-class npc_forest_frog : public CreatureScript
-{
- public:
-
- npc_forest_frog()
- : CreatureScript("npc_forest_frog")
- {
- }
-
- struct npc_forest_frogAI : public ScriptedAI
- {
- npc_forest_frogAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void DoSpawnRandom()
- {
- uint32 cEntry = 0;
- switch (rand()%10)
- {
- case 0: cEntry = 24397; break; //Mannuth
- case 1: cEntry = 24403; break; //Deez
- case 2: cEntry = 24404; break; //Galathryn
- case 3: cEntry = 24405; break; //Adarrah
- case 4: cEntry = 24406; break; //Fudgerick
- case 5: cEntry = 24407; break; //Darwen
- case 6: cEntry = 24445; break; //Mitzi
- case 7: cEntry = 24448; break; //Christian
- case 8: cEntry = 24453; break; //Brennan
- case 9: cEntry = 24455; break; //Hollee
- }
-
- if (!instance->GetData(TYPE_RAND_VENDOR_1))
- if (rand()%10 == 1) cEntry = 24408; //Gunter
- if (!instance->GetData(TYPE_RAND_VENDOR_2))
- if (rand()%10 == 1) cEntry = 24409; //Kyren
-
- if (cEntry) me->UpdateEntry(cEntry);
-
- if (cEntry == 24408) instance->SetData(TYPE_RAND_VENDOR_1, DONE);
- if (cEntry == 24409) instance->SetData(TYPE_RAND_VENDOR_2, DONE);
- }
-
- void SpellHit(Unit* caster, const SpellInfo* spell) OVERRIDE
- {
- if (spell->Id == SPELL_REMOVE_AMANI_CURSE && caster->GetTypeId() == TYPEID_PLAYER && me->GetEntry() == NPC_FOREST_FROG)
- {
- //increase or decrease chance of mojo?
- if (rand()%99 == 50) DoCast(caster, SPELL_PUSH_MOJO, true);
- else DoSpawnRandom();
- }
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_forest_frogAI>(creature);
- }
-};
-
-/*######
-## npc_zulaman_hostage
-######*/
-
-#define GOSSIP_HOSTAGE1 "I am glad to help you."
-
-static uint32 HostageEntry[] = {23790, 23999, 24024, 24001};
-static uint32 ChestEntry[] = {186648, 187021, 186672, 186667};
-
-class npc_zulaman_hostage : public CreatureScript
-{
- public:
- npc_zulaman_hostage() : CreatureScript("npc_zulaman_hostage") { }
-
- struct npc_zulaman_hostageAI : public ScriptedAI
- {
- npc_zulaman_hostageAI(Creature* creature) : ScriptedAI(creature)
- {
- IsLoot = false;
- }
-
- bool IsLoot;
- uint64 PlayerGUID;
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- player->SendLoot(me->GetGUID(), LOOT_CORPSE);
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- if (IsLoot)
- DoCast(me, 7, false);
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_zulaman_hostageAI(creature);
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HOSTAGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
-
- if (action == GOSSIP_ACTION_INFO_DEF + 1)
- player->CLOSE_GOSSIP_MENU();
-
- if (!creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
- return true;
-
- creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance)
- {
- //uint8 progress = instance->GetData(DATA_CHESTLOOTED);
- instance->SetData(DATA_CHESTLOOTED, 0);
- float x, y, z;
- creature->GetPosition(x, y, z);
- uint32 entry = creature->GetEntry();
- for (uint8 i = 0; i < 4; ++i)
- {
- if (HostageEntry[i] == entry)
- {
- creature->SummonGameObject(ChestEntry[i], x-2, y, z, 0, 0, 0, 0, 0, 0);
- break;
- }
- }
- }
- return true;
- }
-};
-
-/*######
-## npc_harrison_jones
-######*/
+#include "zulaman.h"
enum Says
{
- SAY_HARRISON_0 = 0,
- SAY_HARRISON_1 = 1,
- SAY_HARRISON_2 = 0,
- SAY_HARRISON_3 = 1
+ // Vol'jin
+ SAY_INTRO_1 = 0,
+ SAY_INTRO_2 = 1,
+ SAY_INTRO_3 = 2,
+ SAY_INTRO_4 = 3,
+ SAY_INTRO_FAIL = 4,
+
+ // Hex Lord Malacrass
+ SAY_HEXLOR_INTRO = 0
};
enum Spells
{
- SPELL_BANGING_THE_GONG = 45225,
- SPELL_STEALTH = 34189,
- SPELL_COSMETIC_SPEAR_THROW = 43647
+ // Vol'jin
+ SPELL_BANGING_THE_GONG = 45225
};
enum Events
{
- GONG_EVENT_1 = 1,
- GONG_EVENT_2 = 2,
- GONG_EVENT_3 = 3,
- GONG_EVENT_4 = 4,
- GONG_EVENT_5 = 5,
- GONG_EVENT_6 = 6,
- GONG_EVENT_7 = 7,
- GONG_EVENT_8 = 8,
- GONG_EVENT_9 = 9,
- GONG_EVENT_10 = 10,
- GONG_EVENT_11 = 11
+ EVENT_INTRO_MOVEPOINT_1 = 1,
+ EVENT_INTRO_MOVEPOINT_2 = 2,
+ EVENT_INTRO_MOVEPOINT_3 = 3,
+ EVENT_BANGING_THE_GONG = 4,
+ EVENT_START_DOOR_OPENING_1 = 5,
+ EVENT_START_DOOR_OPENING_2 = 6,
+ EVENT_START_DOOR_OPENING_3 = 7,
+ EVENT_START_DOOR_OPENING_4 = 8,
+ EVENT_START_DOOR_OPENING_5 = 9,
+ EVENT_START_DOOR_OPENING_6 = 10,
+ EVENT_START_DOOR_OPENING_7 = 11
};
-enum Waypoints
+enum Points
{
- HARRISON_MOVE_1 = 860440,
- HARRISON_MOVE_2 = 860441,
- HARRISON_MOVE_3 = 860442
+ POINT_INTRO = 1,
+ POINT_STRANGE_GONG = 2,
+ POINT_START_DOOR_OPENING_1 = 3,
+ POINT_START_DOOR_OPENING_2 = 4
};
-enum DisplayIds
+enum Misc
{
- MODEL_HARRISON_JONES_0 = 22340,
- MODEL_HARRISON_JONES_1 = 22354,
- MODEL_HARRISON_JONES_2 = 22347
+ ITEM_VIRTUAL_ITEM = 5301
};
-enum EntryIds
+Position const VoljinIntroWaypoint[4] =
{
- NPC_HARRISON_JONES_1 = 24375,
- NPC_HARRISON_JONES_2 = 24365,
- NPC_AMANISHI_GUARDIAN = 23597,
+ { 117.7349f, 1662.77f, 42.02156f, 0.0f },
+ { 132.14f, 1645.143f, 42.02158f, 0.0f },
+ { 121.8901f, 1639.118f, 42.23253f, 0.0f },
+ { 122.618f, 1639.546f, 42.11659f, 0.0f },
};
-enum Weapons
-{
- WEAPON_MACE = 5301,
- WEAPON_SPEAR = 13631
-};
-
-class npc_harrison_jones : public CreatureScript
+class npc_voljin_zulaman : public CreatureScript
{
public:
+ npc_voljin_zulaman() : CreatureScript("npc_voljin_zulaman") { }
- npc_harrison_jones() : CreatureScript("npc_harrison_jones")
- {
- }
-
- struct npc_harrison_jonesAI : public ScriptedAI
+ struct npc_voljin_zulamanAI : public ScriptedAI
{
- npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature)
+ npc_voljin_zulamanAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
{
- instance = creature->GetInstanceScript();
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid1);
+ if (_instance->GetData(DATA_ZULAMAN_STATE) == NOT_STARTED)
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
}
- InstanceScript* instance;
-
- uint8 _gongEvent;
- uint32 _gongTimer;
- uint64 uiTargetGUID;
-
void Reset() OVERRIDE
{
- _gongEvent = 0;
- _gongTimer = 0;
- uiTargetGUID = 0;
+ _gongCount = 0;
}
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
void sGossipSelect(Player* player, uint32 sender, uint32 action) OVERRIDE
{
- if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
- {
- player->CLOSE_GOSSIP_MENU();
- me->SetFacingToObject(player);
+ if (_instance->GetData(DATA_ZULAMAN_STATE) != NOT_STARTED)
+ return;
+
+ if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
+ {
+ _events.Reset();
+ me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- Talk(SAY_HARRISON_0);
- _gongEvent = GONG_EVENT_1;
- _gongTimer = 4000;
- }
+ me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
+ _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_1, 1000);
+ Talk(SAY_INTRO_1, player);
+ me->SetWalk(true);
+ }
}
- void SpellHit(Unit*, const SpellInfo* spell) OVERRIDE
+ void DoAction(int32 action) OVERRIDE
{
- if (spell->Id == SPELL_COSMETIC_SPEAR_THROW)
+ if (action == ACTION_START_ZULAMAN)
{
- me->RemoveAllAuras();
- me->SetEntry(NPC_HARRISON_JONES_2);
- me->SetDisplayId(MODEL_HARRISON_JONES_2);
- me->SetTarget(0);
- me->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_DEAD);
- me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
- instance->SetData(DATA_GONGEVENT, DONE);
+ if (++_gongCount == 10)
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_1, 500);
}
}
void UpdateAI(uint32 diff) OVERRIDE
{
- if (_gongEvent)
+ _events.Update(diff);
+ while (uint32 eventId = _events.ExecuteEvent())
{
- if (_gongTimer <= diff)
+ switch (eventId)
{
- switch (_gongEvent)
- {
- case GONG_EVENT_1:
- me->GetMotionMaster()->MovePath(HARRISON_MOVE_1, false);
- _gongEvent = GONG_EVENT_2;
- _gongTimer = 12000;
- break;
- case GONG_EVENT_2:
- me->SetFacingTo(6.235659f);
- Talk(SAY_HARRISON_1);
- DoCast(me, SPELL_BANGING_THE_GONG);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE));
- me->SetSheath(SHEATH_STATE_MELEE);
- _gongEvent = GONG_EVENT_3;
- _gongTimer = 4000;
- break;
- case GONG_EVENT_3:
- if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG)))
- gong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- _gongEvent = GONG_EVENT_4;
- _gongTimer = 105000;
- break;
- case GONG_EVENT_4:
- me->RemoveAura(SPELL_BANGING_THE_GONG);
- if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG)))
- gong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
-
- // trigger or gong will need to be scripted to set IN_PROGRESS after enough hits.
- // This is temp workaround.
- instance->SetData(DATA_GONGEVENT, IN_PROGRESS); // to be removed.
-
- if (instance->GetData(DATA_GONGEVENT) == IN_PROGRESS)
- {
- // Players are Now Saved to instance at SPECIAL (Player should be notified?)
- me->GetMotionMaster()->MovePath(HARRISON_MOVE_2, false);
- _gongEvent = GONG_EVENT_5;
- _gongTimer = 5000;
- }
- else
- {
- _gongTimer = 1000;
- _gongEvent = GONG_EVENT_9;
- }
- break;
- case GONG_EVENT_5:
- me->SetEntry(NPC_HARRISON_JONES_1);
- me->SetDisplayId(MODEL_HARRISON_JONES_1);
- Talk(SAY_HARRISON_2);
- _gongTimer = 12000;
- _gongEvent = GONG_EVENT_6;
- break;
- case GONG_EVENT_6:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING);
- Talk(SAY_HARRISON_3);
- _gongTimer = 7000;
- _gongEvent = GONG_EVENT_7;
- break;
- case GONG_EVENT_7:
- if (!uiTargetGUID)
- {
- std::list<Creature*> targetList;
- GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f);
- if (!targetList.empty())
- {
- for (std::list<Creature*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
- {
- if (Creature* ptarget = *itr)
- {
- if (ptarget->GetPositionX() > 120)
- {
- ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR));
- ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- ptarget->SetReactState(REACT_PASSIVE);
- ptarget->AI()->SetData(0, 1);
- }
- else
- {
- ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- ptarget->SetReactState(REACT_PASSIVE);
- ptarget->AI()->SetData(0, 2);
- }
- }
- }
- }
- }
+ case EVENT_INTRO_MOVEPOINT_1:
+ me->GetMotionMaster()->MovePoint(POINT_INTRO, VoljinIntroWaypoint[0]);
+ _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_2, 1000);
+ break;
+ case EVENT_INTRO_MOVEPOINT_2:
+ me->GetMotionMaster()->MovePoint(POINT_STRANGE_GONG, VoljinIntroWaypoint[1]);
+ _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_3, 4000);
+ break;
+ case EVENT_INTRO_MOVEPOINT_3:
+ Talk(SAY_INTRO_2);
+ _events.ScheduleEvent(EVENT_BANGING_THE_GONG, 3000);
+ case EVENT_BANGING_THE_GONG:
+ DoCast(me, SPELL_BANGING_THE_GONG);
+ if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG)))
+ strangeGong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(ITEM_VIRTUAL_ITEM));
+ break;
+ case EVENT_START_DOOR_OPENING_1:
+ me->RemoveAura(SPELL_BANGING_THE_GONG);
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_2, 500);
+ break;
+ case EVENT_START_DOOR_OPENING_2:
+ me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(0));
+ if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG)))
+ strangeGong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_3, 500);
+ break;
+ case EVENT_START_DOOR_OPENING_3:
+ me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_1, VoljinIntroWaypoint[2]);
+ break;
+ case EVENT_START_DOOR_OPENING_4:
+ _instance->SetData(DATA_ZULAMAN_STATE, IN_PROGRESS);
+ if (GameObject* masiveGate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_MASSIVE_GATE)))
+ masiveGate->SetGoState(GO_STATE_ACTIVE);
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_5, 3000);
+ break;
+ case EVENT_START_DOOR_OPENING_5:
+ Talk(SAY_INTRO_4);
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_6, 6000);
+ break;
+ case EVENT_START_DOOR_OPENING_6:
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_7, 6000);
+ break;
+ case EVENT_START_DOOR_OPENING_7:
+ if (Creature* hexLordTrigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HEXLORD_TRIGGER)))
+ sCreatureTextMgr->SendChat(hexLordTrigger, SAY_HEXLOR_INTRO, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
+ break;
+ default:
+ break;
+ }
+ }
+ }
- if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_MASSIVE_GATE)))
- gate->SetGoState(GO_STATE_ACTIVE);
- _gongTimer = 2000;
- _gongEvent = GONG_EVENT_8;
- break;
- case GONG_EVENT_8:
- DoCast(me, SPELL_STEALTH);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0));
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE);
- me->GetMotionMaster()->MovePath(HARRISON_MOVE_3, false);
- _gongTimer = 1000;
- _gongEvent = 0;
- break;
- case GONG_EVENT_9:
- me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f);
- _gongTimer = 12000;
- _gongEvent = GONG_EVENT_10;
- break;
- case GONG_EVENT_10:
- me->SetFacingTo(1.59044f);
- _gongEvent = 11;
- _gongTimer = 6000;
- break;
- case GONG_EVENT_11:
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ void MovementInform(uint32 movementType, uint32 pointId) OVERRIDE
+ {
+ if (movementType != POINT_MOTION_TYPE)
+ return;
- instance->SetData(DATA_GONGEVENT, NOT_STARTED);
- _gongEvent = 0;
- _gongTimer = 1000;
- break;
- }
- }
- else
- _gongTimer -= diff;
+ switch (pointId)
+ {
+ case POINT_STRANGE_GONG:
+ if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG)))
+ me->SetFacingToObject(strangeGong); // setInFront
+ break;
+ case POINT_START_DOOR_OPENING_1:
+ me->SetFacingTo(4.747295f);
+ me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_2, VoljinIntroWaypoint[3]);
+ Talk(SAY_INTRO_3);
+ _events.ScheduleEvent(EVENT_START_DOOR_OPENING_4, 4500);
+ break;
+ default:
+ break;
}
}
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ uint8 _gongCount;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetInstanceAI<npc_harrison_jonesAI>(creature);
+ return GetInstanceAI<npc_voljin_zulamanAI>(creature);
}
};
+// 45226 - Banging the Gong
class spell_banging_the_gong : public SpellScriptLoader
{
public:
@@ -484,11 +245,8 @@ class spell_banging_the_gong : public SpellScriptLoader
}
};
-
void AddSC_zulaman()
{
- new npc_forest_frog();
- new npc_zulaman_hostage();
- new npc_harrison_jones();
+ new npc_voljin_zulaman();
new spell_banging_the_gong();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
index 4d5938d7253..a9a1aaecd05 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
+++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -19,43 +18,73 @@
#ifndef DEF_ZULAMAN_H
#define DEF_ZULAMAN_H
+uint32 const EncounterCount = 6;
+#define ZulAmanScriptName "instance_zulaman"
+
enum DataTypes
{
- DATA_GONGEVENT = 0,
- DATA_NALORAKKEVENT = 1,
- DATA_AKILZONEVENT = 2,
- DATA_JANALAIEVENT = 3,
- DATA_HALAZZIEVENT = 4,
- DATA_HEXLORDEVENT = 5,
- DATA_ZULJINEVENT = 6,
- DATA_CHESTLOOTED = 7,
- TYPE_RAND_VENDOR_1 = 8,
- TYPE_RAND_VENDOR_2 = 9
+ // BossState
+ DATA_AKILZON = 0,
+ DATA_NALORAKK = 1,
+ DATA_JANALAI = 2,
+ DATA_HALAZZI = 3,
+ DATA_HEXLORD = 4,
+ DATA_DAAKARA = 5,
+
+ // Data64
+ DATA_HEXLORD_TRIGGER,
+
+ DATA_STRANGE_GONG,
+ DATA_MASSIVE_GATE,
+
+ // SetData
+ DATA_ZULAMAN_STATE
};
enum CreatureIds
{
- NPC_HARRISON_JONES = 24358,
- NPC_JANALAI = 23578,
- NPC_ZULJIN = 23863,
- NPC_HEXLORD = 24239,
- NPC_HALAZZI = 23577,
- NPC_NALORAKK = 23576
+ NPC_AKILZON = 23574,
+ NPC_NALORAKK = 23576,
+ NPC_JANALAI = 23578,
+ NPC_HALAZZI = 23577,
+ NPC_HEXLORD = 24239,
+ NPC_DAAKARA = 23863,
+
+ NPC_VOLJIN = 52924,
+ NPC_HEXLORD_TRIGGER = 24363
+};
+
+enum GameObjectIds
+{
+ GO_STRANGE_GONG = 187359,
+ GO_MASSIVE_GATE = 186728,
};
-enum GameobjectIds
+enum ZulAmanEvents
{
- GO_DOOR_HALAZZI = 186303,
- GO_GATE_ZULJIN = 186304,
- GO_GATE_HEXLORD = 186305,
- GO_MASSIVE_GATE = 186728,
- GO_DOOR_AKILZON = 186858,
- GO_DOOR_ZULJIN = 186859,
- GO_HARKORS_SATCHEL = 187021,
- GO_TANZARS_TRUNK = 186648,
- GO_ASHLIS_BAG = 186672,
- GO_KRAZS_PACKAGE = 186667,
- GO_STRANGE_GONG = 187359
+ EVENT_START_ZULAMAN = 15897,
+ EVENT_UPDATE_ZULAMAN_TIMER = 1,
};
+enum ZulAmanAction
+{
+ ACTION_START_ZULAMAN = 1
+};
+
+enum ZulAmanWorldStates
+{
+ WORLD_STATE_ZULAMAN_TIMER_ENABLED = 3104,
+ WORLD_STATE_ZULAMAN_TIMER = 3106,
+};
+
+template<class AI>
+CreatureAI* GetZulAmanAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZulAmanScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
#endif
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
deleted file mode 100644
index e542b3c4895..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_arlokk.cpp
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * 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/>.
- */
-
-/* ScriptData
-TCName: Boss_Arlokk
-TC%Complete: 95
-TCComment: Wrong cleave and red aura is missing not yet added.
-TCComment: Prowlers moving through wall hopefully mmaps will fix.
-TCComment: Can't test LOS until mmaps.
-TCCategory: Zul'Gurub
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "SpellInfo.h"
-#include "zulgurub.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_FEAST_PROWLER = 1,
- SAY_DEATH = 2
-};
-
-enum Spells
-{
- SPELL_SHADOW_WORD_PAIN = 24212, // Corrected
- SPELL_GOUGE = 12540, // Corrected
- SPELL_MARK_OF_ARLOKK = 24210, // triggered spell 24211 Added to spell_dbc
- SPELL_RAVAGE = 24213, // Corrected
- SPELL_CLEAVE = 25174, // Searching for right spell
- SPELL_PANTHER_TRANSFORM = 24190, // Transform to panther now used
- SPELL_SUMMON_PROWLER = 24246, // Added to Spell_dbc
- SPELL_VANISH_VISUAL = 24222, // Added
- SPELL_VANISH = 24223, // Added
- SPELL_SUPER_INVIS = 24235 // Added to Spell_dbc
-};
-
-enum Events
-{
- EVENT_SHADOW_WORD_PAIN = 1,
- EVENT_GOUGE = 2,
- EVENT_MARK_OF_ARLOKK = 3,
- EVENT_RAVAGE = 4,
- EVENT_TRANSFORM = 5,
- EVENT_VANISH = 6,
- EVENT_VANISH_2 = 7,
- EVENT_TRANSFORM_BACK = 8,
- EVENT_VISIBLE = 9,
- EVENT_SUMMON_PROWLERS = 10
-};
-
-enum Phases
-{
- PHASE_ALL = 0,
- PHASE_ONE = 1,
- PHASE_TWO = 2
-};
-
-enum Weapon
-{
- WEAPON_DAGGER = 10616
-};
-
-enum Misc
-{
- MAX_PROWLERS_PER_SIDE = 15
-};
-
-Position const PosMoveOnSpawn[1] =
-{
- { -11561.9f, -1627.868f, 41.29941f, 0.0f }
-};
-
-class boss_arlokk : public CreatureScript
-{
- public: boss_arlokk() : CreatureScript("boss_arlokk") { }
-
- struct boss_arlokkAI : public BossAI
- {
- boss_arlokkAI(Creature* creature) : BossAI(creature, DATA_ARLOKK) { }
-
- void Reset() OVERRIDE
- {
- if (events.IsInPhase(PHASE_TWO))
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
- _Reset();
- _summonCountA = 0;
- _summonCountB = 0;
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER));
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER));
- me->SetWalk(false);
- me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL);
- events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL);
- events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE);
- Talk(SAY_AGGRO);
-
- // Sets up list of Panther spawners to cast on
- std::list<Creature*> triggerList;
- GetCreatureListWithEntryInGrid(triggerList, me, NPC_PANTHER_TRIGGER, 100.0f);
- if (!triggerList.empty())
- {
- uint8 sideA = 0;
- uint8 sideB = 0;
- for (std::list<Creature*>::const_iterator itr = triggerList.begin(); itr != triggerList.end(); ++itr)
- {
- if (Creature* trigger = *itr)
- {
- if (trigger->GetPositionY() < -1625.0f)
- {
- _triggersSideAGUID[sideA] = trigger->GetGUID();
- ++sideA;
- }
- else
- {
- _triggersSideBGUID[sideB] = trigger->GetGUID();
- ++sideB;
- }
- }
- }
- }
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- BossAI::EnterEvadeMode();
- if (GameObject* object = ObjectAccessor::GetGameObject(*me, instance->GetData64(GO_GONG_OF_BETHEKK)))
- object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- me->DespawnOrUnsummon(4000);
- }
-
- void SetData(uint32 id, uint32 /*value*/) OVERRIDE
- {
- if (id == 1)
- --_summonCountA;
- else if (id == 2)
- --_summonCountB;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SHADOW_WORD_PAIN:
- DoCastVictim(SPELL_SHADOW_WORD_PAIN, true);
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE);
- break;
- case EVENT_GOUGE:
- DoCastVictim(SPELL_GOUGE, true);
- break;
- case EVENT_SUMMON_PROWLERS:
- if (_summonCountA < MAX_PROWLERS_PER_SIDE)
- {
- if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideAGUID[urand(0, 4)]))
- {
- trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER);
- ++_summonCountA;
- }
- }
- if (_summonCountB < MAX_PROWLERS_PER_SIDE)
- {
- if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideBGUID[urand(0, 4)]))
- {
- trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER);
- ++_summonCountB;
- }
- }
- events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL);
- break;
- case EVENT_MARK_OF_ARLOKK:
- {
- Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, urand(1, 3), 0.0f, false, -SPELL_MARK_OF_ARLOKK);
- if (!target)
- target = me->GetVictim();
- if (target)
- {
- DoCast(target, SPELL_MARK_OF_ARLOKK, true);
- Talk(SAY_FEAST_PROWLER, target);
- }
- events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000));
- break;
- }
- case EVENT_TRANSFORM:
- {
- DoCast(me, SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP));
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(EQUIP_UNEQUIP));
- /*
- const CreatureTemplate* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
- me->UpdateDamagePhysical(BASE_ATTACK);
- */
- me->AttackStop();
- DoResetThreat();
- me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- DoCast(me, SPELL_VANISH_VISUAL);
- DoCast(me, SPELL_VANISH);
- events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE);
- break;
- }
- case EVENT_VANISH:
- DoCast(me, SPELL_SUPER_INVIS);
- me->SetWalk(false);
- me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ());
- events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE);
- break;
- case EVENT_VANISH_2:
- DoCast(me, SPELL_VANISH);
- DoCast(me, SPELL_SUPER_INVIS);
- events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE);
- break;
- case EVENT_VISIBLE:
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- AttackStart(target);
- me->RemoveAura(SPELL_SUPER_INVIS);
- me->RemoveAura(SPELL_VANISH);
- events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO);
- events.SetPhase(PHASE_TWO);
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
- break;
- case EVENT_RAVAGE:
- DoCastVictim(SPELL_RAVAGE, true);
- events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO);
- break;
- case EVENT_TRANSFORM_BACK:
- {
- me->RemoveAura(SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM
- DoCast(me, SPELL_VANISH_VISUAL);
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER));
- me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER));
- /*
- const CreatureTemplate* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg));
- me->UpdateDamagePhysical(BASE_ATTACK);
- */
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE);
- events.SetPhase(PHASE_ONE);
- break;
- }
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- uint8 _summonCountA;
- uint8 _summonCountB;
- uint64 _triggersSideAGUID[5];
- uint64 _triggersSideBGUID[5];
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetZulGurubAI<boss_arlokkAI>(creature);
- }
-};
-
-/*######
-## npc_zulian_prowler
-######*/
-
-enum ZulianProwlerSpells
-{
- SPELL_SNEAK_RANK_1_1 = 22766,
- SPELL_SNEAK_RANK_1_2 = 7939, // Added to Spell_dbc
- SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 // Added to Spell_dbc
-};
-
-enum ZulianProwlerEvents
-{
- EVENT_ATTACK = 1
-};
-
-Position const PosProwlerCenter[1] =
-{
- { -11556.7f, -1631.344f, 41.2994f, 0.0f }
-};
-
-class npc_zulian_prowler : public CreatureScript
-{
- public: npc_zulian_prowler() : CreatureScript("npc_zulian_prowler") { }
-
- struct npc_zulian_prowlerAI : public ScriptedAI
- {
- npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
-
- void Reset() OVERRIDE
- {
- if (me->GetPositionY() < -1625.0f)
- _sideData = 1;
- else
- _sideData = 2;
-
- DoCast(me, SPELL_SNEAK_RANK_1_1);
- DoCast(me, SPELL_SNEAK_RANK_1_2);
-
- if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
- me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ());
- _events.ScheduleEvent(EVENT_ATTACK, 6000);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- me->GetMotionMaster()->Clear(false);
- me->RemoveAura(SPELL_SNEAK_RANK_1_1);
- me->RemoveAura(SPELL_SNEAK_RANK_1_2);
- }
-
- void SpellHit(Unit* caster, SpellInfo const* spell) OVERRIDE
- {
- if (spell->Id == SPELL_MARK_OF_ARLOKK_TRIGGER) // Should only hit if line of sight
- me->Attack(caster, true);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (Unit* arlokk = me->GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
- {
- if (arlokk->IsAlive())
- arlokk->GetAI()->SetData(_sideData, 0);
- }
- me->DespawnOrUnsummon(4000);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (UpdateVictim())
- {
- DoMeleeAttackIfReady();
- return;
- }
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_ATTACK:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0.0f, 100, false))
- me->Attack(target, true);
- break;
- default:
- break;
- }
- }
- }
-
- private:
- int32 _sideData;
- EventMap _events;
- InstanceScript* _instance;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetZulGurubAI<npc_zulian_prowlerAI>(creature);
- }
-};
-
-/*######
-## go_gong_of_bethekk
-######*/
-
-Position const PosSummonArlokk[1] =
-{
- { -11507.22f, -1628.062f, 41.38264f, 3.159046f }
-};
-
-class go_gong_of_bethekk : public GameObjectScript
-{
- public: go_gong_of_bethekk() : GameObjectScript("go_gong_of_bethekk") { }
-
- bool OnGossipHello(Player* /*player*/, GameObject* go) OVERRIDE
- {
- if (go->GetInstanceScript())
- {
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- go->SendCustomAnim(0);
- go->SummonCreature(NPC_ARLOKK, PosSummonArlokk[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 600000);
- }
- return true;
- }
-};
-
-void AddSC_boss_arlokk()
-{
- new boss_arlokk();
- new npc_zulian_prowler();
- new go_gong_of_bethekk();
-}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp
index 120961a087e..7d336d49b62 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_grilek.cpp
@@ -16,52 +16,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Grilek
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Gurub
-EndScriptData */
-
+#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
+enum Yells
+{
+};
+
enum Spells
{
- SPELL_AVATAR = 24646, // Enrage Spell
- SPELL_GROUND_TREMOR = 6524
};
enum Events
{
- EVENT_AVATAR = 1,
- EVENT_GROUND_TREMOR = 2
};
-class boss_grilek : public CreatureScript // grilek
+class boss_grilek : public CreatureScript
{
- public: boss_grilek() : CreatureScript("boss_grilek") { }
+ public:
+ boss_grilek() : CreatureScript("boss_grilek") { }
struct boss_grilekAI : public BossAI
{
- boss_grilekAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
+ boss_grilekAI(Creature* creature) : BossAI(creature, DATA_GRILEK)
+ {
+ }
void Reset() OVERRIDE
{
- _Reset();
}
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- _JustDied();
}
- void EnterCombat(Unit* /*who*/) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- _EnterCombat();
- events.ScheduleEvent(EVENT_AVATAR, urand(15000, 25000));
- events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(15000, 25000));
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -73,31 +65,16 @@ class boss_grilek : public CreatureScript // grilek
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_AVATAR:
- DoCast(me, SPELL_AVATAR);
- if (Unit* victim = me->GetVictim())
- {
- if (DoGetThreat(victim))
- DoModifyThreatPercent(victim, -50);
- }
-
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
- AttackStart(target);
- events.ScheduleEvent(EVENT_AVATAR, urand(25000, 35000));
- break;
- case EVENT_GROUND_TREMOR:
- DoCastVictim(SPELL_GROUND_TREMOR, true);
- events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(12000, 16000));
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
@@ -113,4 +90,3 @@ void AddSC_boss_grilek()
{
new boss_grilek();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
deleted file mode 100644
index 84ebc313b12..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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/>.
- */
-
-/*
-Name: Boss_Hakkar
-%Complete: 95
-Comment: Blood siphon spell buggy cause of Core Issue.
-Category: Zul'Gurub
-*/
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulgurub.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_FLEEING = 1,
- SAY_MINION_DESTROY = 2, // Where does it belong?
- SAY_PROTECT_ALTAR = 3 // Where does it belong?
-};
-
-enum Spells
-{
- SPELL_BLOOD_SIPHON = 24322, // Buggy ?
- SPELL_CORRUPTED_BLOOD = 24328,
- SPELL_CAUSE_INSANITY = 24327, // Spell needs scripting.
- SPELL_WILL_OF_HAKKAR = 24178,
- SPELL_ENRAGE = 24318,
- // The Aspects of all High Priests spells
- SPELL_ASPECT_OF_JEKLIK = 24687,
- SPELL_ASPECT_OF_VENOXIS = 24688,
- SPELL_ASPECT_OF_MARLI = 24686,
- SPELL_ASPECT_OF_THEKAL = 24689,
- SPELL_ASPECT_OF_ARLOKK = 24690
-};
-
-enum Events
-{
- EVENT_BLOOD_SIPHON = 1,
- EVENT_CORRUPTED_BLOOD = 2,
- EVENT_CAUSE_INSANITY = 3, // Spell needs scripting. Event disabled
- EVENT_WILL_OF_HAKKAR = 4,
- EVENT_ENRAGE = 5,
- // The Aspects of all High Priests events
- EVENT_ASPECT_OF_JEKLIK = 6,
- EVENT_ASPECT_OF_VENOXIS = 7,
- EVENT_ASPECT_OF_MARLI = 8,
- EVENT_ASPECT_OF_THEKAL = 9,
- EVENT_ASPECT_OF_ARLOKK = 10
-};
-
-class boss_hakkar : public CreatureScript
-{
- public: boss_hakkar() : CreatureScript("boss_hakkar") { }
-
- struct boss_hakkarAI : public BossAI
- {
- boss_hakkarAI(Creature* creature) : BossAI(creature, DATA_HAKKAR) { }
-
- void Reset() OVERRIDE
- {
- _Reset();
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000);
- events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, 25000);
- events.ScheduleEvent(EVENT_CAUSE_INSANITY, 17000);
- events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, 17000);
- events.ScheduleEvent(EVENT_ENRAGE, 600000);
- if (instance->GetBossState(DATA_JEKLIK) != DONE)
- events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 4000);
- if (instance->GetBossState(DATA_VENOXIS) != DONE)
- events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 7000);
- if (instance->GetBossState(DATA_MARLI) != DONE)
- events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000);
- if (instance->GetBossState(DATA_THEKAL) != DONE)
- events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 8000);
- if (instance->GetBossState(DATA_ARLOKK) != DONE)
- events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, 18000);
- Talk(SAY_AGGRO);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_BLOOD_SIPHON:
- DoCastVictim(SPELL_BLOOD_SIPHON, true);
- events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000);
- break;
- case EVENT_CORRUPTED_BLOOD:
- DoCastVictim(SPELL_CORRUPTED_BLOOD, true);
- events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, urand(30000, 45000));
- break;
- case EVENT_CAUSE_INSANITY:
- // DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CAUSE_INSANITY);
- // events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000));
- break;
- case EVENT_WILL_OF_HAKKAR:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_WILL_OF_HAKKAR);
- events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, urand(25000, 35000));
- break;
- case EVENT_ENRAGE:
- if (!me->HasAura(SPELL_ENRAGE))
- DoCast(me, SPELL_ENRAGE);
- events.ScheduleEvent(EVENT_ENRAGE, 90000);
- break;
- case EVENT_ASPECT_OF_JEKLIK:
- DoCastVictim(SPELL_ASPECT_OF_JEKLIK, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, urand(10000, 14000));
- break;
- case EVENT_ASPECT_OF_VENOXIS:
- DoCastVictim(SPELL_ASPECT_OF_VENOXIS, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 8000);
- break;
- case EVENT_ASPECT_OF_MARLI:
- DoCastVictim(SPELL_ASPECT_OF_MARLI, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 10000);
- break;
- case EVENT_ASPECT_OF_THEKAL:
- DoCastVictim(SPELL_ASPECT_OF_THEKAL, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 15000);
- break;
- case EVENT_ASPECT_OF_ARLOKK:
- DoCastVictim(SPELL_ASPECT_OF_ARLOKK, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, urand(10000, 15000));
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_hakkarAI>(creature);
- }
-};
-
-void AddSC_boss_hakkar()
-{
- new boss_hakkar();
-}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp
index 232c9059b47..00f09bfdd6e 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hazzarah.cpp
@@ -16,54 +16,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Hazzarah
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Gurub
-EndScriptData */
-
+#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
+enum Yells
+{
+};
+
enum Spells
{
- SPELL_MANABURN = 26046,
- SPELL_SLEEP = 24664
};
enum Events
{
- EVENT_MANABURN = 1,
- EVENT_SLEEP = 2,
- EVENT_ILLUSIONS = 3
};
class boss_hazzarah : public CreatureScript
{
- public: boss_hazzarah() : CreatureScript("boss_hazzarah") { }
+ public:
+ boss_hazzarah() : CreatureScript("boss_hazzarah") { }
struct boss_hazzarahAI : public BossAI
{
- boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
+ boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_HAZZARAH)
+ {
+ }
void Reset() OVERRIDE
{
- _Reset();
}
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- _JustDied();
}
- void EnterCombat(Unit* /*who*/) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- _EnterCombat();
- events.ScheduleEvent(EVENT_MANABURN, urand(4000, 10000));
- events.ScheduleEvent(EVENT_SLEEP, urand(10000, 18000));
- events.ScheduleEvent(EVENT_ILLUSIONS, urand(10000, 18000));
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -75,37 +65,16 @@ class boss_hazzarah : public CreatureScript
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_MANABURN:
- DoCastVictim(SPELL_MANABURN, true);
- events.ScheduleEvent(EVENT_MANABURN, urand(8000, 16000));
- break;
- case EVENT_SLEEP:
- DoCastVictim(SPELL_SLEEP, true);
- events.ScheduleEvent(EVENT_SLEEP, urand(12000, 20000));
- break;
- case EVENT_ILLUSIONS:
- // We will summon 3 illusions that will spawn on a random gamer and attack this gamer
- // We will just use one model for the beginning
- for (uint8 i = 0; i < 3; ++i)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- Creature* Illusion = me->SummonCreature(NPC_NIGHTMARE_ILLUSION, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
- if (Illusion)
- Illusion->AI()->AttackStart(target);
- }
- }
- events.ScheduleEvent(EVENT_ILLUSIONS, urand(15000, 25000));
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
deleted file mode 100644
index 336599f2cc5..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jeklik.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * 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 "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulgurub.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_RAIN_FIRE = 1,
- SAY_DEATH = 2
-};
-
-enum Spells
-{
- SPELL_CHARGE = 22911,
- SPELL_SONICBURST = 23918,
- SPELL_SCREECH = 6605,
- SPELL_SHADOW_WORD_PAIN = 23952,
- SPELL_MIND_FLAY = 23953,
- SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled
- SPELL_GREATERHEAL = 23954,
- SPELL_BAT_FORM = 23966,
-
- // Batriders Spell
- SPELL_BOMB = 40332 // Wrong ID but Magmadars bomb is not working...
-};
-
-enum BatIds
-{
- NPC_BLOODSEEKER_BAT = 11368,
- NPC_FRENZIED_BAT = 14965
-};
-
-enum Events
-{
- EVENT_CHARGE_JEKLIK = 1,
- EVENT_SONIC_BURST,
- EVENT_SCREECH,
- EVENT_SPAWN_BATS,
- EVENT_SHADOW_WORD_PAIN,
- EVENT_MIND_FLAY,
- EVENT_CHAIN_MIND_FLAY,
- EVENT_GREATER_HEAL,
- EVENT_SPAWN_FLYING_BATS
-};
-
-enum Phase
-{
- PHASE_ONE = 1,
- PHASE_TWO = 2
-};
-
-Position const SpawnBat[6] =
-{
- { -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
- { -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
- { -12293.6220f, -1380.2640f, 144.8304f, 5.483f },
- { -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
- { -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
- { -12293.6220f, -1380.2640f, 144.8304f, 5.483f }
-};
-
-class boss_jeklik : public CreatureScript
-{
- public: boss_jeklik() : CreatureScript("boss_jeklik") { }
-
- struct boss_jeklikAI : public BossAI
- {
- boss_jeklikAI(Creature* creature) : BossAI(creature, DATA_JEKLIK) { }
-
- void Reset() OVERRIDE
- {
- _Reset();
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- Talk(SAY_AGGRO);
- events.SetPhase(PHASE_ONE);
-
- events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SONIC_BURST, 8000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SCREECH, 13000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
-
- me->SetCanFly(true);
- DoCast(me, SPELL_BAT_FORM);
- }
-
- void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
- {
- if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50))
- {
- me->RemoveAurasDueToSpell(SPELL_BAT_FORM);
- me->SetCanFly(false);
- DoResetThreat();
- events.SetPhase(PHASE_TWO);
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_MIND_FLAY, 11000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_GREATER_HEAL, 50000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10000, 0, PHASE_TWO);
- return;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_CHARGE_JEKLIK:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(target, SPELL_CHARGE);
- AttackStart(target);
- }
- events.ScheduleEvent(EVENT_CHARGE_JEKLIK, urand(15000, 30000), 0, PHASE_ONE);
- break;
- case EVENT_SONIC_BURST:
- DoCastVictim(SPELL_SONICBURST);
- events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE);
- case EVENT_SCREECH:
- DoCastVictim(SPELL_SCREECH);
- events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE);
- case EVENT_SPAWN_BATS:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- for (uint8 i = 0; i < 6; ++i)
- if (Creature* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
- bat->AI()->AttackStart(target);
- events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
- break;
- case EVENT_SHADOW_WORD_PAIN:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_SHADOW_WORD_PAIN);
- events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(12000, 18000), 0, PHASE_TWO);
- break;
- case EVENT_MIND_FLAY:
- DoCastVictim(SPELL_MIND_FLAY);
- events.ScheduleEvent(EVENT_MIND_FLAY, 16000, 0, PHASE_TWO);
- break;
- case EVENT_CHAIN_MIND_FLAY:
- me->InterruptNonMeleeSpells(false);
- DoCastVictim(SPELL_CHAIN_MIND_FLAY);
- events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, urand(15000, 30000), 0, PHASE_TWO);
- break;
- case EVENT_GREATER_HEAL:
- me->InterruptNonMeleeSpells(false);
- DoCast(me, SPELL_GREATERHEAL);
- events.ScheduleEvent(EVENT_GREATER_HEAL, urand(25000, 35000), 0, PHASE_TWO);
- break;
- case EVENT_SPAWN_FLYING_BATS:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- if (Creature* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
- flyingBat->AI()->AttackStart(target);
- events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, urand(10000, 15000), 0, PHASE_TWO);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetZulGurubAI<boss_jeklikAI>(creature);
- }
-};
-
-// Flying Bat
-class npc_batrider : public CreatureScript
-{
- public:
- npc_batrider() : CreatureScript("npc_batrider") { }
-
- struct npc_batriderAI : public ScriptedAI
- {
- npc_batriderAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 Bomb_Timer;
-
- void Reset() OVERRIDE
- {
- Bomb_Timer = 2000;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (Bomb_Timer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(target, SPELL_BOMB);
- Bomb_Timer = 5000;
- }
- }
- else
- Bomb_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_batriderAI(creature);
- }
-};
-
-void AddSC_boss_jeklik()
-{
- new boss_jeklik();
- new npc_batrider();
-}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp
deleted file mode 100644
index b4ba1ef71fb..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo.cpp
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Boss_Jin'do the Hexxer
-SD%Complete: 85
-SDComment: Mind Control not working because of core bug. Shades visible for all.
-SDCategory: Zul'Gurub
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulgurub.h"
-
-enum Say
-{
- SAY_AGGRO = 1
-};
-
-enum Spells
-{
- SPELL_BRAINWASHTOTEM = 24262,
- SPELL_POWERFULLHEALINGWARD = 24309, // HACKED Totem summoned by script because the spell totems will not cast.
- SPELL_HEX = 24053,
- SPELL_DELUSIONSOFJINDO = 24306,
- SPELL_SHADEOFJINDO = 24308, // HACKED
- //Healing Ward Spell
- SPELL_HEAL = 38588, // HACKED Totems are not working right. Right heal spell ID is 24311 but this spell is not casting...
- //Shade of Jindo Spell
- SPELL_SHADOWSHOCK = 19460,
- SPELL_INVISIBLE = 24699
-};
-
-enum Events
-{
- EVENT_BRAINWASHTOTEM = 1,
- EVENT_POWERFULLHEALINGWARD = 2,
- EVENT_HEX = 3,
- EVENT_DELUSIONSOFJINDO = 4,
- EVENT_TELEPORT = 5
-};
-
-Position const TeleportLoc = {-11583.7783f, -1249.4278f, 77.5471f, 4.745f};
-
-class boss_jindo : public CreatureScript
-{
- public: boss_jindo() : CreatureScript("boss_jindo") { }
-
- struct boss_jindoAI : public BossAI
- {
- boss_jindoAI(Creature* creature) : BossAI(creature, DATA_JINDO) { }
-
- void Reset() OVERRIDE
- {
- _Reset();
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_BRAINWASHTOTEM, 20000);
- events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, 16000);
- events.ScheduleEvent(EVENT_HEX, 8000);
- events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, 10000);
- events.ScheduleEvent(EVENT_TELEPORT, 5000);
- Talk(SAY_AGGRO);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_BRAINWASHTOTEM:
- DoCast(me, SPELL_BRAINWASHTOTEM);
- events.ScheduleEvent(EVENT_BRAINWASHTOTEM, urand(18000, 26000));
- break;
- case EVENT_POWERFULLHEALINGWARD: // HACK
- //DoCast(me, SPELL_POWERFULLHEALINGWARD);
- me->SummonCreature(14987, me->GetPositionX()+3, me->GetPositionY()-2, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
- events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
- break;
- case EVENT_HEX:
- if (Unit* target = me->GetVictim())
- {
- DoCast(target, SPELL_HEX, true);
- if (DoGetThreat(target))
- DoModifyThreatPercent(target, -80);
- }
- events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
- break;
- case EVENT_DELUSIONSOFJINDO: // HACK
- // Casting the delusion curse with a shade so shade will attack the same target with the curse.
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(target, SPELL_DELUSIONSOFJINDO);
- Creature* Shade = me->SummonCreature(NPC_SHADE_OF_JINDO, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Shade)
- Shade->AI()->AttackStart(target);
- }
- events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, urand(4000, 12000));
- break;
- case EVENT_TELEPORT: // Possible HACK
- // Teleports a random player and spawns 9 Sacrificed Trolls to attack player
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.m_orientation);
- if (DoGetThreat(me->GetVictim()))
- DoModifyThreatPercent(target, -100);
- Creature* SacrificedTroll;
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()-2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()-4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()+2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()-2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()+4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()-4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (SacrificedTroll)
- SacrificedTroll->AI()->AttackStart(target);
- }
- events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000));
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_jindoAI(creature);
- }
-};
-
-//Healing Ward
-class npc_healing_ward : public CreatureScript
-{
- public:
-
- npc_healing_ward()
- : CreatureScript("npc_healing_ward")
- {
- }
-
- struct npc_healing_wardAI : public ScriptedAI
- {
- npc_healing_wardAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- uint32 Heal_Timer;
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE
- {
- Heal_Timer = 2000;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Heal_Timer
- if (Heal_Timer <= diff)
- {
- Unit* pJindo = Unit::GetUnit(*me, instance->GetData64(DATA_JINDO));
- if (pJindo)
- DoCast(pJindo, SPELL_HEAL);
- Heal_Timer = 3000;
- } else Heal_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_healing_wardAI>(creature);
- }
-};
-
-//Shade of Jindo
-class npc_shade_of_jindo : public CreatureScript
-{
- public:
-
- npc_shade_of_jindo()
- : CreatureScript("npc_shade_of_jindo")
- {
- }
-
- struct npc_shade_of_jindoAI : public ScriptedAI
- {
- npc_shade_of_jindoAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 ShadowShock_Timer;
-
- void Reset() OVERRIDE
- {
- ShadowShock_Timer = 1000;
- DoCast(me, SPELL_INVISIBLE, true);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
-
- //ShadowShock_Timer
- if (ShadowShock_Timer <= diff)
- {
- DoCastVictim(SPELL_SHADOWSHOCK);
- ShadowShock_Timer = 2000;
- } else ShadowShock_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_shade_of_jindoAI(creature);
- }
-};
-
-void AddSC_boss_jindo()
-{
- new boss_jindo();
- new npc_healing_ward();
- new npc_shade_of_jindo();
-}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp
new file mode 100644
index 00000000000..ed8eb0ec817
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_jindo_the_godbreaker.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "zulgurub.h"
+
+enum Yells
+{
+ // Jin'do the Godbreaker
+ SAY_INTRO = 0,
+ SAY_AGGRO = 1,
+ EMOTE_SHADOWS_OF_HAKKAR = 2, // ID - 97172 Shadows of Hakkar
+ SAY_JINDO_SPIRIT_PHASE = 3,
+ //SAY_PLAYER_KILL = 4, // missing data
+
+ // Spirit of Hakkar
+ SAY_SPIRIT_SPIRIT_PHASE = 0,
+ SAY_SPIRIT_DEFEATED = 1,
+
+ // Jin'do the Godbreaker - Trigger
+ SAY_JINDO_DEFEATED = 0,
+
+ // Shadow of Hakkar
+ SAY_SHADOW_DEFEATED = 0,
+};
+
+enum Spells
+{
+};
+
+enum Events
+{
+};
+
+class boss_jindo_the_godbreaker : public CreatureScript
+{
+ public:
+ boss_jindo_the_godbreaker() : CreatureScript("boss_jindo_the_godbreaker") { }
+
+ struct boss_jindo_the_godbreakerAI : public BossAI
+ {
+ boss_jindo_the_godbreakerAI(Creature* creature) : BossAI(creature, DATA_JINDO) { }
+
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ default:
+ break;
+ }
+ }
+ */
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetZulGurubAI<boss_jindo_the_godbreakerAI>(creature);
+ }
+};
+
+void AddSC_boss_jindo_the_godbreaker()
+{
+ new boss_jindo_the_godbreaker();
+}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp
index ef188dd9261..e249abccea6 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_gahzranka.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_kilnara.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,55 +15,60 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Gahz'ranka
-SD%Complete: 85
-SDComment: Massive Geyser with knockback not working. Spell buggy.
-SDCategory: Zul'Gurub
-EndScriptData */
-
+#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "Spell.h"
#include "zulgurub.h"
+enum Yells
+{
+ SAY_AGGRO = 0,
+ SAY_WAVE_OF_AGONY = 1, // ID - 96457 Wave of Agony
+ SAY_TRANSFROM_1 = 2,
+ SAY_TRANSFROM_2 = 3,
+ SAY_PLAYER_KILL = 4,
+ SAY_DEATH = 5
+};
+
enum Spells
{
- SPELL_FROSTBREATH = 16099,
- SPELL_MASSIVEGEYSER = 22421, // Not working. (summon)
- SPELL_SLAM = 24326
};
enum Events
{
- EVENT_FROSTBREATH = 1,
- EVENT_MASSIVEGEYSER = 2,
- EVENT_SLAM = 3
};
-class boss_gahzranka : public CreatureScript // gahzranka
+class boss_kilnara : public CreatureScript
{
- public: boss_gahzranka() : CreatureScript("boss_gahzranka") { }
+ public:
+ boss_kilnara() : CreatureScript("boss_kilnara") { }
- struct boss_gahzrankaAI : public BossAI
+ struct boss_kilnaraAI : public BossAI
{
- boss_gahzrankaAI(Creature* creature) : BossAI(creature, DATA_GAHZRANKA) { }
+ boss_kilnaraAI(Creature* creature) : BossAI(creature, DATA_KILNARA) { }
void Reset() OVERRIDE
{
_Reset();
}
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
+
void JustDied(Unit* /*killer*/) OVERRIDE
{
_JustDied();
+ Talk(SAY_DEATH);
}
- void EnterCombat(Unit* /*who*/) OVERRIDE
+ void KilledUnit(Unit* victim) OVERRIDE
{
- _EnterCombat();
- events.ScheduleEvent(EVENT_FROSTBREATH, 8000);
- events.ScheduleEvent(EVENT_MASSIVEGEYSER, 25000);
- events.ScheduleEvent(EVENT_SLAM, 17000);
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -76,27 +80,16 @@ class boss_gahzranka : public CreatureScript // gahzranka
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_FROSTBREATH:
- DoCastVictim(SPELL_FROSTBREATH, true);
- events.ScheduleEvent(EVENT_FROSTBREATH, urand(7000, 11000));
- break;
- case EVENT_MASSIVEGEYSER:
- DoCastVictim(SPELL_MASSIVEGEYSER, true);
- events.ScheduleEvent(EVENT_MASSIVEGEYSER, urand(22000, 32000));
- break;
- case EVENT_SLAM:
- DoCastVictim(SPELL_SLAM, true);
- events.ScheduleEvent(EVENT_SLAM, urand(12000, 20000));
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
@@ -104,11 +97,11 @@ class boss_gahzranka : public CreatureScript // gahzranka
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new boss_gahzrankaAI(creature);
+ return GetZulGurubAI<boss_kilnaraAI>(creature);
}
};
-void AddSC_boss_gahzranka()
+void AddSC_boss_kilnara()
{
- new boss_gahzranka();
+ new boss_kilnara();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
index d307303f4f4..a217d97ee98 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_mandokir.cpp
@@ -16,97 +16,94 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Mandokir
-SD%Complete: 90
-SDComment: Ohgan function needs improvements.
-SDCategory: Zul'Gurub
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "Spell.h"
-#include "SpellAuras.h"
#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "Player.h"
+#include "GridNotifiers.h"
#include "zulgurub.h"
-enum Says
+enum Yells
{
- SAY_AGGRO = 0,
- SAY_DING_KILL = 1,
- SAY_WATCH = 2,
- SAY_WATCH_WHISPER = 3,
- SAY_OHGAN_DEAD = 4,
- SAY_GRATS_JINDO = 0,
+ SAY_AGGRO = 0,
+ SAY_PLAYER_KILL = 1,
+ SAY_DISMOUNT_OHGAN = 2,
+ EMOTE_DEVASTATING_SLAM = 3,
+ SAY_REANIMATE_OHGAN = 4,
+ EMOTE_FRENZY = 5,
+ SAY_FRENZY = 6,
+ SAY_DEATH = 7
};
enum Spells
{
- SPELL_CHARGE = 24408, // seen
- SPELL_OVERPOWER = 24407, // Seen
- SPELL_FEAR = 29321,
- SPELL_WHIRLWIND = 13736, // Triggers 15589
- SPELL_MORTAL_STRIKE = 16856, // Seen
- SPELL_FRENZY = 24318, // seen
- SPELL_WATCH = 24314, // seen 24315, 24316
- SPELL_WATCH_CHARGE = 24315, // Triggers 24316
- SPELL_LEVEL_UP = 24312 //
+ // Bloodlord Mandokir
+ SPELL_BLOODLORD_AURA = 96480,
+ SPELL_SUMMON_OHGAN = 96717,
+ SPELL_REANIMATE_OHGAN = 96724,
+ SPELL_DECAPITATE = 96682,
+ SPELL_BLOODLETTING = 96776,
+ SPELL_BLOODLETTING_DAMAGE = 96777,
+ SPELL_BLOODLETTING_HEAL = 96778,
+ SPELL_FRENZY = 96800,
+ SPELL_LEVEL_UP = 96662,
+ SPELL_DEVASTATING_SLAM = 96740,
+ SPELL_DEVASTATING_SLAM_TRIGGER = 96761,
+ SPELL_DEVASTATING_SLAM_DAMAGE = 97385,
+ SPELL_SPIRIT_VENGEANCE_CANCEL = 96821,
+
+ // Chained Spirit
+ SPELL_REVIVE = 96484,
+
+ // Ohgan
+ SPELL_OHGAN_HEART_VISUAL = 96727,
+ SPELL_PERMANENT_FEIGN_DEATH = 96733,
+ SPELL_CLEAR_ALL = 28471,
+ SPELL_OHGAN_ORDERS = 96721,
+ SPELL_OHGAN_ORDERS_TRIGGER = 96722
};
enum Events
{
- EVENT_CHECK_SPEAKER = 1,
- EVENT_CHECK_START = 2,
- EVENT_STARTED = 3,
- EVENT_OVERPOWER = 4,
- EVENT_MORTAL_STRIKE = 5,
- EVENT_WHIRLWIND = 6,
- EVENT_CHECK_OHGAN = 7,
- EVENT_WATCH_PLAYER = 8,
- EVENT_CHARGE_PLAYER = 9
+ // Bloodlord Mandokir
+ EVENT_SUMMON_OHGAN = 1,
+ EVENT_DECAPITATE = 2,
+ EVENT_BLOODLETTING = 3,
+ EVENT_REANIMATE_OHGAN = 4,
+ EVENT_REANIMATE_OHGAN_COOLDOWN = 5,
+ EVENT_DEVASTATING_SLAM = 6
};
-enum Misc
+enum Action
{
- MODEL_OHGAN_MOUNT = 15271,
- PATH_MANDOKIR = 492861,
- POINT_MANDOKIR_END = 24,
- CHAINED_SPIRT_COUNT = 20
+ // Bloodlord Mandokir
+ ACTION_OHGAN_IS_DEATH = 1,
+ ACTION_START_REVIVE = 2,
+
+ // Chained Spirit
+ ACTION_REVIVE = 1
};
-Position const PosSummonChainedSpirits[CHAINED_SPIRT_COUNT] =
+enum Misc
{
- { -12167.17f, -1979.330f, 133.0992f, 2.268928f },
- { -12262.74f, -1953.394f, 133.5496f, 0.593412f },
- { -12176.89f, -1983.068f, 133.7841f, 2.129302f },
- { -12226.45f, -1977.933f, 132.7982f, 1.466077f },
- { -12204.74f, -1890.431f, 135.7569f, 4.415683f },
- { -12216.70f, -1891.806f, 136.3496f, 4.677482f },
- { -12236.19f, -1892.034f, 134.1041f, 5.044002f },
- { -12248.24f, -1893.424f, 134.1182f, 5.270895f },
- { -12257.36f, -1897.663f, 133.1484f, 5.462881f },
- { -12265.84f, -1903.077f, 133.1649f, 5.654867f },
- { -12158.69f, -1972.707f, 133.8751f, 2.408554f },
- { -12178.82f, -1891.974f, 134.1786f, 3.944444f },
- { -12193.36f, -1890.039f, 135.1441f, 4.188790f },
- { -12275.59f, -1932.845f, 134.9017f, 0.174533f },
- { -12273.51f, -1941.539f, 136.1262f, 0.314159f },
- { -12247.02f, -1963.497f, 133.9476f, 0.872665f },
- { -12238.68f, -1969.574f, 133.6273f, 1.134464f },
- { -12192.78f, -1982.116f, 132.6966f, 1.919862f },
- { -12210.81f, -1979.316f, 133.8700f, 1.797689f },
- { -12283.51f, -1924.839f, 133.5170f, 0.069813f }
+ POINT_START_REVIVE = 1,
+
+ DATA_OHGANOT_SO_FAST = 5762,
+
+ FACTION_NONE = 1665
};
-Position const PosMandokir[2] =
+enum SummonGroups
{
- { -12167.8f, -1927.25f, 153.73f, 3.76991f },
- { -12197.86f, -1949.392f, 130.2745f, 0.0f }
+ SUMMON_GROUP_CHAINED_SPIRIT = 0
};
class boss_mandokir : public CreatureScript
{
- public: boss_mandokir() : CreatureScript("boss_mandokir") { }
+ public:
+
+ boss_mandokir() : CreatureScript("boss_mandokir") { }
struct boss_mandokirAI : public BossAI
{
@@ -114,115 +111,121 @@ class boss_mandokir : public CreatureScript
void Reset() OVERRIDE
{
- if (me->GetPositionZ() > 140.0f)
- {
- _Reset();
- killCount = 0;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
- events.ScheduleEvent(EVENT_CHECK_START, 1000);
- if (Creature* speaker = Creature::GetCreature(*me, instance->GetData64(NPC_VILEBRANCH_SPEAKER)))
- if (!speaker->IsAlive())
- speaker->Respawn(true);
- }
- summons.DespawnAll();
- me->Mount(MODEL_OHGAN_MOUNT);
- }
+ DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL);
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- // Do not want to unsummon Ohgan
- for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
- if (Creature* unsummon = Creature::GetCreature(*me, chainedSpirtGUIDs[i]))
- unsummon->DespawnOrUnsummon();
- instance->SetBossState(DATA_MANDOKIR, DONE);
- instance->SaveToDB();
+ _Reset();
+
+ me->SummonCreatureGroup(SUMMON_GROUP_CHAINED_SPIRIT);
+ _ohganotSoFast = true;
+ _reanimateOhganCooldown = false;
+ _reviveGUID = 0;
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
- events.ScheduleEvent(EVENT_OVERPOWER, urand(7000, 9000));
- events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
- events.ScheduleEvent(EVENT_WHIRLWIND, urand(24000, 30000));
- events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
- events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(13000, 15000));
- events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(33000, 38000));
- me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
Talk(SAY_AGGRO);
- me->Dismount();
- // Summon Ohgan (Spell missing) TEMP HACK
- me->SummonCreature(NPC_OHGAN, me->GetPositionX()-3, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
- // Summon Chained Spirits
- for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
+
+ DoCastAOE(SPELL_BLOODLORD_AURA);
+
+ if (!summons.empty())
{
- Creature* chainedSpirt = me->SummonCreature(NPC_CHAINED_SPIRT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN);
- chainedSpirtGUIDs[i] = chainedSpirt->GetGUID();
+ for (std::list<uint64>::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
+ {
+ if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, *itr))
+ if (chainedSpirit->GetEntry() == NPC_CHAINED_SPIRIT && chainedSpirit->AI())
+ chainedSpirit->setFaction(FACTION_NONE);
+ }
}
- DoZoneInCombat();
+
+ events.ScheduleEvent(EVENT_DECAPITATE, 10000);
+ events.ScheduleEvent(EVENT_BLOODLETTING, 15000);
+ events.ScheduleEvent(EVENT_SUMMON_OHGAN, 20000);
+ events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 25000);
}
- void KilledUnit(Unit* victim) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- if (victim->GetTypeId() != TYPEID_PLAYER)
- return;
+ DoCastAOE(SPELL_SPIRIT_VENGEANCE_CANCEL);
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
- if (++killCount == 3)
+ void KilledUnit(Unit* victim) OVERRIDE
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
{
- Talk(SAY_DING_KILL);
- if (Creature* jindo = Creature::GetCreature(*me, instance->GetData64(DATA_JINDO)))
- if (jindo->IsAlive())
- jindo->AI()->Talk(SAY_GRATS_JINDO);
- DoCast(me, SPELL_LEVEL_UP, true);
- killCount = 0;
+ Talk(SAY_PLAYER_KILL);
+ DoCast(SPELL_LEVEL_UP);
+ _reviveGUID = victim->GetGUID();
+ DoAction(ACTION_START_REVIVE);
}
}
- void MovementInform(uint32 type, uint32 id) OVERRIDE
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
{
- if (type == WAYPOINT_MOTION_TYPE)
+ if (me->HealthBelowPctDamaged(20, damage) && !me->HasAura(SPELL_FRENZY))
{
- me->SetWalk(false);
- if (id == POINT_MANDOKIR_END)
- {
- me->SetHomePosition(PosMandokir[0]);
- instance->SetBossState(DATA_MANDOKIR, NOT_STARTED);
- me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe.
- }
+ DoCast(me, SPELL_FRENZY, true);
+ Talk(SAY_FRENZY);
+ Talk(EMOTE_FRENZY);
}
}
- void UpdateAI(uint32 diff) OVERRIDE
+ void DoAction(int32 action) OVERRIDE
{
- events.Update(diff);
-
- if (!UpdateVictim())
+ switch (action)
{
- if (instance->GetBossState(DATA_MANDOKIR) == NOT_STARTED || instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
+ case ACTION_OHGAN_IS_DEATH:
+ events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 4000);
+ _ohganotSoFast = false;
+ break;
+ case ACTION_START_REVIVE:
{
- while (uint32 eventId = events.ExecuteEvent())
+ std::list<Creature*> creatures;
+ GetCreatureListWithEntryInGrid(creatures, me, NPC_CHAINED_SPIRIT, 200.0f);
+ creatures.remove_if(Trinity::AnyDeadUnitCheck());
+ creatures.remove_if(Trinity::UnitAuraCheck(true, SPELL_OHGAN_ORDERS_TRIGGER));
+ Trinity::Containers::RandomResizeList(creatures, 1);
+ if (creatures.empty())
+ return;
+
+ for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
{
- switch (eventId)
+ if (Creature* chainedSpirit = ObjectAccessor::GetCreature(*me, (*itr)->GetGUID()))
{
- case EVENT_CHECK_START:
- if (instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
- {
- me->GetMotionMaster()->MovePoint(0, PosMandokir[1].m_positionX, PosMandokir[1].m_positionY, PosMandokir[1].m_positionZ);
- events.ScheduleEvent(EVENT_STARTED, 6000);
- }
- else
- events.ScheduleEvent(EVENT_CHECK_START, 1000);
- break;
- case EVENT_STARTED:
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
- me->GetMotionMaster()->MovePath(PATH_MANDOKIR, false);
- break;
- default:
- break;
+ chainedSpirit->AI()->SetGUID(_reviveGUID);
+ chainedSpirit->AI()->DoAction(ACTION_REVIVE);
+ _reviveGUID = 0;
}
}
+ break;
}
- return;
+ default:
+ break;
+
}
+ }
+
+ uint32 GetData(uint32 type) const OVERRIDE
+ {
+ if (type == DATA_OHGANOT_SO_FAST)
+ return _ohganotSoFast;
+
+ return 0;
+ }
+
+ void SetGUID(uint64 guid, int32 /*type = 0 */) OVERRIDE
+ {
+ _reviveGUID = guid;
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
@@ -231,39 +234,40 @@ class boss_mandokir : public CreatureScript
{
switch (eventId)
{
- case EVENT_OVERPOWER:
- DoCastVictim(SPELL_OVERPOWER, true);
- events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 12000));
+ case EVENT_SUMMON_OHGAN:
+ me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0);
+ DoCast(me, SPELL_SUMMON_OHGAN, true);
break;
- case EVENT_MORTAL_STRIKE:
- if (me->GetVictim() && me->GetVictim()->HealthBelowPct(50))
- DoCastVictim(SPELL_MORTAL_STRIKE, true);
- events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
+ case EVENT_DECAPITATE:
+ DoCastAOE(SPELL_DECAPITATE);
+ events.ScheduleEvent(EVENT_DECAPITATE, me->HasAura(SPELL_FRENZY) ? 17500 : 35000);
break;
- case EVENT_WHIRLWIND:
- DoCast(me, SPELL_WHIRLWIND);
- events.ScheduleEvent(EVENT_WHIRLWIND, urand(22000, 26000));
- break;
- case EVENT_CHECK_OHGAN:
- if (instance->GetBossState(DATA_OHGAN) == DONE)
+ case EVENT_BLOODLETTING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true))
{
- DoCast(me, SPELL_FRENZY);
- Talk(SAY_OHGAN_DEAD);
+ DoCast(target, SPELL_BLOODLETTING, true);
+ me->ClearUnitState(UNIT_STATE_CASTING);
}
- else
- events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
+ events.ScheduleEvent(EVENT_BLOODLETTING, 25000);
break;
- case EVENT_WATCH_PLAYER:
- if (Unit* player = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ case EVENT_REANIMATE_OHGAN:
+ if (_reanimateOhganCooldown)
+ events.ScheduleEvent(EVENT_REANIMATE_OHGAN, 1000);
+ else
{
- DoCast(player, SPELL_WATCH);
- Talk(SAY_WATCH, player);
+ DoCastAOE(SPELL_REANIMATE_OHGAN);
+ Talk(SAY_REANIMATE_OHGAN);
+ // Cooldown
+ _reanimateOhganCooldown = true;
+ events.ScheduleEvent(EVENT_REANIMATE_OHGAN_COOLDOWN, 20000);
}
- events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 15000));
break;
- case EVENT_CHARGE_PLAYER:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_CHARGE);
- events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(22000, 30000));
+ case EVENT_REANIMATE_OHGAN_COOLDOWN:
+ _reanimateOhganCooldown = false;
+ break;
+ case EVENT_DEVASTATING_SLAM:
+ DoCastAOE(SPELL_DEVASTATING_SLAM_TRIGGER);
+ events.ScheduleEvent(EVENT_DEVASTATING_SLAM, 30000);
break;
default:
break;
@@ -274,8 +278,9 @@ class boss_mandokir : public CreatureScript
}
private:
- uint8 killCount;
- uint64 chainedSpirtGUIDs[CHAINED_SPIRT_COUNT];
+ bool _ohganotSoFast;
+ bool _reanimateOhganCooldown;
+ uint64 _reviveGUID;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
@@ -284,51 +289,58 @@ class boss_mandokir : public CreatureScript
}
};
-// Ohgan
-
-enum OhganSpells
-{
- SPELL_SUNDERARMOR = 24317
-};
-
class npc_ohgan : public CreatureScript
{
- public: npc_ohgan() : CreatureScript("npc_ohgan") { }
+ public:
+ npc_ohgan() : CreatureScript("npc_ohgan") { }
struct npc_ohganAI : public ScriptedAI
{
- npc_ohganAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
+ npc_ohganAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = me->GetInstanceScript();
+ }
- void Reset() OVERRIDE
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- SunderArmor_Timer = 5000;
+ DoCastAOE(SPELL_OHGAN_ORDERS, true);
}
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
+ {
+ if (damage >= me->GetHealth())
+ {
+ damage = 0;
+ me->AttackStop();
+ me->SetHealth(0);
+ me->SetTarget(0);
+ DoCast(me, SPELL_CLEAR_ALL, true);
+ DoCast(me, SPELL_PERMANENT_FEIGN_DEATH);
+
+ if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR)))
+ mandokir->AI()->DoAction(ACTION_OHGAN_IS_DEATH);
+ }
+ }
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void KilledUnit(Unit* victim) OVERRIDE
{
- instance->SetBossState(DATA_OHGAN, DONE);
+ if (Creature* creature = victim->ToCreature())
+ {
+ if (creature->GetEntry() == NPC_CHAINED_SPIRIT)
+ DoCastAOE(SPELL_OHGAN_ORDERS, true);
+ }
}
- void UpdateAI(uint32 diff) OVERRIDE
+ void UpdateAI(uint32 /*diff*/) OVERRIDE
{
- // Return since we have no target
if (!UpdateVictim())
return;
- if (SunderArmor_Timer <= diff)
- {
- DoCastVictim(SPELL_SUNDERARMOR, true);
- SunderArmor_Timer = urand(10000, 15000);
- } else SunderArmor_Timer -= diff;
-
DoMeleeAttackIfReady();
}
private:
- uint32 SunderArmor_Timer;
- InstanceScript* instance;
+ InstanceScript* _instance;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
@@ -337,99 +349,428 @@ class npc_ohgan : public CreatureScript
}
};
-enum VilebranchSpells
-{
- SPELL_DEMORALIZING_SHOUT = 13730,
- SPELL_CLEAVE = 15284
-};
-
-class npc_vilebranch_speaker : public CreatureScript
+class npc_chained_spirit : public CreatureScript
{
- public: npc_vilebranch_speaker() : CreatureScript("npc_vilebranch_speaker") { }
+ public:
+ npc_chained_spirit() : CreatureScript("npc_chained_spirit") { }
- struct npc_vilebranch_speakerAI : public ScriptedAI
+ struct npc_chained_spiritAI : public ScriptedAI
{
- npc_vilebranch_speakerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
+ npc_chained_spiritAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = me->GetInstanceScript();
+ me->AddUnitMovementFlag(MOVEMENTFLAG_HOVER);
+ me->SetReactState(REACT_PASSIVE); // correct?
+ }
void Reset() OVERRIDE
{
- demoralizing_Shout_Timer = urand(2000, 4000);
- cleave_Timer = urand(5000, 8000);
+ _revivePlayerGUID = 0;
}
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
+ void SetGUID(uint64 guid, int32 /*type = 0 */) OVERRIDE
+ {
+ _revivePlayerGUID = guid;
+ }
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void DoAction(int32 action) OVERRIDE
{
- instance->SetBossState(DATA_MANDOKIR, SPECIAL);
+ if (action == ACTION_REVIVE)
+ {
+ Position pos;
+ if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID))
+ {
+ target->GetNearPoint(me, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, 5.0f, target->GetAngle(me));
+ me->GetMotionMaster()->MovePoint(POINT_START_REVIVE, pos);
+ }
+ }
}
- void UpdateAI(uint32 diff) OVERRIDE
+ void MovementInform(uint32 type, uint32 pointId) OVERRIDE
{
- // Return since we have no target
- if (!UpdateVictim())
+ if (type != POINT_MOTION_TYPE || !_revivePlayerGUID)
return;
- if (demoralizing_Shout_Timer <= diff)
+ if (pointId == POINT_START_REVIVE)
{
- DoCast(me, SPELL_DEMORALIZING_SHOUT);
- demoralizing_Shout_Timer = urand(22000, 30000);
- } else demoralizing_Shout_Timer -= diff;
+ if (Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID))
+ DoCast(target, SPELL_REVIVE);
+
+ me->DespawnOrUnsummon(2000);
+ }
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ Player* target = ObjectAccessor::GetPlayer(*me, _revivePlayerGUID);
+ if (!target || target->IsAlive())
+ return;
- if (cleave_Timer <= diff)
+ if (Creature* mandokir = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_MANDOKIR)))
{
- DoCastVictim(SPELL_CLEAVE, true);
- cleave_Timer = urand(6000, 9000);
- } else cleave_Timer -= diff;
+ mandokir->GetAI()->SetGUID(target->GetGUID());
+ mandokir->GetAI()->DoAction(ACTION_START_REVIVE);
+ }
- DoMeleeAttackIfReady();
+ me->DespawnOrUnsummon();
}
+ void UpdateAI(uint32 /*diff*/) OVERRIDE { }
+
private:
- uint32 demoralizing_Shout_Timer;
- uint32 cleave_Timer;
- InstanceScript* instance;
+ InstanceScript* _instance;
+ uint64 _revivePlayerGUID;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return GetInstanceAI<npc_vilebranch_speakerAI>(creature);
+ return GetZulGurubAI<npc_chained_spiritAI>(creature);
+ }
+};
+
+class spell_mandokir_decapitate : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_decapitate() : SpellScriptLoader("spell_mandokir_decapitate") { }
+
+ class spell_mandokir_decapitate_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mandokir_decapitate_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Player* target = GetHitPlayer())
+ caster->CastSpell(target, uint32(GetEffectValue()), true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_decapitate_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_decapitate_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mandokir_decapitate_SpellScript();
+ }
+};
+
+class spell_mandokir_bloodletting : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_bloodletting() : SpellScriptLoader("spell_mandokir_bloodletting") { }
+
+ class spell_mandokir_bloodletting_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mandokir_bloodletting_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_DAMAGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_BLOODLETTING_HEAL))
+ return false;
+ return true;
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* aurEff)
+ {
+ Unit* target = GetTarget();
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ int32 damage = std::max<int32>(7500, target->CountPctFromCurHealth(aurEff->GetAmount()));
+
+ caster->CastCustomSpell(target, SPELL_BLOODLETTING_DAMAGE, &damage, 0, 0, true);
+ target->CastCustomSpell(caster, SPELL_BLOODLETTING_HEAL, &damage, 0, 0, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mandokir_bloodletting_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mandokir_bloodletting_AuraScript();
+ }
+};
+
+class spell_mandokir_spirit_vengeance_cancel : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_spirit_vengeance_cancel() : SpellScriptLoader("spell_mandokir_spirit_vengeance_cancel") { }
+
+ class spell_mandokir_spirit_vengeance_cancel_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mandokir_spirit_vengeance_cancel_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Player* target = GetHitPlayer())
+ target->RemoveAura(uint32(GetEffectValue()));
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_spirit_vengeance_cancel_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mandokir_spirit_vengeance_cancel_SpellScript();
+ }
+};
+
+class DevastatingSlamTargetSelector : public std::unary_function<Unit *, bool>
+{
+ public:
+ DevastatingSlamTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {}
+
+ bool operator() (WorldObject* target)
+ {
+ if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)
+ return true;
+
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return true;
+
+ return false;
+ }
+
+ Creature* _me;
+ Unit const* _victim;
+};
+
+class spell_mandokir_devastating_slam : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_devastating_slam() : SpellScriptLoader("spell_mandokir_devastating_slam") { }
+
+ class spell_mandokir_devastating_slam_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mandokir_devastating_slam_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(DevastatingSlamTargetSelector(GetCaster()->ToCreature(), GetCaster()->GetVictim()));
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ float angle = 0.0f;
+ float x, y, z;
+
+ if (Player* target = GetHitPlayer())
+ {
+ caster->AttackStop();
+ caster->SetOrientation(caster->GetAngle(target));
+ caster->SetFacingTo(caster->GetAngle(target));
+
+ caster->CastSpell(caster, SPELL_DEVASTATING_SLAM, false);
+
+ // HACK: Need better way for pos calculation
+ for (uint8 i = 0; i <= 50; ++i)
+ {
+ angle = float(rand_norm()) * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
+ caster->GetClosePoint(x, y, z, 4.0f, frand(-2.5f, 50.0f), angle);
+
+ caster->CastSpell(x, y, z, SPELL_DEVASTATING_SLAM_DAMAGE, true);
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_devastating_slam_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_devastating_slam_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mandokir_devastating_slam_SpellScript();
}
};
-class spell_threatening_gaze : public SpellScriptLoader
+class spell_mandokir_ohgan_orders : public SpellScriptLoader
{
public:
- spell_threatening_gaze() : SpellScriptLoader("spell_threatening_gaze") { }
+ spell_mandokir_ohgan_orders() : SpellScriptLoader("spell_mandokir_ohgan_orders") { }
- class spell_threatening_gaze_AuraScript : public AuraScript
+ class spell_mandokir_ohgan_orders_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_threatening_gaze_AuraScript);
+ PrepareSpellScript(spell_mandokir_ohgan_orders_SpellScript);
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Unit* target = GetHitUnit())
+ caster->CastSpell(target, uint32(GetEffectValue()), true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mandokir_ohgan_orders_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_ohgan_orders_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mandokir_ohgan_orders_SpellScript();
+ }
+};
+
+class spell_mandokir_ohgan_orders_trigger : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_ohgan_orders_trigger() : SpellScriptLoader("spell_mandokir_ohgan_orders_trigger") { }
+
+ class spell_mandokir_ohgan_orders_trigger_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mandokir_ohgan_orders_trigger_AuraScript);
+
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
if (Unit* caster = GetCaster())
- if (Unit* target = GetTarget())
- if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
- caster->CastSpell(target, SPELL_WATCH_CHARGE);
+ {
+ // HACK: research better way
+ caster->ClearUnitState(UNIT_STATE_CASTING);
+ caster->GetMotionMaster()->Clear();
+ caster->DeleteThreatList();
+ caster->AddThreat(target, 50000000.0f);
+ caster->TauntApply(target);
+ }
}
void Register() OVERRIDE
{
- OnEffectRemove += AuraEffectRemoveFn(spell_threatening_gaze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectApply += AuraEffectApplyFn(spell_mandokir_ohgan_orders_trigger_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_threatening_gaze_AuraScript();
+ return new spell_mandokir_ohgan_orders_trigger_AuraScript();
+ }
+};
+
+class spell_mandokir_reanimate_ohgan : public SpellScriptLoader
+{
+ public:
+ spell_mandokir_reanimate_ohgan() : SpellScriptLoader("spell_mandokir_reanimate_ohgan") { }
+
+ class spell_mandokir_reanimate_ohgan_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mandokir_reanimate_ohgan_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->RemoveAura(SPELL_PERMANENT_FEIGN_DEATH);
+ target->CastSpell(target, SPELL_OHGAN_HEART_VISUAL, true);
+ target->CastSpell((Unit*)NULL, SPELL_OHGAN_ORDERS, true);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mandokir_reanimate_ohgan_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mandokir_reanimate_ohgan_SpellScript();
}
};
+class spell_clear_all : public SpellScriptLoader
+{
+ public:
+ spell_clear_all() : SpellScriptLoader("spell_clear_all") { }
+
+ class spell_clear_all_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_clear_all_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ caster->RemoveAllAurasOnDeath();
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_clear_all_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_clear_all_SpellScript();
+ }
+};
+
+class achievement_ohganot_so_fast : public AchievementCriteriaScript
+{
+ public:
+ achievement_ohganot_so_fast() : AchievementCriteriaScript("achievement_ohganot_so_fast") { }
+
+ bool OnCheck(Player* /*player*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_OHGANOT_SO_FAST);
+ }
+};
+
void AddSC_boss_mandokir()
{
new boss_mandokir();
new npc_ohgan();
- new npc_vilebranch_speaker();
- new spell_threatening_gaze();
+ new npc_chained_spirit();
+ new spell_mandokir_decapitate();
+ new spell_mandokir_bloodletting();
+ new spell_mandokir_spirit_vengeance_cancel();
+ new spell_mandokir_devastating_slam();
+ new spell_mandokir_ohgan_orders();
+ new spell_mandokir_ohgan_orders_trigger();
+ new spell_mandokir_reanimate_ohgan();
+ new spell_clear_all();
+ new achievement_ohganot_so_fast();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp
deleted file mode 100644
index efd79d89a2b..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Boss_Marli
-SD%Complete: 80
-SDComment: Charging healers and casters not working. Perhaps wrong Spell Timers.
-SDCategory: Zul'Gurub
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulgurub.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_TRANSFORM = 1,
- SAY_SPIDER_SPAWN = 2,
- SAY_DEATH = 3
-};
-
-enum Spells
-{
- SPELL_CHARGE = 22911,
- SPELL_ASPECT_OF_MARLI = 24686, // A stun spell
- SPELL_ENVOLWINGWEB = 24110,
- SPELL_POISON_VOLLEY = 24099,
- SPELL_SPIDER_FORM = 24084,
- // The Spider Spell
- SPELL_LEVELUP = 24312 // Not right Spell.
-};
-
-enum Events
-{
- EVENT_SPAWN_START_SPIDERS = 1, // Phase 1
- EVENT_POISON_VOLLEY = 2, // Phase All
- EVENT_SPAWN_SPIDER = 3, // Phase All
- EVENT_CHARGE_PLAYER = 4, // Phase 3
- EVENT_ASPECT_OF_MARLI = 5, // Phase 2
- EVENT_TRANSFORM = 6, // Phase 2
- EVENT_TRANSFORM_BACK = 7 // Phase 3
-};
-
-enum Phases
-{
- PHASE_ONE = 1,
- PHASE_TWO = 2,
- PHASE_THREE = 3
-};
-
-class boss_marli : public CreatureScript
-{
- public: boss_marli() : CreatureScript("boss_marli") { }
-
- struct boss_marliAI : public BossAI
- {
- boss_marliAI(Creature* creature) : BossAI(creature, DATA_MARLI) { }
-
- void Reset() OVERRIDE
- {
- if (events.IsInPhase(PHASE_THREE))
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
- _Reset();
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE);
- Talk(SAY_AGGRO);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SPAWN_START_SPIDERS:
-
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- Talk(SAY_SPIDER_SPAWN);
- Creature* Spider = NULL;
- Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Spider)
- Spider->AI()->AttackStart(target);
- Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Spider)
- Spider->AI()->AttackStart(target);
- Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Spider)
- Spider->AI()->AttackStart(target);
- Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Spider)
- Spider->AI()->AttackStart(target);
- }
- events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
- events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
- events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
- events.SetPhase(PHASE_TWO);
- break;
- case EVENT_POISON_VOLLEY:
- DoCastVictim(SPELL_POISON_VOLLEY, true);
- events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000));
- break;
- case EVENT_ASPECT_OF_MARLI:
- DoCastVictim(SPELL_ASPECT_OF_MARLI, true);
- events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, urand(13000, 18000), 0, PHASE_TWO);
- break;
- case EVENT_SPAWN_SPIDER:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
- if (Spider)
- Spider->AI()->AttackStart(target);
- }
- events.ScheduleEvent(EVENT_SPAWN_SPIDER, urand(12000, 17000));
- break;
- case EVENT_TRANSFORM:
- {
- Talk(SAY_TRANSFORM);
- DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM
- /*
- CreatureTemplate const* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
- me->UpdateDamagePhysical(BASE_ATTACK);
- */
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
- DoCastVictim(SPELL_ENVOLWINGWEB);
- if (DoGetThreat(me->GetVictim()))
- DoModifyThreatPercent(me->GetVictim(), -100);
- events.ScheduleEvent(EVENT_CHARGE_PLAYER, 1500, 0, PHASE_THREE);
- events.ScheduleEvent(EVENT_TRANSFORM_BACK, 25000, 0, PHASE_THREE);
- events.SetPhase(PHASE_THREE);
- break;
- }
- case EVENT_CHARGE_PLAYER:
- {
- Unit* target = NULL;
- int i = 0;
- while (i++ < 3) // max 3 tries to get a random target with power_mana
- {
- target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader
- if (target && target->getPowerType() == POWER_MANA)
- break;
- }
- if (target)
- {
- DoCast(target, SPELL_CHARGE);
- AttackStart(target);
- }
- events.ScheduleEvent(EVENT_CHARGE_PLAYER, 8000, 0, PHASE_THREE);
- break;
- }
- case EVENT_TRANSFORM_BACK:
- {
- me->RemoveAura(SPELL_SPIDER_FORM);
- /*
- CreatureTemplate const* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
- me->UpdateDamagePhysical(BASE_ATTACK);
- */
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
- events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
- events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
- events.ScheduleEvent(EVENT_TRANSFORM, urand(35000, 60000), 0, PHASE_TWO);
- events.SetPhase(PHASE_TWO);
- break;
- }
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_marliAI(creature);
- }
-};
-
-// Spawn of Marli
-class npc_spawn_of_marli : public CreatureScript
-{
- public: npc_spawn_of_marli() : CreatureScript("npc_spawn_of_marli") { }
-
- struct npc_spawn_of_marliAI : public ScriptedAI
- {
- npc_spawn_of_marliAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 LevelUp_Timer;
-
- void Reset() OVERRIDE
- {
- LevelUp_Timer = 3000;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //LevelUp_Timer
- if (LevelUp_Timer <= diff)
- {
- DoCast(me, SPELL_LEVELUP);
- LevelUp_Timer = 3000;
- } else LevelUp_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_spawn_of_marliAI(creature);
- }
-};
-
-void AddSC_boss_marli()
-{
- new boss_marli();
- new npc_spawn_of_marli();
-}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp
index 87a8e647f53..220ff5787d2 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_renataki.cpp
@@ -16,66 +16,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Renataki
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Gurub
-EndScriptData */
-
+#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
+enum Yells
+{
+};
+
enum Spells
{
- SPELL_AMBUSH = 34794,
- SPELL_THOUSANDBLADES = 34799
};
-enum Misc
+enum Events
{
- EQUIP_ID_MAIN_HAND = 0 //was item display id 31818, but this id does not exist
};
class boss_renataki : public CreatureScript
{
- public: boss_renataki() : CreatureScript("boss_renataki") { }
+ public:
+ boss_renataki() : CreatureScript("boss_renataki") { }
struct boss_renatakiAI : public BossAI
{
- boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
-
- uint32 Invisible_Timer;
- uint32 Ambush_Timer;
- uint32 Visible_Timer;
- uint32 Aggro_Timer;
- uint32 ThousandBlades_Timer;
-
- bool Invisible;
- bool Ambushed;
+ boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_RENATAKI)
+ {
+ }
void Reset() OVERRIDE
{
- _Reset();
- Invisible_Timer = urand(8000, 18000);
- Ambush_Timer = 3000;
- Visible_Timer = 4000;
- Aggro_Timer = urand(15000, 25000);
- ThousandBlades_Timer = urand(4000, 8000);
-
- Invisible = false;
- Ambushed = false;
}
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- _JustDied();
}
- void EnterCombat(Unit* /*who*/) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- _EnterCombat();
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -83,76 +61,20 @@ class boss_renataki : public CreatureScript
if (!UpdateVictim())
return;
- //Invisible_Timer
- if (Invisible_Timer <= diff)
- {
- me->InterruptSpell(CURRENT_GENERIC_SPELL);
-
- SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
- me->SetDisplayId(11686);
-
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Invisible = true;
-
- Invisible_Timer = urand(15000, 30000);
- } else Invisible_Timer -= diff;
-
- if (Invisible)
- {
- if (Ambush_Timer <= diff)
- {
- Unit* target = NULL;
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
- {
- DoTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
- DoCast(target, SPELL_AMBUSH);
- }
-
- Ambushed = true;
- Ambush_Timer = 3000;
- } else Ambush_Timer -= diff;
- }
-
- if (Ambushed)
- {
- if (Visible_Timer <= diff)
- {
- me->InterruptSpell(CURRENT_GENERIC_SPELL);
-
- me->SetDisplayId(15268);
- SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- Invisible = false;
+ events.Update(diff);
- Visible_Timer = 4000;
- } else Visible_Timer -= diff;
- }
-
- //Resetting some aggro so he attacks other gamers
- if (!Invisible)
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (Aggro_Timer <= diff)
+ switch (eventId)
{
- Unit* target = NULL;
- target = SelectTarget(SELECT_TARGET_RANDOM, 1);
-
- if (DoGetThreat(me->GetVictim()))
- DoModifyThreatPercent(me->GetVictim(), -50);
-
- if (target)
- AttackStart(target);
-
- Aggro_Timer = urand(7000, 20000);
- } else Aggro_Timer -= diff;
-
- if (ThousandBlades_Timer <= diff)
- {
- DoCastVictim(SPELL_THOUSANDBLADES);
- ThousandBlades_Timer = urand(7000, 12000);
- } else ThousandBlades_Timer -= diff;
+ default:
+ break;
+ }
}
+ */
DoMeleeAttackIfReady();
}
@@ -168,4 +90,3 @@ void AddSC_boss_renataki()
{
new boss_renataki();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
deleted file mode 100644
index a70dd5e0a30..00000000000
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_thekal.cpp
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Boss_Thekal
-SD%Complete: 95
-SDComment: Almost finished.
-SDCategory: Zul'Gurub
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "zulgurub.h"
-
-enum Says
-{
- SAY_AGGRO = 0,
- SAY_DEATH = 1
-};
-
-enum Spells
-{
- SPELL_MORTALCLEAVE = 22859, // Phase 1
- SPELL_SILENCE = 22666, // Phase 1
- SPELL_TIGER_FORM = 24169, // Phase 1
- SPELL_RESURRECT = 24173, // Phase 1 // Not used in script.
- SPELL_FRENZY = 8269, // Phase 2
- SPELL_FORCEPUNCH = 24189, // Phase 2
- SPELL_CHARGE = 24193, // Phase 2
- SPELL_ENRAGE = 8269, // Phase 2
- SPELL_SUMMONTIGERS = 24183, // Phase 2
- // Zealot Lor'Khan Spells
- SPELL_SHIELD = 20545,
- SPELL_BLOODLUST = 24185,
- SPELL_GREATERHEAL = 24208,
- SPELL_DISARM = 6713,
- // Zealot Zath Spells
- SPELL_SWEEPINGSTRIKES = 18765,
- SPELL_SINISTERSTRIKE = 15581,
- SPELL_GOUGE = 12540,
- SPELL_KICK = 15614,
- SPELL_BLIND = 21060
-};
-
-enum Events
-{
- EVENT_MORTALCLEAVE = 1, // Phase 1
- EVENT_SILENCE = 2, // Phase 1
- EVENT_CHECK_TIMER = 3, // Phase 1
- EVENT_RESURRECT_TIMER = 4, // Phase 1
- EVENT_FRENZY = 5, // Phase 2
- EVENT_FORCEPUNCH = 6, // Phase 2
- EVENT_SPELL_CHARGE = 7, // Phase 2
- EVENT_ENRAGE = 8, // Phase 2
- EVENT_SUMMONTIGERS = 9 // Phase 2
-};
-
-enum Phases
-{
- PHASE_ONE = 1,
- PHASE_TWO = 2
-};
-
-class boss_thekal : public CreatureScript
-{
- public: boss_thekal() : CreatureScript("boss_thekal") { }
-
- struct boss_thekalAI : public BossAI
- {
- boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL) { }
-
- bool Enraged;
- bool WasDead;
-
- void Reset() OVERRIDE
- {
- if (events.IsInPhase(PHASE_TWO))
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
- _Reset();
- Enraged = false;
- WasDead = false;
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_DEATH);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_MORTALCLEAVE, 4000, 0, PHASE_ONE); // Phase 1
- events.ScheduleEvent(EVENT_SILENCE, 9000, 0, PHASE_ONE); // Phase 1
- events.ScheduleEvent(EVENT_CHECK_TIMER, 10000, 0, PHASE_ONE); // Phase 1
- events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); // Phase 1
- Talk(SAY_AGGRO);
- }
-
- void JustReachedHome() OVERRIDE
- {
- instance->SetBossState(DATA_THEKAL, NOT_STARTED);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- while (uint32 eventId = events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_MORTALCLEAVE:
- DoCastVictim(SPELL_MORTALCLEAVE, true);
- events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE);
- break;
- case EVENT_SILENCE:
- DoCastVictim(SPELL_SILENCE, true);
- events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE);
- break;
- case EVENT_RESURRECT_TIMER:
- //Thekal will transform to Tiger if he died and was not resurrected after 10 seconds.
- if (WasDead)
- {
- DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM
- me->SetObjectScale(2.00f);
- me->SetStandState(UNIT_STAND_STATE_STAND);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- /*
- const CreatureTemplate* cinfo = me->GetCreatureTemplate();
- me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40)));
- me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40)));
- me->UpdateDamagePhysical(BASE_ATTACK);
- */
- me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 40.0f, true); // hack
- DoResetThreat();
- events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2
- events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2
- events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2
- events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2
- events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2
- events.SetPhase(PHASE_TWO);
- }
- events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE);
- break;
- case EVENT_CHECK_TIMER:
- //Check_Timer for the death of LorKhan and Zath.
- if (!WasDead)
- {
- if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
- {
- //Resurrect LorKhan
- if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
- {
- pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pLorKhan->setFaction(14);
- pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pLorKhan->SetFullHealth();
- instance->SetData(DATA_LORKHAN, DONE);
- }
- }
-
- if (instance->GetBossState(DATA_ZATH) == SPECIAL)
- {
- //Resurrect Zath
- if (Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)))
- {
- pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pZath->setFaction(14);
- pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pZath->SetFullHealth();
- instance->SetBossState(DATA_ZATH, DONE);
- }
- }
- }
- events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE);
- break;
- case EVENT_FRENZY:
- DoCast(me, SPELL_FRENZY);
- events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO);
- break;
- case EVENT_FORCEPUNCH:
- DoCastVictim(SPELL_FORCEPUNCH, true);
- events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO);
- break;
- case EVENT_CHARGE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- DoCast(target, SPELL_CHARGE);
- DoResetThreat();
- AttackStart(target);
- }
- events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO);
- break;
- case EVENT_ENRAGE:
- if (HealthBelowPct(11) && !Enraged)
- {
- DoCast(me, SPELL_ENRAGE);
- Enraged = true;
- }
- events.ScheduleEvent(EVENT_ENRAGE, 30000);
- break;
- case EVENT_SUMMONTIGERS:
- DoCastVictim(SPELL_SUMMONTIGERS, true);
- events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO);
- break;
- default:
- break;
- }
-
- if (me->IsFullHealth() && WasDead)
- WasDead = false;
-
- if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5))
- {
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetStandState(UNIT_STAND_STATE_SLEEP);
- me->AttackStop();
- instance->SetBossState(DATA_THEKAL, SPECIAL);
- WasDead=true;
- }
- }
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<boss_thekalAI>(creature);
- }
-};
-
-//Zealot Lor'Khan
-class npc_zealot_lorkhan : public CreatureScript
-{
- public: npc_zealot_lorkhan() : CreatureScript("npc_zealot_lorkhan") { }
-
- struct npc_zealot_lorkhanAI : public ScriptedAI
- {
- npc_zealot_lorkhanAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- uint32 Shield_Timer;
- uint32 BloodLust_Timer;
- uint32 GreaterHeal_Timer;
- uint32 Disarm_Timer;
- uint32 Check_Timer;
-
- bool FakeDeath;
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE
- {
- Shield_Timer = 1000;
- BloodLust_Timer = 16000;
- GreaterHeal_Timer = 32000;
- Disarm_Timer = 6000;
- Check_Timer = 10000;
-
- FakeDeath = false;
-
- instance->SetBossState(DATA_LORKHAN, NOT_STARTED);
-
- me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- //Shield_Timer
- if (Shield_Timer <= diff)
- {
- DoCast(me, SPELL_SHIELD);
- Shield_Timer = 61000;
- } else Shield_Timer -= diff;
-
- //BloodLust_Timer
- if (BloodLust_Timer <= diff)
- {
- DoCast(me, SPELL_BLOODLUST);
- BloodLust_Timer = 20000+rand()%8000;
- } else BloodLust_Timer -= diff;
-
- //Casting Greaterheal to Thekal or Zath if they are in meele range.
- if (GreaterHeal_Timer <= diff)
- {
- Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL));
- Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH));
-
- if (!pThekal || !pZath)
- return;
-
- switch (urand(0, 1))
- {
- case 0:
- if (me->IsWithinMeleeRange(pThekal))
- DoCast(pThekal, SPELL_GREATERHEAL);
- break;
- case 1:
- if (me->IsWithinMeleeRange(pZath))
- DoCast(pZath, SPELL_GREATERHEAL);
- break;
- }
-
- GreaterHeal_Timer = 15000+rand()%5000;
- } else GreaterHeal_Timer -= diff;
-
- //Disarm_Timer
- if (Disarm_Timer <= diff)
- {
- DoCastVictim(SPELL_DISARM);
- Disarm_Timer = 15000+rand()%10000;
- } else Disarm_Timer -= diff;
-
- //Check_Timer for the death of LorKhan and Zath.
- if (!FakeDeath && Check_Timer <= diff)
- {
- if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
- {
- //Resurrect Thekal
- if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
- {
- pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pThekal->setFaction(14);
- pThekal->SetFullHealth();
- }
- }
-
- if (instance->GetBossState(DATA_ZATH) == SPECIAL)
- {
- //Resurrect Zath
- if (Unit* pZath = Unit::GetUnit(*me, instance->GetData64(DATA_ZATH)))
- {
- pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pZath->setFaction(14);
- pZath->SetFullHealth();
- }
- }
-
- Check_Timer = 5000;
- } else Check_Timer -= diff;
-
- if (!HealthAbovePct(5))
- {
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetStandState(UNIT_STAND_STATE_SLEEP);
- me->setFaction(35);
- me->AttackStop();
-
- instance->SetBossState(DATA_LORKHAN, SPECIAL);
-
- FakeDeath = true;
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_zealot_lorkhanAI>(creature);
- }
-};
-
-//Zealot Zath
-class npc_zealot_zath : public CreatureScript
-{
- public:
-
- npc_zealot_zath()
- : CreatureScript("npc_zealot_zath")
- {
- }
-
- struct npc_zealot_zathAI : public ScriptedAI
- {
- npc_zealot_zathAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- uint32 SweepingStrikes_Timer;
- uint32 SinisterStrike_Timer;
- uint32 Gouge_Timer;
- uint32 Kick_Timer;
- uint32 Blind_Timer;
- uint32 Check_Timer;
-
- bool FakeDeath;
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE
- {
- SweepingStrikes_Timer = 13000;
- SinisterStrike_Timer = 8000;
- Gouge_Timer = 25000;
- Kick_Timer = 18000;
- Blind_Timer = 5000;
- Check_Timer = 10000;
-
- FakeDeath = false;
-
- instance->SetBossState(DATA_ZATH, NOT_STARTED);
-
- me->SetStandState(UNIT_STAND_STATE_STAND);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- //SweepingStrikes_Timer
- if (SweepingStrikes_Timer <= diff)
- {
- DoCastVictim(SPELL_SWEEPINGSTRIKES);
- SweepingStrikes_Timer = 22000+rand()%4000;
- } else SweepingStrikes_Timer -= diff;
-
- //SinisterStrike_Timer
- if (SinisterStrike_Timer <= diff)
- {
- DoCastVictim(SPELL_SINISTERSTRIKE);
- SinisterStrike_Timer = 8000+rand()%8000;
- } else SinisterStrike_Timer -= diff;
-
- //Gouge_Timer
- if (Gouge_Timer <= diff)
- {
- DoCastVictim(SPELL_GOUGE);
-
- if (DoGetThreat(me->GetVictim()))
- DoModifyThreatPercent(me->GetVictim(), -100);
-
- Gouge_Timer = 17000+rand()%10000;
- } else Gouge_Timer -= diff;
-
- //Kick_Timer
- if (Kick_Timer <= diff)
- {
- DoCastVictim(SPELL_KICK);
- Kick_Timer = 15000+rand()%10000;
- } else Kick_Timer -= diff;
-
- //Blind_Timer
- if (Blind_Timer <= diff)
- {
- DoCastVictim(SPELL_BLIND);
- Blind_Timer = 10000+rand()%10000;
- } else Blind_Timer -= diff;
-
- //Check_Timer for the death of LorKhan and Zath.
- if (!FakeDeath && Check_Timer <= diff)
- {
- if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
- {
- //Resurrect LorKhan
- if (Unit* pLorKhan = Unit::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
- {
- pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pLorKhan->setFaction(14);
- pLorKhan->SetFullHealth();
- }
- }
-
- if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
- {
- //Resurrect Thekal
- if (Unit* pThekal = Unit::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
- {
- pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- pThekal->setFaction(14);
- pThekal->SetFullHealth();
- }
- }
-
- Check_Timer = 5000;
- } else Check_Timer -= diff;
-
- if (!HealthAbovePct(5))
- {
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
- me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetStandState(UNIT_STAND_STATE_SLEEP);
- me->setFaction(35);
- me->AttackStop();
-
- instance->SetBossState(DATA_ZATH, SPECIAL);
-
- FakeDeath = true;
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetInstanceAI<npc_zealot_zathAI>(creature);
- }
-};
-
-void AddSC_boss_thekal()
-{
- new boss_thekal();
- new npc_zealot_lorkhan();
- new npc_zealot_zath();
-}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp
index e131ed7ad12..2e6f569dbb0 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_venoxis.cpp
@@ -22,70 +22,30 @@
#include "Spell.h"
#include "zulgurub.h"
-/*
- * @todo
- * - Fix timers (research some more)
- */
-
-enum Says
+enum Yells
{
- SAY_VENOXIS_TRANSFORM = 1, // Let the coils of hate unfurl!
- SAY_VENOXIS_DEATH = 2 // Ssserenity.. at lassst!
+ SAY_AGGRO = 0,
+ SAY_BLOODVENOM = 1, // ID - 96842 Venomous Effusion
+ SAY_TRANSFROM = 2, // ID - 97354 Blessing of the Snake God
+ SAY_WORD_OF_HETHISS = 3, // ID - 96560 Word of Hethiss
+ EMOTE_BLOODVENOM = 4, // ID - 96842 Bloodvenom
+ EMOTE_VENOM_WITHDRAWAL = 5, // ID - 96653 Venom Withdrawal
+ SAY_PLAYER_KILL = 6,
+ SAY_DEATH = 7
};
enum Spells
{
- // troll form
- SPELL_THRASH = 3391,
- SPELL_DISPEL_MAGIC = 23859,
- SPELL_RENEW = 23895,
- SPELL_HOLY_NOVA = 23858,
- SPELL_HOLY_FIRE = 23860,
- SPELL_HOLY_WRATH = 23979,
- // snake form
- SPELL_POISON_CLOUD = 23861,
- SPELL_VENOM_SPIT = 23862,
-
- SPELL_PARASITIC_SERPENT = 23865,
- SPELL_SUMMON_PARASITIC_SERPENT = 23866,
- SPELL_PARASITIC_SERPENT_TRIGGER = 23867,
- // used when swapping event-stages
- SPELL_VENOXIS_TRANSFORM = 23849, // 50% health - shapechange to cobra
- SPELL_FRENZY = 8269 // 20% health - frenzy
};
enum Events
{
- // troll form
- EVENT_THRASH = 1,
- EVENT_DISPEL_MAGIC = 2,
- EVENT_RENEW = 3,
- EVENT_HOLY_NOVA = 4,
- EVENT_HOLY_FIRE = 5,
- EVENT_HOLY_WRATH = 6,
- // phase-changing
- EVENT_TRANSFORM = 7,
- // snake form events
- EVENT_POISON_CLOUD = 8,
- EVENT_VENOM_SPIT = 9,
- EVENT_PARASITIC_SERPENT = 10,
- EVENT_FRENZY = 11,
-};
-
-enum Phases
-{
- PHASE_ONE = 1, // troll form
- PHASE_TWO = 2 // snake form
-};
-
-enum NPCs
-{
- NPC_PARASITIC_SERPENT = 14884
};
class boss_venoxis : public CreatureScript
{
- public: boss_venoxis() : CreatureScript("boss_venoxis") { }
+ public:
+ boss_venoxis() : CreatureScript("boss_venoxis") { }
struct boss_venoxisAI : public BossAI
{
@@ -94,57 +54,24 @@ class boss_venoxis : public CreatureScript
void Reset() OVERRIDE
{
_Reset();
- // remove all spells and auras from previous attempts
- me->RemoveAllAuras();
- me->SetReactState(REACT_PASSIVE);
- // set some internally used variables to their defaults
- _inMeleeRange = 0;
- _transformed = false;
- _frenzied = false;
- events.SetPhase(PHASE_ONE);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- _JustDied();
- Talk(SAY_VENOXIS_DEATH);
- me->RemoveAllAuras();
}
void EnterCombat(Unit* /*who*/) OVERRIDE
{
_EnterCombat();
- me->SetReactState(REACT_AGGRESSIVE);
- // Always running events
- events.ScheduleEvent(EVENT_THRASH, 5000);
- // Phase one events (regular form)
- events.ScheduleEvent(EVENT_HOLY_NOVA, 5000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_HOLY_FIRE, 10000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_RENEW, 30000, 0, PHASE_ONE);
- events.ScheduleEvent(EVENT_HOLY_WRATH, 60000, 0, PHASE_ONE);
-
- events.SetPhase(PHASE_ONE);
+ Talk(SAY_AGGRO);
+ }
- // Set zone in combat
- DoZoneInCombat();
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
}
- void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) OVERRIDE
+ void KilledUnit(Unit* victim) OVERRIDE
{
- // check if venoxis is ready to transform
- if (!_transformed && !HealthAbovePct(50))
- {
- _transformed = true;
- // schedule the event that changes our phase
- events.ScheduleEvent(EVENT_TRANSFORM, 100);
- }
- // we're losing health, bad, go frenzy
- else if (!_frenzied && !HealthAbovePct(20))
- {
- _frenzied = true;
- events.ScheduleEvent(EVENT_FRENZY, 100);
- }
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -154,117 +81,26 @@ class boss_venoxis : public CreatureScript
events.Update(diff);
- // return back to main code if we're still casting
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- // thrash is available in all phases
- case EVENT_THRASH:
- DoCast(me, SPELL_THRASH, true);
- events.ScheduleEvent(EVENT_THRASH, urand(10000, 20000));
- break;
-
- // troll form spells and Actions (first part)
- case EVENT_DISPEL_MAGIC:
- DoCast(me, SPELL_DISPEL_MAGIC);
- events.ScheduleEvent(EVENT_DISPEL_MAGIC, urand(15000, 20000), 0, PHASE_ONE);
- break;
- case EVENT_RENEW:
- DoCast(me, SPELL_RENEW);
- events.ScheduleEvent(EVENT_RENEW, urand(25000, 30000), 0, PHASE_ONE);
- break;
- case EVENT_HOLY_NOVA:
- _inMeleeRange = 0;
-
- for (uint8 i = 0; i < 10; ++i)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, i))
- // check if target is within melee-distance
- if (me->IsWithinMeleeRange(target))
- ++_inMeleeRange;
- }
-
- // trigger spellcast only if we have 3 or more targets to affect
- if (_inMeleeRange >= 3)
- DoCastVictim(SPELL_HOLY_NOVA);
-
- events.ScheduleEvent(EVENT_HOLY_NOVA, urand(45000, 75000), 0, PHASE_ONE);
- break;
- case EVENT_HOLY_FIRE:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_HOLY_FIRE);
- events.ScheduleEvent(EVENT_HOLY_FIRE, urand(45000, 60000), 0, PHASE_ONE);
- break;
- case EVENT_HOLY_WRATH:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_HOLY_WRATH);
- events.ScheduleEvent(EVENT_HOLY_WRATH, urand(45000, 60000), 0, PHASE_ONE);
- break;
-
- //
- // snake form spells and Actions
- //
-
- case EVENT_VENOM_SPIT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_VENOM_SPIT);
- events.ScheduleEvent(EVENT_VENOM_SPIT, urand(5000, 15000), 0, PHASE_TWO);
- break;
- case EVENT_POISON_CLOUD:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_POISON_CLOUD);
- events.ScheduleEvent(EVENT_POISON_CLOUD, urand(15000, 20000), 0, PHASE_TWO);
- break;
- case EVENT_PARASITIC_SERPENT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
- DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT);
- events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15000, 0, PHASE_TWO);
- break;
- case EVENT_FRENZY:
- // frenzy at 20% health
- DoCast(me, SPELL_FRENZY, true);
- break;
-
- //
- // shape and phase-changing
- //
-
- case EVENT_TRANSFORM:
- // shapeshift at 50% health
- DoCast(me, SPELL_VENOXIS_TRANSFORM);
- Talk(SAY_VENOXIS_TRANSFORM);
- DoResetThreat();
-
- // phase two events (snakeform)
- events.ScheduleEvent(EVENT_VENOM_SPIT, 5000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_POISON_CLOUD, 10000, 0, PHASE_TWO);
- events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30000, 0, PHASE_TWO);
-
- // transformed, start phase two
- events.SetPhase(PHASE_TWO);
-
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
-
- private:
- uint8 _inMeleeRange;
- bool _transformed;
- bool _frenzied;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new boss_venoxisAI(creature);
+ return GetZulGurubAI<boss_venoxisAI>(creature);
}
};
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp
index a4bd38b8fa7..3f7d15e67b9 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_wushoolay.cpp
@@ -16,52 +16,44 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Wushoolay
-SD%Complete: 100
-SDComment:
-SDCategory: Zul'Gurub
-EndScriptData */
-
+#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "zulgurub.h"
+enum Yells
+{
+};
+
enum Spells
{
- SPELL_LIGHTNINGCLOUD = 25033,
- SPELL_LIGHTNINGWAVE = 24819
};
enum Events
{
- EVENT_LIGHTNINGCLOUD = 1,
- EVENT_LIGHTNINGWAVE = 2
};
class boss_wushoolay : public CreatureScript
{
- public: boss_wushoolay() : CreatureScript("boss_wushoolay") { }
+ public:
+ boss_wushoolay() : CreatureScript("boss_wushoolay") { }
struct boss_wushoolayAI : public BossAI
{
- boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
+ boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_HAZZARAH)
+ {
+ }
void Reset() OVERRIDE
{
- _Reset();
}
- void JustDied(Unit* /*killer*/) OVERRIDE
+ void EnterCombat(Unit* /*who*/) OVERRIDE
{
- _JustDied();
}
- void EnterCombat(Unit* /*who*/) OVERRIDE
+ void JustDied(Unit* /*killer*/) OVERRIDE
{
- _EnterCombat();
- events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(5000, 10000));
- events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(8000, 16000));
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -73,23 +65,16 @@ class boss_wushoolay : public CreatureScript
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
-
+ /*
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
- case EVENT_LIGHTNINGCLOUD:
- DoCastVictim(SPELL_LIGHTNINGCLOUD, true);
- events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(15000, 20000));
- break;
- case EVENT_LIGHTNINGWAVE:
- DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_LIGHTNINGWAVE);
- events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(12000, 16000));
- break;
default:
break;
}
}
+ */
DoMeleeAttackIfReady();
}
@@ -105,4 +90,3 @@ void AddSC_boss_wushoolay()
{
new boss_wushoolay();
}
-
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp
new file mode 100644
index 00000000000..303fc2e49ad
--- /dev/null
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_zanzil.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "zulgurub.h"
+
+enum Yells
+{
+ SAY_AGGRO = 0,
+ EMOTE_ZANZIL_ZOMBIES = 1, // ID - 96319 Zanzil's Resurrection Elixir
+ SAY_ZANZIL_ZOMBIES = 2, // ID - 96319 Zanzil's Resurrection Elixir
+ EMOTE_ZANZIL_GRAVEYARD_GAS = 3, // ID - 96338 Zanzil's Graveyard Gas
+ SAY_ZANZIL_GRAVEYARD_GAS = 4, // ID - 96338 Zanzil's Graveyard Gas
+ EMOTE_ZANZIL_BERSEKER = 5, // ID - 96316 Zanzil's Resurrection Elixir
+ SAY_ZANZIL_BERSEKER = 6, // ID - 96316 Zanzil's Resurrection Elixir
+ SAY_PLAYER_KILL = 7,
+ SAY_DEATH = 8
+};
+
+enum Spells
+{
+};
+
+enum Events
+{
+};
+
+class boss_zanzil : public CreatureScript
+{
+ public:
+ boss_zanzil() : CreatureScript("boss_zanzil") { }
+
+ struct boss_zanzilAI : public BossAI
+ {
+ boss_zanzilAI(Creature* creature) : BossAI(creature, DATA_ZANZIL) { }
+
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ _EnterCombat();
+ Talk(SAY_AGGRO);
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
+ Talk(SAY_DEATH);
+ }
+
+ void KilledUnit(Unit* victim) OVERRIDE
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_PLAYER_KILL);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+ /*
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ default:
+ break;
+ }
+ }
+ */
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetZulGurubAI<boss_zanzilAI>(creature);
+ }
+};
+
+void AddSC_boss_zanzil()
+{
+ new boss_zanzil();
+}
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
index 67d40abaea3..6483eab20e6 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp
@@ -16,26 +16,24 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Instance_ZulGurub
-SD%Complete: 80
-SDComment: Missing reset function after killing a boss for Ohgan, Thekal.
-SDCategory: Zul'Gurub
-EndScriptData */
-
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "zulgurub.h"
DoorData const doorData[] =
{
- { GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
- { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+ { GO_VENOXIS_COIL, DATA_VENOXIS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_ARENA_DOOR_1, DATA_MANDOKIR, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_FORCEFIELD, DATA_KILNARA, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_ZANZIL_DOOR, DATA_ZANZIL, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ //{ GO_THE_CACHE_OF_MADNESS_DOOR, DATA_xxxxxxx, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
};
class instance_zulgurub : public InstanceMapScript
{
- public: instance_zulgurub(): InstanceMapScript(ZGScriptName, 309) { }
+ public:
+ instance_zulgurub() : InstanceMapScript(ZGScriptName, 859) { }
struct instance_zulgurub_InstanceMapScript : public InstanceScript
{
@@ -43,46 +41,53 @@ class instance_zulgurub : public InstanceMapScript
{
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
- }
-
- void Initialize() OVERRIDE
- {
- _zealotLorkhanGUID = 0;
- _zealotZathGUID = 0;
- _highPriestTekalGUID = 0;
- _jindoTheHexxerGUID = 0;
- _vilebranchSpeakerGUID = 0;
- _arlokkGUID = 0;
- _goGongOfBethekkGUID = 0;
- }
-
- bool IsEncounterInProgress() const OVERRIDE
- {
- // not active in Zul'Gurub
- return false;
+ venoxisGUID = 0;
+ mandokirGUID = 0;
+ kilnaraGUID = 0;
+ zanzilGUID = 0;
+ jindoGUID = 0;
+ hazzarahGUID = 0;
+ renatakiGUID = 0;
+ wushoolayGUID = 0;
+ grilekGUID = 0;
+ jindoTiggerGUID = 0;
}
void OnCreatureCreate(Creature* creature) OVERRIDE
{
switch (creature->GetEntry())
{
- case NPC_ZEALOT_LORKHAN:
- _zealotLorkhanGUID = creature->GetGUID();
+ case NPC_VENOXIS:
+ venoxisGUID = creature->GetGUID();
+ break;
+ case NPC_MANDOKIR:
+ mandokirGUID = creature->GetGUID();
+ break;
+ case NPC_KILNARA:
+ kilnaraGUID = creature->GetGUID();
+ break;
+ case NPC_ZANZIL:
+ zanzilGUID = creature->GetGUID();
+ break;
+ case NPC_JINDO:
+ jindoGUID = creature->GetGUID();
break;
- case NPC_ZEALOT_ZATH:
- _zealotZathGUID = creature->GetGUID();
+ case NPC_HAZZARAH:
+ hazzarahGUID = creature->GetGUID();
break;
- case NPC_HIGH_PRIEST_THEKAL:
- _highPriestTekalGUID = creature->GetGUID();
+ case NPC_RENATAKI:
+ renatakiGUID = creature->GetGUID();
break;
- case NPC_JINDO_THE_HEXXER:
- _jindoTheHexxerGUID = creature->GetGUID();
+ case NPC_WUSHOOLAY:
+ wushoolayGUID = creature->GetGUID();
break;
- case NPC_VILEBRANCH_SPEAKER:
- _vilebranchSpeakerGUID = creature->GetGUID();
+ case NPC_GRILEK:
+ grilekGUID = creature->GetGUID();
break;
- case NPC_ARLOKK:
- _arlokkGUID = creature->GetGUID();
+ case NPC_JINDO_TRIGGER:
+ jindoTiggerGUID = creature->GetGUID();
+ break;
+ default:
break;
}
}
@@ -91,16 +96,13 @@ class instance_zulgurub : public InstanceMapScript
{
switch (go->GetEntry())
{
+ case GO_VENOXIS_COIL:
+ case GO_ARENA_DOOR_1:
case GO_FORCEFIELD:
+ case GO_ZANZIL_DOOR:
+ case GO_THE_CACHE_OF_MADNESS_DOOR:
AddDoor(go, true);
break;
- case GO_GONG_OF_BETHEKK:
- _goGongOfBethekkGUID = go->GetGUID();
- if (GetBossState(DATA_ARLOKK) == DONE)
- go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- else
- go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- break;
default:
break;
}
@@ -110,7 +112,11 @@ class instance_zulgurub : public InstanceMapScript
{
switch (go->GetEntry())
{
+ case GO_VENOXIS_COIL:
+ case GO_ARENA_DOOR_1:
case GO_FORCEFIELD:
+ case GO_ZANZIL_DOOR:
+ case GO_THE_CACHE_OF_MADNESS_DOOR:
AddDoor(go, false);
break;
default:
@@ -118,29 +124,76 @@ class instance_zulgurub : public InstanceMapScript
}
}
- uint64 GetData64(uint32 uiData) const OVERRIDE
+ bool SetBossState(uint32 type, EncounterState state) OVERRIDE
{
- switch (uiData)
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
{
- case DATA_LORKHAN:
- return _zealotLorkhanGUID;
- break;
- case DATA_ZATH:
- return _zealotZathGUID;
- break;
- case DATA_THEKAL:
- return _highPriestTekalGUID;
- break;
+ case DATA_VENOXIS:
+ case DATA_MANDOKIR:
+ case DATA_KILNARA:
+ case DATA_ZANZIL:
case DATA_JINDO:
- return _jindoTheHexxerGUID;
+ case DATA_HAZZARAH:
+ case DATA_RENATAKI:
+ case DATA_WUSHOOLAY:
+ case DATA_GRILEK:
break;
- case NPC_ARLOKK:
- return _arlokkGUID;
+ default:
break;
- case GO_GONG_OF_BETHEKK:
- return _goGongOfBethekkGUID;
+ }
+
+ return true;
+ }
+
+ /*
+ void SetData(uint32 type, uint32 data) OVERRIDE
+ {
+ switch (type)
+ {
+ }
+ }
+
+ uint32 GetData(uint32 type) const OVERRIDE
+ {
+ switch (type)
+ {
+ }
+
+ return 0;
+ }
+ */
+
+ uint64 GetData64(uint32 type) const OVERRIDE
+ {
+ switch (type)
+ {
+ case DATA_VENOXIS:
+ return venoxisGUID;
+ case DATA_MANDOKIR:
+ return mandokirGUID;
+ case DATA_KILNARA:
+ return kilnaraGUID;
+ case DATA_ZANZIL:
+ return zanzilGUID;
+ case DATA_JINDO:
+ return jindoGUID;
+ case DATA_HAZZARAH:
+ return hazzarahGUID;
+ case DATA_RENATAKI:
+ return renatakiGUID;
+ case DATA_WUSHOOLAY:
+ return wushoolayGUID;
+ case DATA_GRILEK:
+ return grilekGUID;
+ case DATA_JINDOR_TRIGGER:
+ return jindoTiggerGUID;
+ default:
break;
}
+
return 0;
}
@@ -155,7 +208,7 @@ class instance_zulgurub : public InstanceMapScript
return saveStream.str();
}
- void Load(const char* str) OVERRIDE
+ void Load(char const* str) OVERRIDE
{
if (!str)
{
@@ -172,12 +225,13 @@ class instance_zulgurub : public InstanceMapScript
if (dataHead1 == 'Z' && dataHead2 == 'G')
{
- for (uint32 i = 0; i < EncounterCount; ++i)
+ for (uint8 i = 0; i < EncounterCount; ++i)
{
uint32 tmpState;
loadStream >> tmpState;
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
tmpState = NOT_STARTED;
+
SetBossState(i, EncounterState(tmpState));
}
}
@@ -186,17 +240,18 @@ class instance_zulgurub : public InstanceMapScript
OUT_LOAD_INST_DATA_COMPLETE;
}
- private:
- //If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too.
- //Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too.
-
- uint64 _zealotLorkhanGUID;
- uint64 _zealotZathGUID;
- uint64 _highPriestTekalGUID;
- uint64 _jindoTheHexxerGUID;
- uint64 _vilebranchSpeakerGUID;
- uint64 _arlokkGUID;
- uint64 _goGongOfBethekkGUID;
+
+ protected:
+ uint64 venoxisGUID;
+ uint64 mandokirGUID;
+ uint64 kilnaraGUID;
+ uint64 zanzilGUID;
+ uint64 jindoGUID;
+ uint64 hazzarahGUID;
+ uint64 renatakiGUID;
+ uint64 wushoolayGUID;
+ uint64 grilekGUID;
+ uint64 jindoTiggerGUID;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
index a9386ff1782..5fbd18b7590 100644
--- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
+++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -18,51 +19,72 @@
#ifndef DEF_ZULGURUB_H
#define DEF_ZULGURUB_H
-uint32 const EncounterCount = 13;
-
#define ZGScriptName "instance_zulgurub"
+uint32 const EncounterCount = 5;
+
enum DataTypes
{
- DATA_JEKLIK = 0, // Main boss
- DATA_VENOXIS = 1, // Main boss
- DATA_MARLI = 2, // Main boss
- DATA_ARLOKK = 3, // Main boss
- DATA_THEKAL = 4, // Main boss
- DATA_HAKKAR = 5, // End boss
- DATA_MANDOKIR = 6, // Optional boss
- DATA_JINDO = 7, // Optional boss
- DATA_GAHZRANKA = 8, // Optional boss
- DATA_EDGE_OF_MADNESS = 9, // Optional Event Edge of Madness - one of: Gri'lek, Renataki, Hazza'rah, or Wushoolay
- DATA_LORKHAN = 10, // Zealot Lor'Khan add to High priest Thekal!
- DATA_ZATH = 11, // Zealot Zath add to High priest Thekal!
- DATA_OHGAN = 12, // Bloodlord Mandokir's raptor mount
- TYPE_EDGE_OF_MADNESS = 13 // Boss storage
+ DATA_VENOXIS = 0,
+ DATA_MANDOKIR = 1,
+ DATA_KILNARA = 2,
+ DATA_ZANZIL = 3,
+ DATA_JINDO = 4,
+
+ // Cache of Madness
+ DATA_HAZZARAH = 5,
+ DATA_RENATAKI = 6,
+ DATA_WUSHOOLAY = 7,
+ DATA_GRILEK = 8,
+
+ // Jin'do the Godbreaker
+ DATA_JINDOR_TRIGGER,
};
enum CreatureIds
{
- NPC_ARLOKK = 14515, // Arlokk Event
- NPC_PANTHER_TRIGGER = 15091, // Arlokk Event
- NPC_ZULIAN_PROWLER = 15101, // Arlokk Event
- NPC_ZEALOT_LORKHAN = 11347,
- NPC_ZEALOT_ZATH = 11348,
- NPC_HIGH_PRIEST_THEKAL = 14509,
- NPC_JINDO_THE_HEXXER = 11380,
- NPC_NIGHTMARE_ILLUSION = 15163,
- NPC_SHADE_OF_JINDO = 14986,
- NPC_SACRIFICED_TROLL = 14826,
- NPC_MANDOKIR = 11382, // Mandokir Event
- NPC_OHGAN = 14988, // Mandokir Event
- NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event
- NPC_CHAINED_SPIRT = 15117 // Mandokir Event
+ NPC_VENOXIS = 52155,
+ NPC_MANDOKIR = 52151,
+ NPC_KILNARA = 52059,
+ NPC_ZANZIL = 52053,
+ NPC_JINDO = 52148,
+
+ // Cache of Madness
+ NPC_HAZZARAH = 52271,
+ NPC_RENATAKI = 52269,
+ NPC_WUSHOOLAY = 52286,
+ NPC_GRILEK = 52258,
+ // Bloodlord Mandokir
+ NPC_CHAINED_SPIRIT = 52156,
+ NPC_OHGAN = 52157,
+
+ // Jin'do the Godbreaker
+ NPC_JINDO_TRIGGER = 52150,
+ NPC_SPIRIT_OF_HAKKAR = 52222,
+ NPC_SHADOW_OF_HAKKAR = 52650
};
-enum GameobjectIds
+enum GameObjectIds
{
- GO_FORCEFIELD = 180497, // Arlokk Event
- GO_GONG_OF_BETHEKK = 180526 // Arlokk Event
+ // High Priest Venoxis
+ GO_VENOXIS_COIL = 208844,
+
+ // Bloodlord Mandokir
+ GO_ARENA_DOOR_1 = 208845,
+ GO_ARENA_DOOR_2 = 208847,
+ GO_ARENA_DOOR_3 = 208848,
+ GO_ARENA_DOOR_4 = 208846,
+ GO_ARENA_DOOR_5 = 208849,
+
+ // High Priestess Kilnara
+ GO_FORCEFIELD = 180497,
+
+ // Zanzil
+ GO_ZANZIL_DOOR = 208850,
+
+ // Cache of Madness
+ GO_THE_CACHE_OF_MADNESS_DOOR = 208843
};
template<class AI>
diff --git a/src/server/scripts/EasternKingdoms/boss_kruul.cpp b/src/server/scripts/EasternKingdoms/boss_kruul.cpp
deleted file mode 100644
index faed1a3cc34..00000000000
--- a/src/server/scripts/EasternKingdoms/boss_kruul.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
- *
- * 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/>.
- */
-
-/* ScriptData
-SDName: Boss_Kruul
-SD%Complete: 100
-SDComment: Highlord Kruul are presumably no longer in-game on regular bases, however future events could bring him back.
-SDCategory: Bosses
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-
-enum Spells
-{
- SPELL_SHADOWVOLLEY = 21341,
- SPELL_CLEAVE = 20677,
- SPELL_THUNDERCLAP = 23931,
- SPELL_TWISTEDREFLECTION = 21063,
- SPELL_VOIDBOLT = 21066,
- SPELL_RAGE = 21340,
- SPELL_CAPTURESOUL = 21054
-};
-
-class boss_kruul : public CreatureScript
-{
-public:
- boss_kruul() : CreatureScript("boss_kruul") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new boss_kruulAI(creature);
- }
-
- struct boss_kruulAI : public ScriptedAI
- {
- boss_kruulAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 ShadowVolley_Timer;
- uint32 Cleave_Timer;
- uint32 ThunderClap_Timer;
- uint32 TwistedReflection_Timer;
- uint32 VoidBolt_Timer;
- uint32 Rage_Timer;
- uint32 Hound_Timer;
-
- void Reset() OVERRIDE
- {
- ShadowVolley_Timer = 10000;
- Cleave_Timer = 14000;
- ThunderClap_Timer = 20000;
- TwistedReflection_Timer = 25000;
- VoidBolt_Timer = 30000;
- Rage_Timer = 60000; //Cast rage after 1 minute
- Hound_Timer = 8000;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- }
-
- void KilledUnit(Unit* /*victim*/) OVERRIDE
- {
- // When a player, pet or totem gets killed, Lord Kazzak casts this spell to instantly regenerate 70, 000 health.
- DoCast(me, SPELL_CAPTURESOUL);
- }
-
- void SummonHounds(Unit* victim)
- {
- if (Creature* Hound = DoSpawnCreature(19207, float(irand(-9, 9)), float(irand(-9, 9)), 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 300000))
- Hound->AI()->AttackStart(victim);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
-
- //ShadowVolley_Timer
- if (ShadowVolley_Timer <= diff)
- {
- if (urand(0, 99) < 45)
- DoCastVictim(SPELL_SHADOWVOLLEY);
-
- ShadowVolley_Timer = 5000;
- } else ShadowVolley_Timer -= diff;
-
- //Cleave_Timer
- if (Cleave_Timer <= diff)
- {
- if (urand(0, 1))
- DoCastVictim(SPELL_CLEAVE);
-
- Cleave_Timer = 10000;
- } else Cleave_Timer -= diff;
-
- //ThunderClap_Timer
- if (ThunderClap_Timer <= diff)
- {
- if (urand(0, 9) < 2)
- DoCastVictim(SPELL_THUNDERCLAP);
-
- ThunderClap_Timer = 12000;
- } else ThunderClap_Timer -= diff;
-
- //TwistedReflection_Timer
- if (TwistedReflection_Timer <= diff)
- {
- DoCastVictim(SPELL_TWISTEDREFLECTION);
- TwistedReflection_Timer = 30000;
- } else TwistedReflection_Timer -= diff;
-
- //VoidBolt_Timer
- if (VoidBolt_Timer <= diff)
- {
- if (urand(0, 9) < 4)
- DoCastVictim(SPELL_VOIDBOLT);
-
- VoidBolt_Timer = 18000;
- } else VoidBolt_Timer -= diff;
-
- //Rage_Timer
- if (Rage_Timer <= diff)
- {
- DoCast(me, SPELL_RAGE);
- Rage_Timer = 70000;
- } else Rage_Timer -= diff;
-
- //Hound_Timer
- if (Hound_Timer <= diff)
- {
- SummonHounds(me->GetVictim());
- SummonHounds(me->GetVictim());
- SummonHounds(me->GetVictim());
-
- Hound_Timer = 45000;
- } else Hound_Timer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
-void AddSC_boss_kruul()
-{
- new boss_kruul();
-}
diff --git a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
index 7a2c1cb09db..ddb6575d72f 100644
--- a/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_arathi_highlands.cpp
@@ -49,8 +49,13 @@ enum ProfessorPhizzlethorpe
SAY_PROGRESS_7 = 7,
EMOTE_PROGRESS_8 = 8,
SAY_PROGRESS_9 = 9,
+ EVENT_SAY_3 = 1,
+ EVENT_SAY_6 = 2,
+ EVENT_SAY_8 = 3,
+
// Quests
QUEST_SUNKEN_TREASURE = 665,
+ QUEST_GOGGLE_BOGGLE = 26050,
// Creatures
NPC_VENGEFUL_SURGE = 2776,
FACTION_SUNKEN_TREASURE = 113
@@ -73,33 +78,22 @@ class npc_professor_phizzlethorpe : public CreatureScript
switch (waypointId)
{
- case 4:
+ case 6:
Talk(SAY_PROGRESS_2, player);
- break;
- case 5:
- Talk(SAY_PROGRESS_3, player);
+ events.ScheduleEvent(EVENT_SAY_3, 3000);
break;
case 8:
Talk(EMOTE_PROGRESS_4);
- break;
- case 9:
- me->SummonCreature(NPC_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
- me->SummonCreature(NPC_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
- break;
- case 10:
- Talk(SAY_PROGRESS_5, player);
+ me->SummonCreature(NPC_VENGEFUL_SURGE, -2065.505f, -2136.88f, 22.20362f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ me->SummonCreature(NPC_VENGEFUL_SURGE, -2059.249f, -2134.88f, 21.51582f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
break;
case 11:
- Talk(SAY_PROGRESS_6, player);
- SetRun();
+ Talk(SAY_PROGRESS_5, player);
+ events.ScheduleEvent(EVENT_SAY_6, 11000);
break;
- case 19:
+ case 17:
Talk(SAY_PROGRESS_7, player);
- break;
- case 20:
- Talk(EMOTE_PROGRESS_8);
- Talk(SAY_PROGRESS_9, player);
- player->GroupEventHappens(QUEST_SUNKEN_TREASURE, me);
+ events.ScheduleEvent(EVENT_SAY_8, 6000);
break;
}
}
@@ -126,8 +120,34 @@ class npc_professor_phizzlethorpe : public CreatureScript
void UpdateAI(uint32 diff) OVERRIDE
{
+ Player* player = GetPlayerForEscort();
+ if (!player)
+ return;
+
+ events.Update(diff);
+
+ while (uint32 event = events.ExecuteEvent())
+ {
+ switch (event)
+ {
+ case EVENT_SAY_3:
+ Talk(SAY_PROGRESS_3, player);
+ break;
+ case EVENT_SAY_6:
+ Talk(SAY_PROGRESS_6, player);
+ SetRun();
+ break;
+ case EVENT_SAY_8:
+ Talk(EMOTE_PROGRESS_8);
+ Talk(SAY_PROGRESS_9, player);
+ player->GroupEventHappens(QUEST_GOGGLE_BOGGLE, me);
+ break;
+ }
+ }
npc_escortAI::UpdateAI(diff);
}
+
+ EventMap events;
};
CreatureAI* GetAI(Creature* creature) const OVERRIDE
diff --git a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
index b991ab3c7a2..0c45ba98064 100644
--- a/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_burning_steppes.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,152 +15,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Burning_Steppes
-SD%Complete: 100
-SDComment: Quest support: 4224, 4866
-SDCategory: Burning Steppes
-EndScriptData */
-
-/* ContentData
-npc_ragged_john
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-
-/*######
-## npc_ragged_john
-######*/
-
-#define GOSSIP_HELLO "Official buisness, John. I need some information about Marsha Windsor. Tell me about the last time you saw him."
-#define GOSSIP_SELECT1 "So what did you do?"
-#define GOSSIP_SELECT2 "Start making sense, dwarf. I don't want to have anything to do with your cracker, your pappy, or any sort of 'discreditin'."
-#define GOSSIP_SELECT3 "Ironfoe?"
-#define GOSSIP_SELECT4 "Interesting... continue John."
-#define GOSSIP_SELECT5 "So that's how Windsor died..."
-#define GOSSIP_SELECT6 "So how did he die?"
-#define GOSSIP_SELECT7 "Ok so where the hell is he? Wait a minute! Are you drunk?"
-#define GOSSIP_SELECT8 "WHY is he in Blackrock Depths?"
-#define GOSSIP_SELECT9 "300? So the Dark Irons killed him and dragged him into the Depths?"
-#define GOSSIP_SELECT10 "Ahh... Ironfoe"
-#define GOSSIP_SELECT11 "Thanks, Ragged John. Your story was very uplifting and informative"
-
-enum RaggedJohn
-{
- QUEST_THE_TRUE_MASTERS = 4224,
- QUEST_MOTHERS_MILK = 4866,
- SPELL_MOTHERS_MILK = 16468,
- SPELL_WICKED_MILKING = 16472
-};
-
-class npc_ragged_john : public CreatureScript
-{
-public:
- npc_ragged_john() : CreatureScript("npc_ragged_john") { }
-
- struct npc_ragged_johnAI : public ScriptedAI
- {
- npc_ragged_johnAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
- {
- if (who->HasAura(SPELL_MOTHERS_MILK))
- {
- if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 15) && who->isInAccessiblePlaceFor(me))
- {
- DoCast(who, SPELL_WICKED_MILKING);
- if (Player* player = who->ToPlayer())
- player->AreaExploredOrEventHappens(QUEST_MOTHERS_MILK);
- }
- }
-
- ScriptedAI::MoveInLineOfSight(who);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
- };
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(2714, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(2715, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(2716, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(2717, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(2718, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(2719, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
- player->SEND_GOSSIP_MENU(2720, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT8, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
- player->SEND_GOSSIP_MENU(2721, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+8:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT9, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
- player->SEND_GOSSIP_MENU(2722, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+9:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT10, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
- player->SEND_GOSSIP_MENU(2723, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+10:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT11, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
- player->SEND_GOSSIP_MENU(2725, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+11:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(QUEST_THE_TRUE_MASTERS);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_THE_TRUE_MASTERS) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(2713, creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ragged_johnAI(creature);
- }
-};
-
void AddSC_burning_steppes()
{
- new npc_ragged_john();
+
}
diff --git a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
index a4f75ea23d4..a6e9e8d0342 100644
--- a/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_ghostlands.cpp
@@ -19,7 +19,7 @@
/* ScriptData
SDName: Ghostlands
SD%Complete: 100
-SDComment: Quest support: 9212.
+SDComment:
SDCategory: Ghostlands
EndScriptData */
@@ -35,6 +35,7 @@ EndContentData */
#include "WorldSession.h"
/*######
+
## npc_ranger_lilatha
######*/
diff --git a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
index 9db6a6b4d19..b89d651d8c2 100644
--- a/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_hinterlands.cpp
@@ -19,13 +19,12 @@
/* ScriptData
SDName: Hinterlands
SD%Complete: 100
-SDComment: Quest support: 863, 2742
+SDComment: Quest support: 836
SDCategory: The Hinterlands
EndScriptData */
/* ContentData
npc_oox09hl
-npc_rinji
EndContentData */
#include "ScriptMgr.h"
@@ -37,7 +36,7 @@ EndContentData */
## npc_oox09hl
######*/
-enum OOX
+enum eOOX
{
SAY_OOX_START = 0,
SAY_OOX_AGGRO = 1,
@@ -86,7 +85,7 @@ public:
}
}
- void WaypointReached(uint32 waypointId) OVERRIDE
+ void WaypointReached(uint32 waypointId)
{
switch (waypointId)
{
@@ -136,199 +135,7 @@ public:
}
};
-/*######
-## npc_rinji
-######*/
-
-enum Rinji
-{
- SAY_RIN_BY_OUTRUNNER = 0,
- SAY_RIN_FREE = 0, // from here
- SAY_RIN_HELP = 1,
- SAY_RIN_COMPLETE = 2,
- SAY_RIN_PROGRESS_1 = 3,
- SAY_RIN_PROGRESS_2 = 4,
- QUEST_RINJI_TRAPPED = 2742,
- NPC_RANGER = 2694,
- NPC_OUTRUNNER = 2691,
- GO_RINJI_CAGE = 142036
-};
-
-struct Location
-{
- float posX, posY, posZ;
-};
-
-Location AmbushSpawn[] =
-{
- { 191.296204f, -2839.329346f, 107.388f },
- { 70.972466f, -2848.674805f, 109.459f }
-};
-
-Location AmbushMoveTo[] =
-{
- { 166.630386f, -2824.780273f, 108.153f },
- { 70.886589f, -2874.335449f, 116.675f }
-};
-
-class npc_rinji : public CreatureScript
-{
-public:
- npc_rinji() : CreatureScript("npc_rinji") { }
-
- struct npc_rinjiAI : public npc_escortAI
- {
- npc_rinjiAI(Creature* creature) : npc_escortAI(creature)
- {
- _IsByOutrunner = false;
- spawnId = 0;
- }
-
- void Reset() OVERRIDE
- {
- postEventCount = 0;
- postEventTimer = 3000;
- }
-
- void JustRespawned() OVERRIDE
- {
- _IsByOutrunner = false;
- spawnId = 0;
-
- npc_escortAI::JustRespawned();
- }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- if (HasEscortState(STATE_ESCORT_ESCORTING))
- {
- if (who->GetEntry() == NPC_OUTRUNNER && !_IsByOutrunner)
- {
- if (Creature* talker = who->ToCreature())
- talker->AI()->Talk(SAY_RIN_BY_OUTRUNNER);
- _IsByOutrunner = true;
- }
-
- if (rand()%4)
- return;
-
- //only if attacked and escorter is not in combat?
- Talk(SAY_RIN_HELP);
- }
- }
-
- void DoSpawnAmbush(bool _first)
- {
- if (!_first)
- spawnId = 1;
-
- me->SummonCreature(NPC_RANGER, AmbushSpawn[spawnId].posX, AmbushSpawn[spawnId].posY, AmbushSpawn[spawnId].posZ, 0.0f,
- TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
-
- for (int i = 0; i < 2; ++i)
- {
- me->SummonCreature(NPC_OUTRUNNER, AmbushSpawn[spawnId].posX, AmbushSpawn[spawnId].posY, AmbushSpawn[spawnId].posZ, 0.0f,
- TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000);
- }
- }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- summoned->SetWalk(false);
- summoned->GetMotionMaster()->MovePoint(0, AmbushMoveTo[spawnId].posX, AmbushMoveTo[spawnId].posY, AmbushMoveTo[spawnId].posZ);
- }
-
- void sQuestAccept(Player* player, Quest const* quest)
- {
- if (quest->GetQuestId() == QUEST_RINJI_TRAPPED)
- {
- if (GameObject* go = me->FindNearestGameObject(GO_RINJI_CAGE, INTERACTION_DISTANCE))
- go->UseDoorOrButton();
-
- npc_escortAI::Start(false, false, player->GetGUID(), quest);
- }
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- Player* player = GetPlayerForEscort();
- if (!player)
- return;
-
- switch (waypointId)
- {
- case 1:
- Talk(SAY_RIN_FREE, player);
- break;
- case 7:
- DoSpawnAmbush(true);
- break;
- case 13:
- DoSpawnAmbush(false);
- break;
- case 17:
- Talk(SAY_RIN_COMPLETE, player);
- player->GroupEventHappens(QUEST_RINJI_TRAPPED, me);
- SetRun();
- postEventCount = 1;
- break;
- }
- }
-
- void UpdateEscortAI(const uint32 diff) OVERRIDE
- {
- //Check if we have a current target
- if (!UpdateVictim())
- {
- if (HasEscortState(STATE_ESCORT_ESCORTING) && postEventCount)
- {
- if (postEventTimer <= diff)
- {
- postEventTimer = 3000;
-
- if (Player* player = GetPlayerForEscort())
- {
- switch (postEventCount)
- {
- case 1:
- Talk(SAY_RIN_PROGRESS_1, player);
- ++postEventCount;
- break;
- case 2:
- Talk(SAY_RIN_PROGRESS_2, player);
- postEventCount = 0;
- break;
- }
- }
- else
- {
- me->DespawnOrUnsummon();
- return;
- }
- }
- else
- postEventTimer -= diff;
- }
- return;
- }
- DoMeleeAttackIfReady();
- }
-
- private:
- uint32 postEventCount;
- uint32 postEventTimer;
- int spawnId;
- bool _IsByOutrunner;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_rinjiAI(creature);
- }
-};
-
void AddSC_hinterlands()
{
new npc_oox09hl();
- new npc_rinji();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_ironforge.cpp b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp
index e50bbb9f3e0..5a0951c0b23 100644
--- a/src/server/scripts/EasternKingdoms/zone_ironforge.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_ironforge.cpp
@@ -20,4 +20,6 @@
#include "ScriptedGossip.h"
#include "Player.h"
-void AddSC_ironforge() { }
+void AddSC_ironforge()
+{
+}
diff --git a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp
index 65c070ffcf1..28d5546ae89 100644
--- a/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_isle_of_queldanas.cpp
@@ -44,7 +44,6 @@ enum ConvertedSentry
SPELL_CONVERT_CREDIT = 45009
};
-
class npc_converted_sentry : public CreatureScript
{
public:
diff --git a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp
index af0ec5aa4f5..95be9c9e8b2 100644
--- a/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_loch_modan.cpp
@@ -18,13 +18,12 @@
/* ScriptData
SDName: Loch_Modan
-SD%Complete: 100
-SDComment: Quest support: 3181
+SD%Complete: 0
+SDComment:
SDCategory: Loch Modan
EndScriptData */
/* ContentData
-npc_mountaineer_pebblebitty
EndContentData */
#include "ScriptMgr.h"
@@ -32,75 +31,6 @@ EndContentData */
#include "ScriptedGossip.h"
#include "Player.h"
-/*######
-## npc_mountaineer_pebblebitty
-######*/
-
-#define GOSSIP_MP "Open the gate please, i need to get to Searing Gorge"
-
-#define GOSSIP_MP1 "But i need to get there, now open the gate!"
-#define GOSSIP_MP2 "Ok, so what is this other way?"
-#define GOSSIP_MP3 "Doesn't matter, i'm invulnerable."
-#define GOSSIP_MP4 "Yes..."
-#define GOSSIP_MP5 "Ok, i'll try to remember that."
-#define GOSSIP_MP6 "A key? Ok!"
-
-class npc_mountaineer_pebblebitty : public CreatureScript
-{
-public:
- npc_mountaineer_pebblebitty() : CreatureScript("npc_mountaineer_pebblebitty") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(1833, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(1834, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(1835, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(1836, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 6);
- player->SEND_GOSSIP_MENU(1837, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 7);
- player->SEND_GOSSIP_MENU(1838, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (!player->GetQuestRewardStatus(3181) == 1)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_MP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
void AddSC_loch_modan()
{
- new npc_mountaineer_pebblebitty();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp
index 08028cc5872..f71f78fb9cb 100644
--- a/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_redridge_mountains.cpp
@@ -17,8 +17,8 @@
/* Script Data Start
SDName: Redridge Mountains
-SD%Complete: 100%
-SDComment: Support for quest 219.
+SD%Complete: 0
+SDComment:
Script Data End */
#include "ScriptMgr.h"
@@ -26,147 +26,6 @@ Script Data End */
#include "ScriptedEscortAI.h"
#include "Player.h"
-enum CorporalKeeshan
-{
- QUEST_MISSING_IN_ACTION = 219,
- SAY_CORPORAL_1 = 0,
- SAY_CORPORAL_2 = 1,
- SAY_CORPORAL_3 = 2,
- SAY_CORPORAL_4 = 3,
- SAY_CORPORAL_5 = 4,
- SPELL_MOCKING_BLOW = 21008,
- SPELL_SHIELD_BASH = 11972
-};
-
-class npc_corporal_keeshan : public CreatureScript
-{
-public:
- npc_corporal_keeshan() : CreatureScript("npc_corporal_keeshan") { }
-
- struct npc_corporal_keeshanAI : public npc_escortAI
- {
- npc_corporal_keeshanAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE
- {
- timer = 0;
- phase = 0;
- mockingBlowTimer = 5000;
- shieldBashTimer = 8000;
- }
-
- void sQuestAccept(Player* player, Quest const* quest)
- {
- if (quest->GetQuestId() == QUEST_MISSING_IN_ACTION)
- {
- Talk(SAY_CORPORAL_1, player);
- npc_escortAI::Start(true, false, player->GetGUID(), quest);
- }
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- Player* player = GetPlayerForEscort();
- if (!player)
- return;
-
- if (waypointId >= 65)
- me->SetWalk(false);
-
- switch (waypointId)
- {
- case 39:
- SetEscortPaused(true);
- timer = 2000;
- phase = 1;
- break;
- case 65:
- me->SetWalk(false);
- break;
- case 115:
- player->AreaExploredOrEventHappens(QUEST_MISSING_IN_ACTION);
- timer = 2000;
- phase = 4;
- break;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (HasEscortState(STATE_ESCORT_NONE))
- return;
-
- npc_escortAI::UpdateAI(diff);
-
- if (phase)
- {
- if (timer <= diff)
- {
- switch (phase)
- {
- case 1:
- me->SetStandState(UNIT_STAND_STATE_SIT);
- timer = 1000;
- phase = 2;
- break;
- case 2:
- Talk(SAY_CORPORAL_2);
- timer = 15000;
- phase = 3;
- break;
- case 3:
- Talk(SAY_CORPORAL_3);
- me->SetStandState(UNIT_STAND_STATE_STAND);
- SetEscortPaused(false);
- timer = 0;
- phase = 0;
- break;
- case 4:
- Talk(SAY_CORPORAL_4);
- timer = 2500;
- phase = 5;
- break;
- case 5:
- Talk(SAY_CORPORAL_5);
- timer = 0;
- phase = 0;
- break;
- }
- } else timer -= diff;
- }
-
- if (!UpdateVictim())
- return;
-
- if (mockingBlowTimer <= diff)
- {
- DoCastVictim(SPELL_MOCKING_BLOW);
- mockingBlowTimer = 5000;
- } else mockingBlowTimer -= diff;
-
- if (shieldBashTimer <= diff)
- {
- DoCastVictim(SPELL_MOCKING_BLOW);
- shieldBashTimer = 8000;
- } else shieldBashTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- private:
- uint32 phase;
- uint32 timer;
- uint32 mockingBlowTimer;
- uint32 shieldBashTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_corporal_keeshanAI(creature);
- }
-};
-
void AddSC_redridge_mountains()
{
- new npc_corporal_keeshan();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
index b7ab4227e5e..8f87dec114a 100644
--- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
@@ -19,13 +19,12 @@
/* ScriptData
SDName: Silverpine_Forest
SD%Complete: 100
-SDComment: Quest support: 435, 452
+SDComment: Quest support: 435
SDCategory: Silverpine Forest
EndScriptData */
/* ContentData
npc_deathstalker_erland
-pyrewood_ambush
EndContentData */
#include "ScriptMgr.h"
@@ -37,7 +36,7 @@ EndContentData */
## npc_deathstalker_erland
######*/
-enum Erland
+enum eErland
{
SAY_QUESTACCEPT = 0,
SAY_START = 1,
@@ -67,7 +66,7 @@ public:
{
npc_deathstalker_erlandAI(Creature* creature) : npc_escortAI(creature) { }
- void WaypointReached(uint32 waypointId) OVERRIDE
+ void WaypointReached(uint32 waypointId)
{
Player* player = GetPlayerForEscort();
if (!player)
@@ -110,13 +109,13 @@ public:
void Reset() OVERRIDE { }
- void EnterCombat(Unit* who) OVERRIDE
+ void EnterCombat(Unit* who)
{
Talk(SAY_AGGRO, who);
}
};
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
+ bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
{
if (quest->GetQuestId() == QUEST_ESCORTING)
{
@@ -136,192 +135,10 @@ public:
};
/*######
-## pyrewood_ambush
-#######*/
-
-#define QUEST_PYREWOOD_AMBUSH 452
-
-#define NPCSAY_INIT "Get ready, they'll be arriving any minute..." //not blizzlike
-#define NPCSAY_END "Thanks for your help!" //not blizzlike
-
-static float PyrewoodSpawnPoints[3][4] =
-{
- //pos_x pos_y pos_z orien
- //outside
- /*
- {-400.85f, 1513.64f, 18.67f, 0},
- {-397.32f, 1514.12f, 18.67f, 0},
- {-397.44f, 1511.09f, 18.67f, 0},
- */
- //door
- {-396.17f, 1505.86f, 19.77f, 0},
- {-396.91f, 1505.77f, 19.77f, 0},
- {-397.94f, 1504.74f, 19.77f, 0},
-};
-
-#define WAIT_SECS 6000
-
-class pyrewood_ambush : public CreatureScript
-{
-public:
- pyrewood_ambush() : CreatureScript("pyrewood_ambush") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest *quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_PYREWOOD_AMBUSH && !CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress)
- {
- CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->QuestInProgress = true;
- CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->Phase = 0;
- CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->KillCount = 0;
- CAST_AI(pyrewood_ambush::pyrewood_ambushAI, creature->AI())->PlayerGUID = player->GetGUID();
- }
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new pyrewood_ambushAI(creature);
- }
-
- struct pyrewood_ambushAI : public ScriptedAI
- {
- pyrewood_ambushAI(Creature* creature) : ScriptedAI(creature), Summons(me)
- {
- QuestInProgress = false;
- }
-
- uint32 Phase;
- int8 KillCount;
- uint32 WaitTimer;
- uint64 PlayerGUID;
- SummonList Summons;
-
- bool QuestInProgress;
-
- void Reset() OVERRIDE
- {
- WaitTimer = WAIT_SECS;
-
- if (!QuestInProgress) //fix reset values (see UpdateVictim)
- {
- Phase = 0;
- KillCount = 0;
- PlayerGUID = 0;
- Summons.DespawnAll();
- }
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- Summons.Summon(summoned);
- ++KillCount;
- }
-
- void SummonedCreatureDespawn(Creature* summoned) OVERRIDE
- {
- Summons.Despawn(summoned);
- --KillCount;
- }
-
- void SummonCreatureWithRandomTarget(uint32 creatureId, int position)
- {
- if (Creature* summoned = me->SummonCreature(creatureId, PyrewoodSpawnPoints[position][0], PyrewoodSpawnPoints[position][1], PyrewoodSpawnPoints[position][2], PyrewoodSpawnPoints[position][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000))
- {
- Unit* target = NULL;
- if (PlayerGUID)
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- if (player->IsAlive() && RAND(0, 1))
- target = player;
-
- if (!target)
- target = me;
-
- summoned->setFaction(168);
- summoned->AddThreat(target, 32.0f);
- summoned->AI()->AttackStart(target);
- }
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (PlayerGUID)
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- if (player->GetQuestStatus(QUEST_PYREWOOD_AMBUSH) == QUEST_STATUS_INCOMPLETE)
- player->FailQuest(QUEST_PYREWOOD_AMBUSH);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //TC_LOG_INFO("scripts", "DEBUG: p(%i) k(%i) d(%u) W(%i)", Phase, KillCount, diff, WaitTimer);
-
- if (!QuestInProgress)
- return;
-
- if (KillCount && Phase < 6)
- {
- if (!UpdateVictim()) //reset() on target Despawn...
- return;
-
- DoMeleeAttackIfReady();
- return;
- }
-
- switch (Phase)
- {
- case 0:
- if (WaitTimer == WAIT_SECS)
- me->MonsterSay(NPCSAY_INIT, LANG_UNIVERSAL, NULL); //no blizzlike
-
- if (WaitTimer <= diff)
- {
- WaitTimer -= diff;
- return;
- }
- break;
- case 1:
- SummonCreatureWithRandomTarget(2060, 1);
- break;
- case 2:
- SummonCreatureWithRandomTarget(2061, 2);
- SummonCreatureWithRandomTarget(2062, 0);
- break;
- case 3:
- SummonCreatureWithRandomTarget(2063, 1);
- SummonCreatureWithRandomTarget(2064, 2);
- SummonCreatureWithRandomTarget(2065, 0);
- break;
- case 4:
- SummonCreatureWithRandomTarget(2066, 1);
- SummonCreatureWithRandomTarget(2067, 0);
- SummonCreatureWithRandomTarget(2068, 2);
- break;
- case 5: //end
- if (PlayerGUID)
- {
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- {
- me->MonsterSay(NPCSAY_END, LANG_UNIVERSAL, NULL); //not blizzlike
- player->GroupEventHappens(QUEST_PYREWOOD_AMBUSH, me);
- }
- }
- QuestInProgress = false;
- Reset();
- break;
- }
- ++Phase; //prepare next phase
- }
- };
-};
-
-/*######
## AddSC
######*/
void AddSC_silverpine_forest()
{
new npc_deathstalker_erland();
- new pyrewood_ambush();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
index 0cd1403d48a..f48c3f7556f 100644
--- a/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_stormwind_city.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,629 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Stormwind_City
-SD%Complete: 100
-SDComment: Quest support: 1640, 1447, 4185, 11223, 434.
-SDCategory: Stormwind City
-EndScriptData */
-
-/* ContentData
-npc_archmage_malin
-npc_bartleby
-npc_lady_katrana_prestor
-npc_tyrion
-npc_tyrion_spybot
-npc_marzon_silent_blade
-npc_lord_gregor_lescovar
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "ScriptedEscortAI.h"
-#include "Player.h"
-
-/*######
-## npc_archmage_malin
-######*/
-
-#define GOSSIP_ITEM_MALIN "Can you send me to Theramore? I have an urgent message for Lady Jaina from Highlord Bolvar."
-
-class npc_archmage_malin : public CreatureScript
-{
-public:
- npc_archmage_malin() : CreatureScript("npc_archmage_malin") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, 42711, true);
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(11223) == QUEST_STATUS_COMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MALIN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
-/*######
-## npc_bartleby
-######*/
-
-enum Bartleby
-{
- FACTION_ENEMY = 168,
- QUEST_BEAT = 1640
-};
-
-class npc_bartleby : public CreatureScript
-{
-public:
- npc_bartleby() : CreatureScript("npc_bartleby") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_BEAT)
- {
- creature->setFaction(FACTION_ENEMY);
- creature->AI()->AttackStart(player);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_bartlebyAI(creature);
- }
-
- struct npc_bartlebyAI : public ScriptedAI
- {
- npc_bartlebyAI(Creature* creature) : ScriptedAI(creature)
- {
- m_uiNormalFaction = creature->getFaction();
- }
-
- uint32 m_uiNormalFaction;
-
- void Reset() OVERRIDE
- {
- if (me->getFaction() != m_uiNormalFaction)
- me->setFaction(m_uiNormalFaction);
- }
-
- void AttackedBy(Unit* pAttacker) OVERRIDE
- {
- if (me->GetVictim())
- return;
-
- if (me->IsFriendlyTo(pAttacker))
- return;
-
- AttackStart(pAttacker);
- }
-
- void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) OVERRIDE
- {
- if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage))
- {
- //Take 0 damage
- uiDamage = 0;
-
- if (Player* player = pDoneBy->ToPlayer())
- player->AreaExploredOrEventHappens(QUEST_BEAT);
- EnterEvadeMode();
- }
- }
- };
-};
-
-/*######
-## npc_lady_katrana_prestor
-######*/
-
-#define GOSSIP_ITEM_KAT_1 "Pardon the intrusion, Lady Prestor, but Highlord Bolvar suggested that I seek your advice."
-#define GOSSIP_ITEM_KAT_2 "My apologies, Lady Prestor."
-#define GOSSIP_ITEM_KAT_3 "Begging your pardon, Lady Prestor. That was not my intent."
-#define GOSSIP_ITEM_KAT_4 "Thank you for your time, Lady Prestor."
-
-class npc_lady_katrana_prestor : public CreatureScript
-{
-public:
- npc_lady_katrana_prestor() : CreatureScript("npc_lady_katrana_prestor") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(2694, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(2695, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(2696, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(4185);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(4185) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_KAT_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(2693, creature->GetGUID());
-
- return true;
- }
-};
-
-/*######
-## npc_lord_gregor_lescovar
-######*/
-
-enum LordGregorLescovar
-{
- SAY_GUARD_2 = 0,
- SAY_LESCOVAR_2 = 0,
- SAY_LESCOVAR_3 = 1,
- SAY_LESCOVAR_4 = 2,
- SAY_MARZON_1 = 0,
- SAY_MARZON_2 = 1,
- SAY_TYRION_2 = 1,
-
- NPC_STORMWIND_ROYAL = 1756,
- NPC_MARZON_BLADE = 1755,
- NPC_TYRION = 7766,
-
- QUEST_THE_ATTACK = 434
-};
-
-class npc_lord_gregor_lescovar : public CreatureScript
-{
-public:
- npc_lord_gregor_lescovar() : CreatureScript("npc_lord_gregor_lescovar") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_lord_gregor_lescovarAI(creature);
- }
-
- struct npc_lord_gregor_lescovarAI : public npc_escortAI
- {
- npc_lord_gregor_lescovarAI(Creature* creature) : npc_escortAI(creature) { }
-
- uint32 uiTimer;
- uint32 uiPhase;
-
- uint64 MarzonGUID;
-
- void Reset() OVERRIDE
- {
- uiTimer = 0;
- uiPhase = 0;
-
- MarzonGUID = 0;
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- me->DisappearAndDie();
-
- if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID))
- {
- if (pMarzon->IsAlive())
- pMarzon->DisappearAndDie();
- }
- }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID))
- {
- if (pMarzon->IsAlive() && !pMarzon->IsInCombat())
- pMarzon->AI()->AttackStart(who);
- }
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 14:
- SetEscortPaused(true);
- Talk(SAY_LESCOVAR_2);
- uiTimer = 3000;
- uiPhase = 1;
- break;
- case 16:
- SetEscortPaused(true);
- if (Creature* pMarzon = me->SummonCreature(NPC_MARZON_BLADE, -8411.360352f, 480.069733f, 123.760895f, 4.941504f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 1000))
- {
- pMarzon->GetMotionMaster()->MovePoint(0, -8408.000977f, 468.611450f, 123.759903f);
- MarzonGUID = pMarzon->GetGUID();
- }
- uiTimer = 2000;
- uiPhase = 4;
- break;
- }
- }
- //TO-DO: We don't have movemaps, also we can't make 2 npcs walks to one point propperly (and we can not use escort ai, because they are 2 different spawns and with same entry), because of it we make them, disappear.
- void DoGuardsDisappearAndDie()
- {
- std::list<Creature*> GuardList;
- me->GetCreatureListWithEntryInGrid(GuardList, NPC_STORMWIND_ROYAL, 8.0f);
- if (!GuardList.empty())
- {
- for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
- {
- if (Creature* pGuard = *itr)
- pGuard->DisappearAndDie();
- }
- }
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (uiPhase)
- {
- if (uiTimer <= uiDiff)
- {
- switch (uiPhase)
- {
- case 1:
- if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 8.0f, true))
- pGuard->AI()->Talk(SAY_GUARD_2);
- uiTimer = 3000;
- uiPhase = 2;
- break;
- case 2:
- DoGuardsDisappearAndDie();
- uiTimer = 2000;
- uiPhase = 3;
- break;
- case 3:
- SetEscortPaused(false);
- uiTimer = 0;
- uiPhase = 0;
- break;
- case 4:
- Talk(SAY_LESCOVAR_3);
- uiTimer = 0;
- uiPhase = 0;
- break;
- case 5:
- if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID))
- pMarzon->AI()->Talk(SAY_MARZON_1);
- uiTimer = 3000;
- uiPhase = 6;
- break;
- case 6:
- Talk(SAY_LESCOVAR_4);
- if (Player* player = GetPlayerForEscort())
- player->AreaExploredOrEventHappens(QUEST_THE_ATTACK);
- uiTimer = 2000;
- uiPhase = 7;
- break;
- case 7:
- if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 20.0f, true))
- pTyrion->AI()->Talk(SAY_TYRION_2);
- if (Creature* pMarzon = Unit::GetCreature(*me, MarzonGUID))
- pMarzon->setFaction(14);
- me->setFaction(14);
- uiTimer = 0;
- uiPhase = 0;
- break;
- }
- } else uiTimer -= uiDiff;
- }
- npc_escortAI::UpdateAI(uiDiff);
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
-/*######
-## npc_marzon_silent_blade
-######*/
-
-class npc_marzon_silent_blade : public CreatureScript
-{
-public:
- npc_marzon_silent_blade() : CreatureScript("npc_marzon_silent_blade") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_marzon_silent_bladeAI(creature);
- }
-
- struct npc_marzon_silent_bladeAI : public ScriptedAI
- {
- npc_marzon_silent_bladeAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetWalk(true);
- }
-
- void Reset() OVERRIDE
- {
- me->RestoreFaction();
- }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- Talk(SAY_MARZON_2);
-
- if (me->IsSummon())
- {
- if (Unit* summoner = me->ToTempSummon()->GetSummoner())
- {
- if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive() && !summoner->IsInCombat())
- summoner->ToCreature()->AI()->AttackStart(who);
- }
- }
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- me->DisappearAndDie();
-
- if (me->IsSummon())
- {
- if (Unit* summoner = me->ToTempSummon()->GetSummoner())
- {
- if (summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAlive())
- summoner->ToCreature()->DisappearAndDie();
- }
- }
- }
-
- void MovementInform(uint32 uiType, uint32 /*uiId*/) OVERRIDE
- {
- if (uiType != POINT_MOTION_TYPE)
- return;
-
- if (me->IsSummon())
- {
- Unit* summoner = me->ToTempSummon()->GetSummoner();
- if (summoner && summoner->GetTypeId() == TYPEID_UNIT && summoner->IsAIEnabled)
- {
- npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI* ai =
- CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, summoner->GetAI());
- if (ai)
- {
- ai->uiTimer = 2000;
- ai->uiPhase = 5;
- }
- //me->ChangeOrient(0.0f, summoner);
- }
- }
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
-/*######
-## npc_tyrion_spybot
-######*/
-
-enum TyrionSpybot
-{
- SAY_QUEST_ACCEPT_ATTACK = 0,
- SAY_SPYBOT_1 = 1,
- SAY_SPYBOT_2 = 2,
- SAY_SPYBOT_3 = 3,
- SAY_SPYBOT_4 = 4,
- SAY_TYRION_1 = 0,
- SAY_GUARD_1 = 1,
- SAY_LESCOVAR_1 = 3,
-
- NPC_PRIESTESS_TYRIONA = 7779,
- NPC_LORD_GREGOR_LESCOVAR = 1754,
-};
-
-class npc_tyrion_spybot : public CreatureScript
-{
-public:
- npc_tyrion_spybot() : CreatureScript("npc_tyrion_spybot") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_tyrion_spybotAI(creature);
- }
-
- struct npc_tyrion_spybotAI : public npc_escortAI
- {
- npc_tyrion_spybotAI(Creature* creature) : npc_escortAI(creature) { }
-
- uint32 uiTimer;
- uint32 uiPhase;
-
- void Reset() OVERRIDE
- {
- uiTimer = 0;
- uiPhase = 0;
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 1:
- SetEscortPaused(true);
- uiTimer = 2000;
- uiPhase = 1;
- break;
- case 5:
- SetEscortPaused(true);
- Talk(SAY_SPYBOT_1);
- uiTimer = 2000;
- uiPhase = 5;
- break;
- case 17:
- SetEscortPaused(true);
- Talk(SAY_SPYBOT_3);
- uiTimer = 3000;
- uiPhase = 8;
- break;
- }
- }
-
- void UpdateAI(uint32 uiDiff) OVERRIDE
- {
- if (uiPhase)
- {
- if (uiTimer <= uiDiff)
- {
- switch (uiPhase)
- {
- case 1:
- Talk(SAY_QUEST_ACCEPT_ATTACK);
- uiTimer = 3000;
- uiPhase = 2;
- break;
- case 2:
- if (Creature* pTyrion = me->FindNearestCreature(NPC_TYRION, 10.0f))
- pTyrion->AI()->Talk(SAY_TYRION_1);
- uiTimer = 3000;
- uiPhase = 3;
- break;
- case 3:
- me->UpdateEntry(NPC_PRIESTESS_TYRIONA, ALLIANCE);
- uiTimer = 2000;
- uiPhase = 4;
- break;
- case 4:
- SetEscortPaused(false);
- uiPhase = 0;
- uiTimer = 0;
- break;
- case 5:
- if (Creature* pGuard = me->FindNearestCreature(NPC_STORMWIND_ROYAL, 10.0f, true))
- pGuard->AI()->Talk(SAY_GUARD_1);
- uiTimer = 3000;
- uiPhase = 6;
- break;
- case 6:
- Talk(SAY_SPYBOT_2);
- uiTimer = 3000;
- uiPhase = 7;
- break;
- case 7:
- SetEscortPaused(false);
- uiTimer = 0;
- uiPhase = 0;
- break;
- case 8:
- if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f))
- pLescovar->AI()->Talk(SAY_LESCOVAR_1);
- uiTimer = 3000;
- uiPhase = 9;
- break;
- case 9:
- Talk(SAY_SPYBOT_4);
- uiTimer = 3000;
- uiPhase = 10;
- break;
- case 10:
- if (Creature* pLescovar = me->FindNearestCreature(NPC_LORD_GREGOR_LESCOVAR, 10.0f))
- {
- if (Player* player = GetPlayerForEscort())
- {
- CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->Start(false, false, player->GetGUID());
- CAST_AI(npc_lord_gregor_lescovar::npc_lord_gregor_lescovarAI, pLescovar->AI())->SetMaxPlayerDistance(200.0f);
- }
- }
- me->DisappearAndDie();
- uiTimer = 0;
- uiPhase = 0;
- break;
- }
- } else uiTimer -= uiDiff;
- }
- npc_escortAI::UpdateAI(uiDiff);
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
-/*######
-## npc_tyrion
-######*/
-
-enum Tyrion
-{
- NPC_TYRION_SPYBOT = 8856
-};
-
-class npc_tyrion : public CreatureScript
-{
-public:
- npc_tyrion() : CreatureScript("npc_tyrion") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_THE_ATTACK)
- {
- if (Creature* pSpybot = creature->FindNearestCreature(NPC_TYRION_SPYBOT, 5.0f, true))
- {
- CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->Start(false, false, player->GetGUID());
- CAST_AI(npc_tyrion_spybot::npc_tyrion_spybotAI, pSpybot->AI())->SetMaxPlayerDistance(200.0f);
- }
- return true;
- }
- return false;
- }
-};
-
void AddSC_stormwind_city()
{
- new npc_archmage_malin();
- new npc_bartleby();
- new npc_lady_katrana_prestor();
- new npc_tyrion();
- new npc_tyrion_spybot();
- new npc_lord_gregor_lescovar();
- new npc_marzon_silent_blade();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp
index 9232a7962e3..69b9ca85a23 100644
--- a/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_swamp_of_sorrows.cpp
@@ -16,136 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedEscortAI.h"
-#include "Player.h"
-
-/*######
-## npc_galen_goodward
-######*/
-
-enum Galen
-{
- QUEST_GALENS_ESCAPE = 1393,
- GO_GALENS_CAGE = 37118,
- SAY_PERIODIC = 0,
- SAY_QUEST_ACCEPTED = 1,
- SAY_ATTACKED = 2,
- SAY_QUEST_COMPLETE = 3,
- EMOTE_WHISPER = 4,
- EMOTE_DISAPPEAR = 5
-};
-
-class npc_galen_goodward : public CreatureScript
-{
-public:
- npc_galen_goodward() : CreatureScript("npc_galen_goodward") { }
-
- struct npc_galen_goodwardAI : public npc_escortAI
- {
- npc_galen_goodwardAI(Creature* creature) : npc_escortAI(creature)
- {
- galensCageGUID = 0;
- Reset();
- }
-
- void Reset() OVERRIDE
- {
- periodicSay = 6000;
- }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- if (HasEscortState(STATE_ESCORT_ESCORTING))
- Talk(SAY_ATTACKED, who);
- }
-
- void sQuestAccept(Player* player, Quest const* quest)
- {
- if (quest->GetQuestId() == QUEST_GALENS_ESCAPE)
- {
- Talk(SAY_QUEST_ACCEPTED, player);
- npc_escortAI::Start(false, false, player->GetGUID(), quest);
- }
- }
-
- void WaypointStart(uint32 uiPointId) OVERRIDE
- {
- switch (uiPointId)
- {
- case 0:
- {
- GameObject* cage = NULL;
- if (galensCageGUID)
- cage = me->GetMap()->GetGameObject(galensCageGUID);
- else
- cage = GetClosestGameObjectWithEntry(me, GO_GALENS_CAGE, INTERACTION_DISTANCE);
- if (cage)
- {
- cage->UseDoorOrButton();
- galensCageGUID = cage->GetGUID();
- }
- break;
- }
- case 21:
- Talk(EMOTE_DISAPPEAR);
- break;
- }
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 0:
- if (GameObject* cage = me->GetMap()->GetGameObject(galensCageGUID))
- cage->ResetDoorOrButton();
- break;
- case 20:
- if (Player* player = GetPlayerForEscort())
- {
- me->SetFacingToObject(player);
- Talk(SAY_QUEST_COMPLETE, player);
- Talk(EMOTE_WHISPER, player);
- player->GroupEventHappens(QUEST_GALENS_ESCAPE, me);
- }
- SetRun(true);
- break;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- npc_escortAI::UpdateAI(diff);
-
- if (HasEscortState(STATE_ESCORT_NONE))
- return;
-
- if (periodicSay < diff)
- {
- if (!HasEscortState(STATE_ESCORT_ESCORTING))
- Talk(SAY_PERIODIC);
- periodicSay = 15000;
- }
- else
- periodicSay -= diff;
-
- DoMeleeAttackIfReady();
- }
-
- private:
- uint64 galensCageGUID;
- uint32 periodicSay;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_galen_goodwardAI(creature);
- }
-};
-
void AddSC_swamp_of_sorrows()
{
- new npc_galen_goodward();
}
diff --git a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
index 925d0d73a70..b03965ea9e3 100644
--- a/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_tirisfal_glades.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,202 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Tirisfal_Glades
-SD%Complete: 100
-SDComment: Quest support: 590, 1819
-SDCategory: Tirisfal Glades
-EndScriptData */
-
-/* ContentData
-npc_calvin_montague
-go_mausoleum_door
-go_mausoleum_trigger
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "Player.h"
-
-/*######
-## npc_calvin_montague
-######*/
-
-enum Calvin
-{
- SAY_COMPLETE = 0,
- SPELL_DRINK = 2639, // possibly not correct spell (but iconId is correct)
- QUEST_590 = 590,
- FACTION_HOSTILE = 168
-};
-
-class npc_calvin_montague : public CreatureScript
-{
-public:
- npc_calvin_montague() : CreatureScript("npc_calvin_montague") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_590)
- {
- creature->setFaction(FACTION_HOSTILE);
- creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- CAST_AI(npc_calvin_montague::npc_calvin_montagueAI, creature->AI())->AttackStart(player);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_calvin_montagueAI(creature);
- }
-
- struct npc_calvin_montagueAI : public ScriptedAI
- {
- npc_calvin_montagueAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 m_uiPhase;
- uint32 m_uiPhaseTimer;
- uint64 m_uiPlayerGUID;
-
- void Reset() OVERRIDE
- {
- m_uiPhase = 0;
- m_uiPhaseTimer = 5000;
- m_uiPlayerGUID = 0;
-
- me->RestoreFaction();
-
- if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void AttackedBy(Unit* pAttacker) OVERRIDE
- {
- if (me->GetVictim() || me->IsFriendlyTo(pAttacker))
- return;
-
- AttackStart(pAttacker);
- }
-
- void DamageTaken(Unit* pDoneBy, uint32 &uiDamage) OVERRIDE
- {
- if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage))
- {
- uiDamage = 0;
-
- me->RestoreFaction();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- me->CombatStop(true);
-
- m_uiPhase = 1;
-
- if (pDoneBy->GetTypeId() == TYPEID_PLAYER)
- m_uiPlayerGUID = pDoneBy->GetGUID();
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (m_uiPhase)
- {
- if (m_uiPhaseTimer <= diff)
- m_uiPhaseTimer = 7500;
- else
- {
- m_uiPhaseTimer -= diff;
- return;
- }
-
- switch (m_uiPhase)
- {
- case 1:
- Talk(SAY_COMPLETE);
- ++m_uiPhase;
- break;
- case 2:
- if (Player* player = ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID))
- player->AreaExploredOrEventHappens(QUEST_590);
-
- DoCast(me, SPELL_DRINK, true);
- ++m_uiPhase;
- break;
- case 3:
- EnterEvadeMode();
- break;
- }
-
- return;
- }
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
-/*######
-## go_mausoleum_door
-## go_mausoleum_trigger
-######*/
-
-enum Mausoleum
-{
- QUEST_ULAG = 1819,
- NPC_ULAG = 6390,
- GO_TRIGGER = 104593,
- GO_DOOR = 176594
-};
-
-class go_mausoleum_door : public GameObjectScript
-{
-public:
- go_mausoleum_door() : GameObjectScript("go_mausoleum_door") { }
-
- bool OnGossipHello(Player* player, GameObject* /*go*/) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE)
- return false;
-
- if (GameObject* pTrigger = player->FindNearestGameObject(GO_TRIGGER, 30.0f))
- {
- pTrigger->SetGoState(GO_STATE_READY);
- player->SummonCreature(NPC_ULAG, 2390.26f, 336.47f, 40.01f, 2.26f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 300000);
- return false;
- }
-
- return false;
- }
-};
-
-class go_mausoleum_trigger : public GameObjectScript
-{
-public:
- go_mausoleum_trigger() : GameObjectScript("go_mausoleum_trigger") { }
-
- bool OnGossipHello(Player* player, GameObject* go) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_ULAG) != QUEST_STATUS_INCOMPLETE)
- return false;
-
- if (GameObject* pDoor = player->FindNearestGameObject(GO_DOOR, 30.0f))
- {
- go->SetGoState(GO_STATE_ACTIVE);
- pDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
- return true;
- }
-
- return false;
- }
-};
-
void AddSC_tirisfal_glades()
{
- new npc_calvin_montague();
- new go_mausoleum_door();
- new go_mausoleum_trigger();
}
diff --git a/src/server/scripts/Events/childrens_week.cpp b/src/server/scripts/Events/childrens_week.cpp
index 92e70cd028b..b1b51a10dc4 100644
--- a/src/server/scripts/Events/childrens_week.cpp
+++ b/src/server/scripts/Events/childrens_week.cpp
@@ -152,7 +152,7 @@ class npc_winterfin_playmate : public CreatureScript
{
npc_winterfin_playmateAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -174,7 +174,7 @@ class npc_winterfin_playmate : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -233,7 +233,7 @@ class npc_winterfin_playmate : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_winterfin_playmateAI(creature);
}
@@ -251,7 +251,7 @@ class npc_snowfall_glade_playmate : public CreatureScript
{
npc_snowfall_glade_playmateAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -273,7 +273,7 @@ class npc_snowfall_glade_playmate : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -352,7 +352,7 @@ class npc_the_biggest_tree : public CreatureScript
me->SetDisplayId(DISPLAY_INVISIBLE);
}
- void Reset()
+ void Reset() OVERRIDE
{
timer = 1000;
phase = 0;
@@ -374,7 +374,7 @@ class npc_the_biggest_tree : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -421,7 +421,7 @@ class npc_the_biggest_tree : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_the_biggest_treeAI(creature);
}
@@ -439,7 +439,7 @@ class npc_high_oracle_soo_roo : public CreatureScript
{
npc_high_oracle_soo_rooAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -461,7 +461,7 @@ class npc_high_oracle_soo_roo : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -510,7 +510,7 @@ class npc_high_oracle_soo_roo : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_high_oracle_soo_rooAI(creature);
}
@@ -528,7 +528,7 @@ class npc_elder_kekek : public CreatureScript
{
npc_elder_kekekAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -550,7 +550,7 @@ class npc_elder_kekek : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -598,7 +598,7 @@ class npc_elder_kekek : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_elder_kekekAI(creature);
}
@@ -617,7 +617,7 @@ class npc_the_etymidian : public CreatureScript
{
npc_the_etymidianAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -639,7 +639,7 @@ class npc_the_etymidian : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -695,7 +695,7 @@ class npc_the_etymidian : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_the_etymidianAI(creature);
}
@@ -713,7 +713,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript
{
npc_alexstraza_the_lifebinderAI(Creature* creature) : ScriptedAI(creature) { }
- void Reset()
+ void Reset() OVERRIDE
{
timer = 0;
phase = 0;
@@ -761,7 +761,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript
}
}
- void UpdateAI(uint32 diff)
+ void UpdateAI(uint32 diff) OVERRIDE
{
if (!phase)
return;
@@ -856,7 +856,7 @@ class npc_alexstraza_the_lifebinder : public CreatureScript
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_alexstraza_the_lifebinderAI(creature);
}
@@ -1009,7 +1009,7 @@ class npc_cw_area_trigger : public CreatureScript
}
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_cw_area_triggerAI(creature);
}
@@ -1044,7 +1044,7 @@ class npc_grizzlemaw_cw_trigger : public CreatureScript
}
};
- CreatureAI* GetAI(Creature* creature) const
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
return new npc_grizzlemaw_cw_triggerAI(creature);
}
diff --git a/src/server/scripts/Kalimdor/CMakeLists.txt b/src/server/scripts/Kalimdor/CMakeLists.txt
index 1adc8a53271..26a57727d73 100644
--- a/src/server/scripts/Kalimdor/CMakeLists.txt
+++ b/src/server/scripts/Kalimdor/CMakeLists.txt
@@ -118,6 +118,14 @@ set(scripts_STAT_SRCS
Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
Kalimdor/RagefireChasm/instance_ragefire_chasm.cpp
Kalimdor/DireMaul/instance_dire_maul.cpp
+ Kalimdor/HallsOfOrigination/halls_of_origination.h
+ Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
+ Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
+ Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp
+ Kalimdor/HallsOfOrigination/boss_anraphet.cpp
+ Kalimdor/Firelands/instance_firelands.cpp
+ Kalimdor/Firelands/firelands.h
+ Kalimdor/Firelands/boss_alysrazor.cpp
)
message(" -> Prepared: Kalimdor")
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
index af7b0c1d899..6a9f34d4fc2 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
@@ -223,7 +223,7 @@ class spell_mark_of_kazrogal : public SpellScriptLoader
}
};
- SpellScript* GetSpellScript() const
+ SpellScript* GetSpellScript() const OVERRIDE
{
return new spell_mark_of_kazrogal_SpellScript();
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
index 0c3f33dea55..52a5f0bc0ed 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
@@ -31,6 +31,7 @@ EndScriptData */
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Chat.h"
+#include "WorldSession.h"
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
@@ -191,7 +192,8 @@ public:
i->GetSource()->GetSession()->SendPacket(&packet);
WorldPacket data2(SMSG_PLAY_SOUND, 4);
- data2 << 10986;
+ data2 << uint32(10986);
+ data2 << uint64(unit->GetGUID());
i->GetSource()->GetSession()->SendPacket(&data2);
}
}
diff --git a/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp
new file mode 100644
index 00000000000..02f4d34c1de
--- /dev/null
+++ b/src/server/scripts/Kalimdor/Firelands/boss_alysrazor.cpp
@@ -0,0 +1,704 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "PassiveAI.h"
+#include "SpellScript.h"
+#include "MoveSplineInit.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "firelands.h"
+
+enum Texts
+{
+ // Egg Pile
+ EMOTE_CRACKING_EGGS = 0, // The Molten Eggs begin to crack and splinter!
+};
+
+enum Spells
+{
+ // Harbinger of Flame
+ SPELL_FIRE_IT_UP = 100093,
+ SPELL_FIEROBLAST_TRASH = 100094,
+ SPELL_FIEROCLAST_BARRAGE = 100095,
+ SPELL_FIRE_CHANNELING = 100109,
+
+ // Blazing Monstrosity
+ SPELL_RIDE_MONSTROSITY = 93970,
+ SPELL_SHARE_HEALTH_LEFT = 101502,
+ SPELL_SHARE_HEALTH_RIGHT = 101503,
+ SPELL_SLEEP_ULTRA_HIGH_PRIORITY = 99480,
+ SPELL_GENERIC_DUMMY_CAST = 100088,
+ SPELL_LEFT_SIDE_SMACK_L = 100076,
+ SPELL_RIGHT_SIDE_SMACK_L = 100078,
+ SPELL_HEAD_BONK_L = 100080,
+ SPELL_TICKLE_L = 100082,
+ SPELL_KNOCKBACK_RIGHT = 100084,
+ SPELL_KNOCKBACK_LEFT = 100085,
+ SPELL_KNOCKBACK_FORWARD = 100086,
+ SPELL_KNOCKBACK_BACK = 100087,
+ SPELL_HEAD_BONK_R = 100089,
+ SPELL_LEFT_SIDE_SMACK_R = 100090,
+ SPELL_RIGHT_SIDE_SMACK_R = 100091,
+ SPELL_TICKLE_R = 100092,
+ SPELL_MOLTEN_BARRAGE_EFFECT_L = 100071,
+ SPELL_MOLTEN_BARRAGE_LEFT = 100072,
+ SPELL_MOLTEN_BARRAGE_RIGHT = 100073,
+ SPELL_MOLTEN_BARRAGE_EFFECT_R = 100074,
+ SPELL_MOLTEN_BARRAGE_VISUAL = 100075,
+ SPELL_AGGRO_CLOSEST = 100462,
+ SPELL_INVISIBILITY_AND_STEALTH_DETECTION = 18950,
+
+ // Egg Pile
+ SPELL_SUMMON_SMOULDERING_HATCHLING = 100096,
+ SPELL_MOLTEN_EGG_TRASH_CALL_L = 100097,
+ SPELL_MOLTEN_EGG_TRASH_CALL_R = 100098,
+ SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION = 100099,
+};
+
+#define SPELL_SHARE_HEALTH (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_SHARE_HEALTH_LEFT : SPELL_SHARE_HEALTH_RIGHT)
+#define SPELL_MOLTEN_BARRAGE (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_LEFT : SPELL_MOLTEN_BARRAGE_RIGHT)
+#define SPELL_MOLTEN_BARRAGE_EFFECT (me->GetEntry() == NPC_BLAZING_MONSTROSITY_LEFT ? SPELL_MOLTEN_BARRAGE_EFFECT_L : SPELL_MOLTEN_BARRAGE_EFFECT_R)
+
+enum Events
+{
+ // Blazing Monstrosity
+ EVENT_START_SPITTING = 1,
+ EVENT_CONTINUE_SPITTING = 2,
+
+ // Harbinger of Flame
+ EVENT_FIEROBLAST = 1,
+ EVENT_FIEROCLAST_BARRAGE = 2,
+
+ // Egg Pile
+ EVENT_SUMMON_SMOULDERING_HATCHLING = 1,
+};
+
+enum MiscData
+{
+ MODEL_INVISIBLE_STALKER = 11686,
+ ANIM_KIT_BIRD_WAKE = 1469,
+ ANIM_KIT_BIRD_TURN = 1473,
+};
+
+class RespawnEggEvent : public BasicEvent
+{
+ public:
+ explicit RespawnEggEvent(Creature* egg) : _egg(egg) { }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _egg->RestoreDisplayId();
+ return true;
+ }
+
+ private:
+ Creature* _egg;
+};
+
+class MoltenEggCheck
+{
+ public:
+ explicit MoltenEggCheck(Creature* pile) : _eggPile(pile) { }
+
+ bool operator()(Unit* object) const
+ {
+ if (object->GetEntry() != NPC_MOLTEN_EGG_TRASH)
+ return false;
+
+ if (object->GetDisplayId() != object->GetNativeDisplayId())
+ return false;
+
+ if (_eggPile->GetDistance2d(object) > 20.0f)
+ return false;
+
+ return true;
+ }
+
+ private:
+ Creature* _eggPile;
+};
+
+class TrashRespawnWorker
+{
+ public:
+ void operator()(Creature* creature) const
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_BLAZING_MONSTROSITY_LEFT:
+ case NPC_BLAZING_MONSTROSITY_RIGHT:
+ case NPC_EGG_PILE:
+ case NPC_HARBINGER_OF_FLAME:
+ case NPC_MOLTEN_EGG_TRASH:
+ if (!creature->IsAlive())
+ creature->Respawn(true);
+ break;
+ case NPC_SMOULDERING_HATCHLING:
+ creature->DespawnOrUnsummon();
+ break;
+ }
+ }
+};
+
+static void AlysrazorTrashEvaded(Creature* creature)
+{
+ TrashRespawnWorker check;
+ Trinity::CreatureWorker<TrashRespawnWorker> worker(creature, check);
+ creature->VisitNearbyGridObject(SIZE_OF_GRIDS, worker);
+}
+
+class npc_harbinger_of_flame : public CreatureScript
+{
+ public:
+ npc_harbinger_of_flame() : CreatureScript("npc_harbinger_of_flame") { }
+
+ struct npc_harbinger_of_flameAI : public ScriptedAI
+ {
+ npc_harbinger_of_flameAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ if (Creature* bird = ObjectAccessor::GetCreature(*me, me->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)))
+ DoZoneInCombat(bird, 200.0f);
+
+ me->InterruptSpell(CURRENT_CHANNELED_SPELL);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_FIEROBLAST, 1);
+ _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, 6000);
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ AlysrazorTrashEvaded(me);
+ }
+
+ void MoveInLineOfSight(Unit* unit) OVERRIDE
+ {
+ if (me->IsInCombat())
+ return;
+
+ if (!unit->IsCharmedOwnedByPlayerOrPlayer())
+ return;
+
+ ScriptedAI::MoveInLineOfSight(unit);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!me->IsInCombat())
+ if (!me->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
+ if (Creature* fireBird = me->FindNearestCreature((me->GetHomePosition().GetPositionY() > -275.0f ? NPC_BLAZING_MONSTROSITY_LEFT : NPC_BLAZING_MONSTROSITY_RIGHT), 100.0f))
+ DoCast(fireBird, SPELL_FIRE_CHANNELING);
+
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_FIEROBLAST:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY))
+ DoCast(target, SPELL_FIEROBLAST_TRASH);
+ _events.RescheduleEvent(EVENT_FIEROBLAST, 500); // cast time is longer, but thanks to UNIT_STATE_CASTING check it won't trigger more often (need this because this creature gets a stacking haste aura)
+ break;
+ case EVENT_FIEROCLAST_BARRAGE:
+ DoCastAOE(SPELL_FIEROCLAST_BARRAGE);
+ _events.ScheduleEvent(EVENT_FIEROCLAST_BARRAGE, urand(9000, 12000));
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_harbinger_of_flameAI(creature);
+ }
+};
+
+class npc_blazing_monstrosity : public CreatureScript
+{
+ public:
+ npc_blazing_monstrosity() : CreatureScript("npc_blazing_monstrosity") { }
+
+ struct npc_blazing_monstrosityAI : public PassiveAI
+ {
+ npc_blazing_monstrosityAI(Creature* creature) : PassiveAI(creature), _summons(creature)
+ {
+ }
+
+ void EnterEvadeMode() OVERRIDE
+ {
+ _summons.DespawnAll();
+ _events.Reset();
+ PassiveAI::EnterEvadeMode();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _summons.DespawnAll();
+ _events.Reset();
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ AlysrazorTrashEvaded(me);
+ }
+
+ void EnterCombat(Unit* /*target*/)
+ {
+ DoZoneInCombat();
+ me->RemoveAurasDueToSpell(SPELL_SLEEP_ULTRA_HIGH_PRIORITY);
+ me->PlayOneShotAnimKit(ANIM_KIT_BIRD_WAKE);
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_START_SPITTING, 6000);
+ _events.ScheduleEvent(EVENT_CONTINUE_SPITTING, 9000);
+ }
+
+ void PassengerBoarded(Unit* passenger, int8 /*seat*/, bool apply) OVERRIDE
+ {
+ if (!apply)
+ return;
+
+ // Our passenger is another vehicle (boardable by players)
+ DoCast(passenger, SPELL_SHARE_HEALTH, true);
+ passenger->setFaction(35);
+ passenger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ // Hack to relocate vehicle on vehicle so exiting players are not moved under map
+ Movement::MoveSplineInit init(passenger);
+ init.DisableTransportPathTransformations();
+ init.MoveTo(0.6654003f, 0.0f, 1.9815f);
+ init.SetFacing(0.0f);
+ init.Launch();
+ }
+
+ void JustSummoned(Creature* summon) OVERRIDE
+ {
+ _summons.Summon(summon);
+ }
+
+ void SummonedCreatureDespawn(Creature* summon) OVERRIDE
+ {
+ _summons.Despawn(summon);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_SPITTING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, false, -SPELL_RIDE_MONSTROSITY))
+ DoCast(target, SPELL_MOLTEN_BARRAGE);
+ break;
+ case EVENT_CONTINUE_SPITTING:
+ DoCastAOE(SPELL_MOLTEN_BARRAGE_EFFECT);
+ if (Creature* egg = me->FindNearestCreature(NPC_EGG_PILE, 100.0f))
+ egg->AI()->DoAction(me->GetEntry());
+ break;
+ }
+ }
+ }
+
+ private:
+ SummonList _summons;
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_blazing_monstrosityAI(creature);
+ }
+};
+
+class npc_molten_barrage : public CreatureScript
+{
+ public:
+ npc_molten_barrage() : CreatureScript("npc_molten_barrage") { }
+
+ struct npc_molten_barrageAI : public NullCreatureAI
+ {
+ npc_molten_barrageAI(Creature* creature) : NullCreatureAI(creature)
+ {
+ }
+
+ void AttackStart(Unit* target) OVERRIDE
+ {
+ if (target)
+ me->GetMotionMaster()->MoveFollow(target, 0.0f, 0.0f, MOTION_SLOT_IDLE);
+ }
+
+ void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
+ {
+ DoCastAOE(SPELL_AGGRO_CLOSEST, true);
+ DoCast(me, SPELL_MOLTEN_BARRAGE_VISUAL);
+ DoCast(me, SPELL_INVISIBILITY_AND_STEALTH_DETECTION, true);
+ }
+
+ void MovementInform(uint32 movementType, uint32 /*pointId*/) OVERRIDE
+ {
+ if (movementType != EFFECT_MOTION_TYPE)
+ return;
+
+ DoCastAOE(SPELL_AGGRO_CLOSEST);
+ me->ClearUnitState(UNIT_STATE_CANNOT_TURN);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_molten_barrageAI(creature);
+ }
+};
+
+class npc_egg_pile : public CreatureScript
+{
+ public:
+ npc_egg_pile() : CreatureScript("npc_egg_pile") { }
+
+ struct npc_egg_pileAI : public CreatureAI
+ {
+ npc_egg_pileAI(Creature* creature) : CreatureAI(creature)
+ {
+ }
+
+ void AttackStart(Unit* /*target*/) OVERRIDE { }
+
+ void Reset() OVERRIDE
+ {
+ me->SetReactState(REACT_PASSIVE);
+ _events.Reset();
+ _callHatchlingSpell = 0;
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _events.Reset();
+ std::list<Creature*> eggs;
+ GetCreatureListWithEntryInGrid(eggs, me, NPC_MOLTEN_EGG_TRASH, 20.0f);
+ for (std::list<Creature*>::const_iterator itr = eggs.begin(); itr != eggs.end(); ++itr)
+ (*itr)->CastSpell(*itr, SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION, TRIGGERED_FULL_MASK);
+
+ DoCast(me, SPELL_ALYSRAZOR_COSMETIC_EGG_XPLOSION, true);
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ AlysrazorTrashEvaded(me);
+ }
+
+ void DoAction(int32 action) OVERRIDE
+ {
+ if (action != NPC_BLAZING_MONSTROSITY_LEFT &&
+ action != NPC_BLAZING_MONSTROSITY_RIGHT)
+ return;
+
+ if (action == NPC_BLAZING_MONSTROSITY_LEFT)
+ Talk(EMOTE_CRACKING_EGGS);
+
+ _callHatchlingSpell = (action == NPC_BLAZING_MONSTROSITY_LEFT) ? SPELL_MOLTEN_EGG_TRASH_CALL_L : SPELL_MOLTEN_EGG_TRASH_CALL_R;
+ DoZoneInCombat();
+ _events.Reset();
+ _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, 1);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
+
+ _events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SUMMON_SMOULDERING_HATCHLING:
+ {
+ std::list<Creature*> eggs;
+ MoltenEggCheck check(me);
+ Trinity::CreatureListSearcher<MoltenEggCheck> searcher(me, eggs, check);
+ me->VisitNearbyGridObject(20.0f, searcher);
+ if (!eggs.empty())
+ {
+ Creature* egg = Trinity::Containers::SelectRandomContainerElement(eggs);
+ egg->CastSpell(egg, SPELL_SUMMON_SMOULDERING_HATCHLING, TRIGGERED_FULL_MASK);
+ egg->SetDisplayId(MODEL_INVISIBLE_STALKER);
+ egg->m_Events.AddEvent(new RespawnEggEvent(egg), egg->m_Events.CalculateTime(5000));
+ }
+
+ if (_callHatchlingSpell)
+ DoCastAOE(_callHatchlingSpell, true);
+ _events.ScheduleEvent(EVENT_SUMMON_SMOULDERING_HATCHLING, urand(6000, 10000));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ EventMap _events;
+ uint32 _callHatchlingSpell;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_egg_pileAI(creature);
+ }
+};
+
+class spell_alysrazor_cosmetic_egg_xplosion : public SpellScriptLoader
+{
+ public:
+ spell_alysrazor_cosmetic_egg_xplosion() : SpellScriptLoader("spell_alysrazor_cosmetic_egg_xplosion") { }
+
+ class spell_alysrazor_cosmetic_egg_xplosion_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_alysrazor_cosmetic_egg_xplosion_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sCreatureDisplayInfoStore.LookupEntry(MODEL_INVISIBLE_STALKER))
+ return false;
+ return true;
+ }
+
+ void HandleExplosion(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->SetDisplayId(MODEL_INVISIBLE_STALKER);
+ if (Creature* creature = GetHitCreature())
+ creature->DespawnOrUnsummon(4000);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_alysrazor_cosmetic_egg_xplosion_SpellScript::HandleExplosion, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_alysrazor_cosmetic_egg_xplosion_SpellScript();
+ }
+};
+
+class spell_alysrazor_turn_monstrosity : public SpellScriptLoader
+{
+ public:
+ spell_alysrazor_turn_monstrosity() : SpellScriptLoader("spell_alysrazor_turn_monstrosity") { }
+
+ class spell_alysrazor_turn_monstrosity_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_alysrazor_turn_monstrosity_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_GENERIC_DUMMY_CAST))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_RIGHT))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_LEFT))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_FORWARD))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_KNOCKBACK_BACK))
+ return false;
+ return true;
+ }
+
+ void KnockBarrage(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->GetMotionMaster()->MoveIdle();
+ if (TempSummon* summ = GetHitUnit()->ToTempSummon())
+ if (Unit* summoner = summ->GetSummoner())
+ GetHitUnit()->CastSpell(summoner, SPELL_GENERIC_DUMMY_CAST, TRIGGERED_FULL_MASK);
+
+ float angle = 0.0f;
+ if (Unit* bird = GetCaster()->GetVehicleBase())
+ {
+ bird->SetInFront(GetHitUnit());
+ angle = bird->GetOrientation();
+ }
+
+ uint32 spellId = 0;
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_RIGHT_SIDE_SMACK_R:
+ case SPELL_RIGHT_SIDE_SMACK_L:
+ spellId = SPELL_KNOCKBACK_RIGHT;
+ angle -= M_PI * 0.5f;
+ break;
+ case SPELL_LEFT_SIDE_SMACK_R:
+ case SPELL_LEFT_SIDE_SMACK_L:
+ spellId = SPELL_KNOCKBACK_LEFT;
+ angle += M_PI * 0.5f;
+ break;
+ case SPELL_HEAD_BONK_R:
+ case SPELL_HEAD_BONK_L:
+ spellId = SPELL_KNOCKBACK_FORWARD;
+ break;
+ case SPELL_TICKLE_R:
+ case SPELL_TICKLE_L:
+ spellId = SPELL_KNOCKBACK_BACK;
+ angle -= M_PI;
+ break;
+ }
+
+ // Cannot wait for object update to process facing spline, it's needed in next spell cast
+ GetHitUnit()->SetOrientation(angle);
+ GetHitUnit()->SetFacingTo(angle);
+ GetHitUnit()->AddUnitState(UNIT_STATE_CANNOT_TURN);
+ GetHitUnit()->CastSpell(GetHitUnit(), spellId, TRIGGERED_FULL_MASK);
+ }
+
+ void TurnBird(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ GetHitUnit()->PlayOneShotAnimKit(ANIM_KIT_BIRD_TURN);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_alysrazor_turn_monstrosity_SpellScript::KnockBarrage, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHitTarget += SpellEffectFn(spell_alysrazor_turn_monstrosity_SpellScript::TurnBird, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_alysrazor_turn_monstrosity_SpellScript();
+ }
+};
+
+class spell_alysrazor_aggro_closest : public SpellScriptLoader
+{
+ public:
+ spell_alysrazor_aggro_closest() : SpellScriptLoader("spell_alysrazor_aggro_closest") { }
+
+ class spell_alysrazor_aggro_closest_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_alysrazor_aggro_closest_SpellScript);
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void HandleEffect(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ float curThreat = GetCaster()->getThreatManager().getThreat(GetHitUnit(), true);
+ GetCaster()->getThreatManager().addThreat(GetHitUnit(), -curThreat + 50000.0f / std::min(1.0f, GetCaster()->GetDistance(GetHitUnit())));
+ }
+
+ void UpdateThreat()
+ {
+ GetCaster()->ClearUnitState(UNIT_STATE_CASTING);
+ GetCaster()->GetAI()->AttackStart(GetCaster()->ToCreature()->SelectVictim());
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_alysrazor_aggro_closest_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
+ AfterCast += SpellCastFn(spell_alysrazor_aggro_closest_SpellScript::UpdateThreat);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_alysrazor_aggro_closest_SpellScript();
+ }
+};
+
+class spell_alysrazor_fieroblast : public SpellScriptLoader
+{
+ public:
+ spell_alysrazor_fieroblast() : SpellScriptLoader("spell_alysrazor_fieroblast") { }
+
+ class spell_alysrazor_fieroblast_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_alysrazor_fieroblast_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FIRE_IT_UP))
+ return false;
+ return true;
+ }
+
+ void FireItUp()
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_FIRE_IT_UP, TRIGGERED_FULL_MASK);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterCast += SpellCastFn(spell_alysrazor_fieroblast_SpellScript::FireItUp);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_alysrazor_fieroblast_SpellScript();
+ }
+};
+
+void AddSC_boss_alysrazor()
+{
+ new npc_harbinger_of_flame();
+ new npc_blazing_monstrosity();
+ new npc_molten_barrage();
+ new npc_egg_pile();
+ new spell_alysrazor_cosmetic_egg_xplosion();
+ new spell_alysrazor_turn_monstrosity();
+ new spell_alysrazor_aggro_closest();
+ new spell_alysrazor_fieroblast();
+}
diff --git a/src/server/scripts/Kalimdor/Firelands/firelands.h b/src/server/scripts/Kalimdor/Firelands/firelands.h
new file mode 100644
index 00000000000..d02d244dfc6
--- /dev/null
+++ b/src/server/scripts/Kalimdor/Firelands/firelands.h
@@ -0,0 +1,74 @@
+/*
+ * 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 FIRELANDS_H_
+#define FIRELANDS_H_
+
+#include "Map.h"
+#include "CreatureAI.h"
+
+#define FirelandsScriptName "instance_firelands"
+
+uint32 const EncounterCount = 7;
+
+enum DataTypes
+{
+ DATA_BETH_TILAC = 0,
+ DATA_LORD_RHYOLITH = 1,
+ DATA_SHANNOX = 2,
+ DATA_ALYSRAZOR = 3,
+ DATA_BALEROC = 4,
+ DATA_MAJORDOMO_STAGHELM = 5,
+ DATA_RAGNAROS = 6,
+};
+
+enum CreatureIds
+{
+ NPC_BLAZING_MONSTROSITY_LEFT = 53786,
+ NPC_BLAZING_MONSTROSITY_RIGHT = 53791,
+ NPC_EGG_PILE = 53795,
+ NPC_HARBINGER_OF_FLAME = 53793,
+ NPC_MOLTEN_EGG_TRASH = 53914,
+ NPC_SMOULDERING_HATCHLING = 53794,
+};
+
+class DelayedAttackStartEvent : public BasicEvent
+{
+ public:
+ DelayedAttackStartEvent(Creature* owner) : _owner(owner) { }
+
+ bool Execute(uint64 /*e_time*/, uint32 /*p_time*/)
+ {
+ _owner->AI()->DoZoneInCombat(_owner, 200.0f);
+ return true;
+ }
+
+ private:
+ Creature* _owner;
+};
+
+template<class AI>
+CreatureAI* GetFirelandsAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(FirelandsScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
+#endif // FIRELANDS_H_
diff --git a/src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp b/src/server/scripts/Kalimdor/Firelands/instance_firelands.cpp
new file mode 100644
index 00000000000..9ad179e9795
--- /dev/null
+++ b/src/server/scripts/Kalimdor/Firelands/instance_firelands.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 "ScriptMgr.h"
+#include "InstanceScript.h"
+#include "firelands.h"
+
+class instance_firelands : public InstanceMapScript
+{
+ public:
+ instance_firelands() : InstanceMapScript(FirelandsScriptName, 720) { }
+
+ struct instance_firelands_InstanceScript : public InstanceScript
+ {
+ instance_firelands_InstanceScript(InstanceMap* map) : InstanceScript(map)
+ {
+ }
+
+ void Initialize() OVERRIDE
+ {
+ SetBossNumber(EncounterCount);
+ }
+
+ void OnCreatureCreate(Creature* creature) OVERRIDE
+ {
+ switch (creature->GetEntry())
+ {
+ case NPC_SMOULDERING_HATCHLING:
+ // Cannot directly start attacking here as the creature is not yet on map
+ creature->m_Events.AddEvent(new DelayedAttackStartEvent(creature), creature->m_Events.CalculateTime(500));
+ break;
+ }
+ }
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
+ {
+ return new instance_firelands_InstanceScript(map);
+ }
+};
+
+void AddSC_instance_firelands()
+{
+ new instance_firelands();
+}
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
new file mode 100644
index 00000000000..e9ddc6ffeff
--- /dev/null
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_anraphet.cpp
@@ -0,0 +1,571 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "GridNotifiers.h"
+#include "Player.h"
+#include "ObjectAccessor.h"
+#include "halls_of_origination.h"
+
+enum Texts
+{
+ ANRAPHET_SAY_INTRO = 0,
+ ANRAPHET_SAY_AGGRO = 1,
+ ANRAPHET_SAY_OMEGA_STANCE = 2,
+ ANRAPHET_SAY_KILL = 3,
+ ANRAPHET_SAY_DEATH = 4,
+
+ BRANN_SAY_DOOR_INTRO = 0, // Right, let's go! Just need to input the final entry sequence into the door mechanism... and...
+ BRANN_SAY_UNLOCK_DOOR = 1, // That did the trick! The control room should be right behind this... oh... wow...
+ BRANN_SAY_TROGGS = 2, // What? This isn't the control room! There's another entire defense mechanism in place, and the blasted Rock Troggs broke into here somehow. Troggs. Why did it have to be Troggs!
+ BRANN_SAY_THINK = 3, // Ok, let me think a moment.
+ BRANN_SAY_MIRRORS = 4, // Mirrors pointing all over the place.
+ BRANN_SAY_ELEMENTALS = 5, // Four platforms with huge elementals.
+ BRANN_SAY_GET_IT = 6, // I got it! I saw a tablet that mentioned this chamber. This is the Vault of Lights! Ok, simple enough. I need you adventurers to take out each of the four elementals to trigger the opening sequence for the far door!
+ BRANN_1_ELEMENTAL_DEAD = 7, // One down!
+ BRANN_2_ELEMENTAL_DEAD = 8, // Another one down! Just look at those light beams! They seem to be connecting to the far door!
+ BRANN_3_ELEMENTAL_DEAD = 9, // One more elemental to go! The door is almost open!
+ BRANN_4_ELEMENTAL_DEAD = 10, // That''s it, you''ve done it! The vault door is opening! Now we can... oh, no!
+ BRANN_SAY_ANRAPHET_DIED = 11, // We''ve done it! The control room is breached!
+ BRANN_SAY_MOMENT = 12 // Here we go! Now this should only take a moment...
+};
+
+enum Events
+{
+ EVENT_BRANN_MOVE_INTRO = 1,
+ EVENT_BRANN_UNLOCK_DOOR = 2,
+ EVENT_BRANN_THINK = 3,
+ EVENT_BRANN_SET_ORIENTATION_1 = 4,
+ EVENT_BRANN_SET_ORIENTATION_2 = 5,
+ EVENT_BRANN_SET_ORIENTATION_3 = 6,
+ EVENT_BRANN_SAY_ELEMENTALS = 7,
+ EVENT_BRANN_SAY_GET_IT = 8,
+ EVENT_BRANN_SET_ORIENTATION_4 = 9,
+
+ EVENT_ANRAPHET_APPEAR = 10,
+ EVENT_ANRAPHET_ACTIVATE = 11,
+ EVENT_ANRAPHET_DESTROY = 12,
+ EVENT_ANRAPHET_READY = 13,
+ EVENT_ANRAPHET_NEMESIS_STRIKE = 14,
+ EVENT_ANRAPHET_ALPHA_BEAMS = 15,
+ EVENT_ANRAPHET_OMEGA_STANCE = 16,
+ EVENT_ANRAPHET_CRUMBLING_RUIN = 17,
+ EVENT_ANRAPHET_ACTIVATE_OMEGA = 18
+};
+
+enum Spells
+{
+ SPELL_DESTRUCTION_PROTOCOL = 77437,
+
+ SPELL_ALPHA_BEAMS = 76184,
+ SPELL_ALPHA_BEAMS_BACK_CAST = 76912,
+
+ SPELL_CRUMBLING_RUIN = 75609,
+
+
+ SPELL_NEMESIS_STRIKE = 75604,
+
+ SPELL_OMEGA_STANCE_SUMMON = 77106,
+ SPELL_OMEGA_STANCE = 75622,
+ SPELL_OMEGA_STANCE_SPIDER_TRIGGER = 77121,
+};
+
+enum Phases
+{
+ PHASE_INTRO = 1,
+ PHASE_COMBAT = 2,
+
+ PHASE_MASK_COMBAT = (1 << PHASE_COMBAT),
+};
+
+enum Points
+{
+ POINT_ANRAPHET_ACTIVATE = 0,
+ MAX_BRANN_WAYPOINTS_INTRO = 17
+};
+
+Position const AnraphetActivatePos = {-193.656f, 366.689f, 75.91001f, 3.138207f};
+
+Position const BrannIntroWaypoint[MAX_BRANN_WAYPOINTS_INTRO] =
+{
+ {-429.583f, 367.019f, 89.79282f, 0.0f},
+ {-409.9531f, 367.0469f, 89.81111f, 0.0f},
+ {-397.8246f, 366.967f, 86.37722f, 0.0f},
+ {-383.7813f, 366.8229f, 82.07919f, 0.0f},
+ {-368.2604f, 366.7448f, 77.0984f, 0.0f},
+ {-353.6458f, 366.4896f, 75.92504f, 0.0f},
+ {-309.0608f, 366.7205f, 75.91345f, 0.0f},
+ {-276.3303f, 367.0f, 75.92413f, 0.0f},
+ {-246.5104f, 366.6389f, 75.87791f, 0.0f},
+ {-202.0417f, 366.7517f, 75.92508f, 0.0f},
+ {-187.6024f, 366.7656f, 76.23077f, 0.0f},
+ {-155.0938f, 366.783f, 86.45834f, 0.0f},
+ {-143.5694f, 366.8177f, 89.73354f, 0.0f},
+ {-128.5608f, 366.8629f, 89.74199f, 0.0f},
+ {-103.559f, 366.5938f, 89.79725f, 0.0f},
+ {-71.58507f, 367.0278f, 89.77069f, 0.0f},
+ {-35.04861f, 366.6563f, 89.77447f, 0.0f},
+};
+
+class boss_anraphet : public CreatureScript
+{
+public:
+ boss_anraphet() : CreatureScript("boss_anraphet") { }
+
+ struct boss_anraphetAI : public BossAI
+ {
+ boss_anraphetAI(Creature* creature) : BossAI(creature, DATA_ANRAPHET) { }
+
+ void ScheduleCombatEvents()
+ {
+ events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 8000, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, 10000, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, 35000, 0, PHASE_COMBAT);
+ }
+
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ me->SetWalk(false);
+ events.SetPhase(PHASE_INTRO);
+ if (instance->GetData(DATA_DEAD_ELEMENTALS) == 4)
+ {
+ // Set to combat automatically, Brann's event won't repeat
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ events.SetPhase(PHASE_COMBAT);
+ ScheduleCombatEvents();
+ me->SetHomePosition(AnraphetActivatePos);
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
+ Talk(ANRAPHET_SAY_AGGRO);
+ _EnterCombat();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ Talk(ANRAPHET_SAY_DEATH);
+
+ if (Creature* brann = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_BRANN_0_GUID)))
+ brann->AI()->DoAction(ACTION_ANRAPHET_DIED);
+
+ _JustDied();
+ }
+
+ void KilledUnit(Unit* victim) OVERRIDE
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(ANRAPHET_SAY_KILL);
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _JustReachedHome();
+ instance->SetBossState(DATA_ANRAPHET, FAIL);
+ }
+
+ void DoAction(int32 action) OVERRIDE
+ {
+ if (action == ACTION_ANRAPHET_INTRO)
+ events.ScheduleEvent(EVENT_ANRAPHET_APPEAR, 6000, 0, PHASE_INTRO);
+ }
+
+ void MovementInform(uint32 type, uint32 point) OVERRIDE
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (point == POINT_ANRAPHET_ACTIVATE)
+ {
+ events.ScheduleEvent(EVENT_ANRAPHET_ACTIVATE, 1500, 0, PHASE_INTRO);
+ me->SetHomePosition(AnraphetActivatePos);
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if ((events.GetPhaseMask() & PHASE_MASK_COMBAT) && (!UpdateVictim() || !CheckInRoom()))
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ANRAPHET_APPEAR:
+ me->SetWalk(true);
+ me->GetMotionMaster()->MovePoint(POINT_ANRAPHET_ACTIVATE, AnraphetActivatePos);
+ break;
+ case EVENT_ANRAPHET_ACTIVATE:
+ me->SetWalk(false);
+ Talk(ANRAPHET_SAY_INTRO);
+ events.ScheduleEvent(EVENT_ANRAPHET_DESTROY, 17500, 0, PHASE_INTRO);
+ return;
+ case EVENT_ANRAPHET_DESTROY:
+ DoCastAOE(SPELL_DESTRUCTION_PROTOCOL);
+ events.ScheduleEvent(EVENT_ANRAPHET_READY, 6000, 0, PHASE_INTRO);
+ break;
+ case EVENT_ANRAPHET_READY:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ events.SetPhase(PHASE_COMBAT);
+ ScheduleCombatEvents();
+ break;
+ case EVENT_ANRAPHET_NEMESIS_STRIKE:
+ DoCastVictim(SPELL_NEMESIS_STRIKE);
+ events.ScheduleEvent(EVENT_ANRAPHET_NEMESIS_STRIKE, 21500, 0, PHASE_COMBAT);
+ break;
+ case EVENT_ANRAPHET_ALPHA_BEAMS:
+ DoCast(me, SPELL_ALPHA_BEAMS);
+ events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 12500, 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_ANRAPHET_ALPHA_BEAMS, urand(40000, 45000), 0, PHASE_COMBAT);
+ break;
+ case EVENT_ANRAPHET_OMEGA_STANCE:
+ DoCast(me, SPELL_OMEGA_STANCE_SUMMON);
+ DoCast(me, SPELL_OMEGA_STANCE);
+ Talk(ANRAPHET_SAY_OMEGA_STANCE);
+ events.ScheduleEvent(EVENT_ANRAPHET_OMEGA_STANCE, urand(45000, 50000), 0, PHASE_COMBAT);
+ events.ScheduleEvent(EVENT_ANRAPHET_CRUMBLING_RUIN, 13000, 0, PHASE_COMBAT);
+ break;
+ case EVENT_ANRAPHET_CRUMBLING_RUIN:
+ DoCast(me, SPELL_CRUMBLING_RUIN);
+ break;
+ }
+ }
+
+ if (events.GetPhaseMask() & PHASE_MASK_COMBAT)
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetHallsOfOriginationAI<boss_anraphetAI>(creature);
+ }
+};
+
+class npc_omega_stance : public CreatureScript
+{
+ public:
+ npc_omega_stance() : CreatureScript("npc_omega_stance") { }
+
+ struct npc_omega_stanceAI : public ScriptedAI
+ {
+ npc_omega_stanceAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(Unit* /*who*/) OVERRIDE
+ {
+ DoCast(me, SPELL_OMEGA_STANCE_SPIDER_TRIGGER, true);
+ }
+
+ void EnterEvadeMode() OVERRIDE { }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_omega_stanceAI(creature);
+ }
+};
+
+class npc_alpha_beam : public CreatureScript
+{
+ public:
+ npc_alpha_beam() : CreatureScript("npc_alpha_beam") { }
+
+ struct npc_alpha_beamAI : public ScriptedAI
+ {
+ npc_alpha_beamAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
+
+ void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
+ {
+ if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID)))
+ anraphet->CastSpell(me, SPELL_ALPHA_BEAMS_BACK_CAST);
+ }
+
+ void EnterEvadeMode() OVERRIDE { } // Never evade
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetHallsOfOriginationAI<npc_alpha_beamAI>(creature);
+ }
+};
+
+class npc_brann_bronzebeard_anraphet : public CreatureScript
+{
+ public:
+ npc_brann_bronzebeard_anraphet() : CreatureScript("npc_brann_bronzebeard_anraphet") { }
+
+ struct npc_brann_bronzebeard_anraphetAI : public CreatureAI
+ {
+ npc_brann_bronzebeard_anraphetAI(Creature* creature) : CreatureAI(creature), _currentPoint(0), _instance(creature->GetInstanceScript()) { }
+
+ void sGossipSelect(Player* /*player*/, uint32 sender, uint32 action) OVERRIDE
+ {
+ if (_instance->GetBossState(DATA_VAULT_OF_LIGHTS) == DONE)
+ return;
+
+ if (me->GetCreatureTemplate()->GossipMenuId == sender && !action)
+ {
+ _instance->SetBossState(DATA_VAULT_OF_LIGHTS, IN_PROGRESS);
+ _currentPoint = 0;
+ events.Reset();
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ me->SetWalk(true);
+ Talk(BRANN_SAY_DOOR_INTRO);
+ events.ScheduleEvent(EVENT_BRANN_UNLOCK_DOOR, 7500);
+ }
+ }
+
+ void DoAction(int32 action) OVERRIDE
+ {
+ switch (action)
+ {
+ case ACTION_ELEMENTAL_DIED:
+ {
+ uint32 dead = _instance->GetData(DATA_DEAD_ELEMENTALS);
+ Talk(BRANN_1_ELEMENTAL_DEAD + dead - 1);
+ if (dead == 4)
+ {
+ _instance->DoCastSpellOnPlayers(SPELL_VAULT_OF_LIGHTS_CREDIT);
+ if (Creature* anraphet = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_ANRAPHET_GUID)))
+ anraphet->AI()->DoAction(ACTION_ANRAPHET_INTRO);
+ }
+ break;
+ }
+ case ACTION_ANRAPHET_DIED:
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 1000);
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BRANN_MOVE_INTRO:
+ if (_currentPoint < MAX_BRANN_WAYPOINTS_INTRO)
+ me->GetMotionMaster()->MovePoint(_currentPoint, BrannIntroWaypoint[_currentPoint]);
+ break;
+ case EVENT_BRANN_UNLOCK_DOOR:
+ Talk(BRANN_SAY_UNLOCK_DOOR);
+ _instance->SetBossState(DATA_VAULT_OF_LIGHTS, DONE);
+ _instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_VAULT_OF_LIGHTS_EVENT);
+ events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, 3500);
+ break;
+ case EVENT_BRANN_THINK:
+ Talk(BRANN_SAY_THINK);
+ events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_1, 6000);
+ break;
+ case EVENT_BRANN_SET_ORIENTATION_1:
+ me->SetFacingTo(5.445427f);
+ Talk(BRANN_SAY_MIRRORS);
+ events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_2, 1000);
+ break;
+ case EVENT_BRANN_SET_ORIENTATION_2:
+ me->SetFacingTo(0.6283185f);
+ events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_3, 2500);
+ break;
+ case EVENT_BRANN_SET_ORIENTATION_3:
+ me->SetFacingTo(0.01745329f);
+ events.ScheduleEvent(EVENT_BRANN_SAY_ELEMENTALS, 200);
+ break;
+ case EVENT_BRANN_SAY_ELEMENTALS:
+ Talk(BRANN_SAY_ELEMENTALS);
+ events.ScheduleEvent(EVENT_BRANN_SAY_GET_IT, 3500);
+ break;
+ case EVENT_BRANN_SAY_GET_IT:
+ Talk(BRANN_SAY_GET_IT);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ break;
+ case EVENT_BRANN_SET_ORIENTATION_4:
+ me->SetFacingTo(3.141593f);
+ break;
+ }
+ }
+ }
+
+ void MovementInform(uint32 movementType, uint32 pointId) OVERRIDE
+ {
+ if (movementType != POINT_MOTION_TYPE)
+ return;
+
+ _currentPoint = pointId + 1;
+ uint32 delay = 1;
+
+ switch (pointId)
+ {
+ case 0:
+ Talk(BRANN_SAY_TROGGS);
+ events.ScheduleEvent(EVENT_BRANN_THINK, 15000);
+ return;
+ case 1:
+ Talk(BRANN_SAY_ANRAPHET_DIED);
+ delay = 1000;
+ break;
+ case 14:
+ Talk(BRANN_SAY_MOMENT);
+ delay = 2200;
+ break;
+ case 16:
+ events.ScheduleEvent(EVENT_BRANN_SET_ORIENTATION_4, 6000);
+ return;
+ default:
+ break;
+ }
+
+ events.ScheduleEvent(EVENT_BRANN_MOVE_INTRO, delay);
+ }
+
+ protected:
+ EventMap events;
+ uint32 _currentPoint;
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetHallsOfOriginationAI<npc_brann_bronzebeard_anraphetAI>(creature);
+ }
+};
+
+class spell_anraphet_alpha_beams : public SpellScriptLoader
+{
+public:
+ spell_anraphet_alpha_beams() : SpellScriptLoader("spell_anraphet_alpha_beams") { }
+
+ class spell_anraphet_alpha_beams_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_anraphet_alpha_beams_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (targets.empty())
+ return;
+
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anraphet_alpha_beams_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_anraphet_alpha_beams_SpellScript();
+ }
+};
+
+class spell_anraphet_omega_stance_summon : public SpellScriptLoader
+{
+public:
+ spell_anraphet_omega_stance_summon() : SpellScriptLoader("spell_anraphet_omega_stance_summon") { }
+
+ class spell_anraphet_omega_stance_summon_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_anraphet_omega_stance_summon_SpellScript);
+
+ void ModDestHeight(SpellEffIndex /*effIndex*/)
+ {
+ Position offset = {0.0f, 0.0f, 30.0f, 0.0f};
+ const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ GetHitDest()->RelocateOffset(offset);
+ }
+
+ void Register()
+ {
+ OnEffectLaunch += SpellEffectFn(spell_anraphet_omega_stance_summon_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_anraphet_omega_stance_summon_SpellScript();
+ }
+};
+
+class spell_omega_stance_spider_effect : public SpellScriptLoader
+{
+public:
+ spell_omega_stance_spider_effect() : SpellScriptLoader("spell_omega_stance_spider_effect") { }
+
+ class spell_omega_stance_spider_effect_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_omega_stance_spider_effect_SpellScript);
+
+ void SetDestPosition(SpellEffIndex effIndex)
+ {
+ // Do our own calculations for the destination position.
+ /// 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();
+
+ float x = caster->GetPositionX() + dist * std::cos(angle);
+ float y = caster->GetPositionY() + dist * std::sin(angle);
+ float z = caster->GetMap()->GetHeight(x, y, caster->GetPositionZ());
+
+ const_cast<WorldLocation*>(GetExplTargetDest())->Relocate(x, y, z);
+ GetHitDest()->Relocate(x, y, z);
+ }
+
+ void Register()
+ {
+ OnEffectLaunch += SpellEffectFn(spell_omega_stance_spider_effect_SpellScript::SetDestPosition, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_omega_stance_spider_effect_SpellScript();
+ }
+};
+
+void AddSC_boss_anraphet()
+{
+ new boss_anraphet();
+ new spell_anraphet_alpha_beams();
+ new npc_brann_bronzebeard_anraphet();
+ new npc_alpha_beam();
+ new spell_anraphet_omega_stance_summon();
+ new spell_omega_stance_spider_effect();
+ new npc_omega_stance();
+}
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp
new file mode 100644
index 00000000000..a547e9683a0
--- /dev/null
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_earthrager_ptah.cpp
@@ -0,0 +1,346 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "Player.h"
+#include "Weather.h"
+#include "WorldSession.h"
+#include "halls_of_origination.h"
+
+enum Texts
+{
+ SAY_AGGRO = 0,
+ SAY_DEATH = 1,
+};
+
+enum Events
+{
+ EVENT_RAGING_SMASH = 1,
+ EVENT_FLAME_BOLT = 2,
+ EVENT_EARTH_SPIKE = 3,
+ EVENT_PTAH_EXPLODE = 4,
+ EVENT_QUICKSAND = 5,
+};
+
+enum Spells
+{
+ SPELL_RAGING_SMASH = 83650,
+ SPELL_FLAME_BOLT = 77370,
+ SPELL_EARTH_SPIKE_WARN = 94974,
+
+ SPELL_PTAH_EXPLOSION = 75519,
+ SPELL_SANDSTORM = 75491,
+
+ SPELL_SUMMON_QUICKSAND = 75550, // Spell not in DBC, no SMSG_SPELL_START/GO for it
+
+ SPELL_BEETLE_BURROW = 75463,
+
+ SPELL_SUMMON_JEWELED_SCARAB = 75462,
+ SPELL_SUMMON_DUSTBONE_HORROR = 75521,
+};
+
+enum Phases
+{
+ PHASE_NORMAL = 1,
+ PHASE_DISPERSE = 2,
+
+ PHASE_MASK_DISPERSE = (1 << PHASE_DISPERSE),
+ PHASE_MASK_NORMAL = (1 << PHASE_NORMAL),
+};
+
+enum PtahData
+{
+ DATA_SUMMON_DEATHS = 0
+};
+
+class SummonScarab : public BasicEvent
+{
+public:
+ SummonScarab(Unit* owner, InstanceScript* instance) : _owner(owner), _instance(instance) { }
+
+ bool Execute(uint64 /*execTime*/, uint32 /*diff*/)
+ {
+ if (!_instance || _instance->GetBossState(DATA_EARTHRAGER_PTAH) != IN_PROGRESS)
+ return true; // delete event
+
+ _owner->CastSpell(_owner, SPELL_SUMMON_JEWELED_SCARAB);
+ _owner->RemoveAurasDueToSpell(SPELL_BEETLE_BURROW);
+ return true;
+ }
+protected:
+ Unit* _owner;
+ InstanceScript* _instance;
+};
+
+class boss_earthrager_ptah : public CreatureScript
+{
+public:
+ boss_earthrager_ptah() : CreatureScript("boss_earthrager_ptah") { }
+
+ struct boss_earthrager_ptahAI : public BossAI
+ {
+ boss_earthrager_ptahAI(Creature* creature) : BossAI(creature, DATA_EARTHRAGER_PTAH), _summonDeaths(0), _hasDispersed(false) { }
+
+ void Cleanup()
+ {
+ std::list<Creature*> units;
+
+ GetCreatureListWithEntryInGrid(units, me, NPC_DUSTBONE_HORROR, 100.0f);
+ for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+
+ GetCreatureListWithEntryInGrid(units, me, NPC_JEWELED_SCARAB, 100.0f);
+ for (std::list<Creature*>::iterator itr = units.begin(); itr != units.end(); ++itr)
+ (*itr)->DespawnOrUnsummon();
+ }
+
+ void SendWeather(WeatherState weather, float grade) const
+ {
+ WorldPacket data(SMSG_WEATHER, 9);
+ data << uint32(weather);
+ data << float(grade);
+ data << uint8(0);
+ SendPacketToPlayers(&data);
+ }
+
+ // Send packet to all players in Tomb of the Earthrager
+ void SendPacketToPlayers(WorldPacket const* data) const
+ {
+ Map::PlayerList const& players = me->GetMap()->GetPlayers();
+ if (!players.isEmpty())
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
+ if (Player* player = itr->GetSource())
+ if (player->GetAreaId() == AREA_TOMB_OF_THE_EARTHRAGER)
+ player->GetSession()->SendPacket(data);
+ }
+
+ void Reset() OVERRIDE
+ {
+ _summonDeaths = 0;
+ _hasDispersed = false;
+ Cleanup();
+ _Reset();
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
+ {
+ if (me->HealthBelowPctDamaged(50, damage) && (events.GetPhaseMask() & PHASE_MASK_NORMAL) && !_hasDispersed)
+ {
+ events.SetPhase(PHASE_DISPERSE);
+ _hasDispersed = true;
+
+ me->AttackStop();
+ DoCast(me, SPELL_SANDSTORM);
+ SendWeather(WEATHER_STATE_LIGHT_SANDSTORM, 1.0f);
+ events.ScheduleEvent(EVENT_PTAH_EXPLODE, 6000, 0, PHASE_DISPERSE);
+ events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE);
+
+ std::list<Creature*> stalkers;
+ GetCreatureListWithEntryInGrid(stalkers, me, NPC_BEETLE_STALKER, 100.0f);
+ std::list<Creature*> beetlers = stalkers;
+
+ Trinity::Containers::RandomResizeList(beetlers, 9); // Holds the summoners of Jeweled Scarab
+
+ for (std::list<Creature*>::iterator itr = beetlers.begin(); itr != beetlers.end(); ++itr)
+ {
+ stalkers.remove((*itr)); // Remove it to prevent a single trigger from spawning multiple npcs.
+ (*itr)->CastSpell((*itr), SPELL_BEETLE_BURROW); // Cast visual
+ // Summon after 5 seconds.
+ (*itr)->m_Events.AddEvent(new SummonScarab((*itr), instance), (*itr)->m_Events.CalculateTime(5000));
+ }
+
+ Trinity::Containers::RandomResizeList(stalkers, 2); // Holds the summoners of Dustbone Horror
+
+ for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
+ (*itr)->CastSpell((*itr), SPELL_SUMMON_DUSTBONE_HORROR);
+ }
+ }
+
+ void SetData(uint32 index, uint32 /*value*/) OVERRIDE
+ {
+ if (index == DATA_SUMMON_DEATHS)
+ {
+ ++_summonDeaths;
+ if (_summonDeaths == 11) // All summons died
+ {
+ SendWeather(WEATHER_STATE_FOG, 0.0f);
+ me->RemoveAurasDueToSpell(SPELL_PTAH_EXPLOSION);
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL);
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
+ Talk(SAY_AGGRO);
+ _EnterCombat();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ Talk(SAY_DEATH);
+ _JustDied();
+ Cleanup();
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _JustReachedHome();
+ instance->SetBossState(DATA_EARTHRAGER_PTAH, FAIL);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim() || !CheckInRoom())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_RAGING_SMASH:
+ DoCastVictim(SPELL_RAGING_SMASH);
+ events.ScheduleEvent(EVENT_RAGING_SMASH, urand(7000, 12000), 0, PHASE_NORMAL);
+ break;
+ case EVENT_FLAME_BOLT:
+ DoCast(me, SPELL_FLAME_BOLT);
+ events.ScheduleEvent(EVENT_FLAME_BOLT, 15000, 0, PHASE_NORMAL);
+ break;
+ case EVENT_EARTH_SPIKE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_EARTH_SPIKE_WARN);
+ events.ScheduleEvent(EVENT_EARTH_SPIKE, urand(16000, 21000), 0, PHASE_NORMAL);
+ break;
+ case EVENT_PTAH_EXPLODE:
+ DoCast(me, SPELL_PTAH_EXPLOSION);
+ break;
+ case EVENT_QUICKSAND:
+ // Spell not in DBC, it is not cast either, according to sniffs
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ if (Creature* quicksand = me->SummonCreature(NPC_QUICKSAND, *target))
+ quicksand->SetUInt32Value(UNIT_CREATED_BY_SPELL, SPELL_SUMMON_QUICKSAND);
+ events.ScheduleEvent(EVENT_QUICKSAND, 10000, 0, PHASE_DISPERSE);
+ break;
+ }
+ }
+
+ if (events.GetPhaseMask() & PHASE_MASK_NORMAL) // Do not melee in the disperse phase
+ DoMeleeAttackIfReady();
+ }
+
+ protected:
+ uint8 _summonDeaths;
+ bool _hasDispersed;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetHallsOfOriginationAI<boss_earthrager_ptahAI>(creature);
+ }
+};
+
+class spell_earthrager_ptah_flame_bolt : public SpellScriptLoader
+{
+ public:
+ spell_earthrager_ptah_flame_bolt() : SpellScriptLoader("spell_earthrager_ptah_flame_bolt") { }
+
+ class spell_earthrager_ptah_flame_bolt_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_earthrager_ptah_flame_bolt_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ Trinity::Containers::RandomResizeList(targets, GetCaster()->GetMap()->IsHeroic() ? 3 : 2);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_earthrager_ptah_flame_bolt_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_earthrager_ptah_flame_bolt_SpellScript();
+ }
+};
+
+class spell_earthrager_ptah_explosion : public SpellScriptLoader
+{
+public:
+ spell_earthrager_ptah_explosion() : SpellScriptLoader("spell_earthrager_ptah_explosion") { }
+
+ class spell_earthrager_ptah_explosion_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_earthrager_ptah_explosion_AuraScript);
+
+ void SetFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* ptah = GetCaster())
+ {
+ ptah->SetFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_29 | UNIT_FLAG_UNK_31));
+ ptah->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ }
+ }
+
+ void RemoveFlags(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* ptah = GetCaster())
+ {
+ ptah->RemoveFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_29 | UNIT_FLAG_UNK_31));
+ ptah->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_earthrager_ptah_explosion_AuraScript::SetFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_earthrager_ptah_explosion_AuraScript::RemoveFlags, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_earthrager_ptah_explosion_AuraScript();
+ }
+};
+
+void AddSC_boss_earthrager_ptah()
+{
+ new boss_earthrager_ptah();
+ new spell_earthrager_ptah_flame_bolt();
+ new spell_earthrager_ptah_explosion();
+}
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
new file mode 100644
index 00000000000..a6127aa907f
--- /dev/null
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/boss_temple_guardian_anhuur.cpp
@@ -0,0 +1,404 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "GridNotifiers.h"
+#include "Player.h"
+#include "halls_of_origination.h"
+
+enum Texts
+{
+ SAY_AGGRO = 0,
+ SAY_SHIELD = 1,
+ EMOTE_SHIELD = 2,
+ EMOTE_UNSHIELD = 3,
+ SAY_KILL = 4,
+ SAY_DEATH = 5
+};
+
+enum Events
+{
+ EVENT_DIVINE_RECKONING = 1,
+ EVENT_BURNING_LIGHT = 2,
+ EVENT_SEAR = 3,
+};
+
+enum Spells
+{
+ SPELL_DIVINE_RECKONING = 75592,
+ SPELL_BURNING_LIGHT = 75115,
+ SPELL_REVERBERATING_HYMN = 75322,
+ SPELL_SHIELD_OF_LIGHT = 74938,
+
+ SPELL_ACTIVATE_BEACONS = 76599,
+ SPELL_TELEPORT = 74969,
+
+ SPELL_SHIELD_VISUAL_RIGHT = 83698,
+ SPELL_BEAM_OF_LIGHT_RIGHT = 76573,
+
+ SPELL_SHIELD_VISUAL_LEFT = 83697,
+ SPELL_BEAM_OF_LIGHT_LEFT = 74930,
+
+ SPELL_SEARING_LIGHT = 75194,
+};
+
+enum Phases
+{
+ PHASE_SHIELDED = 0,
+ PHASE_FIRST_SHIELD = 1, // Ready to be shielded for the first time
+ PHASE_SECOND_SHIELD = 2, // First shield already happened, ready to be shielded a second time
+ PHASE_FINAL = 3 // Already shielded twice, ready to finish the encounter normally.
+};
+
+enum Actions
+{
+ ACTION_DISABLE_BEACON,
+};
+
+class boss_temple_guardian_anhuur : public CreatureScript
+{
+public:
+ boss_temple_guardian_anhuur() : CreatureScript("boss_temple_guardian_anhuur") { }
+
+ struct boss_temple_guardian_anhuurAI : public BossAI
+ {
+ boss_temple_guardian_anhuurAI(Creature* creature) : BossAI(creature, DATA_TEMPLE_GUARDIAN_ANHUUR) { }
+
+ void CleanStalkers()
+ {
+ std::list<Creature*> stalkers;
+ GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
+ for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
+ {
+ (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_RIGHT);
+ (*itr)->RemoveAurasDueToSpell(SPELL_BEAM_OF_LIGHT_LEFT);
+ }
+ }
+
+ void Reset() OVERRIDE
+ {
+ _phase = PHASE_FIRST_SHIELD;
+ _oldPhase = PHASE_FIRST_SHIELD;
+ _beacons = 0;
+ _Reset();
+ CleanStalkers();
+ me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
+ events.ScheduleEvent(EVENT_DIVINE_RECKONING, urand(10000, 12000));
+ events.ScheduleEvent(EVENT_BURNING_LIGHT, 12000);
+ }
+
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) OVERRIDE
+ {
+ if ((me->HealthBelowPctDamaged(66, damage) && _phase == PHASE_FIRST_SHIELD) ||
+ (me->HealthBelowPctDamaged(33, damage) && _phase == PHASE_SECOND_SHIELD))
+ {
+ _beacons = 2;
+ _phase++; // Increase the phase
+ _oldPhase = _phase;
+
+ _phase = PHASE_SHIELDED;
+
+ me->InterruptNonMeleeSpells(true);
+ me->AttackStop();
+ DoCast(me, SPELL_TELEPORT);
+
+ DoCast(me, SPELL_SHIELD_OF_LIGHT);
+ me->SetFlag(UNIT_FIELD_FLAGS, uint32(UNIT_FLAG_UNK_31));
+
+ DoCastAOE(SPELL_ACTIVATE_BEACONS);
+
+ std::list<Creature*> stalkers;
+ GameObject* door = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_ANHUUR_DOOR));
+ GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
+
+ stalkers.remove_if(Trinity::HeightDifferenceCheck(door, 0.0f, false)); // Target only the bottom ones
+ for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
+ {
+ if ((*itr)->GetPositionX() > door->GetPositionX())
+ {
+ (*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_LEFT, true);
+ (*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_LEFT, true);
+ }
+ else
+ {
+ (*itr)->CastSpell((*itr), SPELL_SHIELD_VISUAL_RIGHT, true);
+ (*itr)->CastSpell((*itr), SPELL_BEAM_OF_LIGHT_RIGHT, true);
+ }
+ }
+
+ DoCast(me, SPELL_REVERBERATING_HYMN);
+
+ Talk(EMOTE_SHIELD);
+ Talk(SAY_SHIELD);
+ }
+ }
+
+ void DoAction(int32 action) OVERRIDE
+ {
+ if (action == ACTION_DISABLE_BEACON)
+ {
+ --_beacons;
+ if (!_beacons)
+ {
+ me->RemoveAurasDueToSpell(SPELL_SHIELD_OF_LIGHT);
+ Talk(EMOTE_UNSHIELD);
+ _phase = _oldPhase;
+ }
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me, 1);
+ Talk(SAY_AGGRO);
+ _EnterCombat();
+ }
+
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ Talk(SAY_DEATH);
+ _JustDied();
+ }
+
+ void KilledUnit(Unit* victim) OVERRIDE
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL);
+ }
+
+ void JustReachedHome() OVERRIDE
+ {
+ instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
+ _JustReachedHome();
+ instance->SetBossState(DATA_TEMPLE_GUARDIAN_ANHUUR, FAIL);
+ }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim() || !CheckInRoom() || me->GetCurrentSpell(CURRENT_CHANNELED_SPELL) || _phase == PHASE_SHIELDED)
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_DIVINE_RECKONING:
+ DoCastVictim(SPELL_DIVINE_RECKONING);
+ events.ScheduleEvent(EVENT_DIVINE_RECKONING, urand(10000, 12000));
+ break;
+ case EVENT_BURNING_LIGHT:
+ {
+ Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me));
+ if (!unit)
+ unit = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true);
+ DoCast(unit, SPELL_BURNING_LIGHT);
+ events.ScheduleEvent(EVENT_SEAR, 2000);
+ events.ScheduleEvent(EVENT_BURNING_LIGHT, 12000);
+ break;
+ }
+ case EVENT_SEAR:
+ {
+ Unit* target = me->FindNearestCreature(NPC_SEARING_LIGHT, 100.0f);
+ if (!target)
+ break;
+
+ std::list<Creature*> stalkers;
+ GetCreatureListWithEntryInGrid(stalkers, me, NPC_CAVE_IN_STALKER, 100.0f);
+ stalkers.remove_if(Trinity::HeightDifferenceCheck(ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_ANHUUR_DOOR)), 5.0f, true));
+
+ if (stalkers.empty())
+ break;
+
+ stalkers.sort(Trinity::ObjectDistanceOrderPred(target));
+
+ // Get the closest statue face (any of its eyes)
+ Creature* eye1 = stalkers.front();
+ stalkers.remove(eye1); // Remove the eye.
+ stalkers.sort(Trinity::ObjectDistanceOrderPred(eye1)); // Find the second eye.
+ Creature* eye2 = stalkers.front();
+
+ eye1->CastSpell(eye1, SPELL_SEARING_LIGHT, true);
+ eye2->CastSpell(eye2, SPELL_SEARING_LIGHT, true);
+ break;
+ }
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+ private:
+ uint8 _phase;
+ uint8 _oldPhase;
+ uint8 _beacons;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return GetHallsOfOriginationAI<boss_temple_guardian_anhuurAI>(creature);
+ }
+};
+
+class spell_anhuur_shield_of_light : public SpellScriptLoader
+{
+ public:
+ spell_anhuur_shield_of_light() : SpellScriptLoader("spell_anhuur_shield_of_light") { }
+
+ class spell_anhuur_shield_of_light_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_anhuur_shield_of_light_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap())
+ {
+ if (InstanceScript* const script = instance->GetInstanceScript())
+ {
+ if (GameObject* go = ObjectAccessor::GetGameObject(*GetCaster(), script->GetData64(DATA_ANHUUR_DOOR)))
+ {
+ targets.remove_if(Trinity::HeightDifferenceCheck(go, 5.0f, false));
+ targets.remove(GetCaster());
+ targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
+ targets.resize(2);
+ }
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_anhuur_shield_of_light_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_anhuur_shield_of_light_SpellScript();
+ }
+};
+
+class spell_anhuur_disable_beacon_beams : public SpellScriptLoader
+{
+ public:
+ spell_anhuur_disable_beacon_beams() : SpellScriptLoader("spell_anhuur_disable_beacon_beams") { }
+
+ class spell_anhuur_disable_beacon_beams_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_anhuur_disable_beacon_beams_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetHitUnit()->RemoveAurasDueToSpell(GetEffectValue());
+ }
+
+ void Notify(SpellEffIndex /*index*/)
+ {
+ if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap())
+ if (InstanceScript* const script = instance->GetInstanceScript())
+ if (Creature* anhuur = instance->GetCreature(script->GetData64(DATA_ANHUUR_GUID)))
+ anhuur->AI()->DoAction(ACTION_DISABLE_BEACON);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHit += SpellEffectFn(spell_anhuur_disable_beacon_beams_SpellScript::Notify, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_anhuur_disable_beacon_beams_SpellScript();
+ }
+};
+
+class spell_anhuur_activate_beacons : public SpellScriptLoader
+{
+ public:
+ spell_anhuur_activate_beacons() : SpellScriptLoader("spell_anhuur_activate_beacons") { }
+
+ class spell_anhuur_activate_beacons_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_anhuur_activate_beacons_SpellScript);
+
+ void Activate(SpellEffIndex index)
+ {
+ PreventHitDefaultEffect(index);
+ GetHitGObj()->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_anhuur_activate_beacons_SpellScript::Activate, EFFECT_0, SPELL_EFFECT_ACTIVATE_OBJECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_anhuur_activate_beacons_SpellScript();
+ }
+};
+
+class spell_anhuur_divine_reckoning : public SpellScriptLoader
+{
+public:
+ spell_anhuur_divine_reckoning() : SpellScriptLoader("spell_anhuur_divine_reckoning") { }
+
+ class spell_anhuur_divine_reckoning_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_anhuur_divine_reckoning_AuraScript);
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ CustomSpellValues values;
+ values.AddSpellMod(SPELLVALUE_BASE_POINT0, aurEff->GetAmount());
+ caster->CastCustomSpell(GetSpellInfo()->Effects[EFFECT_0].TriggerSpell, values, GetTarget());
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_anhuur_divine_reckoning_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_anhuur_divine_reckoning_AuraScript();
+ }
+};
+
+void AddSC_boss_temple_guardian_anhuur()
+{
+ new boss_temple_guardian_anhuur();
+ new spell_anhuur_shield_of_light();
+ new spell_anhuur_disable_beacon_beams();
+ new spell_anhuur_activate_beacons();
+ new spell_anhuur_divine_reckoning();
+}
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h
new file mode 100644
index 00000000000..b4022baaadc
--- /dev/null
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/halls_of_origination.h
@@ -0,0 +1,126 @@
+/*
+ * 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 HALLS_OF_ORIGINATION_H
+#define HALLS_OF_ORIGINATION_H
+
+#define HoOScriptName "instance_halls_of_origination"
+
+uint32 const EncounterCount = 12;
+
+enum Data
+{
+ // Bosses
+ DATA_TEMPLE_GUARDIAN_ANHUUR,
+ DATA_EARTHRAGER_PTAH,
+ DATA_VAULT_OF_LIGHTS,
+ DATA_FIRE_WARDEN,
+ DATA_EARTH_WARDEN,
+ DATA_WATER_WARDEN,
+ DATA_AIR_WARDEN,
+ DATA_ANRAPHET,
+ DATA_ISISET,
+ DATA_AMMUNAE,
+ DATA_SETESH,
+ DATA_RAJH,
+
+ // Temple Guardian Anhuur
+ DATA_ANHUUR_GUID,
+ DATA_ANHUUR_LEFT_BEACON,
+ DATA_ANHUUR_RIGHT_BEACON,
+ DATA_ANHUUR_BRIDGE,
+ DATA_ANHUUR_DOOR,
+
+ // Anraphet
+ DATA_BRANN_0_GUID,
+ DATA_DEAD_ELEMENTALS,
+ DATA_ANRAPHET_GUID,
+};
+
+enum Creatures
+{
+ BOSS_TEMPLE_GUARDIAN_ANHUUR = 39425,
+ NPC_CAVE_IN_STALKER = 40183,
+ NPC_SEARING_LIGHT = 40283,
+
+ BOSS_EARTHRAGER_PTAH = 39428,
+ NPC_BEETLE_STALKER = 40459, // Summons both Jeweled Scarab and Dustbone Horror
+ NPC_JEWELED_SCARAB = 40458,
+ NPC_DUSTBONE_HORROR = 40450,
+ NPC_QUICKSAND = 40503, // Summoned by a spell not in dbc (75550)
+
+ BOSS_ANRAPHET = 39788,
+ NPC_FIRE_WARDEN = 39800,
+ NPC_EARTH_WARDEN = 39801,
+ NPC_WATER_WARDEN = 39802,
+ NPC_AIR_WARDEN = 39803,
+
+ WARDEN_ENTRY_DATA_DELTA = NPC_FIRE_WARDEN - DATA_FIRE_WARDEN,
+
+ NPC_BRANN_BRONZEBEARD_0 = 39908,
+ NPC_OMEGA_STANCE = 41194,
+};
+
+enum GameObjects
+{
+ GO_ANHUURS_BRIDGE = 206506,
+ GO_DOODAD_ULDUM_ELEVATOR_COL01 = 207725,
+ GO_ANHUURS_DOOR = 202307,
+ GO_ANHUURS_RIGHT_BEACON = 203136,
+ GO_ANHUURS_LEFT_BEACON = 203133,
+
+ GO_VAULT_OF_LIGHTS_DOOR = 202313,
+ GO_SUN_MIRROR = 207726,
+ GO_ANRAPHET_DOOR = 202314,
+
+ GO_DOODAD_ULDUM_LIGHTMACHINE_01 = 207375,
+ GO_DOODAD_ULDUM_LIGHTMACHINE_02 = 207374,
+ GO_DOODAD_ULDUM_LIGHTMACHINE_03 = 207377,
+ GO_DOODAD_ULDUM_LIGHTMACHINE_04 = 207376,
+
+ GO_DOODAD_ULDUM_LASERBEAMS01 = 207662, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_02
+ GO_DOODAD_ULDUM_LASERBEAMS_01 = 207663, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_01
+ GO_DOODAD_ULDUM_LASERBEAMS_02 = 207664, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_04
+ GO_DOODAD_ULDUM_LASERBEAMS_03 = 207665, // Matches GO_DOODAD_ULDUM_LIGHTMACHINE_03
+};
+
+enum Misc
+{
+ AREA_TOMB_OF_THE_EARTHRAGER = 5610,
+ ACHIEV_VAULT_OF_LIGHTS_EVENT = 24212, // Faster Than The Speed Of Light
+ SPELL_VAULT_OF_LIGHTS_CREDIT = 94067, // Not in DBC
+};
+
+enum GlobalActions
+{
+ ACTION_ANRAPHET_INTRO,
+ ACTION_ELEMENTAL_DIED,
+ ACTION_ANRAPHET_DIED,
+ ACTION_OMEGA_TRIGGER,
+};
+
+template<class AI>
+CreatureAI* GetHallsOfOriginationAI(Creature* creature)
+{
+ if (InstanceMap* instance = creature->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(HoOScriptName))
+ return new AI(creature);
+ return NULL;
+}
+
+#endif // HALLS_OF_ORIGINATION_H
diff --git a/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
new file mode 100644
index 00000000000..5a7b6489c94
--- /dev/null
+++ b/src/server/scripts/Kalimdor/HallsOfOrigination/instance_halls_of_origination.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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 "ObjectMgr.h"
+#include "ScriptMgr.h"
+#include "InstanceScript.h"
+#include "ScriptedCreature.h"
+#include "Map.h"
+#include "PoolMgr.h"
+#include "AccountMgr.h"
+#include "halls_of_origination.h"
+#include "Player.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+
+DoorData const doorData[] =
+{
+ {GO_ANHUURS_DOOR, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_ANHUURS_BRIDGE, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_ELEVATOR_COL01, DATA_TEMPLE_GUARDIAN_ANHUUR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_VAULT_OF_LIGHTS_DOOR, DATA_VAULT_OF_LIGHTS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LIGHTMACHINE_02, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LASERBEAMS01, DATA_EARTH_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LIGHTMACHINE_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LASERBEAMS_01, DATA_FIRE_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LIGHTMACHINE_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LASERBEAMS_03, DATA_WATER_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LIGHTMACHINE_04, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {GO_DOODAD_ULDUM_LASERBEAMS_02, DATA_AIR_WARDEN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }
+};
+
+class instance_halls_of_origination : public InstanceMapScript
+{
+ public:
+ instance_halls_of_origination() : InstanceMapScript(HoOScriptName, 644) { }
+
+ struct instance_halls_of_origination_InstanceMapScript : public InstanceScript
+ {
+ instance_halls_of_origination_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
+ {
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
+ TempleGuardianAnhuurGUID = 0;
+ AnhuursBridgeGUID = 0;
+ AnhuursDoorGUID = 0;
+ AnhuurRightBeaconGUID = 0;
+ AnhuurLeftBeaconGUID = 0;
+ BrannBronzebeardGUID = 0;
+ AnraphetGUID = 0;
+ AnraphetDoorGUID = 0;
+ SunMirrorGUID = 0;
+ _deadElementals = 0;
+ }
+
+ void OnGameObjectCreate(GameObject* go) OVERRIDE
+ {
+ switch (go->GetEntry())
+ {
+ case GO_ANHUURS_BRIDGE:
+ AnhuursBridgeGUID = go->GetGUID();
+ case GO_DOODAD_ULDUM_ELEVATOR_COL01:
+ case GO_VAULT_OF_LIGHTS_DOOR:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_01:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_02:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_03:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_04:
+ case GO_DOODAD_ULDUM_LASERBEAMS01:
+ case GO_DOODAD_ULDUM_LASERBEAMS_01:
+ case GO_DOODAD_ULDUM_LASERBEAMS_02:
+ case GO_DOODAD_ULDUM_LASERBEAMS_03:
+ AddDoor(go, true);
+ break;
+ case GO_ANHUURS_DOOR:
+ AnhuursDoorGUID = go->GetGUID();
+ AddDoor(go, true);
+ break;
+ case GO_ANHUURS_RIGHT_BEACON:
+ AnhuurRightBeaconGUID = go->GetGUID();
+ break;
+ case GO_ANHUURS_LEFT_BEACON:
+ AnhuurLeftBeaconGUID = go->GetGUID();
+ break;
+ case GO_SUN_MIRROR:
+ SunMirrorGUID = go->GetGUID();
+ break;
+ case GO_ANRAPHET_DOOR:
+ AnraphetDoorGUID = go->GetGUID();
+ break;
+ }
+ }
+
+ void OnGameObjectRemove(GameObject* go) OVERRIDE
+ {
+ switch (go->GetEntry())
+ {
+ case GO_ANHUURS_BRIDGE:
+ case GO_DOODAD_ULDUM_ELEVATOR_COL01:
+ case GO_ANHUURS_DOOR:
+ case GO_VAULT_OF_LIGHTS_DOOR:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_01:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_02:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_03:
+ case GO_DOODAD_ULDUM_LIGHTMACHINE_04:
+ case GO_DOODAD_ULDUM_LASERBEAMS01:
+ case GO_DOODAD_ULDUM_LASERBEAMS_01:
+ case GO_DOODAD_ULDUM_LASERBEAMS_02:
+ case GO_DOODAD_ULDUM_LASERBEAMS_03:
+ AddDoor(go, false);
+ break;
+ }
+ }
+
+ void OnCreatureCreate(Creature* creature) OVERRIDE
+ {
+ switch (creature->GetEntry())
+ {
+ case BOSS_TEMPLE_GUARDIAN_ANHUUR:
+ TempleGuardianAnhuurGUID = creature->GetGUID();
+ break;
+ case NPC_BRANN_BRONZEBEARD_0:
+ BrannBronzebeardGUID = creature->GetGUID();
+ break;
+ case BOSS_ANRAPHET:
+ AnraphetGUID = creature->GetGUID();
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 data) const OVERRIDE
+ {
+ switch (data)
+ {
+ case DATA_DEAD_ELEMENTALS:
+ return _deadElementals;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ uint64 GetData64(uint32 index) const OVERRIDE
+ {
+ switch (index)
+ {
+ case DATA_ANHUUR_BRIDGE:
+ return AnhuursBridgeGUID;
+ case DATA_ANHUUR_DOOR:
+ return AnhuursDoorGUID;
+ case DATA_ANHUUR_LEFT_BEACON:
+ return AnhuurLeftBeaconGUID;
+ case DATA_ANHUUR_RIGHT_BEACON:
+ return AnhuurRightBeaconGUID;
+ case DATA_ANHUUR_GUID:
+ return TempleGuardianAnhuurGUID;
+ case DATA_BRANN_0_GUID:
+ return BrannBronzebeardGUID;
+ case DATA_ANRAPHET_GUID:
+ return AnraphetGUID;
+ }
+
+ return 0;
+ }
+
+ void IncreaseDeadElementals(uint32 inc)
+ {
+ _deadElementals += inc;
+ if (_deadElementals == 4)
+ {
+ if (GameObject* mirror = instance->GetGameObject(SunMirrorGUID))
+ mirror->SetGoState(GO_STATE_ACTIVE);
+ if (GameObject* door = instance->GetGameObject(AnraphetDoorGUID))
+ door->SetGoState(GO_STATE_ACTIVE);
+ }
+ }
+
+ void OnUnitDeath(Unit* unit) OVERRIDE
+ {
+ Creature* creature = unit->ToCreature();
+ if (!creature)
+ return;
+
+ switch (creature->GetEntry())
+ {
+ case NPC_FIRE_WARDEN:
+ case NPC_EARTH_WARDEN:
+ case NPC_WATER_WARDEN:
+ case NPC_AIR_WARDEN:
+ uint32 data = creature->GetEntry() - WARDEN_ENTRY_DATA_DELTA;
+ SetBossState(data, IN_PROGRESS); // Needs to be set to IN_PROGRESS or else the gameobjects state won't be updated
+ SetBossState(data, DONE);
+ IncreaseDeadElementals(1);
+ if (Creature* brann = instance->GetCreature(BrannBronzebeardGUID))
+ brann->AI()->DoAction(ACTION_ELEMENTAL_DIED);
+ break;
+ }
+ }
+
+ std::string GetSaveData() OVERRIDE
+ {
+ OUT_SAVE_INST_DATA;
+
+ std::ostringstream saveStream;
+ saveStream << "H O " << GetBossSaveData() << _deadElementals;
+
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
+ }
+
+ void Load(const char* str) OVERRIDE
+ {
+ if (!str)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
+
+ OUT_LOAD_INST_DATA(str);
+
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
+
+ if (dataHead1 == 'H' && dataHead2 == 'O')
+ {
+ for (uint32 i = 0; i < EncounterCount; ++i)
+ {
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
+ }
+ uint32 tmp;
+ loadStream >> tmp;
+ IncreaseDeadElementals(tmp);
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
+
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ protected:
+ uint64 TempleGuardianAnhuurGUID;
+ uint64 AnhuursBridgeGUID;
+ uint64 AnhuursDoorGUID;
+ uint64 AnhuurRightBeaconGUID;
+ uint64 AnhuurLeftBeaconGUID;
+ uint64 BrannBronzebeardGUID;
+ uint64 AnraphetGUID;
+ uint64 AnraphetDoorGUID;
+ uint64 SunMirrorGUID;
+ uint32 _deadElementals;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const OVERRIDE
+ {
+ return new instance_halls_of_origination_InstanceMapScript(map);
+ }
+};
+
+void AddSC_instance_halls_of_origination()
+{
+ new instance_halls_of_origination();
+}
diff --git a/src/server/scripts/Kalimdor/zone_azshara.cpp b/src/server/scripts/Kalimdor/zone_azshara.cpp
index edc13c8d446..b4515da25ef 100644
--- a/src/server/scripts/Kalimdor/zone_azshara.cpp
+++ b/src/server/scripts/Kalimdor/zone_azshara.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,519 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Azshara
-SD%Complete: 90
-SDComment: Quest support: 2744, 3141, 9364, 10994
-SDCategory: Azshara
-EndScriptData */
-
-/* ContentData
-npc_spitelashes
-npc_loramus_thalipedes
-npc_rizzle_sprysprocket
-npc_depth_charge
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-#include "SpellInfo.h"
-
-/*######
-## npc_spitelashes
-######*/
-
-enum Spitelashes
-{
- SPELL_POLYMORPH_RANK1 = 118,
- SPELL_POLYMORPH_RANK2 = 12824,
- SPELL_POLYMORPH_RANK3 = 12825,
- SPELL_POLYMORPH_RANK4 = 12826,
- SPELL_POLYMORPH = 29124,
- SPELL_POLYMORPH_BACKFIRE = 28406,
- SPELL_REMOVE_POLYMORPH = 6924
-};
-
-class npc_spitelashes : public CreatureScript
-{
-public:
- npc_spitelashes() : CreatureScript("npc_spitelashes") { }
-
- struct npc_spitelashesAI : public ScriptedAI
- {
- npc_spitelashesAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 morphtimer;
- bool spellhit;
-
- void Reset() OVERRIDE
- {
- morphtimer = 0;
- spellhit = false;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void SpellHit(Unit* unit, const SpellInfo* spell) OVERRIDE
- {
- if (spellhit)
- return;
-
- switch (spell->Id)
- {
- case SPELL_POLYMORPH_RANK1:
- case SPELL_POLYMORPH_RANK2:
- case SPELL_POLYMORPH_RANK3:
- case SPELL_POLYMORPH_RANK4:
- if (Player* player = unit->ToPlayer())
- if (player->GetQuestStatus(9364) == QUEST_STATUS_INCOMPLETE)
- {
- spellhit = true;
- DoCast(me, SPELL_POLYMORPH);
- }
- break;
- default:
- break;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- // we mustn't remove the Creature in the same round in which we cast the summon spell, otherwise there will be no summons
- if (spellhit && morphtimer >= 5000)
- {
- me->DespawnOrUnsummon();
- return;
- }
- // walk 5 seconds before summoning
- if (spellhit && morphtimer<5000)
- {
- morphtimer+=diff;
- if (morphtimer >= 5000)
- {
- DoCast(me, SPELL_POLYMORPH_BACKFIRE); // summon copies
- DoCast(me, SPELL_REMOVE_POLYMORPH); // visual explosion
- }
- }
- if (!UpdateVictim())
- return;
-
- /// @todo add abilities for the different creatures
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_spitelashesAI(creature);
- }
-};
-
-/*######
-## npc_loramus_thalipedes
-######*/
-
-#define GOSSIP_HELLO_LT1 "Can you help me?"
-#define GOSSIP_HELLO_LT2 "Tell me your story"
-#define GOSSIP_SELECT_LT1 "Please continue"
-#define GOSSIP_SELECT_LT2 "I do not understand"
-#define GOSSIP_SELECT_LT3 "Indeed"
-#define GOSSIP_SELECT_LT4 "I will do this with or your help, Loramus"
-#define GOSSIP_SELECT_LT5 "Yes"
-
-class npc_loramus_thalipedes : public CreatureScript
-{
-public:
- npc_loramus_thalipedes() : CreatureScript("npc_loramus_thalipedes") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(2744);
- break;
-
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
- player->SEND_GOSSIP_MENU(1813, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+21:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
- player->SEND_GOSSIP_MENU(1814, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+22:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 23);
- player->SEND_GOSSIP_MENU(1815, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+23:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 24);
- player->SEND_GOSSIP_MENU(1816, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+24:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SELECT_LT5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
- player->SEND_GOSSIP_MENU(1817, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+25:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(3141);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(2744) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- if (player->GetQuestStatus(3141) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO_LT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-};
-
-/*####
-# npc_rizzle_sprysprocket
-####*/
-
-enum RizzleSprysprocketData
-{
- QUEST_CHASING_THE_MOONSTONE = 10994,
-
- NPC_DEPTH_CHARGE = 23025,
-
- SPELL_RIZZLE_BLACKJACK = 39865,
- SPELL_RIZZLE_ESCAPE = 39871,
- SPELL_RIZZLE_FROST_GRENADE = 40525,
- SPELL_DEPTH_CHARGE_TRAP = 38576,
- SPELL_PERIODIC_DEPTH_CHARGE = 39912,
- SPELL_GIVE_SOUTHFURY_MOONSTONE = 39886,
-
- SAY_RIZZLE_START = 0,
- SAY_RIZZLE_GRENADE = 1,
- SAY_RIZZLE_FINAL = 2,
- MSG_ESCAPE_NOTICE = 3
-};
-
-#define GOSSIP_GET_MOONSTONE "Hand over the Southfury moonstone and I'll let you go."
-
-Position const WPs[58] =
-{
- {3691.97f, -3962.41f, 35.9118f, 3.67f},
- {3675.02f, -3960.49f, 35.9118f, 3.67f},
- {3653.19f, -3958.33f, 33.9118f, 3.59f},
- {3621.12f, -3958.51f, 29.9118f, 3.48f},
- {3604.86f, -3963, 29.9118f, 3.48f},
- {3569.94f, -3970.25f, 29.9118f, 3.44f},
- {3541.03f, -3975.64f, 29.9118f, 3.41f},
- {3510.84f, -3978.71f, 29.9118f, 3.41f},
- {3472.7f, -3997.07f, 29.9118f, 3.35f},
- {3439.15f, -4014.55f, 29.9118f, 3.29f},
- {3412.8f, -4025.87f, 29.9118f, 3.25f},
- {3384.95f, -4038.04f, 29.9118f, 3.24f},
- {3346.77f, -4052.93f, 29.9118f, 3.22f},
- {3299.56f, -4071.59f, 29.9118f, 3.20f},
- {3261.22f, -4080.38f, 30.9118f, 3.19f},
- {3220.68f, -4083.09f, 31.9118f, 3.18f},
- {3187.11f, -4070.45f, 33.9118f, 3.16f},
- {3162.78f, -4062.75f, 33.9118f, 3.15f},
- {3136.09f, -4050.32f, 33.9118f, 3.07f},
- {3119.47f, -4044.51f, 36.0363f, 3.07f},
- {3098.95f, -4019.8f, 33.9118f, 3.07f},
- {3073.07f, -4011.42f, 33.9118f, 3.07f},
- {3051.71f, -3993.37f, 33.9118f, 3.02f},
- {3027.52f, -3978.6f, 33.9118f, 3.00f},
- {3003.78f, -3960.14f, 33.9118f, 2.98f},
- {2977.99f, -3941.98f, 31.9118f, 2.96f},
- {2964.57f, -3932.07f, 30.9118f, 2.96f},
- {2947.9f, -3921.31f, 29.9118f, 2.96f},
- {2924.91f, -3910.8f, 29.9118f, 2.94f},
- {2903.04f, -3896.42f, 29.9118f, 2.93f},
- {2884.75f, -3874.03f, 29.9118f, 2.90f},
- {2868.19f, -3851.48f, 29.9118f, 2.82f},
- {2854.62f, -3819.72f, 29.9118f, 2.80f},
- {2825.53f, -3790.4f, 29.9118f, 2.744f},
- {2804.31f, -3773.05f, 29.9118f, 2.71f},
- {2769.78f, -3763.57f, 29.9118f, 2.70f},
- {2727.23f, -3745.92f, 30.9118f, 2.69f},
- {2680.12f, -3737.49f, 30.9118f, 2.67f},
- {2647.62f, -3739.94f, 30.9118f, 2.66f},
- {2616.6f, -3745.75f, 30.9118f, 2.64f},
- {2589.38f, -3731.97f, 30.9118f, 2.61f},
- {2562.94f, -3722.35f, 31.9118f, 2.56f},
- {2521.05f, -3716.6f, 31.9118f, 2.55f},
- {2485.26f, -3706.67f, 31.9118f, 2.51f},
- {2458.93f, -3696.67f, 31.9118f, 2.51f},
- {2432, -3692.03f, 31.9118f, 2.46f},
- {2399.59f, -3681.97f, 31.9118f, 2.45f},
- {2357.75f, -3666.6f, 31.9118f, 2.44f},
- {2311.99f, -3656.88f, 31.9118f, 2.94f},
- {2263.41f, -3649.55f, 31.9118f, 3.02f},
- {2209.05f, -3641.76f, 31.9118f, 2.99f},
- {2164.83f, -3637.64f, 31.9118f, 3.15f},
- {2122.42f, -3639, 31.9118f, 3.21f},
- {2075.73f, -3643.59f, 31.9118f, 3.22f},
- {2033.59f, -3649.52f, 31.9118f, 3.42f},
- {1985.22f, -3662.99f, 31.9118f, 3.42f},
- {1927.09f, -3679.56f, 33.9118f, 3.42f},
- {1873.57f, -3695.32f, 33.9118f, 3.44f}
-};
-
-class npc_rizzle_sprysprocket : public CreatureScript
-{
-public:
- npc_rizzle_sprysprocket() : CreatureScript("npc_rizzle_sprysprocket") { }
-
- struct npc_rizzle_sprysprocketAI : public ScriptedAI
- {
- npc_rizzle_sprysprocketAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- SpellEscapeTimer = 1300;
- TeleportTimer = 3500;
- CheckTimer = 10000;
- GrenadeTimer = 30000;
- MustDieTimer = 3000;
- CurrWP = 0;
-
- PlayerGUID = 0;
-
- MustDie = false;
- Escape = false;
- ContinueWP = false;
- Reached = false;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void AttackStart(Unit* who) OVERRIDE
- {
- if (!who || PlayerGUID)
- return;
-
- Player* player = who->ToPlayer();
-
- if (player && player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) == QUEST_STATUS_INCOMPLETE)
- {
- PlayerGUID = who->GetGUID();
- Talk(SAY_RIZZLE_START);
- DoCast(who, SPELL_RIZZLE_BLACKJACK, false);
- return;
- }
- }
-
- void sGossipSelect(Player* player, uint32 /*sender*/, uint32 /*action*/) OVERRIDE
- {
- player->CLOSE_GOSSIP_MENU();
- me->CastSpell(player, SPELL_GIVE_SOUTHFURY_MOONSTONE, true);
- MustDieTimer = 3000;
- MustDie = true;
- }
-
- void MovementInform(uint32 type, uint32 id) OVERRIDE
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (id == 57)
- {
- me->DespawnOrUnsummon();
- return;
- }
-
- ++CurrWP;
- ContinueWP = true;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (MustDie)
- {
- if (MustDieTimer <= diff)
- {
- me->DespawnOrUnsummon();
- return;
- } else MustDieTimer -= diff;
- }
-
- if (!Escape)
- {
- if (!PlayerGUID)
- return;
-
- if (SpellEscapeTimer <= diff)
- {
- DoCast(me, SPELL_RIZZLE_ESCAPE, false);
- SpellEscapeTimer = 10000;
- } else SpellEscapeTimer -= diff;
-
- if (TeleportTimer <= diff)
- {
- // temp solution - unit can't be teleported by core using spelleffect 5, only players
- DoTeleportTo(3706.39f, -3969.15f, 35.9118f);
-
- //begin swimming and summon depth charges
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (!player)
- return;
-
- Talk(MSG_ESCAPE_NOTICE, player);
- DoCast(me, SPELL_PERIODIC_DEPTH_CHARGE);
- me->SetHover(true);
- me->SetSwim(true);
- me->SetSpeed(MOVE_RUN, 0.85f, true);
- me->GetMotionMaster()->MovementExpired();
- me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]);
- Escape = true;
- } else TeleportTimer -= diff;
-
- return;
- }
-
- if (ContinueWP)
- {
- me->GetMotionMaster()->MovePoint(CurrWP, WPs[CurrWP]);
- ContinueWP = false;
- }
-
- if (GrenadeTimer <= diff)
- {
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- {
- Talk(SAY_RIZZLE_GRENADE, player);
- DoCast(player, SPELL_RIZZLE_FROST_GRENADE, true);
- }
- GrenadeTimer = 30000;
- } else GrenadeTimer -= diff;
-
- if (CheckTimer <= diff)
- {
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (!player)
- {
- me->DespawnOrUnsummon();
- return;
- }
-
- if (me->IsWithinDist(player, 10) && me->GetPositionX() > player->GetPositionX() && !Reached)
- {
- Talk(SAY_RIZZLE_FINAL);
- me->SetUInt32Value(UNIT_NPC_FLAGS, 1);
- me->setFaction(35);
- me->GetMotionMaster()->MoveIdle();
- me->RemoveAurasDueToSpell(SPELL_PERIODIC_DEPTH_CHARGE);
- Reached = true;
- }
-
- CheckTimer = 1000;
- } else CheckTimer -= diff;
- }
-
- private:
- uint64 PlayerGUID;
- uint32 SpellEscapeTimer;
- uint32 TeleportTimer;
- uint32 CheckTimer;
- uint32 GrenadeTimer;
- uint32 MustDieTimer;
- uint32 CurrWP;
- bool MustDie;
- bool Escape;
- bool ContinueWP;
- bool Reached;
- };
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_CHASING_THE_MOONSTONE) != QUEST_STATUS_INCOMPLETE)
- return true;
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_GET_MOONSTONE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(10811, creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_rizzle_sprysprocketAI(creature);
- }
-};
-
-/*####
-# npc_depth_charge
-####*/
-class npc_depth_charge : public CreatureScript
-{
-public:
- npc_depth_charge() : CreatureScript("npc_depth_charge") { }
-
- struct npc_depth_chargeAI : public ScriptedAI
- {
- npc_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { }
-
- bool WeMustDie;
- uint32 WeMustDieTimer;
-
- void Reset() OVERRIDE
- {
- me->SetHover(true);
- me->SetSwim(true);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- WeMustDie = false;
- WeMustDieTimer = 1000;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void AttackStart(Unit* /*who*/) OVERRIDE { }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
- {
- if (!who)
- return;
-
- if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 5))
- {
- DoCast(who, SPELL_DEPTH_CHARGE_TRAP);
- WeMustDie = true;
- return;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (WeMustDie)
- {
- if (WeMustDieTimer <= diff)
- me->DespawnOrUnsummon();
- else
- WeMustDieTimer -= diff;
- }
- return;
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_depth_chargeAI(creature);
- }
-};
-
void AddSC_azshara()
{
- new npc_spitelashes();
- new npc_loramus_thalipedes();
- new npc_rizzle_sprysprocket();
- new npc_depth_charge();
}
diff --git a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
index 38bc321d2af..57043699c13 100644
--- a/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
+++ b/src/server/scripts/Kalimdor/zone_azuremyst_isle.cpp
@@ -19,7 +19,7 @@
/* ScriptData
SDName: Azuremyst_Isle
SD%Complete: 75
-SDComment: Quest support: 9283, 9537, 9582, 9554, 9531, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582.
+SDComment: Quest support: 9283, 9537, 9582, 9554, ? (special flight path, proper model for mount missing). Injured Draenei cosmetic only, 9582.
SDCategory: Azuremyst Isle
EndScriptData */
@@ -28,7 +28,6 @@ npc_draenei_survivor
npc_engineer_spark_overgrind
npc_injured_draenei
npc_magwin
-npc_geezle
go_ravager_cage
npc_death_ravager
EndContentData */
@@ -736,7 +735,6 @@ void AddSC_azuremyst_isle()
new npc_engineer_spark_overgrind();
new npc_injured_draenei();
new npc_magwin();
- new npc_geezle();
new npc_death_ravager();
new go_ravager_cage();
new npc_stillpine_capitive();
diff --git a/src/server/scripts/Kalimdor/zone_darkshore.cpp b/src/server/scripts/Kalimdor/zone_darkshore.cpp
index ae98fbc4072..e49ee99fdfa 100644
--- a/src/server/scripts/Kalimdor/zone_darkshore.cpp
+++ b/src/server/scripts/Kalimdor/zone_darkshore.cpp
@@ -16,378 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Darkshore
-SD%Complete: 100
-SDComment: Quest support: 731, 2078, 5321
-SDCategory: Darkshore
-EndScriptData */
-
-/* ContentData
-npc_kerlonian
-npc_prospector_remtravel
-npc_threshwackonator
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "ScriptedEscortAI.h"
-#include "ScriptedFollowerAI.h"
-#include "Player.h"
-#include "SpellInfo.h"
-
-/*####
-# npc_kerlonian
-####*/
-
-enum Kerlonian
-{
- SAY_KER_START = 0,
- EMOTE_KER_SLEEP = 1,
- SAY_KER_SLEEP = 2,
- SAY_KER_ALERT_1 = 3,
- SAY_KER_END = 4,
- EMOTE_KER_AWAKEN = 5,
-
- SPELL_SLEEP_VISUAL = 25148,
- SPELL_AWAKEN = 17536,
- QUEST_SLEEPER_AWAKENED = 5321,
- NPC_LILADRIS = 11219, //attackers entries unknown
- FACTION_KER_ESCORTEE = 113
-};
-
-/// @todo make concept similar as "ringo" -escort. Find a way to run the scripted attacks, _if_ player are choosing road.
-class npc_kerlonian : public CreatureScript
-{
-public:
- npc_kerlonian() : CreatureScript("npc_kerlonian") { }
-
- struct npc_kerlonianAI : public FollowerAI
- {
- npc_kerlonianAI(Creature* creature) : FollowerAI(creature) { }
-
- uint32 FallAsleepTimer;
-
- void Reset() OVERRIDE
- {
- FallAsleepTimer = urand(10000, 45000);
- }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
- {
- FollowerAI::MoveInLineOfSight(who);
-
- if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_LILADRIS)
- {
- if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE*5))
- {
- if (Player* player = GetLeaderForFollower())
- {
- if (player->GetQuestStatus(QUEST_SLEEPER_AWAKENED) == QUEST_STATUS_INCOMPLETE)
- player->GroupEventHappens(QUEST_SLEEPER_AWAKENED, me);
-
- Talk(SAY_KER_END);
- }
-
- SetFollowComplete();
- }
- }
- }
-
- void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) OVERRIDE
- {
- if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_AWAKEN)
- ClearSleeping();
- }
-
- void SetSleeping()
- {
- SetFollowPaused(true);
-
- Talk(EMOTE_KER_SLEEP);
-
- Talk(SAY_KER_SLEEP);
-
- me->SetStandState(UNIT_STAND_STATE_SLEEP);
- DoCast(me, SPELL_SLEEP_VISUAL, false);
- }
-
- void ClearSleeping()
- {
- me->RemoveAurasDueToSpell(SPELL_SLEEP_VISUAL);
- me->SetStandState(UNIT_STAND_STATE_STAND);
-
- Talk(EMOTE_KER_AWAKEN);
-
- SetFollowPaused(false);
- }
-
- void UpdateFollowerAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- {
- if (!HasFollowState(STATE_FOLLOW_INPROGRESS))
- return;
-
- if (!HasFollowState(STATE_FOLLOW_PAUSED))
- {
- if (FallAsleepTimer <= diff)
- {
- SetSleeping();
- FallAsleepTimer = urand(25000, 90000);
- }
- else
- FallAsleepTimer -= diff;
- }
-
- return;
- }
-
- DoMeleeAttackIfReady();
- }
- };
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_SLEEPER_AWAKENED)
- {
- if (npc_kerlonianAI* pKerlonianAI = CAST_AI(npc_kerlonian::npc_kerlonianAI, creature->AI()))
- {
- creature->SetStandState(UNIT_STAND_STATE_STAND);
- creature->AI()->Talk(SAY_KER_START, player);
- pKerlonianAI->StartFollow(player, FACTION_KER_ESCORTEE, quest);
- }
- }
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_kerlonianAI(creature);
- }
-};
-
-/*####
-# npc_prospector_remtravel
-####*/
-
-enum Remtravel
-{
- SAY_REM_START = 0,
- SAY_REM_AGGRO = 1,
- SAY_REM_RAMP1_1 = 2,
- SAY_REM_RAMP1_2 = 3,
- SAY_REM_BOOK = 4,
- SAY_REM_TENT1_1 = 5,
- SAY_REM_TENT1_2 = 6,
- SAY_REM_MOSS = 7,
- EMOTE_REM_MOSS = 8,
- SAY_REM_MOSS_PROGRESS = 9,
- SAY_REM_PROGRESS = 10,
- SAY_REM_REMEMBER = 11,
- EMOTE_REM_END = 12,
-
- FACTION_ESCORTEE = 10,
- QUEST_ABSENT_MINDED_PT2 = 731,
- NPC_GRAVEL_SCOUT = 2158,
- NPC_GRAVEL_BONE = 2159,
- NPC_GRAVEL_GEO = 2160
-};
-
-class npc_prospector_remtravel : public CreatureScript
-{
-public:
- npc_prospector_remtravel() : CreatureScript("npc_prospector_remtravel") { }
-
- struct npc_prospector_remtravelAI : public npc_escortAI
- {
- npc_prospector_remtravelAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* who) OVERRIDE
- {
- if (urand(0, 1))
- Talk(SAY_REM_AGGRO, who);
- }
-
- void JustSummoned(Creature* /*pSummoned*/) OVERRIDE
- {
- //unsure if it should be any
- //pSummoned->AI()->AttackStart(me);
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- if (Player* player = GetPlayerForEscort())
- {
- switch (waypointId)
- {
- case 0:
- Talk(SAY_REM_START, player);
- break;
- case 5:
- Talk(SAY_REM_RAMP1_1, player);
- break;
- case 6:
- DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- break;
- case 9:
- Talk(SAY_REM_RAMP1_2, player);
- break;
- case 14:
- //depend quest rewarded?
- Talk(SAY_REM_BOOK, player);
- break;
- case 15:
- Talk(SAY_REM_TENT1_1, player);
- break;
- case 16:
- DoSpawnCreature(NPC_GRAVEL_SCOUT, -10.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- DoSpawnCreature(NPC_GRAVEL_BONE, -10.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- break;
- case 17:
- Talk(SAY_REM_TENT1_2, player);
- break;
- case 26:
- Talk(SAY_REM_MOSS, player);
- break;
- case 27:
- Talk(EMOTE_REM_MOSS, player);
- break;
- case 28:
- Talk(SAY_REM_MOSS_PROGRESS, player);
- break;
- case 29:
- DoSpawnCreature(NPC_GRAVEL_SCOUT, -15.0f, 3.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- DoSpawnCreature(NPC_GRAVEL_BONE, -15.0f, 5.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- DoSpawnCreature(NPC_GRAVEL_GEO, -15.0f, 7.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- break;
- case 31:
- Talk(SAY_REM_PROGRESS, player);
- break;
- case 41:
- Talk(SAY_REM_REMEMBER, player);
- break;
- case 42:
- Talk(EMOTE_REM_END, player);
- player->GroupEventHappens(QUEST_ABSENT_MINDED_PT2, me);
- break;
- }
- }
- }
- };
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_ABSENT_MINDED_PT2)
- {
- if (npc_escortAI* pEscortAI = CAST_AI(npc_prospector_remtravel::npc_prospector_remtravelAI, creature->AI()))
- pEscortAI->Start(false, false, player->GetGUID());
-
- creature->setFaction(FACTION_ESCORTEE);
- }
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_prospector_remtravelAI(creature);
- }
-};
-
-/*####
-# npc_threshwackonator
-####*/
-
-enum Threshwackonator
-{
- EMOTE_START = 0,
- SAY_AT_CLOSE = 1,
- QUEST_GYROMAST_REV = 2078,
- NPC_GELKAK = 6667,
- FACTION_HOSTILE = 14
-};
-
-#define GOSSIP_ITEM_INSERT_KEY "[PH] Insert key"
-
-class npc_threshwackonator : public CreatureScript
-{
-public:
- npc_threshwackonator() : CreatureScript("npc_threshwackonator") { }
-
- struct npc_threshwackonatorAI : public FollowerAI
- {
- npc_threshwackonatorAI(Creature* creature) : FollowerAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
- {
- FollowerAI::MoveInLineOfSight(who);
-
- if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_GELKAK)
- {
- if (me->IsWithinDistInMap(who, 10.0f))
- {
- Talk(SAY_AT_CLOSE, who);
- DoAtEnd();
- }
- }
- }
-
- void DoAtEnd()
- {
- me->setFaction(FACTION_HOSTILE);
-
- if (Player* pHolder = GetLeaderForFollower())
- me->AI()->AttackStart(pHolder);
-
- SetFollowComplete();
- }
- };
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
-
- if (npc_threshwackonatorAI* pThreshAI = CAST_AI(npc_threshwackonator::npc_threshwackonatorAI, creature->AI()))
- {
- creature->AI()->Talk(EMOTE_START);
- pThreshAI->StartFollow(player);
- }
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_GYROMAST_REV) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_INSERT_KEY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_threshwackonatorAI(creature);
- }
-};
-
void AddSC_darkshore()
{
- new npc_kerlonian();
- new npc_prospector_remtravel();
- new npc_threshwackonator();
}
diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp
index 58322963c6e..106362cd677 100644
--- a/src/server/scripts/Kalimdor/zone_desolace.cpp
+++ b/src/server/scripts/Kalimdor/zone_desolace.cpp
@@ -19,14 +19,12 @@
/* ScriptData
SDName: Desolace
SD%Complete: 100
-SDComment: Quest support: 5561
+SDComment: Quest support: 5561, 5581
SDCategory: Desolace
EndScriptData */
/* ContentData
npc_aged_dying_ancient_kodo
-go_iruxos
-npc_dalinda_malem
go_demon_portal
EndContentData */
@@ -65,8 +63,7 @@ public:
{
npc_aged_dying_ancient_kodoAI(Creature* creature) : ScriptedAI(creature) { }
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
+ void MoveInLineOfSight(Unit* who)
{
if (who->GetEntry() == NPC_SMEED && me->IsWithinDistInMap(who, 10.0f) && !me->HasAura(SPELL_KODO_KOMBO_GOSSIP))
{
@@ -77,7 +74,7 @@ public:
}
}
- void SpellHit(Unit* caster, SpellInfo const* spell) OVERRIDE
+ void SpellHit(Unit* caster, SpellInfo const* spell)
{
if (spell->Id == SPELL_KODO_KOMBO_ITEM)
{
@@ -119,106 +116,6 @@ public:
};
/*######
-## go_iruxos
-## Hand of Iruxos
-######*/
-
-enum Iruxos
-{
- QUEST_HAND_IRUXOS = 5381,
- NPC_DEMON_SPIRIT = 11876
-};
-
-class go_iruxos : public GameObjectScript
-{
- public:
- go_iruxos() : GameObjectScript("go_iruxos") { }
-
- bool OnGossipHello(Player* player, GameObject* go) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_HAND_IRUXOS) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_SPIRIT, 25.0f, true))
- player->SummonCreature(NPC_DEMON_SPIRIT, go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
-
- return true;
- }
-};
-
-/*######
-## npc_dalinda_malem. Quest 1440
-######*/
-
-enum Dalinda
-{
- QUEST_RETURN_TO_VAHLARRIEL = 1440
-};
-
-class npc_dalinda : public CreatureScript
-{
-public:
- npc_dalinda() : CreatureScript("npc_dalinda") { }
-
- struct npc_dalindaAI : public npc_escortAI
- {
- npc_dalindaAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (Player* player = GetPlayerForEscort())
- player->FailQuest(QUEST_RETURN_TO_VAHLARRIEL);
- return;
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- Player* player = GetPlayerForEscort();
-
- switch (waypointId)
- {
- case 1:
- me->SetStandState(UNIT_STAND_STATE_STAND);
- break;
- case 15:
- if (player)
- player->GroupEventHappens(QUEST_RETURN_TO_VAHLARRIEL, me);
- break;
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- npc_escortAI::UpdateAI(diff);
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_RETURN_TO_VAHLARRIEL)
- {
- if (npc_escortAI* escortAI = CAST_AI(npc_dalinda::npc_dalindaAI, creature->AI()))
- {
- escortAI->Start(true, false, player->GetGUID());
- creature->setFaction(113);
- }
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_dalindaAI(creature);
- }
-};
-
-/*######
## go_demon_portal
######*/
@@ -233,7 +130,7 @@ class go_demon_portal : public GameObjectScript
public:
go_demon_portal() : GameObjectScript("go_demon_portal") { }
- bool OnGossipHello(Player* player, GameObject* go) OVERRIDE
+ bool OnGossipHello(Player* player, GameObject* go)
{
if (player->GetQuestStatus(QUEST_PORTAL_OF_THE_LEGION) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(NPC_DEMON_GUARDIAN, 5.0f, true))
{
@@ -248,7 +145,5 @@ class go_demon_portal : public GameObjectScript
void AddSC_desolace()
{
new npc_aged_dying_ancient_kodo();
- new go_iruxos();
- new npc_dalinda();
new go_demon_portal();
}
diff --git a/src/server/scripts/Kalimdor/zone_durotar.cpp b/src/server/scripts/Kalimdor/zone_durotar.cpp
index 08f4f2ebfdf..e587c98445b 100644
--- a/src/server/scripts/Kalimdor/zone_durotar.cpp
+++ b/src/server/scripts/Kalimdor/zone_durotar.cpp
@@ -17,13 +17,12 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "Vehicle.h"
#include "SpellScript.h"
#include "Player.h"
/*######
-##Quest 5441: Lazy Peons
-##npc_lazy_peon
+## Quest 25134: Lazy Peons
+## npc_lazy_peon
######*/
enum LazyPeonYells
@@ -33,10 +32,10 @@ enum LazyPeonYells
enum LazyPeon
{
- QUEST_LAZY_PEONS = 5441,
- GO_LUMBERPILE = 175784,
- SPELL_BUFF_SLEEP = 17743,
- SPELL_AWAKEN_PEON = 19938
+ QUEST_LAZY_PEONS = 25134,
+ GO_LUMBERPILE = 175784,
+ SPELL_BUFF_SLEEP = 17743,
+ SPELL_AWAKEN_PEON = 19938
};
class npc_lazy_peon : public CreatureScript
@@ -65,13 +64,13 @@ public:
work = false;
}
- void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
+ void MovementInform(uint32 /*type*/, uint32 id)
{
if (id == 1)
work = true;
}
- void SpellHit(Unit* caster, const SpellInfo* spell) OVERRIDE
+ void SpellHit(Unit* caster, const SpellInfo* spell)
{
if (spell->Id != SPELL_AWAKEN_PEON)
return;
@@ -94,7 +93,7 @@ public:
if (RebuffTimer <= diff)
{
DoCast(me, SPELL_BUFF_SLEEP);
- RebuffTimer = 300000; //Rebuff agian in 5 minutes
+ RebuffTimer = 300000; //Rebuff agian in 5 minutes
}
else
RebuffTimer -= diff;
@@ -105,434 +104,6 @@ public:
};
};
-enum Texts
-{
- // Tiger Matriarch Credit
- SAY_MATRIARCH_AGGRO = 0,
-
- // Troll Volunteer
- SAY_VOLUNTEER_START = 0,
- SAY_VOLUNTEER_END = 1,
-};
-
-enum Spells
-{
- // Tiger Matriarch Credit
- SPELL_SUMMON_MATRIARCH = 75187,
- SPELL_NO_SUMMON_AURA = 75213,
- SPELL_DETECT_INVIS = 75180,
- SPELL_SUMMON_ZENTABRA_TRIGGER = 75212,
-
- // Tiger Matriarch
- SPELL_POUNCE = 61184,
- SPELL_FURIOUS_BITE = 75164,
- SPELL_SUMMON_ZENTABRA = 75181,
- SPELL_SPIRIT_OF_THE_TIGER_RIDER = 75166,
- SPELL_EJECT_PASSENGERS = 50630,
-
- // Troll Volunteer
- SPELL_VOLUNTEER_AURA = 75076,
- SPELL_PETACT_AURA = 74071,
- SPELL_QUEST_CREDIT = 75106,
- SPELL_MOUNTING_CHECK = 75420,
- SPELL_TURNIN = 73953,
- SPELL_AOE_TURNIN = 75107,
-
- // Vol'jin War Drums
- SPELL_MOTIVATE_1 = 75088,
- SPELL_MOTIVATE_2 = 75086,
-};
-
-enum Creatures
-{
- // Tiger Matriarch Credit
- NPC_TIGER_VEHICLE = 40305,
-
- // Troll Volunteer
- NPC_URUZIN = 40253,
- NPC_VOLUNTEER_1 = 40264,
- NPC_VOLUNTEER_2 = 40260,
-
- // Vol'jin War Drums
- NPC_CITIZEN_1 = 40256,
- NPC_CITIZEN_2 = 40257,
-};
-
-enum Events
-{
- // Tiger Matriarch Credit
- EVENT_CHECK_SUMMON_AURA = 1,
-
- // Tiger Matriarch
- EVENT_POUNCE = 2,
- EVENT_NOSUMMON = 3,
-};
-
-enum Points
-{
- POINT_URUZIN = 4026400,
-};
-
-class npc_tiger_matriarch_credit : public CreatureScript
-{
- public:
- npc_tiger_matriarch_credit() : CreatureScript("npc_tiger_matriarch_credit") { }
-
- struct npc_tiger_matriarch_creditAI : public ScriptedAI
- {
- npc_tiger_matriarch_creditAI(Creature* creature) : ScriptedAI(creature)
- {
- SetCombatMovement(false);
- events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 2000);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- events.Update(diff);
-
- if (events.ExecuteEvent() == EVENT_CHECK_SUMMON_AURA)
- {
- std::list<Creature*> tigers;
- GetCreatureListWithEntryInGrid(tigers, me, NPC_TIGER_VEHICLE, 15.0f);
- if (!tigers.empty())
- {
- for (std::list<Creature*>::iterator itr = tigers.begin(); itr != tigers.end(); ++itr)
- {
- if (!(*itr)->IsSummon())
- continue;
-
- if (Unit* summoner = (*itr)->ToTempSummon()->GetSummoner())
- if (!summoner->HasAura(SPELL_NO_SUMMON_AURA) && !summoner->HasAura(SPELL_SUMMON_ZENTABRA_TRIGGER)
- && !summoner->IsInCombat())
- {
- me->AddAura(SPELL_NO_SUMMON_AURA, summoner);
- me->AddAura(SPELL_DETECT_INVIS, summoner);
- summoner->CastSpell(summoner, SPELL_SUMMON_MATRIARCH, true);
- Talk(SAY_MATRIARCH_AGGRO, summoner);
- }
- }
- }
-
- events.ScheduleEvent(EVENT_CHECK_SUMMON_AURA, 5000);
- }
- }
-
- private:
- EventMap events;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_tiger_matriarch_creditAI(creature);
- }
-};
-
-class npc_tiger_matriarch : public CreatureScript
-{
- public:
- npc_tiger_matriarch() : CreatureScript("npc_tiger_matriarch") { }
-
- struct npc_tiger_matriarchAI : public ScriptedAI
- {
- npc_tiger_matriarchAI(Creature* creature) : ScriptedAI(creature),
- _tigerGuid(0)
- {
- }
-
- void EnterCombat(Unit* /*target*/) OVERRIDE
- {
- _events.Reset();
- _events.ScheduleEvent(EVENT_POUNCE, 100);
- _events.ScheduleEvent(EVENT_NOSUMMON, 50000);
- }
-
- void IsSummonedBy(Unit* summoner) OVERRIDE
- {
- if (summoner->GetTypeId() != TYPEID_PLAYER || !summoner->GetVehicle())
- return;
-
- _tigerGuid = summoner->GetVehicle()->GetBase()->GetGUID();
- if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid))
- {
- me->AddThreat(tiger, 500000.0f);
- DoCast(me, SPELL_FURIOUS_BITE);
- }
- }
-
- void KilledUnit(Unit* victim) OVERRIDE
- {
- if (victim->GetTypeId() != TYPEID_UNIT || !victim->IsSummon())
- return;
-
- if (Unit* vehSummoner = victim->ToTempSummon()->GetSummoner())
- {
- vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA);
- vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS);
- vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER);
- vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER);
- }
- me->DespawnOrUnsummon();
- }
-
- void DamageTaken(Unit* attacker, uint32& damage) OVERRIDE
- {
- if (!attacker->IsSummon())
- return;
-
- if (HealthBelowPct(20))
- {
- damage = 0;
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- if (Unit* vehSummoner = attacker->ToTempSummon()->GetSummoner())
- {
- vehSummoner->AddAura(SPELL_SUMMON_ZENTABRA_TRIGGER, vehSummoner);
- vehSummoner->CastSpell(vehSummoner, SPELL_SUMMON_ZENTABRA, true);
- attacker->CastSpell(attacker, SPELL_EJECT_PASSENGERS, true);
- vehSummoner->RemoveAurasDueToSpell(SPELL_NO_SUMMON_AURA);
- vehSummoner->RemoveAurasDueToSpell(SPELL_DETECT_INVIS);
- vehSummoner->RemoveAurasDueToSpell(SPELL_SPIRIT_OF_THE_TIGER_RIDER);
- vehSummoner->RemoveAurasDueToSpell(SPELL_SUMMON_ZENTABRA_TRIGGER);
- }
-
- me->DespawnOrUnsummon();
- }
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (!_tigerGuid)
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_POUNCE:
- DoCastVictim(SPELL_POUNCE);
- _events.ScheduleEvent(EVENT_POUNCE, 30000);
- break;
- case EVENT_NOSUMMON: // Reapply SPELL_NO_SUMMON_AURA
- if (Unit* tiger = ObjectAccessor::GetUnit(*me, _tigerGuid))
- {
- if (tiger->IsSummon())
- if (Unit* vehSummoner = tiger->ToTempSummon()->GetSummoner())
- me->AddAura(SPELL_NO_SUMMON_AURA, vehSummoner);
- }
- _events.ScheduleEvent(EVENT_NOSUMMON, 50000);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- uint64 _tigerGuid;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_tiger_matriarchAI(creature);
- }
-};
-
-// These models was found in sniff.
-/// @todo generalize these models with race from dbc
-uint32 const trollmodel[] =
-{11665, 11734, 11750, 12037, 12038, 12042, 12049, 12849, 13529, 14759, 15570, 15701,
-15702, 1882, 1897, 1976, 2025, 27286, 2734, 2735, 4084, 4085, 4087, 4089, 4231, 4357,
-4358, 4360, 4361, 4362, 4363, 4370, 4532, 4537, 4540, 4610, 6839, 7037, 9767, 9768};
-
-class npc_troll_volunteer : public CreatureScript
-{
- public:
- npc_troll_volunteer() : CreatureScript("npc_troll_volunteer") { }
-
- struct npc_troll_volunteerAI : public ScriptedAI
- {
- npc_troll_volunteerAI(Creature* creature) : ScriptedAI(creature)
- {
- }
-
- void InitializeAI() OVERRIDE
- {
- if (me->isDead() || !me->GetOwner())
- return;
-
- Reset();
-
- switch (urand(0, 3))
- {
- case 0:
- _mountModel = 6471;
- break;
- case 1:
- _mountModel = 6473;
- break;
- case 2:
- _mountModel = 6469;
- break;
- default:
- _mountModel = 6472;
- break;
- }
- me->SetDisplayId(trollmodel[urand(0, 39)]);
- if (Player* player = me->GetOwner()->ToPlayer())
- me->GetMotionMaster()->MoveFollow(player, 5.0f, float(rand_norm() + 1.0f) * M_PI / 3.0f * 4.0f);
- }
-
- void Reset() OVERRIDE
- {
- _complete = false;
- me->AddAura(SPELL_VOLUNTEER_AURA, me);
- me->AddAura(SPELL_MOUNTING_CHECK, me);
- DoCast(me, SPELL_PETACT_AURA);
- me->SetReactState(REACT_PASSIVE);
- Talk(SAY_VOLUNTEER_START);
- }
-
- // This is needed for mount check aura to know what mountmodel the npc got stored
- uint32 GetMountId()
- {
- return _mountModel;
- }
-
- void MovementInform(uint32 type, uint32 id) OVERRIDE
- {
- if (type != POINT_MOTION_TYPE)
- return;
- if (id == POINT_URUZIN)
- me->DespawnOrUnsummon();
- }
-
- void SpellHit(Unit* caster, SpellInfo const* spell) OVERRIDE
- {
- if (spell->Id == SPELL_AOE_TURNIN && caster->GetEntry() == NPC_URUZIN && !_complete)
- {
- _complete = true; // Preventing from giving credit twice
- DoCast(me, SPELL_TURNIN);
- DoCast(me, SPELL_QUEST_CREDIT);
- me->RemoveAurasDueToSpell(SPELL_MOUNTING_CHECK);
- me->Dismount();
- Talk(SAY_VOLUNTEER_END);
- me->GetMotionMaster()->MovePoint(POINT_URUZIN, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
- }
- }
-
- private:
- uint32 _mountModel;
- bool _complete;
- };
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_troll_volunteerAI(creature);
- }
-};
-
-typedef npc_troll_volunteer::npc_troll_volunteerAI VolunteerAI;
-
-class spell_mount_check : public SpellScriptLoader
-{
- public:
- spell_mount_check() : SpellScriptLoader("spell_mount_check") { }
-
- class spell_mount_check_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_mount_check_AuraScript)
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTING_CHECK))
- return false;
- return true;
- }
-
- void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
- {
- Unit* target = GetTarget();
- Unit* owner = target->GetOwner();
-
- if (!owner)
- return;
-
- if (owner->IsMounted() && !target->IsMounted())
- {
- if (VolunteerAI* volunteerAI = CAST_AI(VolunteerAI, target->GetAI()))
- target->Mount(volunteerAI->GetMountId());
- }
- else if (!owner->IsMounted() && target->IsMounted())
- target->Dismount();
-
- target->SetSpeed(MOVE_RUN, owner->GetSpeedRate(MOVE_RUN));
- target->SetSpeed(MOVE_WALK, owner->GetSpeedRate(MOVE_WALK));
- }
-
- void Register() OVERRIDE
- {
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_mount_check_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_mount_check_AuraScript();
- }
-};
-
-class spell_voljin_war_drums : public SpellScriptLoader
-{
- public:
- spell_voljin_war_drums() : SpellScriptLoader("spell_voljin_war_drums") { }
-
- class spell_voljin_war_drums_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_voljin_war_drums_SpellScript)
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_1))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_MOTIVATE_2))
- return false;
- return true;
- }
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- Unit* caster = GetCaster();
- if (Unit* target = GetHitUnit())
- {
- uint32 motivate = 0;
- if (target->GetEntry() == NPC_CITIZEN_1)
- motivate = SPELL_MOTIVATE_1;
- else if (target->GetEntry() == NPC_CITIZEN_2)
- motivate = SPELL_MOTIVATE_2;
- if (motivate)
- caster->CastSpell(target, motivate, false);
- }
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_voljin_war_drums_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_voljin_war_drums_SpellScript();
- }
-};
-
enum VoodooSpells
{
SPELL_BREW = 16712, // Special Brew
@@ -552,7 +123,7 @@ class spell_voodoo : public SpellScriptLoader
class spell_voodoo_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_voodoo_SpellScript)
+ PrepareSpellScript(spell_voodoo_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
@@ -586,10 +157,5 @@ class spell_voodoo : public SpellScriptLoader
void AddSC_durotar()
{
new npc_lazy_peon();
- new npc_tiger_matriarch_credit();
- new npc_tiger_matriarch();
- new npc_troll_volunteer();
- new spell_mount_check();
- new spell_voljin_war_drums();
new spell_voodoo();
}
diff --git a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
index 6030ce9f8fc..8894a1378f9 100644
--- a/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/zone_dustwallow_marsh.cpp
@@ -19,16 +19,13 @@
/* ScriptData
SDName: Dustwallow_Marsh
SD%Complete: 95
-SDComment: Quest support: 11180, 558, 11126, 11142, 11174, Vendor Nat Pagle
+SDComment: Quest support: 1270, 1222, 27245
SDCategory: Dustwallow Marsh
EndScriptData */
/* ContentData
-npc_risen_husk_spirit
-npc_lady_jaina_proudmoore
-npc_nat_pagle
-npc_private_hendel
-npc_cassa_crimsonwing - handled by npc_taxi
+npc_stinky
+go_blackhoof_cage
EndContentData */
#include "ScriptMgr.h"
@@ -766,13 +763,7 @@ public:
void AddSC_dustwallow_marsh()
{
- new npc_risen_husk_spirit();
- new npc_lady_jaina_proudmoore();
- new npc_nat_pagle();
- new npc_private_hendel();
- new npc_zelfrax();
new npc_stinky();
- new npc_theramore_guard();
new spell_ooze_zap();
new spell_ooze_zap_channel_end();
new spell_energize_aoe();
diff --git a/src/server/scripts/Kalimdor/zone_felwood.cpp b/src/server/scripts/Kalimdor/zone_felwood.cpp
index 2d322a7c079..9383a05f655 100644
--- a/src/server/scripts/Kalimdor/zone_felwood.cpp
+++ b/src/server/scripts/Kalimdor/zone_felwood.cpp
@@ -19,12 +19,11 @@
/* ScriptData
SDName: Felwood
SD%Complete: 95
-SDComment: Quest support: 4101, 4102
+SDComment: Quest support:
SDCategory: Felwood
EndScriptData */
/* ContentData
-npcs_riverbreeze_and_silversky
EndContentData */
#include "ScriptMgr.h"
@@ -32,75 +31,6 @@ EndContentData */
#include "ScriptedGossip.h"
#include "Player.h"
-/*######
-## npcs_riverbreeze_and_silversky
-######*/
-
-#define GOSSIP_ITEM_BEACON "Please make me a Cenarion Beacon"
-
-enum RiverbreezeAndSilversky
-{
- SPELL_CENARION_BEACON = 15120,
-
- NPC_ARATHANDRIS_SILVERSKY = 9528,
- NPC_MAYBESS_RIVERBREEZE = 9529,
-
- QUEST_CLEASING_FELWOOD_A = 4101,
- QUEST_CLEASING_FELWOOD_H = 4102
-};
-
-class npcs_riverbreeze_and_silversky : public CreatureScript
-{
-public:
- npcs_riverbreeze_and_silversky() : CreatureScript("npcs_riverbreeze_and_silversky") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, SPELL_CENARION_BEACON, false);
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- uint32 creatureId = creature->GetEntry();
-
- if (creatureId == NPC_ARATHANDRIS_SILVERSKY)
- {
- if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_A))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(2848, creature->GetGUID());
- } else if (player->GetTeam() == HORDE)
- player->SEND_GOSSIP_MENU(2845, creature->GetGUID());
- else
- player->SEND_GOSSIP_MENU(2844, creature->GetGUID());
- }
-
- if (creatureId == NPC_MAYBESS_RIVERBREEZE)
- {
- if (player->GetQuestRewardStatus(QUEST_CLEASING_FELWOOD_H))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEACON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(2849, creature->GetGUID());
- } else if (player->GetTeam() == ALLIANCE)
- player->SEND_GOSSIP_MENU(2843, creature->GetGUID());
- else
- player->SEND_GOSSIP_MENU(2842, creature->GetGUID());
- }
-
- return true;
- }
-};
-
void AddSC_felwood()
{
- new npcs_riverbreeze_and_silversky();
}
diff --git a/src/server/scripts/Kalimdor/zone_feralas.cpp b/src/server/scripts/Kalimdor/zone_feralas.cpp
index 11e95f325c2..2186752b135 100644
--- a/src/server/scripts/Kalimdor/zone_feralas.cpp
+++ b/src/server/scripts/Kalimdor/zone_feralas.cpp
@@ -16,237 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Feralas
-SD%Complete: 100
-SDComment: Quest support: 3520, 2767, Special vendor Gregan Brewspewer
-SDCategory: Feralas
-EndScriptData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedEscortAI.h"
-#include "ScriptedGossip.h"
-#include "SpellScript.h"
-#include "Player.h"
-#include "WorldSession.h"
-
-/*######
-## npc_gregan_brewspewer
-######*/
-
-#define GOSSIP_HELLO "Buy somethin', will ya?"
-
-class npc_gregan_brewspewer : public CreatureScript
-{
-public:
- npc_gregan_brewspewer() : CreatureScript("npc_gregan_brewspewer") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
- player->SEND_GOSSIP_MENU(2434, creature->GetGUID());
- }
- if (action == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (creature->IsVendor() && player->GetQuestStatus(3909) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HELLO, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(2433, creature->GetGUID());
- return true;
- }
-
-};
-
-/*######
-## npc_oox22fe
-######*/
-
-enum OOX
-{
- SAY_OOX_START = 0,
- SAY_OOX_AGGRO = 1,
- SAY_OOX_AMBUSH = 2,
- SAY_OOX_END = 3,
-
- NPC_YETI = 7848,
- NPC_GORILLA = 5260,
- NPC_WOODPAW_REAVER = 5255,
- NPC_WOODPAW_BRUTE = 5253,
- NPC_WOODPAW_ALPHA = 5258,
- NPC_WOODPAW_MYSTIC = 5254,
-
- QUEST_RESCUE_OOX22FE = 2767,
- FACTION_ESCORTEE_A = 774,
- FACTION_ESCORTEE_H = 775
-};
-
-class npc_oox22fe : public CreatureScript
-{
-public:
- npc_oox22fe() : CreatureScript("npc_oox22fe") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_RESCUE_OOX22FE)
- {
- creature->AI()->Talk(SAY_OOX_START);
- //change that the npc is not lying dead on the ground
- creature->SetStandState(UNIT_STAND_STATE_STAND);
-
- if (player->GetTeam() == ALLIANCE)
- creature->setFaction(FACTION_ESCORTEE_A);
-
- if (player->GetTeam() == HORDE)
- creature->setFaction(FACTION_ESCORTEE_H);
-
- if (npc_escortAI* pEscortAI = CAST_AI(npc_oox22fe::npc_oox22feAI, creature->AI()))
- pEscortAI->Start(true, false, player->GetGUID());
-
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_oox22feAI(creature);
- }
-
- struct npc_oox22feAI : public npc_escortAI
- {
- npc_oox22feAI(Creature* creature) : npc_escortAI(creature) { }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- // First Ambush(3 Yetis)
- case 11:
- Talk(SAY_OOX_AMBUSH);
- me->SummonCreature(NPC_YETI, -4841.01f, 1593.91f, 73.42f, 3.98f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_YETI, -4837.61f, 1568.58f, 78.21f, 3.13f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_YETI, -4841.89f, 1569.95f, 76.53f, 0.68f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- break;
- //Second Ambush(3 Gorillas)
- case 21:
- Talk(SAY_OOX_AMBUSH);
- me->SummonCreature(NPC_GORILLA, -4595.81f, 2005.99f, 53.08f, 3.74f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_GORILLA, -4597.53f, 2008.31f, 52.70f, 3.78f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_GORILLA, -4599.37f, 2010.59f, 52.77f, 3.84f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- break;
- //Third Ambush(4 Gnolls)
- case 30:
- Talk(SAY_OOX_AMBUSH);
- me->SummonCreature(NPC_WOODPAW_REAVER, -4425.14f, 2075.87f, 47.77f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_WOODPAW_BRUTE, -4426.68f, 2077.98f, 47.57f, 3.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_WOODPAW_MYSTIC, -4428.33f, 2080.24f, 47.43f, 3.87f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- me->SummonCreature(NPC_WOODPAW_ALPHA, -4430.04f, 2075.54f, 46.83f, 3.81f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000);
- break;
- case 37:
- Talk(SAY_OOX_END);
- // Award quest credit
- if (Player* player = GetPlayerForEscort())
- player->GroupEventHappens(QUEST_RESCUE_OOX22FE, me);
- break;
- }
- }
-
- void Reset() OVERRIDE
- {
- if (!HasEscortState(STATE_ESCORT_ESCORTING))
- me->SetStandState(UNIT_STAND_STATE_DEAD);
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- //For an small probability the npc says something when he get aggro
- if (urand(0, 9) > 7)
- Talk(SAY_OOX_AGGRO);
- }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- summoned->AI()->AttackStart(me);
- }
- };
-
-};
-
-/*######
-## npc_screecher_spirit
-######*/
-
-class npc_screecher_spirit : public CreatureScript
-{
-public:
- npc_screecher_spirit() : CreatureScript("npc_screecher_spirit") { }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- player->SEND_GOSSIP_MENU(2039, creature->GetGUID());
- player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- return true;
- }
-
-};
-
-enum GordunniTrap
-{
- GO_GORDUNNI_DIRT_MOUND = 144064,
-};
-
-class spell_gordunni_trap : public SpellScriptLoader
-{
- public:
- spell_gordunni_trap() : SpellScriptLoader("spell_gordunni_trap") { }
-
- class spell_gordunni_trap_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_gordunni_trap_SpellScript);
-
- void HandleDummy()
- {
- if (Unit* caster = GetCaster())
- if (GameObject* chest = caster->SummonGameObject(GO_GORDUNNI_DIRT_MOUND, caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ(), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0))
- {
- chest->SetSpellId(GetSpellInfo()->Id);
- caster->RemoveGameObject(chest, false);
- }
- }
-
- void Register() OVERRIDE
- {
- OnCast += SpellCastFn(spell_gordunni_trap_SpellScript::HandleDummy);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_gordunni_trap_SpellScript();
- }
-};
-
-/*######
-## AddSC
-######*/
-
void AddSC_feralas()
{
- new npc_gregan_brewspewer();
- new npc_oox22fe();
- new npc_screecher_spirit();
- new spell_gordunni_trap();
+
}
diff --git a/src/server/scripts/Kalimdor/zone_moonglade.cpp b/src/server/scripts/Kalimdor/zone_moonglade.cpp
index 3b77a2c7a0b..9c07e55707a 100644
--- a/src/server/scripts/Kalimdor/zone_moonglade.cpp
+++ b/src/server/scripts/Kalimdor/zone_moonglade.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,21 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Moonglade
-SD%Complete: 100
-SDComment: Quest support: 30, 272, 5929, 5930, 10965. Special Flight Paths for Druid class.
-SDCategory: Moonglade
-EndScriptData */
-
-/* ContentData
-npc_bunthen_plainswind
-npc_great_bear_spirit
-npc_silva_filnaveth
-npc_clintar_spirit
-npc_clintar_dreamwalker
-EndContentData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
@@ -42,521 +26,6 @@ EndContentData */
#include "Cell.h"
#include "CellImpl.h"
-/*######
-## npc_bunthen_plainswind
-######*/
-
-enum Bunthen
-{
- QUEST_SEA_LION_HORDE = 30,
- QUEST_SEA_LION_ALLY = 272,
- TAXI_PATH_ID_ALLY = 315,
- TAXI_PATH_ID_HORDE = 316
-};
-
-#define GOSSIP_ITEM_THUNDER "I'd like to fly to Thunder Bluff."
-#define GOSSIP_ITEM_AQ_END "Do you know where I can find Half Pendant of Aquatic Endurance?"
-
-class npc_bunthen_plainswind : public CreatureScript
-{
-public:
- npc_bunthen_plainswind() : CreatureScript("npc_bunthen_plainswind") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->CLOSE_GOSSIP_MENU();
- if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE)
- player->ActivateTaxiPathTo(TAXI_PATH_ID_HORDE);
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- player->SEND_GOSSIP_MENU(5373, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(5376, creature->GetGUID());
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (player->getClass() != CLASS_DRUID)
- player->SEND_GOSSIP_MENU(4916, creature->GetGUID());
- else if (player->GetTeam() != HORDE)
- {
- if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
-
- player->SEND_GOSSIP_MENU(4917, creature->GetGUID());
- }
- else if (player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_THUNDER, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
-
- if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_END, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
-
- player->SEND_GOSSIP_MENU(4918, creature->GetGUID());
- }
- return true;
- }
-
-};
-
-/*######
-## npc_great_bear_spirit
-######*/
-
-#define GOSSIP_BEAR1 "What do you represent, spirit?"
-#define GOSSIP_BEAR2 "I seek to understand the importance of strength of the body."
-#define GOSSIP_BEAR3 "I seek to understand the importance of strength of the heart."
-#define GOSSIP_BEAR4 "I have heard your words, Great Bear Spirit, and I understand. I now seek your blessings to fully learn the way of the Claw."
-
-class npc_great_bear_spirit : public CreatureScript
-{
-public:
- npc_great_bear_spirit() : CreatureScript("npc_great_bear_spirit") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(4721, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(4733, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(4734, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(4735, creature->GetGUID());
- if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE)
- player->AreaExploredOrEventHappens(5929);
- if (player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE)
- player->AreaExploredOrEventHappens(5930);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- //ally or horde quest
- if (player->GetQuestStatus(5929) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(5930) == QUEST_STATUS_INCOMPLETE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_BEAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
- player->SEND_GOSSIP_MENU(4719, creature->GetGUID());
- }
- else
- player->SEND_GOSSIP_MENU(4718, creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
-## npc_silva_filnaveth
-######*/
-
-#define GOSSIP_ITEM_RUTHERAN "I'd like to fly to Rut'theran Village."
-#define GOSSIP_ITEM_AQ_AGI "Do you know where I can find Half Pendant of Aquatic Agility?"
-
-class npc_silva_filnaveth : public CreatureScript
-{
-public:
- npc_silva_filnaveth() : CreatureScript("npc_silva_filnaveth") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->CLOSE_GOSSIP_MENU();
- if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE)
- player->ActivateTaxiPathTo(TAXI_PATH_ID_ALLY);
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- player->SEND_GOSSIP_MENU(5374, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 3:
- player->SEND_GOSSIP_MENU(5375, creature->GetGUID());
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (player->getClass() != CLASS_DRUID)
- player->SEND_GOSSIP_MENU(4913, creature->GetGUID());
- else if (player->GetTeam() != ALLIANCE)
- {
- if (player->GetQuestStatus(QUEST_SEA_LION_HORDE) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
-
- player->SEND_GOSSIP_MENU(4915, creature->GetGUID());
- }
- else if (player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RUTHERAN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
-
- if (player->GetQuestStatus(QUEST_SEA_LION_ALLY) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AQ_AGI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
-
- player->SEND_GOSSIP_MENU(4914, creature->GetGUID());
- }
- return true;
- }
-
-};
-
-/*######
-## npc_clintar_spirit
-######*/
-
-float const Clintar_spirit_WP[41][5] =
-{
- //pos_x pos_y pos_z orien waitTime
- {7465.28f, -3115.46f, 439.327f, 0.83f, 4000},
- {7476.49f, -3101, 443.457f, 0.89f, 0},
- {7486.57f, -3085.59f, 439.478f, 1.07f, 0},
- {7472.19f, -3085.06f, 443.142f, 3.07f, 0},
- {7456.92f, -3085.91f, 438.862f, 3.24f, 0},
- {7446.68f, -3083.43f, 438.245f, 2.40f, 0},
- {7446.17f, -3080.21f, 439.826f, 1.10f, 6000},
- {7452.41f, -3085.8f, 438.984f, 5.78f, 0},
- {7469.11f, -3084.94f, 443.048f, 6.25f, 0},
- {7483.79f, -3085.44f, 439.607f, 6.25f, 0},
- {7491.14f, -3090.96f, 439.983f, 5.44f, 0},
- {7497.62f, -3098.22f, 436.854f, 5.44f, 0},
- {7498.72f, -3113.41f, 434.596f, 4.84f, 0},
- {7500.06f, -3122.51f, 434.749f, 5.17f, 0},
- {7504.96f, -3131.53f, 434.475f, 4.74f, 0},
- {7504.31f, -3133.53f, 435.693f, 3.84f, 6000},
- {7504.55f, -3133.27f, 435.476f, 0.68f, 15000},
- {7501.99f, -3126.01f, 434.93f, 1.83f, 0},
- {7490.76f, -3114.97f, 434.431f, 2.51f, 0},
- {7479.64f, -3105.51f, 431.123f, 1.83f, 0},
- {7474.63f, -3086.59f, 428.994f, 1.83f, 2000},
- {7472.96f, -3074.18f, 427.566f, 1.57f, 0},
- {7472.25f, -3063, 428.268f, 1.55f, 0},
- {7473.46f, -3054.22f, 427.588f, 0.36f, 0},
- {7475.08f, -3053.6f, 428.653f, 0.36f, 6000},
- {7474.66f, -3053.56f, 428.433f, 3.19f, 4000},
- {7471.81f, -3058.84f, 427.073f, 4.29f, 0},
- {7472.16f, -3064.91f, 427.772f, 4.95f, 0},
- {7471.56f, -3085.36f, 428.924f, 4.72f, 0},
- {7473.56f, -3093.48f, 429.294f, 5.04f, 0},
- {7478.94f, -3104.29f, 430.638f, 5.23f, 0},
- {7484.46f, -3109.61f, 432.769f, 5.79f, 0},
- {7490.23f, -3111.08f, 434.431f, 0.02f, 0},
- {7496.29f, -3108, 434.783f, 1.15f, 0},
- {7497.46f, -3100.66f, 436.191f, 1.50f, 0},
- {7495.64f, -3093.39f, 438.349f, 2.10f, 0},
- {7492.44f, -3086.01f, 440.267f, 1.38f, 0},
- {7498.26f, -3076.44f, 440.808f, 0.71f, 0},
- {7506.4f, -3067.35f, 443.64f, 0.77f, 0},
- {7518.37f, -3057.42f, 445.584f, 0.74f, 0},
- {7517.51f, -3056.3f, 444.568f, 2.49f, 4500}
-};
-
-Position const AspectRavenSummon = {7472.96f, -3074.18f, 427.566f, 0.0f};
-Position const ClintarSpiritSummon = {7459.2275f, -3122.5632f, 438.9842f, 0.8594f};
-
-enum ClintarSpirit
-{
- ASPECT_RAVEN = 22915,
-
- // Texts for EnterCombat, the event and the end of the event are missing
- CLINTAR_SPIRIT_SAY_START = 0,
-};
-
-class npc_clintar_spirit : public CreatureScript
-{
-public:
- npc_clintar_spirit() : CreatureScript("npc_clintar_spirit") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_clintar_spiritAI(creature);
- }
-
- struct npc_clintar_spiritAI : public npc_escortAI
- {
- public:
- npc_clintar_spiritAI(Creature* creature) : npc_escortAI(creature)
- {
- PlayerGUID = 0;
- }
-
- uint8 Step;
- uint32 CurrWP;
- uint32 EventTimer;
- uint32 checkPlayerTimer;
-
- uint64 PlayerGUID;
-
- bool EventOnWait;
-
- void Reset() OVERRIDE
- {
- if (!PlayerGUID)
- {
- Step = 0;
- CurrWP = 0;
- EventTimer = 0;
- PlayerGUID = 0;
- checkPlayerTimer = 1000;
- EventOnWait = false;
- }
- }
-
- void IsSummonedBy(Unit* /*summoner*/) OVERRIDE
- {
- std::list<Player*> playerOnQuestList;
- Trinity::AnyPlayerInObjectRangeCheck checker(me, 5.0f);
- Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(me, playerOnQuestList, checker);
- me->VisitNearbyWorldObject(5.0f, searcher);
- for (std::list<Player*>::const_iterator itr = playerOnQuestList.begin(); itr != playerOnQuestList.end(); ++itr)
- {
- // Check if found player target has active quest
- if (Player* player = (*itr))
- {
- if (player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
- {
- StartEvent(player);
- break;
- }
- }
- else
- break;
- }
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (!PlayerGUID)
- return;
-
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
- {
- player->FailQuest(10965);
- PlayerGUID = 0;
- Reset();
- }
- }
-
- void EnterEvadeMode() OVERRIDE
- {
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (player && player->IsInCombat() && player->getAttackerForHelper())
- {
- AttackStart(player->getAttackerForHelper());
- return;
- }
- npc_escortAI::EnterEvadeMode();
- }
-
- void StartEvent(Player* player)
- {
- if (player && player->GetQuestStatus(10965) == QUEST_STATUS_INCOMPLETE)
- {
- for (uint8 i = 0; i < 41; ++i)
- {
- AddWaypoint(i, Clintar_spirit_WP[i][0], Clintar_spirit_WP[i][1], Clintar_spirit_WP[i][2], (uint32)Clintar_spirit_WP[i][4]);
- }
- PlayerGUID = player->GetGUID();
- Start(true, false, PlayerGUID);
- }
- return;
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- npc_escortAI::UpdateAI(diff);
-
- if (!PlayerGUID)
- {
- me->setDeathState(JUST_DIED);
- return;
- }
-
- if (!me->IsInCombat() && !EventOnWait)
- {
- if (checkPlayerTimer <= diff)
- {
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (player && player->IsInCombat() && player->getAttackerForHelper())
- AttackStart(player->getAttackerForHelper());
- checkPlayerTimer = 1000;
- } else checkPlayerTimer -= diff;
- }
-
- if (EventOnWait && EventTimer <= diff)
- {
- Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID);
- if (!player || player->GetQuestStatus(10965) == QUEST_STATUS_NONE)
- {
- me->setDeathState(JUST_DIED);
- return;
- }
-
- switch (CurrWP)
- {
- case 0:
- switch (Step)
- {
- case 0:
- Talk(CLINTAR_SPIRIT_SAY_START, player);
- EventTimer = 8000;
- Step = 1;
- break;
- case 1:
- EventOnWait = false;
- break;
- }
- break;
- case 6:
- switch (Step)
- {
- case 0:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
- EventTimer = 5000;
- Step = 1;
- break;
- case 1:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- // Needs text
- EventOnWait = false;
- break;
- }
- break;
- case 15:
- switch (Step)
- {
- case 0:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
- EventTimer = 5000;
- Step = 1;
- break;
- case 1:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- EventOnWait = false;
- break;
- }
- break;
- case 16:
- switch (Step)
- {
- case 0:
- // Needs text
- EventTimer = 15000;
- Step = 1;
- break;
- case 1:
- EventOnWait = false;
- break;
- }
- break;
- case 20:
- switch (Step)
- {
- case 0:
- if (Creature* mob = me->SummonCreature(ASPECT_RAVEN, AspectRavenSummon, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 2000))
- {
- mob->AddThreat(me, 10000.0f);
- mob->AI()->AttackStart(me);
- }
- EventTimer = 2000;
- Step = 1;
- break;
- case 1:
- EventOnWait = false;
- break;
- }
- break;
- case 24:
- switch (Step)
- {
- case 0:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 133);
- EventTimer = 5000;
- Step = 1;
- break;
- case 1:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- EventOnWait = false;
- break;
- }
- break;
- case 25:
- switch (Step)
- {
- case 0:
- // Needs text
- EventTimer = 4000;
- Step = 1;
- break;
- case 1:
- EventOnWait = false;
- break;
- }
- break;
- case 40:
- switch (Step)
- {
- case 0:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 2);
- // Needs text
- player->CompleteQuest(10965);
- EventTimer = 1500;
- Step = 1;
- break;
- case 1:
- me->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- EventTimer = 3000;
- Step = 2;
- break;
- case 2:
- player->TalkedToCreature(me->GetEntry(), me->GetGUID());
- PlayerGUID = 0;
- Reset();
- me->setDeathState(JUST_DIED);
- break;
- }
- break;
- default:
- EventOnWait = false;
- break;
- }
-
- } else if (EventOnWait) EventTimer -= diff;
- }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- CurrWP = waypointId;
- EventTimer = 0;
- Step = 0;
- EventOnWait = true;
- }
- };
-
-};
-
/*####
# npc_omen
####*/
@@ -705,10 +174,6 @@ public:
void AddSC_moonglade()
{
- new npc_bunthen_plainswind();
- new npc_great_bear_spirit();
- new npc_silva_filnaveth();
- new npc_clintar_spirit();
new npc_omen();
new npc_giant_spotlight();
}
diff --git a/src/server/scripts/Kalimdor/zone_mulgore.cpp b/src/server/scripts/Kalimdor/zone_mulgore.cpp
index f70460ec7b6..654efd571f6 100644
--- a/src/server/scripts/Kalimdor/zone_mulgore.cpp
+++ b/src/server/scripts/Kalimdor/zone_mulgore.cpp
@@ -19,14 +19,13 @@
/* ScriptData
SDName: Mulgore
SD%Complete: 100
-SDComment: Support for quest: 11129, 772
+SDComment: Support for quest: 11129, 861
SDCategory: Mulgore
EndScriptData */
/* ContentData
npc_skorn_whitecloud
npc_kyle_frenzied
-npc_plains_vision
EndContentData */
#include "ScriptMgr.h"
@@ -46,7 +45,7 @@ class npc_skorn_whitecloud : public CreatureScript
public:
npc_skorn_whitecloud() : CreatureScript("npc_skorn_whitecloud") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_ACTION_INFO_DEF)
@@ -55,7 +54,7 @@ public:
return true;
}
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
+ bool OnGossipHello(Player* player, Creature* creature)
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
@@ -93,7 +92,7 @@ public:
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_kyle_frenziedAI(creature);
+ return new npc_kyle_frenziedAI (creature);
}
struct npc_kyle_frenziedAI : public ScriptedAI
@@ -118,7 +117,7 @@ public:
me->UpdateEntry(NPC_KYLE_FRENZIED);
}
- void SpellHit(Unit* Caster, SpellInfo const* Spell) OVERRIDE
+ void SpellHit(Unit* Caster, SpellInfo const* Spell)
{
if (!me->GetVictim() && !EventActive && Spell->Id == SPELL_LUNCH)
{
@@ -138,12 +137,12 @@ public:
}
}
- void MovementInform(uint32 Type, uint32 PointId) OVERRIDE
+ void MovementInform(uint32 type, uint32 pointId) OVERRIDE
{
- if (Type != POINT_MOTION_TYPE || !EventActive)
+ if (type != POINT_MOTION_TYPE || !EventActive)
return;
- if (PointId == POINT_ID)
+ if (pointId == POINT_ID)
IsMovingToLunch = false;
}
@@ -201,127 +200,8 @@ public:
};
-/*#####
-# npc_plains_vision
-######*/
-
-Position const wpPlainVision[50] =
-{
- {-2226.32f, -408.095f, -9.36235f, 0.0f},
- {-2203.04f, -437.212f, -5.72498f, 0.0f},
- {-2163.91f, -457.851f, -7.09049f, 0.0f},
- {-2123.87f, -448.137f, -9.29591f, 0.0f},
- {-2104.66f, -427.166f, -6.49513f, 0.0f},
- {-2101.48f, -422.826f, -5.3567f, 0.0f},
- {-2097.56f, -417.083f, -7.16716f, 0.0f},
- {-2084.87f, -398.626f, -9.88973f, 0.0f},
- {-2072.71f, -382.324f, -10.2488f, 0.0f},
- {-2054.05f, -356.728f, -6.22468f, 0.0f},
- {-2051.8f, -353.645f, -5.35791f, 0.0f},
- {-2049.08f, -349.912f, -6.15723f, 0.0f},
- {-2030.6f, -310.724f, -9.59302f, 0.0f},
- {-2002.15f, -249.308f, -10.8124f, 0.0f},
- {-1972.85f, -195.811f, -10.6316f, 0.0f},
- {-1940.93f, -147.652f, -11.7055f, 0.0f},
- {-1888.06f, -81.943f, -11.4404f, 0.0f},
- {-1837.05f, -34.0109f, -12.258f, 0.0f},
- {-1796.12f, -14.6462f, -10.3581f, 0.0f},
- {-1732.61f, -4.27746f, -10.0213f, 0.0f},
- {-1688.94f, -0.829945f, -11.7103f, 0.0f},
- {-1681.32f, 13.0313f, -9.48056f, 0.0f},
- {-1677.04f, 36.8349f, -7.10318f, 0.0f},
- {-1675.2f, 68.559f, -8.95384f, 0.0f},
- {-1676.57f, 89.023f, -9.65104f, 0.0f},
- {-1678.16f, 110.939f, -10.1782f, 0.0f},
- {-1677.86f, 128.681f, -5.73869f, 0.0f},
- {-1675.27f, 144.324f, -3.47916f, 0.0f},
- {-1671.7f, 163.169f, -1.23098f, 0.0f},
- {-1666.61f, 181.584f, 5.26145f, 0.0f},
- {-1661.51f, 196.154f, 8.95252f, 0.0f},
- {-1655.47f, 210.811f, 8.38727f, 0.0f},
- {-1647.07f, 226.947f, 5.27755f, 0.0f},
- {-1621.65f, 232.91f, 2.69579f, 0.0f},
- {-1600.23f, 237.641f, 2.98539f, 0.0f},
- {-1576.07f, 242.546f, 4.66541f, 0.0f},
- {-1554.57f, 248.494f, 6.60377f, 0.0f},
- {-1547.53f, 259.302f, 10.6741f, 0.0f},
- {-1541.7f, 269.847f, 16.4418f, 0.0f},
- {-1539.83f, 278.989f, 21.0597f, 0.0f},
- {-1540.16f, 290.219f, 27.8247f, 0.0f},
- {-1538.99f, 298.983f, 34.0032f, 0.0f},
- {-1540.38f, 307.337f, 41.3557f, 0.0f},
- {-1536.61f, 314.884f, 48.0179f, 0.0f},
- {-1532.42f, 323.277f, 55.6667f, 0.0f},
- {-1528.77f, 329.774f, 61.1525f, 0.0f},
- {-1525.65f, 333.18f, 63.2161f, 0.0f},
- {-1517.01f, 350.713f, 62.4286f, 0.0f},
- {-1511.39f, 362.537f, 62.4539f, 0.0f},
- {-1508.68f, 366.822f, 62.733f, 0.0f}
-};
-
-class npc_plains_vision : public CreatureScript
-{
-public:
- npc_plains_vision() : CreatureScript("npc_plains_vision") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_plains_visionAI(creature);
- }
-
- struct npc_plains_visionAI : public ScriptedAI
- {
- npc_plains_visionAI(Creature* creature) : ScriptedAI(creature) { }
-
- bool newWaypoint;
- uint8 WayPointId;
- uint8 amountWP;
-
- void Reset() OVERRIDE
- {
- WayPointId = 0;
- newWaypoint = true;
- amountWP = 49;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void MovementInform(uint32 type, uint32 id) OVERRIDE
- {
- if (type != POINT_MOTION_TYPE)
- return;
-
- if (id < amountWP)
- {
- ++WayPointId;
- newWaypoint = true;
- }
- else
- {
- me->setDeathState(JUST_DIED);
- me->RemoveCorpse();
- }
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- if (newWaypoint)
- {
- me->GetMotionMaster()->MovePoint(WayPointId, wpPlainVision[WayPointId]);
- newWaypoint = false;
- }
- }
- };
-
-};
-
-/*#####
-#
-######*/
-
void AddSC_mulgore()
{
new npc_skorn_whitecloud();
new npc_kyle_frenzied();
- new npc_plains_vision();
}
diff --git a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
index 4b6670043bf..22daddff5b9 100644
--- a/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
+++ b/src/server/scripts/Kalimdor/zone_orgrimmar.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,239 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Orgrimmar
-SD%Complete: 100
-SDComment: Quest support: 2460, 6566
-SDCategory: Orgrimmar
-EndScriptData */
-
-/* ContentData
-npc_shenthul
-npc_thrall_warchief
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "Player.h"
-
-/*######
-## npc_shenthul
-######*/
-
-enum Shenthul
-{
- QUEST_SHATTERED_SALUTE = 2460
-};
-
-class npc_shenthul : public CreatureScript
-{
-public:
- npc_shenthul() : CreatureScript("npc_shenthul") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_SHATTERED_SALUTE)
- {
- CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->CanTalk = true;
- CAST_AI(npc_shenthul::npc_shenthulAI, creature->AI())->PlayerGUID = player->GetGUID();
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_shenthulAI(creature);
- }
-
- struct npc_shenthulAI : public ScriptedAI
- {
- npc_shenthulAI(Creature* creature) : ScriptedAI(creature) { }
-
- bool CanTalk;
- bool CanEmote;
- uint32 SaluteTimer;
- uint32 ResetTimer;
- uint64 PlayerGUID;
-
- void Reset() OVERRIDE
- {
- CanTalk = false;
- CanEmote = false;
- SaluteTimer = 6000;
- ResetTimer = 0;
- PlayerGUID = 0;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (CanEmote)
- {
- if (ResetTimer <= diff)
- {
- if (Player* player = ObjectAccessor::GetPlayer(*me, PlayerGUID))
- {
- if (player->GetTypeId() == TYPEID_PLAYER && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE)
- player->FailQuest(QUEST_SHATTERED_SALUTE);
- }
- Reset();
- } else ResetTimer -= diff;
- }
-
- if (CanTalk && !CanEmote)
- {
- if (SaluteTimer <= diff)
- {
- me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
- CanEmote = true;
- ResetTimer = 60000;
- } else SaluteTimer -= diff;
- }
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
-
- void ReceiveEmote(Player* player, uint32 emote) OVERRIDE
- {
- if (emote == TEXT_EMOTE_SALUTE && player->GetQuestStatus(QUEST_SHATTERED_SALUTE) == QUEST_STATUS_INCOMPLETE)
- {
- if (CanEmote)
- {
- player->AreaExploredOrEventHappens(QUEST_SHATTERED_SALUTE);
- Reset();
- }
- }
- }
- };
-
-};
-
-/*######
-## npc_thrall_warchief
-######*/
-
-enum ThrallWarchief
-{
- QUEST_6566 = 6566,
-
- SPELL_CHAIN_LIGHTNING = 16033,
- SPELL_SHOCK = 16034
-};
-
-#define GOSSIP_HTW "Please share your wisdom with me, Warchief."
-#define GOSSIP_STW1 "What discoveries?"
-#define GOSSIP_STW2 "Usurper?"
-#define GOSSIP_STW3 "With all due respect, Warchief - why not allow them to be destroyed? Does this not strengthen our position?"
-#define GOSSIP_STW4 "I... I did not think of it that way, Warchief."
-#define GOSSIP_STW5 "I live only to serve, Warchief! My life is empty and meaningless without your guidance."
-#define GOSSIP_STW6 "Of course, Warchief!"
-
-/// @todo verify abilities/timers
-class npc_thrall_warchief : public CreatureScript
-{
-public:
- npc_thrall_warchief() : CreatureScript("npc_thrall_warchief") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(5733, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
- player->SEND_GOSSIP_MENU(5734, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
- player->SEND_GOSSIP_MENU(5735, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
- player->SEND_GOSSIP_MENU(5736, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
- player->SEND_GOSSIP_MENU(5737, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+6:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_STW6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
- player->SEND_GOSSIP_MENU(5738, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+7:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(QUEST_6566);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_6566) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HTW, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_thrall_warchiefAI(creature);
- }
-
- struct npc_thrall_warchiefAI : public ScriptedAI
- {
- npc_thrall_warchiefAI(Creature* creature) : ScriptedAI(creature) { }
-
- uint32 ChainLightningTimer;
- uint32 ShockTimer;
-
- void Reset() OVERRIDE
- {
- ChainLightningTimer = 2000;
- ShockTimer = 8000;
- }
-
- void EnterCombat(Unit* /*who*/) OVERRIDE { }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- if (ChainLightningTimer <= diff)
- {
- DoCastVictim(SPELL_CHAIN_LIGHTNING);
- ChainLightningTimer = 9000;
- } else ChainLightningTimer -= diff;
-
- if (ShockTimer <= diff)
- {
- DoCastVictim(SPELL_SHOCK);
- ShockTimer = 15000;
- } else ShockTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
void AddSC_orgrimmar()
{
- new npc_shenthul();
- new npc_thrall_warchief();
}
diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp
index b002bbe8a48..6a820a88895 100644
--- a/src/server/scripts/Kalimdor/zone_silithus.cpp
+++ b/src/server/scripts/Kalimdor/zone_silithus.cpp
@@ -19,13 +19,13 @@
/* ScriptData
SDName: Silithus
SD%Complete: 100
-SDComment: Quest support: 8304, 8507.
+SDComment: Quest support: 7785, 8304.
SDCategory: Silithus
EndScriptData */
/* ContentData
npcs_rutgar_and_frankal
-quest_a_pawn_on_the_eternal_pawn
+go_wind_stone
EndContentData */
#include "ScriptMgr.h"
diff --git a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
index 92fd5a3fd47..251006ff545 100644
--- a/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
+++ b/src/server/scripts/Kalimdor/zone_stonetalon_mountains.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,164 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Stonetalon_Mountains
-SD%Complete: 95
-SDComment: Quest support: 6627, 6523
-SDCategory: Stonetalon Mountains
-EndScriptData */
-
-/* ContentData
-npc_braug_dimspirit
-npc_kaya_flathoof
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "ScriptedEscortAI.h"
-#include "Player.h"
-
-/*######
-## npc_braug_dimspirit
-######*/
-
-#define GOSSIP_HBD1 "Ysera"
-#define GOSSIP_HBD2 "Neltharion"
-#define GOSSIP_HBD3 "Nozdormu"
-#define GOSSIP_HBD4 "Alexstrasza"
-#define GOSSIP_HBD5 "Malygos"
-
-class npc_braug_dimspirit : public CreatureScript
-{
-public:
- npc_braug_dimspirit() : CreatureScript("npc_braug_dimspirit") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, 6766, false);
-
- }
- if (action == GOSSIP_ACTION_INFO_DEF+2)
- {
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(6627);
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(6627) == QUEST_STATUS_INCOMPLETE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HBD5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(5820, creature->GetGUID());
- }
- else
- player->SEND_GOSSIP_MENU(5819, creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
-## npc_kaya_flathoof
-######*/
-
-enum Kaya
-{
- FACTION_ESCORTEE_H = 775,
-
- NPC_GRIMTOTEM_RUFFIAN = 11910,
- NPC_GRIMTOTEM_BRUTE = 11912,
- NPC_GRIMTOTEM_SORCERER = 11913,
-
- SAY_START = 0,
- SAY_AMBUSH = 1,
- SAY_END = 2,
-
- QUEST_PROTECT_KAYA = 6523
-};
-
-class npc_kaya_flathoof : public CreatureScript
-{
-public:
- npc_kaya_flathoof() : CreatureScript("npc_kaya_flathoof") { }
-
- struct npc_kaya_flathoofAI : public npc_escortAI
- {
- npc_kaya_flathoofAI(Creature* creature) : npc_escortAI(creature) { }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- Player* player = GetPlayerForEscort();
- if (!player)
- return;
-
- switch (waypointId)
- {
- case 16:
- Talk(SAY_AMBUSH);
- me->SummonCreature(NPC_GRIMTOTEM_BRUTE, -48.53f, -503.34f, -46.31f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- me->SummonCreature(NPC_GRIMTOTEM_RUFFIAN, -38.85f, -503.77f, -45.90f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- me->SummonCreature(NPC_GRIMTOTEM_SORCERER, -36.37f, -496.23f, -45.71f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
- break;
- case 18:
- me->SetInFront(player);
- Talk(SAY_END);
- player->GroupEventHappens(QUEST_PROTECT_KAYA, me);
- break;
- }
- }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- summoned->AI()->AttackStart(me);
- }
-
- void Reset() OVERRIDE { }
- };
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_PROTECT_KAYA)
- {
- if (npc_escortAI* pEscortAI = CAST_AI(npc_kaya_flathoof::npc_kaya_flathoofAI, creature->AI()))
- pEscortAI->Start(true, false, player->GetGUID());
-
- creature->AI()->Talk(SAY_START);
- creature->setFaction(113);
- creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_kaya_flathoofAI(creature);
- }
-
-};
-
-/*######
-## AddSC
-######*/
-
void AddSC_stonetalon_mountains()
{
- new npc_braug_dimspirit();
- new npc_kaya_flathoof();
}
diff --git a/src/server/scripts/Kalimdor/zone_tanaris.cpp b/src/server/scripts/Kalimdor/zone_tanaris.cpp
index 204a2960611..3269bfb77db 100644
--- a/src/server/scripts/Kalimdor/zone_tanaris.cpp
+++ b/src/server/scripts/Kalimdor/zone_tanaris.cpp
@@ -19,18 +19,14 @@
/* ScriptData
SDName: Tanaris
SD%Complete: 80
-SDComment: Quest support: 648, 1560, 2954, 4005, 10277, 10279(Special flight path). Noggenfogger vendor
+SDComment: Quest support: 648, 10277, 10279(Special flight path).
SDCategory: Tanaris
EndScriptData */
/* ContentData
-npc_aquementas
npc_custodian_of_time
-npc_marin_noggenfogger
npc_steward_of_time
-npc_stone_watcher_of_norgannon
npc_OOX17
-npc_tooga
EndContentData */
#include "ScriptMgr.h"
@@ -60,7 +56,7 @@ public:
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_aquementasAI(creature);
+ return new npc_aquementasAI (creature);
}
struct npc_aquementasAI : public ScriptedAI
@@ -101,7 +97,7 @@ public:
}
}
- void EnterCombat(Unit* who) OVERRIDE
+ void EnterCombat(Unit* who)
{
Talk(AGGRO_YELL_AQUE, who);
}
@@ -184,7 +180,7 @@ public:
{
npc_custodian_of_timeAI(Creature* creature) : npc_escortAI(creature) { }
- void WaypointReached(uint32 waypointId) OVERRIDE
+ void WaypointReached(uint32 waypointId)
{
if (Player* player = GetPlayerForEscort())
{
@@ -251,8 +247,7 @@ public:
}
}
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
+ void MoveInLineOfSight(Unit* who)
{
if (HasEscortState(STATE_ESCORT_ESCORTING))
return;
@@ -282,39 +277,6 @@ public:
};
/*######
-## npc_marin_noggenfogger
-######*/
-
-class npc_marin_noggenfogger : public CreatureScript
-{
-public:
- npc_marin_noggenfogger() : CreatureScript("npc_marin_noggenfogger") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (creature->IsVendor() && player->GetQuestRewardStatus(2662))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_steward_of_time
######*/
@@ -325,7 +287,7 @@ class npc_steward_of_time : public CreatureScript
public:
npc_steward_of_time() : CreatureScript("npc_steward_of_time") { }
- bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest) OVERRIDE
+ bool OnQuestAccept(Player* player, Creature* /*creature*/, Quest const* quest)
{
if (quest->GetQuestId() == 10279) //Quest: To The Master's Lair
player->CastSpell(player, 34891, true); //(Flight through Caverns)
@@ -333,7 +295,7 @@ public:
return false;
}
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) OVERRIDE
+ bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_ACTION_INFO_DEF + 1)
@@ -342,7 +304,7 @@ public:
return true;
}
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
+ bool OnGossipHello(Player* player, Creature* creature)
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
@@ -361,70 +323,6 @@ public:
};
/*######
-## npc_stone_watcher_of_norgannon
-######*/
-
-#define GOSSIP_ITEM_NORGANNON_1 "What function do you serve?"
-#define GOSSIP_ITEM_NORGANNON_2 "What are the Plates of Uldum?"
-#define GOSSIP_ITEM_NORGANNON_3 "Where are the Plates of Uldum?"
-#define GOSSIP_ITEM_NORGANNON_4 "Excuse me? We've been \"reschedueled for visitations\"? What does that mean?!"
-#define GOSSIP_ITEM_NORGANNON_5 "So, what's inside Uldum?"
-#define GOSSIP_ITEM_NORGANNON_6 "I will return when i have the Plates of Uldum."
-
-class npc_stone_watcher_of_norgannon : public CreatureScript
-{
-public:
- npc_stone_watcher_of_norgannon() : CreatureScript("npc_stone_watcher_of_norgannon") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(1675, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(1676, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
- player->SEND_GOSSIP_MENU(1677, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
- player->SEND_GOSSIP_MENU(1678, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_6, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
- player->SEND_GOSSIP_MENU(1679, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(2954);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(2954) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_NORGANNON_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(1674, creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_OOX17
######*/
@@ -447,7 +345,7 @@ class npc_OOX17 : public CreatureScript
public:
npc_OOX17() : CreatureScript("npc_OOX17") { }
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
+ bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
{
if (quest->GetQuestId() == Q_OOX17)
{
@@ -472,7 +370,7 @@ public:
{
npc_OOX17AI(Creature* creature) : npc_escortAI(creature) { }
- void WaypointReached(uint32 waypointId) OVERRIDE
+ void WaypointReached(uint32 waypointId)
{
if (Player* player = GetPlayerForEscort())
{
@@ -542,7 +440,7 @@ class npc_tooga : public CreatureScript
public:
npc_tooga() : CreatureScript("npc_tooga") { }
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
+ bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest)
{
if (quest->GetQuestId() == QUEST_TOOGA)
{
@@ -577,8 +475,7 @@ public:
TortaGUID = 0;
}
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
+ void MoveInLineOfSight(Unit* who)
{
FollowerAI::MoveInLineOfSight(who);
@@ -596,7 +493,7 @@ public:
}
}
- void MovementInform(uint32 MotionType, uint32 PointId) OVERRIDE
+ void MovementInform(uint32 MotionType, uint32 PointId)
{
FollowerAI::MovementInform(MotionType, PointId);
@@ -607,7 +504,7 @@ public:
SetFollowComplete();
}
- void UpdateFollowerAI(uint32 Diff) OVERRIDE
+ void UpdateFollowerAI(uint32 Diff)
{
if (!UpdateVictim())
{
@@ -679,11 +576,7 @@ public:
void AddSC_tanaris()
{
- new npc_aquementas();
new npc_custodian_of_time();
- new npc_marin_noggenfogger();
new npc_steward_of_time();
- new npc_stone_watcher_of_norgannon();
new npc_OOX17();
- new npc_tooga();
}
diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
index 7b08baa0511..1498c00d0fb 100644
--- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp
+++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
@@ -19,16 +19,11 @@
/* ScriptData
SDName: The_Barrens
SD%Complete: 90
-SDComment: Quest support: 863, 898, 1719, 2458, 4921, 6981,
+SDComment: Quest support: 863
SDCategory: Barrens
EndScriptData */
/* ContentData
-npc_beaten_corpse
-npc_gilthares
-npc_sputtervalve
-npc_taskmaster_fizzule
-npc_twiggy_flathead
npc_wizzlecrank_shredder
EndContentData */
@@ -652,9 +647,5 @@ public:
void AddSC_the_barrens()
{
- new npc_beaten_corpse();
- new npc_gilthares();
- new npc_taskmaster_fizzule();
- new npc_twiggy_flathead();
new npc_wizzlecrank_shredder();
}
diff --git a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp
index f027fd05f8b..46df1cb3397 100644
--- a/src/server/scripts/Kalimdor/zone_thousand_needles.cpp
+++ b/src/server/scripts/Kalimdor/zone_thousand_needles.cpp
@@ -16,448 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Thousand Needles
-SD%Complete: 100
-SDComment: Support for Quest: 1950, 4770, 4904, 4966, 5151.
-SDCategory: Thousand Needles
-EndScriptData */
-
-/* ContentData
-npc_kanati
-npc_lakota_windsong
-npc_swiftmountain
-npc_plucky
-npc_enraged_panther
-go_panther_cage
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedGossip.h"
-#include "ScriptedEscortAI.h"
-#include "Player.h"
-
-/*#####
-# npc_kanati
-######*/
-
-enum Kanati
-{
- SAY_KAN_START = 0,
-
- QUEST_PROTECT_KANATI = 4966,
- NPC_GALAK_ASS = 10720
-};
-
-Position const GalakLoc = {-4867.387695f, -1357.353760f, -48.226f, 0.0f};
-
-class npc_kanati : public CreatureScript
-{
-public:
- npc_kanati() : CreatureScript("npc_kanati") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_PROTECT_KANATI)
- if (npc_kanatiAI* pEscortAI = CAST_AI(npc_kanati::npc_kanatiAI, creature->AI()))
- pEscortAI->Start(false, false, player->GetGUID(), quest, true);
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_kanatiAI(creature);
- }
-
- struct npc_kanatiAI : public npc_escortAI
- {
- npc_kanatiAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 0:
- Talk(SAY_KAN_START);
- DoSpawnGalak();
- break;
- case 1:
- if (Player* player = GetPlayerForEscort())
- player->GroupEventHappens(QUEST_PROTECT_KANATI, me);
- break;
- }
- }
-
- void DoSpawnGalak()
- {
- for (int i = 0; i < 3; ++i)
- me->SummonCreature(NPC_GALAK_ASS, GalakLoc, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
- }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- summoned->AI()->AttackStart(me);
- }
- };
-
-};
-
-/*######
-# npc_lakota_windsong
-######*/
-
-enum Lakota
-{
- SAY_LAKO_START = 0,
- SAY_LAKO_LOOK_OUT = 1,
- SAY_LAKO_HERE_COME = 2,
- SAY_LAKO_MORE = 3,
- SAY_LAKO_END = 4,
-
- QUEST_FREE_AT_LAST = 4904,
- NPC_GRIM_BANDIT = 10758,
- FACTION_ESCORTEE_LAKO = 232, //guessed
-
- ID_AMBUSH_1 = 0,
- ID_AMBUSH_2 = 2,
- ID_AMBUSH_3 = 4
-};
-
-Position const BanditLoc[6] =
-{
- {-4905.479492f, -2062.732666f, 84.352f, 0.0f},
- {-4915.201172f, -2073.528320f, 84.733f, 0.0f},
- {-4878.883301f, -1986.947876f, 91.966f, 0.0f},
- {-4877.503906f, -1966.113403f, 91.859f, 0.0f},
- {-4767.985352f, -1873.169189f, 90.192f, 0.0f},
- {-4788.861328f, -1888.007813f, 89.888f, 0.0f}
-};
-
-class npc_lakota_windsong : public CreatureScript
-{
-public:
- npc_lakota_windsong() : CreatureScript("npc_lakota_windsong") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_FREE_AT_LAST)
- {
- creature->AI()->Talk(SAY_LAKO_START, player);
- creature->setFaction(FACTION_ESCORTEE_LAKO);
-
- if (npc_lakota_windsongAI* pEscortAI = CAST_AI(npc_lakota_windsong::npc_lakota_windsongAI, creature->AI()))
- pEscortAI->Start(false, false, player->GetGUID(), quest);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_lakota_windsongAI(creature);
- }
-
- struct npc_lakota_windsongAI : public npc_escortAI
- {
- npc_lakota_windsongAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 8:
- Talk(SAY_LAKO_LOOK_OUT);
- DoSpawnBandits(ID_AMBUSH_1);
- break;
- case 14:
- Talk(SAY_LAKO_HERE_COME);
- DoSpawnBandits(ID_AMBUSH_2);
- break;
- case 21:
- Talk(SAY_LAKO_MORE);
- DoSpawnBandits(ID_AMBUSH_3);
- break;
- case 45:
- if (Player* player = GetPlayerForEscort())
- player->GroupEventHappens(QUEST_FREE_AT_LAST, me);
- break;
- }
- }
-
- void DoSpawnBandits(int AmbushId)
- {
- for (int i = 0; i < 2; ++i)
- me->SummonCreature(NPC_GRIM_BANDIT, BanditLoc[i+AmbushId], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
- }
- };
-
-};
-
-/*######
-# npc_paoka_swiftmountain
-######*/
-
-enum Packa
-{
- SAY_START = 0,
- SAY_WYVERN = 1,
- SAY_COMPLETE = 2,
-
- QUEST_HOMEWARD = 4770,
- NPC_WYVERN = 4107,
- FACTION_ESCORTEE = 232 //guessed
-};
-
-Position const WyvernLoc[3] =
-{
- {-4990.606f, -906.057f, -5.343f, 0.0f},
- {-4970.241f, -927.378f, -4.951f, 0.0f},
- {-4985.364f, -952.528f, -5.199f, 0.0f}
-};
-
-class npc_paoka_swiftmountain : public CreatureScript
-{
-public:
- npc_paoka_swiftmountain() : CreatureScript("npc_paoka_swiftmountain") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_HOMEWARD)
- {
- creature->AI()->Talk(SAY_START, player);
- creature->setFaction(FACTION_ESCORTEE);
-
- if (npc_paoka_swiftmountainAI* pEscortAI = CAST_AI(npc_paoka_swiftmountain::npc_paoka_swiftmountainAI, creature->AI()))
- pEscortAI->Start(false, false, player->GetGUID(), quest);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_paoka_swiftmountainAI(creature);
- }
-
- struct npc_paoka_swiftmountainAI : public npc_escortAI
- {
- npc_paoka_swiftmountainAI(Creature* creature) : npc_escortAI(creature) { }
-
- void Reset() OVERRIDE { }
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- switch (waypointId)
- {
- case 15:
- Talk(SAY_WYVERN);
- DoSpawnWyvern();
- break;
- case 26:
- Talk(SAY_COMPLETE);
- break;
- case 27:
- if (Player* player = GetPlayerForEscort())
- player->GroupEventHappens(QUEST_HOMEWARD, me);
- break;
- }
- }
-
- void DoSpawnWyvern()
- {
- for (int i = 0; i < 3; ++i)
- me->SummonCreature(NPC_WYVERN, WyvernLoc[i], TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000);
- }
- };
-};
-
-/*#####
-# npc_plucky
-######*/
-
-#define GOSSIP_P "Please tell me the Phrase.."
-
-enum Plucky
-{
- FACTION_FRIENDLY = 35,
- QUEST_SCOOP = 1950,
- SPELL_PLUCKY_HUMAN = 9192,
- SPELL_PLUCKY_CHICKEN = 9220
-};
-
-class npc_plucky : public CreatureScript
-{
-public:
- npc_plucky() : CreatureScript("npc_plucky") { }
-
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->CLOSE_GOSSIP_MENU();
- player->CompleteQuest(QUEST_SCOOP);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_P, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(738, creature->GetGUID());
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_pluckyAI(creature);
- }
-
- struct npc_pluckyAI : public ScriptedAI
- {
- npc_pluckyAI(Creature* creature) : ScriptedAI(creature) { NormFaction = creature->getFaction(); }
-
- uint32 NormFaction;
- uint32 ResetTimer;
-
- void Reset() OVERRIDE
- {
- ResetTimer = 120000;
-
- if (me->getFaction() != NormFaction)
- me->setFaction(NormFaction);
-
- if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-
- DoCast(me, SPELL_PLUCKY_CHICKEN, false);
- }
-
- void ReceiveEmote(Player* player, uint32 TextEmote) OVERRIDE
- {
- if (player->GetQuestStatus(QUEST_SCOOP) == QUEST_STATUS_INCOMPLETE)
- {
- if (TextEmote == TEXT_EMOTE_BECKON)
- {
- me->setFaction(FACTION_FRIENDLY);
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- DoCast(me, SPELL_PLUCKY_HUMAN, false);
- }
- }
-
- if (TextEmote == TEXT_EMOTE_CHICKEN)
- {
- if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
- return;
- else
- {
- me->setFaction(FACTION_FRIENDLY);
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- DoCast(me, SPELL_PLUCKY_HUMAN, false);
- me->HandleEmoteCommand(EMOTE_ONESHOT_WAVE);
- }
- }
- }
-
- void UpdateAI(uint32 Diff) OVERRIDE
- {
- if (me->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP))
- {
- if (ResetTimer <= Diff)
- {
- if (!me->GetVictim())
- EnterEvadeMode();
- else
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
-
- return;
- }
- else
- ResetTimer -= Diff;
- }
-
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
-enum PantherCage
-{
- ENRAGED_PANTHER = 10992
-};
-
-class go_panther_cage : public GameObjectScript
-{
-public:
- go_panther_cage() : GameObjectScript("go_panther_cage") { }
-
- bool OnGossipHello(Player* player, GameObject* go) OVERRIDE
- {
- go->UseDoorOrButton();
- if (player->GetQuestStatus(5151) == QUEST_STATUS_INCOMPLETE)
- {
- if (Creature* panther = go->FindNearestCreature(ENRAGED_PANTHER, 5, true))
- {
- panther->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- panther->SetReactState(REACT_AGGRESSIVE);
- panther->AI()->AttackStart(player);
- }
- }
-
- return true;
- }
-};
-
-class npc_enraged_panther : public CreatureScript
-{
-public:
- npc_enraged_panther() : CreatureScript("npc_enraged_panther") { }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_enraged_pantherAI(creature);
- }
-
- struct npc_enraged_pantherAI : public ScriptedAI
- {
- npc_enraged_pantherAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() OVERRIDE
- {
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_PASSIVE);
- }
-
- void UpdateAI(uint32 /*diff*/) OVERRIDE
- {
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
- }
- };
-
-};
-
void AddSC_thousand_needles()
{
- new npc_kanati();
- new npc_lakota_windsong();
- new npc_paoka_swiftmountain();
- new npc_plucky();
- new npc_enraged_panther();
- new go_panther_cage();
}
diff --git a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp
index 10538fb2387..b20ad20dea2 100644
--- a/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp
+++ b/src/server/scripts/Kalimdor/zone_thunder_bluff.cpp
@@ -48,33 +48,9 @@ class npc_cairne_bloodhoof : public CreatureScript
public:
npc_cairne_bloodhoof() : CreatureScript("npc_cairne_bloodhoof") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_SENDER_INFO)
- {
- player->CastSpell(player, 23123, false);
- player->SEND_GOSSIP_MENU(7014, creature->GetGUID());
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (creature->IsQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(925) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HCB, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
-
- player->SEND_GOSSIP_MENU(7013, creature->GetGUID());
-
- return true;
- }
-
CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- return new npc_cairne_bloodhoofAI(creature);
+ return new npc_cairne_bloodhoofAI (creature);
}
struct npc_cairne_bloodhoofAI : public ScriptedAI
diff --git a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp
index dd165f807b2..80354cbb1fd 100644
--- a/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp
+++ b/src/server/scripts/Kalimdor/zone_ungoro_crater.cpp
@@ -16,334 +16,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Ungoro Crater
-SD%Complete: 100
-SDComment: Support for Quest: 4245, 4491
-SDCategory: Ungoro Crater
-EndScriptData */
-
-/* ContentData
-npc_a-me
-npc_ringo
-EndContentData */
-
-#include "ScriptMgr.h"
-#include "ScriptedCreature.h"
-#include "ScriptedEscortAI.h"
-#include "ScriptedFollowerAI.h"
-#include "Player.h"
-#include "SpellInfo.h"
-
-enum AmeData
-{
- SAY_READY = 0,
- SAY_AGGRO1 = 1,
- SAY_SEARCH = 2,
- SAY_AGGRO2 = 3,
- SAY_AGGRO3 = 4,
- SAY_FINISH = 5,
-
- SPELL_DEMORALIZINGSHOUT = 13730,
-
- QUEST_CHASING_AME = 4245,
- ENTRY_TARLORD = 6519,
- ENTRY_TARLORD1 = 6519,
- ENTRY_STOMPER = 6513,
-};
-
-class npc_ame : public CreatureScript
-{
-public:
- npc_ame() : CreatureScript("npc_ame") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_CHASING_AME)
- {
- CAST_AI(npc_escortAI, (creature->AI()))->Start(false, false, player->GetGUID());
- creature->AI()->Talk(SAY_READY, player);
- creature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
- // Change faction so mobs attack
- creature->setFaction(113);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ameAI(creature);
- }
-
- struct npc_ameAI : public npc_escortAI
- {
- npc_ameAI(Creature* creature) : npc_escortAI(creature) { }
-
- uint32 DemoralizingShoutTimer;
-
- void WaypointReached(uint32 waypointId) OVERRIDE
- {
- if (Player* player = GetPlayerForEscort())
- {
- switch (waypointId)
- {
- case 19:
- me->SummonCreature(ENTRY_STOMPER, -6391.69f, -1730.49f, -272.83f, 4.96f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
- Talk(SAY_AGGRO1, player);
- break;
- case 28:
- Talk(SAY_SEARCH, player);
- break;
- case 38:
- me->SummonCreature(ENTRY_TARLORD, -6370.75f, -1382.84f, -270.51f, 6.06f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
- Talk(SAY_AGGRO2, player);
- break;
- case 49:
- me->SummonCreature(ENTRY_TARLORD1, -6324.44f, -1181.05f, -270.17f, 4.34f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 25000);
- Talk(SAY_AGGRO3, player);
- break;
- case 55:
- Talk(SAY_FINISH, player);
- player->GroupEventHappens(QUEST_CHASING_AME, me);
- break;
- }
- }
- }
-
- void Reset() OVERRIDE
- {
- DemoralizingShoutTimer = 5000;
- }
-
- void JustSummoned(Creature* summoned) OVERRIDE
- {
- summoned->AI()->AttackStart(me);
- }
-
- void JustDied(Unit* /*killer*/) OVERRIDE
- {
- if (Player* player = GetPlayerForEscort())
- player->FailQuest(QUEST_CHASING_AME);
- }
-
- void UpdateAI(uint32 diff) OVERRIDE
- {
- npc_escortAI::UpdateAI(diff);
- if (!UpdateVictim())
- return;
-
- if (DemoralizingShoutTimer <= diff)
- {
- DoCastVictim(SPELL_DEMORALIZINGSHOUT);
- DemoralizingShoutTimer = 70000;
- } else DemoralizingShoutTimer -= diff;
- }
- };
-};
-
-/*####
-# npc_ringo
-####*/
-
-enum Ringo
-{
- SAY_RIN_START = 0,
-
- SAY_FAINT = 1,
-
- SAY_WAKE = 2,
-
- SAY_RIN_END_1 = 3,
- SAY_SPR_END_2 = 0,
- SAY_RIN_END_3 = 4,
- EMOTE_RIN_END_4 = 5,
- EMOTE_RIN_END_5 = 6,
- SAY_RIN_END_6 = 7,
- SAY_SPR_END_7 = 1,
- EMOTE_RIN_END_8 = 8,
-
- SPELL_REVIVE_RINGO = 15591,
- QUEST_A_LITTLE_HELP = 4491,
- NPC_SPRAGGLE = 9997,
- FACTION_ESCORTEE = 113
-};
-
-class npc_ringo : public CreatureScript
-{
-public:
- npc_ringo() : CreatureScript("npc_ringo") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, const Quest* quest) OVERRIDE
- {
- if (quest->GetQuestId() == QUEST_A_LITTLE_HELP)
- {
- if (npc_ringoAI* ringoAI = CAST_AI(npc_ringo::npc_ringoAI, creature->AI()))
- {
- creature->SetStandState(UNIT_STAND_STATE_STAND);
- ringoAI->StartFollow(player, FACTION_ESCORTEE, quest);
- }
- }
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return new npc_ringoAI(creature);
- }
-
- struct npc_ringoAI : public FollowerAI
- {
- npc_ringoAI(Creature* creature) : FollowerAI(creature) { }
-
- uint32 FaintTimer;
- uint32 EndEventProgress;
- uint32 EndEventTimer;
-
- uint64 SpraggleGUID;
-
- void Reset() OVERRIDE
- {
- FaintTimer = urand(30000, 60000);
- EndEventProgress = 0;
- EndEventTimer = 1000;
- SpraggleGUID = 0;
- }
-
- void MoveInLineOfSight(Unit* who) OVERRIDE
-
- {
- FollowerAI::MoveInLineOfSight(who);
-
- if (!me->GetVictim() && !HasFollowState(STATE_FOLLOW_COMPLETE) && who->GetEntry() == NPC_SPRAGGLE)
- {
- if (me->IsWithinDistInMap(who, INTERACTION_DISTANCE))
- {
- if (Player* player = GetLeaderForFollower())
- {
- if (player->GetQuestStatus(QUEST_A_LITTLE_HELP) == QUEST_STATUS_INCOMPLETE)
- player->GroupEventHappens(QUEST_A_LITTLE_HELP, me);
- }
-
- SpraggleGUID = who->GetGUID();
- SetFollowComplete(true);
- }
- }
- }
-
- void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell) OVERRIDE
- {
- if (HasFollowState(STATE_FOLLOW_INPROGRESS | STATE_FOLLOW_PAUSED) && pSpell->Id == SPELL_REVIVE_RINGO)
- ClearFaint();
- }
-
- void SetFaint()
- {
- if (!HasFollowState(STATE_FOLLOW_POSTEVENT))
- {
- SetFollowPaused(true);
-
- Talk(SAY_FAINT);
- }
-
- //what does actually happen here? Emote? Aura?
- me->SetStandState(UNIT_STAND_STATE_SLEEP);
- }
-
- void ClearFaint()
- {
- me->SetStandState(UNIT_STAND_STATE_STAND);
-
- if (HasFollowState(STATE_FOLLOW_POSTEVENT))
- return;
-
- Talk(SAY_WAKE);
-
- SetFollowPaused(false);
- }
-
- void UpdateFollowerAI(uint32 Diff) OVERRIDE
- {
- if (!UpdateVictim())
- {
- if (HasFollowState(STATE_FOLLOW_POSTEVENT))
- {
- if (EndEventTimer <= Diff)
- {
- Creature* spraggle = Creature::GetCreature(*me, SpraggleGUID);
- if (!spraggle || !spraggle->IsAlive())
- {
- SetFollowComplete();
- return;
- }
-
- switch (EndEventProgress)
- {
- case 1:
- Talk(SAY_RIN_END_1);
- EndEventTimer = 3000;
- break;
- case 2:
- spraggle->AI()->Talk(SAY_SPR_END_2);
- EndEventTimer = 5000;
- break;
- case 3:
- Talk(SAY_RIN_END_3);
- EndEventTimer = 1000;
- break;
- case 4:
- Talk(EMOTE_RIN_END_4);
- SetFaint();
- EndEventTimer = 9000;
- break;
- case 5:
- Talk(EMOTE_RIN_END_5);
- ClearFaint();
- EndEventTimer = 1000;
- break;
- case 6:
- Talk(SAY_RIN_END_6);
- EndEventTimer = 3000;
- break;
- case 7:
- spraggle->AI()->Talk(SAY_SPR_END_7);
- EndEventTimer = 10000;
- break;
- case 8:
- Talk(EMOTE_RIN_END_8);
- EndEventTimer = 5000;
- break;
- case 9:
- SetFollowComplete();
- break;
- }
-
- ++EndEventProgress;
- }
- else
- EndEventTimer -= Diff;
- }
- else if (HasFollowState(STATE_FOLLOW_INPROGRESS) && !HasFollowState(STATE_FOLLOW_PAUSED))
- {
- if (FaintTimer <= Diff)
- {
- SetFaint();
- FaintTimer = urand(60000, 120000);
- }
- else
- FaintTimer -= Diff;
- }
-
- return;
- }
-
- DoMeleeAttackIfReady();
- }
- };
-};
-
void AddSC_ungoro_crater()
{
- new npc_ame();
- new npc_ringo();
}
diff --git a/src/server/scripts/Maelstrom/CMakeLists.txt b/src/server/scripts/Maelstrom/CMakeLists.txt
new file mode 100644
index 00000000000..79f0789fd3f
--- /dev/null
+++ b/src/server/scripts/Maelstrom/CMakeLists.txt
@@ -0,0 +1,14 @@
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+set(scripts_STAT_SRCS
+ ${scripts_STAT_SRCS}
+ Maelstrom/kezan.cpp
+)
+
+message(" -> Prepared: The Maelstrom")
diff --git a/src/server/scripts/Maelstrom/kezan.cpp b/src/server/scripts/Maelstrom/kezan.cpp
new file mode 100644
index 00000000000..c20ed30ea74
--- /dev/null
+++ b/src/server/scripts/Maelstrom/kezan.cpp
@@ -0,0 +1,129 @@
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedGossip.h"
+#include "Player.h"
+
+/*####
+## npc_defiant_troll (http://www.wowhead.com/quest=14069)
+####*/
+
+enum DefiantTrollEnum
+{
+ DEFFIANT_KILL_CREDIT = 34830,
+ SPELL_LIGHTNING_VISUAL = 45870,
+ SPELL_ENRAGE = 45111,
+ QUEST_GOOD_HELP_IS_HARD_TO_FIND = 14069,
+ GO_DEPOSIT = 195489,
+ SAY_WORK = 0
+};
+
+class npc_defiant_troll : public CreatureScript
+{
+public:
+ npc_defiant_troll() : CreatureScript("npc_defiant_troll") { }
+
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
+ {
+ return new npc_defiant_trollAI(creature);
+ }
+
+ struct npc_defiant_trollAI : public ScriptedAI
+ {
+ npc_defiant_trollAI(Creature* creature) : ScriptedAI(creature) { }
+
+ uint32 rebuffTimer;
+ bool work;
+
+ void Reset () OVERRIDE
+ {
+ rebuffTimer = 0;
+ work = false;
+ me->CastSpell(me, SPELL_ENRAGE, true);
+ }
+
+ void MovementInform(uint32 /*type*/, uint32 id) OVERRIDE
+ {
+ if (id == 1)
+ work = true;
+ }
+
+ bool IsWorking() const { return work; }
+
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (IsWorking())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_WORK_MINING);
+
+ if (rebuffTimer <= diff)
+ {
+ Reset();
+
+ switch (urand(0, 2))
+ {
+ case 0:
+ me->HandleEmoteCommand(EMOTE_STATE_EXCLAIM);
+ break;
+ case 1:
+ me->HandleEmoteCommand(EMOTE_STATE_DANCE);
+ break;
+ case 2:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_NONE);
+ break;
+ }
+ rebuffTimer = 120000; // Rebuff again in 2 minutes
+ }
+ else
+ rebuffTimer -= diff;
+
+ if (!UpdateVictim())
+ return;
+
+ //DoMeleeAttackIfReady();
+ }
+ };
+
+ bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
+ {
+ if (player->GetQuestStatus(QUEST_GOOD_HELP_IS_HARD_TO_FIND) == QUEST_STATUS_INCOMPLETE && !CAST_AI(npc_defiant_troll::npc_defiant_trollAI, creature->AI())->IsWorking())
+ {
+ player->CastSpell(creature, SPELL_LIGHTNING_VISUAL, true);
+ player->KilledMonsterCredit(DEFFIANT_KILL_CREDIT, creature->GetGUID());
+ creature->AI()->Talk(SAY_WORK);
+ creature->RemoveAllAuras();
+
+ if (GameObject* deposit = creature->FindNearestGameObject(GO_DEPOSIT, 20))
+ creature->GetMotionMaster()->MovePoint(1, deposit->GetPositionX() - 1.0f, deposit->GetPositionY(), deposit->GetPositionZ());
+
+ if (player->GetQuestStatus(QUEST_GOOD_HELP_IS_HARD_TO_FIND) == QUEST_STATUS_COMPLETE)
+ player->RemoveAura(SPELL_LIGHTNING_VISUAL);
+
+ player->CLOSE_GOSSIP_MENU();
+
+ return true;
+ }
+
+ player->CLOSE_GOSSIP_MENU();
+
+ return false;
+ }
+};
+
+void AddSC_kezan()
+{
+ new npc_defiant_troll();
+}
diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp
index 84c9181e495..fd6cce871d0 100644
--- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp
+++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_elder_nadox.cpp
@@ -145,7 +145,7 @@ class boss_elder_nadox : public CreatureScript
}
}
- if (me->HealthBelowPct(100 - AmountHealthModifier * 25))
+ if (me->HealthBelowPct(100 - AmountHealthModifier* 25))
{
Talk(EMOTE_HATCHES, me);
DoCast(me, SPELL_SUMMON_SWARM_GUARD);
@@ -271,7 +271,7 @@ public:
void FilterTargets(std::list<WorldObject*>& targets)
{
- targets.remove_if(GuardianCheck());
+ targets.remove_if (GuardianCheck());
}
void Register() OVERRIDE
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
index c35c9ba2d11..b5bd510addc 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp
@@ -20,7 +20,6 @@
#include "SpellAuraEffects.h"
#include "Spell.h"
#include "Vehicle.h"
-#include "MapManager.h"
#include "GameObjectAI.h"
#include "ScriptedCreature.h"
#include "ruby_sanctum.h"
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
index d2f6b8a3420..92eee0e9151 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_grand_champions.cpp
@@ -132,9 +132,9 @@ bool GrandChampionsOutVehicle(Creature* me)
if (pGrandChampion1 && pGrandChampion2 && pGrandChampion3)
{
- if (!pGrandChampion1->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
- !pGrandChampion2->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) &&
- !pGrandChampion3->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!pGrandChampion1->m_movementInfo.transport.guid &&
+ !pGrandChampion2->m_movementInfo.transport.guid &&
+ !pGrandChampion3->m_movementInfo.transport.guid)
return true;
}
@@ -383,7 +383,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiInterceptTimer <= uiDiff)
@@ -525,7 +525,7 @@ public:
uiFireBallTimer = 5000;
} else uiFireBallTimer -= uiDiff;
- if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiFireBallTimer <= uiDiff)
@@ -661,7 +661,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiChainLightningTimer <= uiDiff)
@@ -805,7 +805,7 @@ public:
}
}else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiLightningArrowsTimer <= uiDiff)
@@ -951,7 +951,7 @@ public:
}
} else uiPhaseTimer -= uiDiff;
- if (!UpdateVictim() || me->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ if (!UpdateVictim() || me->m_movementInfo.transport.guid)
return;
if (uiEviscerateTimer <= uiDiff)
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
index f05f2c20b12..b678c22bf25 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lady_deathwhisper.cpp
@@ -356,7 +356,7 @@ class boss_lady_deathwhisper : public CreatureScript
void DamageTaken(Unit* /*damageDealer*/, uint32& damage) OVERRIDE
{
// phase transition
- if (events.IsInPhase(PHASE_ONE) && damage > me->GetPower(POWER_MANA))
+ if (events.IsInPhase(PHASE_ONE) && damage > uint32(me->GetPower(POWER_MANA)))
{
Talk(SAY_PHASE_2);
Talk(EMOTE_PHASE_2);
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 30d520ce7bf..d79c6a7f8e3 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -343,9 +343,7 @@ enum MiscData
SOUND_PAIN = 17360, // separate sound, not attached to any text
EQUIP_ASHBRINGER_GLOWING = 50442,
- EQUIP_BROKEN_FROSTMOURNE = 50840,
-
- MOVIE_FALL_OF_THE_LICH_KING = 16,
+ EQUIP_BROKEN_FROSTMOURNE = 50840
};
enum Misc
@@ -377,25 +375,6 @@ class NecroticPlagueTargetCheck : public std::unary_function<Unit*, bool>
uint32 _notAura2;
};
-class HeightDifferenceCheck
-{
- public:
- HeightDifferenceCheck(GameObject* go, float diff, bool reverse)
- : _baseObject(go), _difference(diff), _reverse(reverse)
- {
- }
-
- bool operator()(WorldObject* unit) const
- {
- return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;
- }
-
- private:
- GameObject* _baseObject;
- float _difference;
- bool _reverse;
-};
-
class FrozenThroneResetWorker
{
public:
@@ -1118,6 +1097,7 @@ class boss_the_lich_king : public CreatureScript
{
WorldPacket data(SMSG_PLAY_MUSIC, 4);
data << uint32(musicId);
+ data << uint64(me->GetGUID());
SendPacketToPlayers(&data);
}
@@ -1529,7 +1509,7 @@ class npc_valkyr_shadowguard : public CreatureScript
{
std::list<Creature*> triggers;
GetCreatureListWithEntryInGrid(triggers, me, NPC_WORLD_TRIGGER, 150.0f);
- triggers.remove_if(HeightDifferenceCheck(platform, 5.0f, true));
+ triggers.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, true));
if (triggers.empty())
return;
@@ -2320,7 +2300,7 @@ class spell_the_lich_king_quake : public SpellScriptLoader
void FilterTargets(std::list<WorldObject*>& targets)
{
if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM)))
- targets.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
+ targets.remove_if(Trinity::HeightDifferenceCheck(platform, 5.0f, false));
}
void HandleSendEvent(SpellEffIndex /*effIndex*/)
@@ -3183,41 +3163,6 @@ class spell_the_lich_king_jump_remove_aura : public SpellScriptLoader
}
};
-class spell_the_lich_king_play_movie : public SpellScriptLoader
-{
- public:
- spell_the_lich_king_play_movie() : SpellScriptLoader("spell_the_lich_king_play_movie") { }
-
- class spell_the_lich_king_play_movie_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_the_lich_king_play_movie_SpellScript);
-
- bool Validate(SpellInfo const* /*spell*/) OVERRIDE
- {
- if (!sMovieStore.LookupEntry(MOVIE_FALL_OF_THE_LICH_KING))
- return false;
- return true;
- }
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- if (Player* player = GetHitPlayer())
- player->SendMovieStart(MOVIE_FALL_OF_THE_LICH_KING);
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_play_movie_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_the_lich_king_play_movie_SpellScript();
- }
-};
-
class achievement_been_waiting_long_time : public AchievementCriteriaScript
{
public:
@@ -3288,7 +3233,6 @@ void AddSC_boss_the_lich_king()
new spell_the_lich_king_jump();
new spell_the_lich_king_jump_remove_aura();
new spell_trigger_spell_from_caster("spell_the_lich_king_mass_resurrection", SPELL_MASS_RESURRECTION_REAL);
- new spell_the_lich_king_play_movie();
new achievement_been_waiting_long_time();
new achievement_neck_deep_in_vile();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index edd80377d68..f110f04f16c 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -520,13 +520,9 @@ class instance_icecrown_citadel : public InstanceMapScript
go->SetGoState(GO_STATE_ACTIVE);
break;
case GO_ARTHAS_PLATFORM:
- // this enables movement at The Frozen Throne, when printed this value is 0.000000f
- // however, when represented as integer client will accept only this value
- go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 5535469);
ArthasPlatformGUID = go->GetGUID();
break;
case GO_ARTHAS_PRECIPICE:
- go->SetUInt32Value(GAMEOBJECT_PARENTROTATION, 4178312);
ArthasPrecipiceGUID = go->GetGUID();
break;
case GO_DOODAD_ICECROWN_THRONEFROSTYEDGE01:
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 7ae9ce3faa6..58f8943fae6 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -95,8 +95,8 @@ enum Spells
SPELL_RANDOM_PORTAL = 56047,
SPELL_PORTAL_BEAM = 56046, // Malygos cast on portal to activate it during PHASE_NOT_STARTED
- //Phase I
- SPELL_BERSERK = 60670,
+ // Phase I
+ SPELL_BERSERK = 60670,
SPELL_MALYGOS_BERSERK = 47008, // it's the berserk spell that will hit only Malygos after 10 min of 60670
SPELL_PORTAL_VISUAL_CLOSED = 55949,
SPELL_SUMMON_POWER_PARK = 56142,
@@ -1534,7 +1534,7 @@ public:
}
}
- void UpdateAI(uint32 /*diff*/)
+ void UpdateAI(uint32 /*diff*/) OVERRIDE
{
}
diff --git a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp
index 7a9ea8ec9c3..9a43c54f7bc 100644
--- a/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp
+++ b/src/server/scripts/Northrend/Nexus/Nexus/boss_commander_stoutbeard.cpp
@@ -35,7 +35,6 @@ enum CommanderStoutbeard
SPELL_WHIRLWIND_2 = 38618
};
-
class boss_commander_stoutbeard : public CreatureScript
{
public:
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
index a809eb4ddff..5b43e8d1bf6 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
@@ -535,7 +535,6 @@ class spell_auriaya_sentinel_blast : public SpellScriptLoader
}
};
-
class achievement_nine_lives : public AchievementCriteriaScript
{
public:
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 ee1345590f3..96840842d24 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -535,7 +535,7 @@ class boss_flame_leviathan : public CreatureScript
}
private:
- //! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough getVictim this way -
+ //! Copypasta from DoSpellAttackIfReady, only difference is the target - it cannot be selected trough GetVictim this way -
//! I also removed the spellInfo check
void DoBatteringRamIfReady()
{
@@ -1179,7 +1179,7 @@ class npc_lorekeeper : public CreatureScript
if (Creature* Branz = creature->FindNearestCreature(NPC_BRANZ_BRONZBEARD, 1000, true))
{
Delorah->GetMotionMaster()->MovePoint(0, Branz->GetPositionX()-4, Branz->GetPositionY(), Branz->GetPositionZ());
- /// @todo Delorah->AI()->Talk(xxxx, Branz->GetGUID()); when reached at branz
+ /// @todo Delorah->AI()->Talk(xxxx, Branz); when reached at branz
}
}
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
index 1bcbc63a8ab..8479a6bee21 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
@@ -348,7 +348,6 @@ class spell_frost_tomb : public SpellScriptLoader
}
};
-
class achievement_on_the_rocks : public AchievementCriteriaScript
{
public:
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp
index 0ad12a15092..9d044d712bd 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/utgarde_keep.cpp
@@ -21,6 +21,11 @@
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+enum Spells
+{
+ SPELL_UK_SECOUND_WIND_TRIGGER = 42771
+};
+
uint32 ForgeSearch[3] =
{
GO_GLOWING_ANVIL_1,
@@ -295,10 +300,56 @@ class npc_enslaved_proto_drake : public CreatureScript
}
};
+class spell_uk_second_wind_proc : public SpellScriptLoader
+{
+ public:
+ spell_uk_second_wind_proc() : SpellScriptLoader("spell_uk_second_wind_proc") { }
+
+ class spell_uk_second_wind_proc_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_uk_second_wind_proc_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_UK_SECOUND_WIND_TRIGGER))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ if (eventInfo.GetProcTarget() == GetTarget())
+ return false;
+ if (!(eventInfo.GetDamageInfo() || eventInfo.GetDamageInfo()->GetSpellInfo()->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastCustomSpell(SPELL_UK_SECOUND_WIND_TRIGGER, SPELLVALUE_BASE_POINT0, 5, GetTarget(), true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_uk_second_wind_proc_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_uk_second_wind_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_uk_second_wind_proc_AuraScript();
+ }
+};
+
void AddSC_utgarde_keep()
{
new npc_dragonflayer_forge_master();
new npc_enslaved_proto_drake();
new spell_ticking_time_bomb();
new spell_fixate();
+ new spell_uk_second_wind_proc();
}
diff --git a/src/server/scripts/Northrend/zone_dalaran.cpp b/src/server/scripts/Northrend/zone_dalaran.cpp
index a9c89dbf3da..bfdbfcee2ef 100644
--- a/src/server/scripts/Northrend/zone_dalaran.cpp
+++ b/src/server/scripts/Northrend/zone_dalaran.cpp
@@ -129,52 +129,7 @@ public:
}
};
-/*######
-## npc_hira_snowdawn
-######*/
-
-enum HiraSnowdawn
-{
- SPELL_COLD_WEATHER_FLYING = 54197
-};
-
-#define GOSSIP_TEXT_TRAIN_HIRA "I seek training to ride a steed."
-
-class npc_hira_snowdawn : public CreatureScript
-{
-public:
- npc_hira_snowdawn() : CreatureScript("npc_hira_snowdawn") { }
-
- bool OnGossipHello(Player* player, Creature* creature) OVERRIDE
- {
- if (!creature->IsVendor() || !creature->IsTrainer())
- return false;
-
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_TRAIN_HIRA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRAIN);
-
- if (player->getLevel() >= 80 && player->HasSpell(SPELL_COLD_WEATHER_FLYING))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) OVERRIDE
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_TRAIN)
- player->GetSession()->SendTrainerList(creature->GetGUID());
-
- if (action == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
-
- return true;
- }
-};
-
void AddSC_dalaran()
{
new npc_mageguard_dalaran;
- new npc_hira_snowdawn;
}
diff --git a/src/server/scripts/OutdoorPvP/CMakeLists.txt b/src/server/scripts/OutdoorPvP/CMakeLists.txt
index 01347e134ea..3c22f1431d8 100644
--- a/src/server/scripts/OutdoorPvP/CMakeLists.txt
+++ b/src/server/scripts/OutdoorPvP/CMakeLists.txt
@@ -17,8 +17,6 @@ set(scripts_STAT_SRCS
OutdoorPvP/OutdoorPvPNA.cpp
OutdoorPvP/OutdoorPvPHP.cpp
OutdoorPvP/OutdoorPvPTF.h
- OutdoorPvP/OutdoorPvPEP.h
- OutdoorPvP/OutdoorPvPEP.cpp
OutdoorPvP/OutdoorPvPHP.h
OutdoorPvP/OutdoorPvPZM.h
OutdoorPvP/OutdoorPvPNA.h
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp
deleted file mode 100644
index b8a28a3248a..00000000000
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.cpp
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * 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 "ScriptMgr.h"
-#include "OutdoorPvPEP.h"
-#include "WorldPacket.h"
-#include "Player.h"
-#include "GameObject.h"
-#include "ObjectMgr.h"
-#include "ObjectAccessor.h"
-#include "OutdoorPvPMgr.h"
-#include "Creature.h"
-#include "Language.h"
-#include "World.h"
-#include "GossipDef.h"
-
-OPvPCapturePointEP_EWT::OPvPCapturePointEP_EWT(OutdoorPvP* pvp)
-: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_UnitsSummonedSide(0)
-{
- SetCapturePointData(EPCapturePoints[EP_EWT].entry, EPCapturePoints[EP_EWT].map, EPCapturePoints[EP_EWT].x, EPCapturePoints[EP_EWT].y, EPCapturePoints[EP_EWT].z, EPCapturePoints[EP_EWT].o, EPCapturePoints[EP_EWT].rot0, EPCapturePoints[EP_EWT].rot1, EPCapturePoints[EP_EWT].rot2, EPCapturePoints[EP_EWT].rot3);
- AddObject(EP_EWT_FLAGS, EPTowerFlags[EP_EWT].entry, EPTowerFlags[EP_EWT].map, EPTowerFlags[EP_EWT].x, EPTowerFlags[EP_EWT].y, EPTowerFlags[EP_EWT].z, EPTowerFlags[EP_EWT].o, EPTowerFlags[EP_EWT].rot0, EPTowerFlags[EP_EWT].rot1, EPTowerFlags[EP_EWT].rot2, EPTowerFlags[EP_EWT].rot3);
-}
-
-void OPvPCapturePointEP_EWT::ChangeState()
-{
- // if changing from controlling alliance to horde or vice versa
- if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_A));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0);
- }
- else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_EWT_H));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, 0);
- }
-
- uint32 artkit = 21;
-
- switch (m_State)
- {
- case OBJECTIVESTATE_ALLIANCE:
- m_TowerState = EP_TS_A;
- artkit = 2;
- SummonSupportUnitAtNorthpassTower(ALLIANCE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, ALLIANCE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_A));
- break;
- case OBJECTIVESTATE_HORDE:
- m_TowerState = EP_TS_H;
- artkit = 1;
- SummonSupportUnitAtNorthpassTower(HORDE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_EWT, HORDE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_H));
- break;
- case OBJECTIVESTATE_NEUTRAL:
- m_TowerState = EP_TS_N;
- break;
- case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
- case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- break;
- case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
- case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- break;
- }
-
- GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
- GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_EWT_FLAGS]);
- if (flag)
- {
- flag->SetGoArtKit(artkit);
- }
- if (flag2)
- {
- flag2->SetGoArtKit(artkit);
- }
-
- UpdateTowerState();
-
- // complete quest objective
- if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
- SendObjectiveComplete(EP_EWT_CM, 0);
-}
-
-void OPvPCapturePointEP_EWT::SendChangePhase()
-{
- // send this too, sometimes the slider disappears, dunno why :(
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- // send these updates to only the ones in this objective
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- // send this too, sometimes it resets :S
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
-}
-
-void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket &data)
-{
- data << EP_EWT_A << uint32(bool(m_TowerState & EP_TS_A));
- data << EP_EWT_H << uint32(bool(m_TowerState & EP_TS_H));
- data << EP_EWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
- data << EP_EWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
- data << EP_EWT_N << uint32(bool(m_TowerState & EP_TS_N));
-}
-
-void OPvPCapturePointEP_EWT::UpdateTowerState()
-{
- m_PvP->SendUpdateWorldState(EP_EWT_A, bool(m_TowerState & EP_TS_A));
- m_PvP->SendUpdateWorldState(EP_EWT_H, bool(m_TowerState & EP_TS_H));
- m_PvP->SendUpdateWorldState(EP_EWT_N_A, bool(m_TowerState & EP_TS_N_A));
- m_PvP->SendUpdateWorldState(EP_EWT_N_H, bool(m_TowerState & EP_TS_N_H));
- m_PvP->SendUpdateWorldState(EP_EWT_N, bool(m_TowerState & EP_TS_N));
-}
-
-bool OPvPCapturePointEP_EWT::HandlePlayerEnter(Player* player)
-{
- if (OPvPCapturePoint::HandlePlayerEnter(player))
- {
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
- return true;
- }
- return false;
-}
-
-void OPvPCapturePointEP_EWT::HandlePlayerLeave(Player* player)
-{
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
- OPvPCapturePoint::HandlePlayerLeave(player);
-}
-
-void OPvPCapturePointEP_EWT::SummonSupportUnitAtNorthpassTower(uint32 team)
-{
- if (m_UnitsSummonedSide != team)
- {
- m_UnitsSummonedSide = team;
- const creature_type * ct = NULL;
- if (team == ALLIANCE)
- ct=EP_EWT_Summons_A;
- else
- ct=EP_EWT_Summons_H;
-
- for (uint8 i = 0; i < EP_EWT_NUM_CREATURES; ++i)
- {
- DelCreature(i);
- AddCreature(i, ct[i].entry, ct[i].teamval, ct[i].map, ct[i].x, ct[i].y, ct[i].z, ct[i].o, 1000000);
- }
- }
-}
-
-// NPT
-OPvPCapturePointEP_NPT::OPvPCapturePointEP_NPT(OutdoorPvP* pvp)
-: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_SummonedGOSide(0)
-{
- SetCapturePointData(EPCapturePoints[EP_NPT].entry, EPCapturePoints[EP_NPT].map, EPCapturePoints[EP_NPT].x, EPCapturePoints[EP_NPT].y, EPCapturePoints[EP_NPT].z, EPCapturePoints[EP_NPT].o, EPCapturePoints[EP_NPT].rot0, EPCapturePoints[EP_NPT].rot1, EPCapturePoints[EP_NPT].rot2, EPCapturePoints[EP_NPT].rot3);
- AddObject(EP_NPT_FLAGS, EPTowerFlags[EP_NPT].entry, EPTowerFlags[EP_NPT].map, EPTowerFlags[EP_NPT].x, EPTowerFlags[EP_NPT].y, EPTowerFlags[EP_NPT].z, EPTowerFlags[EP_NPT].o, EPTowerFlags[EP_NPT].rot0, EPTowerFlags[EP_NPT].rot1, EPTowerFlags[EP_NPT].rot2, EPTowerFlags[EP_NPT].rot3);
-}
-
-void OPvPCapturePointEP_NPT::ChangeState()
-{
- // if changing from controlling alliance to horde or vice versa
- if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_A));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0);
- }
- else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_NPT_H));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, 0);
- }
-
- uint32 artkit = 21;
-
- switch (m_State)
- {
- case OBJECTIVESTATE_ALLIANCE:
- m_TowerState = EP_TS_A;
- artkit = 2;
- SummonGO(ALLIANCE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, ALLIANCE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_A));
- break;
- case OBJECTIVESTATE_HORDE:
- m_TowerState = EP_TS_H;
- artkit = 1;
- SummonGO(HORDE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_NPT, HORDE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_H));
- break;
- case OBJECTIVESTATE_NEUTRAL:
- m_TowerState = EP_TS_N;
- m_SummonedGOSide = 0;
- DelObject(EP_NPT_BUFF);
- break;
- case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- break;
- case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- m_SummonedGOSide = 0;
- DelObject(EP_NPT_BUFF);
- break;
- case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- break;
- case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- m_SummonedGOSide = 0;
- DelObject(EP_NPT_BUFF);
- break;
- }
-
- GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
- GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_FLAGS]);
- if (flag)
- {
- flag->SetGoArtKit(artkit);
- }
- if (flag2)
- {
- flag2->SetGoArtKit(artkit);
- }
-
- UpdateTowerState();
-
- // complete quest objective
- if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
- SendObjectiveComplete(EP_NPT_CM, 0);
-}
-
-void OPvPCapturePointEP_NPT::SendChangePhase()
-{
- // send this too, sometimes the slider disappears, dunno why :(
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- // send these updates to only the ones in this objective
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- // send this too, sometimes it resets :S
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
-}
-
-void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket &data)
-{
- data << EP_NPT_A << uint32(bool(m_TowerState & EP_TS_A));
- data << EP_NPT_H << uint32(bool(m_TowerState & EP_TS_H));
- data << EP_NPT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
- data << EP_NPT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
- data << EP_NPT_N << uint32(bool(m_TowerState & EP_TS_N));
-}
-
-void OPvPCapturePointEP_NPT::UpdateTowerState()
-{
- m_PvP->SendUpdateWorldState(EP_NPT_A, bool(m_TowerState & EP_TS_A));
- m_PvP->SendUpdateWorldState(EP_NPT_H, bool(m_TowerState & EP_TS_H));
- m_PvP->SendUpdateWorldState(EP_NPT_N_A, bool(m_TowerState & EP_TS_N_A));
- m_PvP->SendUpdateWorldState(EP_NPT_N_H, bool(m_TowerState & EP_TS_N_H));
- m_PvP->SendUpdateWorldState(EP_NPT_N, bool(m_TowerState & EP_TS_N));
-}
-
-bool OPvPCapturePointEP_NPT::HandlePlayerEnter(Player* player)
-{
- if (OPvPCapturePoint::HandlePlayerEnter(player))
- {
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
- return true;
- }
- return false;
-}
-
-void OPvPCapturePointEP_NPT::HandlePlayerLeave(Player* player)
-{
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
- OPvPCapturePoint::HandlePlayerLeave(player);
-}
-
-void OPvPCapturePointEP_NPT::SummonGO(uint32 team)
-{
- if (m_SummonedGOSide != team)
- {
- m_SummonedGOSide = team;
- DelObject(EP_NPT_BUFF);
- AddObject(EP_NPT_BUFF, EP_NPT_LordaeronShrine.entry, EP_NPT_LordaeronShrine.map, EP_NPT_LordaeronShrine.x, EP_NPT_LordaeronShrine.y, EP_NPT_LordaeronShrine.z, EP_NPT_LordaeronShrine.o, EP_NPT_LordaeronShrine.rot0, EP_NPT_LordaeronShrine.rot1, EP_NPT_LordaeronShrine.rot2, EP_NPT_LordaeronShrine.rot3);
- GameObject* go = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_BUFF]);
- if (go)
- go->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 84 : 83));
- }
-}
-
-// CGT
-OPvPCapturePointEP_CGT::OPvPCapturePointEP_CGT(OutdoorPvP* pvp)
-: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_GraveyardSide(0)
-{
- SetCapturePointData(EPCapturePoints[EP_CGT].entry, EPCapturePoints[EP_CGT].map, EPCapturePoints[EP_CGT].x, EPCapturePoints[EP_CGT].y, EPCapturePoints[EP_CGT].z, EPCapturePoints[EP_CGT].o, EPCapturePoints[EP_CGT].rot0, EPCapturePoints[EP_CGT].rot1, EPCapturePoints[EP_CGT].rot2, EPCapturePoints[EP_CGT].rot3);
- AddObject(EP_CGT_FLAGS, EPTowerFlags[EP_CGT].entry, EPTowerFlags[EP_CGT].map, EPTowerFlags[EP_CGT].x, EPTowerFlags[EP_CGT].y, EPTowerFlags[EP_CGT].z, EPTowerFlags[EP_CGT].o, EPTowerFlags[EP_CGT].rot0, EPTowerFlags[EP_CGT].rot1, EPTowerFlags[EP_CGT].rot2, EPTowerFlags[EP_CGT].rot3);
-}
-
-void OPvPCapturePointEP_CGT::ChangeState()
-{
- // if changing from controlling alliance to horde or vice versa
- if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_A));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0);
- }
- else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_CGT_H));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, 0);
- }
-
- uint32 artkit = 21;
-
- switch (m_State)
- {
- case OBJECTIVESTATE_ALLIANCE:
- m_TowerState = EP_TS_A;
- artkit = 2;
- LinkGraveYard(ALLIANCE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, ALLIANCE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_A));
- break;
- case OBJECTIVESTATE_HORDE:
- m_TowerState = EP_TS_H;
- artkit = 1;
- LinkGraveYard(HORDE);
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_CGT, HORDE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_H));
- break;
- case OBJECTIVESTATE_NEUTRAL:
- m_TowerState = EP_TS_N;
- break;
- case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
- case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- break;
- case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
- case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- break;
- }
-
- GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
- GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_CGT_FLAGS]);
- if (flag)
- {
- flag->SetGoArtKit(artkit);
- }
- if (flag2)
- {
- flag2->SetGoArtKit(artkit);
- }
-
- UpdateTowerState();
-
- // complete quest objective
- if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
- SendObjectiveComplete(EP_CGT_CM, 0);
-}
-
-void OPvPCapturePointEP_CGT::SendChangePhase()
-{
- // send this too, sometimes the slider disappears, dunno why :(
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- // send these updates to only the ones in this objective
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- // send this too, sometimes it resets :S
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
-}
-
-void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket &data)
-{
- data << EP_CGT_A << uint32(bool(m_TowerState & EP_TS_A));
- data << EP_CGT_H << uint32(bool(m_TowerState & EP_TS_H));
- data << EP_CGT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
- data << EP_CGT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
- data << EP_CGT_N << uint32(bool(m_TowerState & EP_TS_N));
-}
-
-void OPvPCapturePointEP_CGT::UpdateTowerState()
-{
- m_PvP->SendUpdateWorldState(EP_CGT_A, bool(m_TowerState & EP_TS_A));
- m_PvP->SendUpdateWorldState(EP_CGT_H, bool(m_TowerState & EP_TS_H));
- m_PvP->SendUpdateWorldState(EP_CGT_N_A, bool(m_TowerState & EP_TS_N_A));
- m_PvP->SendUpdateWorldState(EP_CGT_N_H, bool(m_TowerState & EP_TS_N_H));
- m_PvP->SendUpdateWorldState(EP_CGT_N, bool(m_TowerState & EP_TS_N));
-}
-
-bool OPvPCapturePointEP_CGT::HandlePlayerEnter(Player* player)
-{
- if (OPvPCapturePoint::HandlePlayerEnter(player))
- {
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
- return true;
- }
- return false;
-}
-
-void OPvPCapturePointEP_CGT::HandlePlayerLeave(Player* player)
-{
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
- OPvPCapturePoint::HandlePlayerLeave(player);
-}
-
-void OPvPCapturePointEP_CGT::LinkGraveYard(uint32 team)
-{
- if (m_GraveyardSide != team)
- {
- m_GraveyardSide = team;
- sObjectMgr->RemoveGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false);
- sObjectMgr->AddGraveYardLink(EP_GraveYardId, EP_GraveYardZone, team, false);
- }
-}
-
-// PWT
-OPvPCapturePointEP_PWT::OPvPCapturePointEP_PWT(OutdoorPvP* pvp)
-: OPvPCapturePoint(pvp), m_FlightMasterSpawned(0), m_TowerState(EP_TS_N)
-{
- SetCapturePointData(EPCapturePoints[EP_PWT].entry, EPCapturePoints[EP_PWT].map, EPCapturePoints[EP_PWT].x, EPCapturePoints[EP_PWT].y, EPCapturePoints[EP_PWT].z, EPCapturePoints[EP_PWT].o, EPCapturePoints[EP_PWT].rot0, EPCapturePoints[EP_PWT].rot1, EPCapturePoints[EP_PWT].rot2, EPCapturePoints[EP_PWT].rot3);
- AddObject(EP_PWT_FLAGS, EPTowerFlags[EP_PWT].entry, EPTowerFlags[EP_PWT].map, EPTowerFlags[EP_PWT].x, EPTowerFlags[EP_PWT].y, EPTowerFlags[EP_PWT].z, EPTowerFlags[EP_PWT].o, EPTowerFlags[EP_PWT].rot0, EPTowerFlags[EP_PWT].rot1, EPTowerFlags[EP_PWT].rot2, EPTowerFlags[EP_PWT].rot3);
-}
-
-void OPvPCapturePointEP_PWT::ChangeState()
-{
- // if changing from controlling alliance to horde or vice versa
- if ( m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_A));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0);
- }
- else if ( m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State )
- {
- sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOSE_PWT_H));
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, 0);
- }
-
- uint32 artkit = 21;
-
- switch (m_State)
- {
- case OBJECTIVESTATE_ALLIANCE:
- m_TowerState = EP_TS_A;
- SummonFlightMaster(ALLIANCE);
- artkit = 2;
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, ALLIANCE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_A));
- break;
- case OBJECTIVESTATE_HORDE:
- m_TowerState = EP_TS_H;
- SummonFlightMaster(HORDE);
- artkit = 1;
- ((OutdoorPvPEP*)m_PvP)->SetControlledState(EP_PWT, HORDE);
- if (m_OldState != m_State) sWorld->SendZoneText(EP_GraveYardZone, sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_H));
- break;
- case OBJECTIVESTATE_NEUTRAL:
- m_TowerState = EP_TS_N;
- DelCreature(EP_PWT_FLIGHTMASTER);
- m_FlightMasterSpawned = 0;
- break;
- case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- break;
- case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
- m_TowerState = EP_TS_N_A;
- DelCreature(EP_PWT_FLIGHTMASTER);
- m_FlightMasterSpawned = 0;
- break;
- case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- break;
- case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
- m_TowerState = EP_TS_N_H;
- DelCreature(EP_PWT_FLIGHTMASTER);
- m_FlightMasterSpawned = 0;
- break;
- }
-
- GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
- GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_PWT_FLAGS]);
- if (flag)
- {
- flag->SetGoArtKit(artkit);
- }
- if (flag2)
- {
- flag2->SetGoArtKit(artkit);
- }
-
- UpdateTowerState();
-
- // complete quest objective
- if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
- SendObjectiveComplete(EP_PWT_CM, 0);
-}
-
-void OPvPCapturePointEP_PWT::SendChangePhase()
-{
- // send this too, sometimes the slider disappears, dunno why :(
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- // send these updates to only the ones in this objective
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- // send this too, sometimes it resets :S
- SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
-}
-
-void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket &data)
-{
- data << EP_PWT_A << uint32(bool(m_TowerState & EP_TS_A));
- data << EP_PWT_H << uint32(bool(m_TowerState & EP_TS_H));
- data << EP_PWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
- data << EP_PWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
- data << EP_PWT_N << uint32(bool(m_TowerState & EP_TS_N));
-}
-
-void OPvPCapturePointEP_PWT::UpdateTowerState()
-{
- m_PvP->SendUpdateWorldState(EP_PWT_A, bool(m_TowerState & EP_TS_A));
- m_PvP->SendUpdateWorldState(EP_PWT_H, bool(m_TowerState & EP_TS_H));
- m_PvP->SendUpdateWorldState(EP_PWT_N_A, bool(m_TowerState & EP_TS_N_A));
- m_PvP->SendUpdateWorldState(EP_PWT_N_H, bool(m_TowerState & EP_TS_N_H));
- m_PvP->SendUpdateWorldState(EP_PWT_N, bool(m_TowerState & EP_TS_N));
-}
-
-bool OPvPCapturePointEP_PWT::HandlePlayerEnter(Player* player)
-{
- if (OPvPCapturePoint::HandlePlayerEnter(player))
- {
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
- uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
- return true;
- }
- return false;
-}
-
-void OPvPCapturePointEP_PWT::HandlePlayerLeave(Player* player)
-{
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
- OPvPCapturePoint::HandlePlayerLeave(player);
-}
-
-void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team)
-{
- if (m_FlightMasterSpawned != team)
- {
- m_FlightMasterSpawned = team;
- DelCreature(EP_PWT_FLIGHTMASTER);
- AddCreature(EP_PWT_FLIGHTMASTER, EP_PWT_FlightMaster.entry, team, EP_PWT_FlightMaster.map, EP_PWT_FlightMaster.x, EP_PWT_FlightMaster.y, EP_PWT_FlightMaster.z, EP_PWT_FlightMaster.o);
- /*
- // sky - we need update gso code
-
- Creature* c = HashMapHolder<Creature>::Find(m_Creatures[EP_PWT_FLIGHTMASTER]);
- //Spawn flight master as friendly to capturing team
- c->SetUInt32Value(GAMEOBJECT_FACTION, (team == ALLIANCE ? 55 : 68));
- if (c)
- {
- GossipOption gso;
- gso.Action = GOSSIP_OPTION_OUTDOORPVP;
- gso.GossipId = 0;
- gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT));
- gso.Id = 50;
- gso.Icon = 0;
- gso.NpcFlag = 0;
- gso.BoxMoney = 0;
- gso.Coded = false;
- c->addGossipOption(gso);
-
- gso.Action = GOSSIP_OPTION_OUTDOORPVP;
- gso.GossipId = 0;
- gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT));
- gso.Id = 50;
- gso.Icon = 0;
- gso.NpcFlag = 0;
- gso.BoxMoney = 0;
- gso.Coded = false;
- c->addGossipOption(gso);
-
- gso.Action = GOSSIP_OPTION_OUTDOORPVP;
- gso.GossipId = 0;
- gso.OptionText.assign(sObjectMgr->GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT));
- gso.Id = 50;
- gso.Icon = 0;
- gso.NpcFlag = 0;
- gso.BoxMoney = 0;
- gso.Coded = false;
- c->addGossipOption(gso);
- }
- */
- }
-}
-
-// ep
-OutdoorPvPEP::OutdoorPvPEP()
-{
- m_TypeId = OUTDOOR_PVP_EP;
- memset(EP_Controls, 0, sizeof(EP_Controls));
- m_AllianceTowersControlled = 0;
- m_HordeTowersControlled = 0;
-}
-
-bool OutdoorPvPEP::SetupOutdoorPvP()
-{
- for (uint8 i = 0; i < EPBuffZonesNum; ++i)
- RegisterZone(EPBuffZones[i]);
-
- AddCapturePoint(new OPvPCapturePointEP_EWT(this));
- AddCapturePoint(new OPvPCapturePointEP_PWT(this));
- AddCapturePoint(new OPvPCapturePointEP_CGT(this));
- AddCapturePoint(new OPvPCapturePointEP_NPT(this));
- return true;
-}
-
-bool OutdoorPvPEP::Update(uint32 diff)
-{
- if (OutdoorPvP::Update(diff))
- {
- m_AllianceTowersControlled = 0;
- m_HordeTowersControlled = 0;
- for (int i = 0; i < EP_TOWER_NUM; ++i)
- {
- if (EP_Controls[i] == ALLIANCE)
- ++m_AllianceTowersControlled;
- else if (EP_Controls[i] == HORDE)
- ++m_HordeTowersControlled;
- SendUpdateWorldState(EP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
- SendUpdateWorldState(EP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
- BuffTeams();
- }
- return true;
- }
- return false;
-}
-
-void OutdoorPvPEP::HandlePlayerEnterZone(Player* player, uint32 zone)
-{
- // add buffs
- if (player->GetTeam() == ALLIANCE)
- {
- if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5)
- player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true);
- }
- else
- {
- if (m_HordeTowersControlled && m_HordeTowersControlled < 5)
- player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true);
- }
- OutdoorPvP::HandlePlayerEnterZone(player, zone);
-}
-
-void OutdoorPvPEP::HandlePlayerLeaveZone(Player* player, uint32 zone)
-{
- // remove buffs
- if (player->GetTeam() == ALLIANCE)
- {
- for (int i = 0; i < 4; ++i)
- player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]);
- }
- else
- {
- for (int i = 0; i < 4; ++i)
- player->RemoveAurasDueToSpell(EP_HordeBuffs[i]);
- }
- OutdoorPvP::HandlePlayerLeaveZone(player, zone);
-}
-
-void OutdoorPvPEP::BuffTeams()
-{
- for (PlayerSet::iterator itr = m_players[0].begin(); itr != m_players[0].end(); ++itr)
- {
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
- {
- for (int i = 0; i < 4; ++i)
- player->RemoveAurasDueToSpell(EP_AllianceBuffs[i]);
- if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5)
- player->CastSpell(player, EP_AllianceBuffs[m_AllianceTowersControlled-1], true);
- }
- }
- for (PlayerSet::iterator itr = m_players[1].begin(); itr != m_players[1].end(); ++itr)
- {
- if (Player* player = ObjectAccessor::FindPlayer(*itr))
- {
- for (int i = 0; i < 4; ++i)
- player->RemoveAurasDueToSpell(EP_HordeBuffs[i]);
- if (m_HordeTowersControlled && m_HordeTowersControlled < 5)
- player->CastSpell(player, EP_HordeBuffs[m_HordeTowersControlled-1], true);
- }
- }
-}
-
-void OutdoorPvPEP::SetControlledState(uint32 index, uint32 state)
-{
- EP_Controls[index] = state;
-}
-
-void OutdoorPvPEP::FillInitialWorldStates(WorldPacket & data)
-{
- data << EP_UI_TOWER_COUNT_A << m_AllianceTowersControlled;
- data << EP_UI_TOWER_COUNT_H << m_HordeTowersControlled;
- data << EP_UI_TOWER_SLIDER_DISPLAY << uint32(0);
- data << EP_UI_TOWER_SLIDER_POS << uint32(50);
- data << EP_UI_TOWER_SLIDER_N << uint32(100);
- for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
- {
- itr->second->FillInitialWorldStates(data);
- }
-}
-
-void OutdoorPvPEP::SendRemoveWorldStates(Player* player)
-{
- player->SendUpdateWorldState(EP_UI_TOWER_COUNT_A, 0);
- player->SendUpdateWorldState(EP_UI_TOWER_COUNT_H, 0);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, 0);
- player->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, 0);
-
- player->SendUpdateWorldState(EP_EWT_A, 0);
- player->SendUpdateWorldState(EP_EWT_H, 0);
- player->SendUpdateWorldState(EP_EWT_N, 0);
- player->SendUpdateWorldState(EP_EWT_N_A, 0);
- player->SendUpdateWorldState(EP_EWT_N_H, 0);
-
- player->SendUpdateWorldState(EP_PWT_A, 0);
- player->SendUpdateWorldState(EP_PWT_H, 0);
- player->SendUpdateWorldState(EP_PWT_N, 0);
- player->SendUpdateWorldState(EP_PWT_N_A, 0);
- player->SendUpdateWorldState(EP_PWT_N_H, 0);
-
- player->SendUpdateWorldState(EP_NPT_A, 0);
- player->SendUpdateWorldState(EP_NPT_H, 0);
- player->SendUpdateWorldState(EP_NPT_N, 0);
- player->SendUpdateWorldState(EP_NPT_N_A, 0);
- player->SendUpdateWorldState(EP_NPT_N_H, 0);
-
- player->SendUpdateWorldState(EP_CGT_A, 0);
- player->SendUpdateWorldState(EP_CGT_H, 0);
- player->SendUpdateWorldState(EP_CGT_N, 0);
- player->SendUpdateWorldState(EP_CGT_N_A, 0);
- player->SendUpdateWorldState(EP_CGT_N_H, 0);
-}
-
-class OutdoorPvP_eastern_plaguelands : public OutdoorPvPScript
-{
- public:
-
- OutdoorPvP_eastern_plaguelands()
- : OutdoorPvPScript("outdoorpvp_ep")
- {
- }
-
- OutdoorPvP* GetOutdoorPvP() const OVERRIDE
- {
- return new OutdoorPvPEP();
- }
-};
-
-void AddSC_outdoorpvp_ep()
-{
- new OutdoorPvP_eastern_plaguelands();
-}
diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h b/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h
deleted file mode 100644
index ecf9d80f071..00000000000
--- a/src/server/scripts/OutdoorPvP/OutdoorPvPEP.h
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * 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 OUTDOOR_PVP_EP_
-#define OUTDOOR_PVP_EP_
-
-#include "DBCStructure.h"
-#include "OutdoorPvP.h"
-
-const uint32 EP_AllianceBuffs[4] = {11413, 11414, 11415, 1386};
-
-const uint32 EP_HordeBuffs[4] = {30880, 30683, 30682, 29520};
-
-const uint32 EP_GraveYardZone = 139;
-
-const uint32 EP_GraveYardId = 927;
-
-const uint8 EPBuffZonesNum = 3;
-
-const uint32 EP_EWT_CM = 17690;
-const uint32 EP_CGT_CM = 17689;
-const uint32 EP_NPT_CM = 17696;
-const uint32 EP_PWT_CM = 17698;
-
-const uint32 EPBuffZones[EPBuffZonesNum] = {139, 2017, 2057};
-
-enum EP_TaxiNodes
-{
- EP_CGT_Taxi = 87,
- EP_EWT_Taxi = 86,
- EP_NPT_Taxi = 85,
- EP_PWT_Taxi = 84
-};
-
-enum EP_EastwallTowerWorldStates
-{
- EP_EWT_A = 2354,
- EP_EWT_H = 2356,
- EP_EWT_N_A = 2359, // ally conquested
- EP_EWT_N_H = 2360,
- EP_EWT_N = 2361
-};
-
-enum EP_NorthpassTowerWorldStates
-{
- EP_NPT_N = 2352,
- EP_NPT_N_A = 2362,
- EP_NPT_N_H = 2363,
- EP_NPT_A = 2372,
- EP_NPT_H = 2373
-};
-
-enum EP_PlagewoodTowerWorldStates
-{
- EP_PWT_N_A = 2366,
- EP_PWT_N_H = 2353, //2367 not present! use neutral!
- EP_PWT_A = 2370,
- EP_PWT_H = 2371,
- EP_PWT_N = 2353
-};
-
-enum EP_CrownGuardTowerWorldStates
-{
- EP_CGT_N_A = 2374,
- EP_CGT_N_H = 2375,
- EP_CGT_A = 2378,
- EP_CGT_H = 2379,
- EP_CGT_N = 2355
-};
-
-enum EP_WorldStates
-{
- EP_UI_TOWER_SLIDER_DISPLAY = 2426,
- EP_UI_TOWER_SLIDER_POS = 2427,
- EP_UI_TOWER_SLIDER_N = 2428,
-
- EP_UI_TOWER_COUNT_A = 2327,
- EP_UI_TOWER_COUNT_H = 2328
-};
-
-enum EP_Summons
-{
- EP_EWT_COMMANDER = 0,
- EP_EWT_SOLDIER1,
- EP_EWT_SOLDIER2,
- EP_EWT_SOLDIER3,
- EP_EWT_SOLDIER4,
- EP_PWT_FLIGHTMASTER,
-};
-
-enum EP_GoSummons
-{
- EP_NPT_BUFF = 0,
- EP_NPT_FLAGS,
- EP_EWT_FLAGS,
- EP_CGT_FLAGS,
- EP_PWT_FLAGS
-};
-
-enum EP_Towers
-{
- EP_EWT = 0, // plaguelands 03
- EP_NPT, // plaguelands 01
- EP_PWT, // plaguelands 04
- EP_CGT, // plaguelands 02
- EP_TOWER_NUM
-};
-
-const go_type EPCapturePoints[EP_TOWER_NUM] =
-{
- {182097, 0, 2574.51f, -4794.89f, 144.704f, -1.45003f, -0.097056f, 0.095578f, -0.656229f, 0.742165f},
- {181899, 0, 3181.08f, -4379.36f, 174.123f, -2.03472f, -0.065392f, 0.119494f, -0.842275f, 0.521553f},
- {182098, 0, 2962.71f, -3042.31f, 154.789f, 2.08426f, -0.074807f, -0.113837f, 0.855928f, 0.49883f},
- {182096, 0, 1860.85f, -3731.23f, 196.716f, -2.53214f, 0.033967f, -0.131914f, 0.944741f, -0.298177f}
-};
-
-const go_type EPTowerFlags[EP_TOWER_NUM] =
-{
- {182106, 0, 2569.60f, -4772.93f, 115.399f, 2.72271f, 0.0f, 0.0f, 0.978148f, 0.207912f},
- {182106, 0, 3148.17f, -4365.51f, 145.029f, 1.53589f, 0.0f, 0.0f, 0.694658f, 0.71934f},
- {182106, 0, 2992.63f, -3022.95f, 125.593f, 3.03687f, 0.0f, 0.0f, 0.99863f, 0.052336f},
- {182106, 0, 1838.42f, -3703.56f, 167.713f, 0.890118f, 0.0f, 0.0f, 0.430511f, 0.902585f}
-};
-
-const uint32 EPTowerPlayerEnterEvents[EP_TOWER_NUM] = {10691, 10699, 10701, 10705};
-
-const uint32 EPTowerPlayerLeaveEvents[EP_TOWER_NUM] = {10692, 10698, 10700, 10704};
-
-const uint8 EP_NUM_CREATURES = 6;
-const uint8 EP_EWT_NUM_CREATURES = 5;
-
-// one lordaeron commander, 4 soldiers
-// should be spawned at EWT and follow a path, but trans-grid pathing isn't safe, so summon them directly at NPT
-const creature_type EP_EWT_Summons_A[EP_EWT_NUM_CREATURES] =
-{
- {17635, 469, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f},
- {17647, 469, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f},
- {17647, 469, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f},
- {17647, 469, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f},
- {17647, 469, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f}
-};
-
-const creature_type EP_EWT_Summons_H[EP_EWT_NUM_CREATURES] =
-{
- {17995, 67, 0, 3167.61f, -4352.09f, 138.20f, 4.5811f},
- {17996, 67, 0, 3172.74f, -4352.99f, 139.14f, 4.9873f},
- {17996, 67, 0, 3165.89f, -4354.46f, 138.67f, 3.7244f},
- {17996, 67, 0, 3164.65f, -4350.26f, 138.22f, 2.4794f},
- {17996, 67, 0, 3169.91f, -4349.68f, 138.37f, 0.7444f}
-};
-
-enum EP_TowerStates
-{
- EP_TS_N = 1,
- EP_TS_N_A = 2,
- EP_TS_N_H = 4,
- EP_TS_A_P = 8,
- EP_TS_H_P = 16,
- EP_TS_A = 32,
- EP_TS_H = 64
-};
-
-// when spawning, pay attention at setting the faction manually!
-const creature_type EP_PWT_FlightMaster = {17209, 0, 0, 2987.5f, -3049.11f, 120.126f, 5.75959f};
-
-// after spawning, modify the faction so that only the controller will be able to use it with SetUInt32Value(GAMEOBJECT_FACTION, faction_id);
-const go_type EP_NPT_LordaeronShrine = {181682, 0, 3167.72f, -4355.91f, 138.785f, 1.69297f, 0.0f, 0.0f, 0.748956f, 0.66262f};
-
-class OutdoorPvPEP;
-
-class OPvPCapturePointEP_EWT : public OPvPCapturePoint
-{
- public:
-
- OPvPCapturePointEP_EWT(OutdoorPvP* pvp);
-
- void ChangeState();
-
- void SendChangePhase();
-
- void FillInitialWorldStates(WorldPacket & data);
-
- // used when player is activated/inactivated in the area
- bool HandlePlayerEnter(Player* player);
- void HandlePlayerLeave(Player* player);
-
- protected:
-
- void SummonSupportUnitAtNorthpassTower(uint32 team);
-
- void UpdateTowerState();
-
- protected:
-
- uint32 m_TowerState;
-
- uint32 m_UnitsSummonedSide;
-};
-
-class OPvPCapturePointEP_NPT : public OPvPCapturePoint
-{
- public:
-
- OPvPCapturePointEP_NPT(OutdoorPvP* pvp);
-
- void ChangeState();
-
- void SendChangePhase();
-
- void FillInitialWorldStates(WorldPacket & data);
-
- // used when player is activated/inactivated in the area
- bool HandlePlayerEnter(Player* player);
- void HandlePlayerLeave(Player* player);
-
- protected:
-
- void SummonGO(uint32 team);
-
- void UpdateTowerState();
-
- protected:
-
- uint32 m_TowerState;
-
- uint32 m_SummonedGOSide;
-};
-
-class OPvPCapturePointEP_CGT : public OPvPCapturePoint
-{
- public:
-
- OPvPCapturePointEP_CGT(OutdoorPvP* pvp);
-
- void ChangeState();
-
- void SendChangePhase();
-
- void FillInitialWorldStates(WorldPacket & data);
-
- // used when player is activated/inactivated in the area
- bool HandlePlayerEnter(Player* player);
- void HandlePlayerLeave(Player* player);
-
- protected:
-
- void LinkGraveYard(uint32 team);
-
- void UpdateTowerState();
-
- protected:
-
- uint32 m_TowerState;
-
- uint32 m_GraveyardSide;
-};
-
-class OPvPCapturePointEP_PWT : public OPvPCapturePoint
-{
- public:
-
- OPvPCapturePointEP_PWT(OutdoorPvP* pvp);
-
- void ChangeState();
-
- void SendChangePhase();
-
- void FillInitialWorldStates(WorldPacket & data);
-
- // used when player is activated/inactivated in the area
- bool HandlePlayerEnter(Player* player);
- void HandlePlayerLeave(Player* player);
-
- protected:
-
- void SummonFlightMaster(uint32 team);
-
- void UpdateTowerState();
-
- protected:
-
- uint32 m_FlightMasterSpawned;
-
- uint32 m_TowerState;
-};
-
-class OutdoorPvPEP : public OutdoorPvP
-{
- public:
-
- OutdoorPvPEP();
-
- bool SetupOutdoorPvP();
-
- void HandlePlayerEnterZone(Player* player, uint32 zone);
- void HandlePlayerLeaveZone(Player* player, uint32 zone);
-
- bool Update(uint32 diff);
-
- void FillInitialWorldStates(WorldPacket &data);
-
- void SendRemoveWorldStates(Player* player);
-
- void BuffTeams();
-
- void SetControlledState(uint32 index, uint32 state);
-
- private:
-
- // how many towers are controlled
- uint32 EP_Controls[EP_TOWER_NUM];
-
- uint32 m_AllianceTowersControlled;
- uint32 m_HordeTowersControlled;
-};
-
-#endif
diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp
index 267acbc95eb..b19318e9c89 100644
--- a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_pandemonius.cpp
@@ -39,7 +39,6 @@ enum Pandemonius
H_SPELL_DARK_SHELL = 38759
};
-
class boss_pandemonius : public CreatureScript
{
public:
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index e2e4d30541c..76f2461bb28 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -32,35 +32,33 @@ enum DeathKnightSpells
SPELL_DK_BLACK_ICE_R1 = 49140,
SPELL_DK_BLOOD_BOIL_TRIGGERED = 65658,
SPELL_DK_BLOOD_GORGED_HEAL = 50454,
- SPELL_DK_BLOOD_PRESENCE = 48266,
+ SPELL_DK_BLOOD_PRESENCE = 48263,
+ SPELL_DK_BLOOD_PRESENCE_TRIGGERED = 61261,
+ SPELL_DK_BLOOD_SHIELD_MASTERY = 77513,
+ SPELL_DK_BLOOD_SHIELD_ABSORB = 77535,
+ SPELL_DK_BUTCHERY = 50163,
SPELL_DK_CORPSE_EXPLOSION_TRIGGERED = 43999,
- SPELL_DK_CORPSE_EXPLOSION_VISUAL = 51270,
SPELL_DK_DEATH_COIL_DAMAGE = 47632,
SPELL_DK_DEATH_COIL_HEAL = 47633,
SPELL_DK_DEATH_STRIKE_HEAL = 45470,
- SPELL_DK_FROST_PRESENCE = 48263,
- SPELL_DK_FROST_PRESENCE_TRIGGERED = 61261,
+ SPELL_DK_DEATH_STRIKE_ENABLER = 89832,
+ SPELL_DK_FROST_PRESENCE = 48266,
SPELL_DK_GHOUL_EXPLODE = 47496,
SPELL_DK_GLYPH_OF_ICEBOUND_FORTITUDE = 58625,
SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1 = 50365,
+ SPELL_DK_IMPROVED_DEATH_STRIKE = 62905,
SPELL_DK_IMPROVED_FROST_PRESENCE_R1 = 50384,
+ SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED = 63621,
SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1 = 50391,
- SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611,
SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622,
SPELL_DK_ITEM_SIGIL_VENGEFUL_HEART = 64962,
SPELL_DK_ITEM_T8_MELEE_4P_BONUS = 64736,
SPELL_DK_RUNIC_POWER_ENERGIZE = 49088,
+ SPELL_DK_RUNE_TAP = 48982,
SPELL_DK_SCENT_OF_BLOOD = 50422,
SPELL_DK_SCOURGE_STRIKE_TRIGGERED = 70890,
SPELL_DK_UNHOLY_PRESENCE = 48265,
- SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772,
- SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189,
- SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284
-};
-
-enum DeathKnightSpellIcons
-{
- DK_ICON_ID_IMPROVED_DEATH_STRIKE = 2751
+ SPELL_DK_WILL_OF_THE_NECROPOLIS = 96171
};
// 50462 - Anti-Magic Shell (on raid member)
@@ -290,15 +288,14 @@ class spell_dk_blood_gorged : public SpellScriptLoader
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
- PreventDefaultAction();
- int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 1.5f);
- GetTarget()->CastCustomSpell(SPELL_DK_BLOOD_GORGED_HEAL, SPELLVALUE_BASE_POINT0, bp, _procTarget, true, NULL, aurEff);
+ int32 heal = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), 150));
+ GetTarget()->CastCustomSpell(SPELL_DK_BLOOD_GORGED_HEAL, SPELLVALUE_BASE_POINT0, heal, _procTarget, true, NULL, aurEff);
}
void Register() OVERRIDE
{
DoCheckProc += AuraCheckProcFn(spell_dk_blood_gorged_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
private:
@@ -311,60 +308,42 @@ class spell_dk_blood_gorged : public SpellScriptLoader
}
};
-// 49158 - Corpse Explosion (51325, 51326, 51327, 51328)
-class spell_dk_corpse_explosion : public SpellScriptLoader
+// -48979 - Butchery
+class spell_dk_butchery : public SpellScriptLoader
{
public:
- spell_dk_corpse_explosion() : SpellScriptLoader("spell_dk_corpse_explosion") { }
+ spell_dk_butchery() : SpellScriptLoader("spell_dk_butchery") { }
- class spell_dk_corpse_explosion_SpellScript : public SpellScript
+ class spell_dk_blood_gorged_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_dk_corpse_explosion_SpellScript);
+ PrepareAuraScript(spell_dk_blood_gorged_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_TRIGGERED) || !sSpellMgr->GetSpellInfo(SPELL_DK_GHOUL_EXPLODE))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_CORPSE_EXPLOSION_VISUAL))
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_BUTCHERY))
return false;
return true;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
- if (Unit* unitTarget = GetHitUnit())
- {
- int32 bp = 0;
- if (unitTarget->IsAlive()) // Living ghoul as a target
- {
- bp = int32(unitTarget->CountPctFromMaxHealth(25));
- unitTarget->CastCustomSpell(unitTarget, SPELL_DK_GHOUL_EXPLODE, &bp, NULL, NULL, false);
- }
- else // Some corpse
- {
- bp = GetEffectValue();
- GetCaster()->CastCustomSpell(unitTarget, GetSpellInfo()->Effects[EFFECT_1].CalcValue(), &bp, NULL, NULL, true);
- // Corpse Explosion (Suicide)
- unitTarget->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_TRIGGERED, true);
- }
- // Set corpse look
- GetCaster()->CastSpell(unitTarget, SPELL_DK_CORPSE_EXPLOSION_VISUAL, true);
- }
+ PreventDefaultAction();
+ GetTarget()->CastCustomSpell(SPELL_DK_BUTCHERY, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff);
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_dk_corpse_explosion_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_dk_blood_gorged_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
- SpellScript* GetSpellScript() const OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_dk_corpse_explosion_SpellScript();
+ return new spell_dk_blood_gorged_AuraScript();
}
};
-// -47541, 52375, 59134, -62900 - Death Coil
+// 47541, 52375, 59134, -62900 - Death Coil
class spell_dk_death_coil : public SpellScriptLoader
{
public:
@@ -562,7 +541,7 @@ class spell_dk_death_pact : public SpellScriptLoader
}
};
-// -49998 - Death Strike
+// 49998 - Death Strike
class spell_dk_death_strike : public SpellScriptLoader
{
public:
@@ -574,30 +553,39 @@ class spell_dk_death_strike : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_HEAL))
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_ENABLER) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DK_DEATH_STRIKE_HEAL) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_SHIELD_MASTERY) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_SHIELD_ABSORB))
return false;
return true;
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- Unit* caster = GetCaster();
- if (Unit* target = GetHitUnit())
+ if (AuraEffect* enabler = GetCaster()->GetAuraEffect(SPELL_DK_DEATH_STRIKE_ENABLER, EFFECT_0, GetCaster()->GetGUID()))
{
- uint32 count = target->GetDiseasesByCaster(caster->GetGUID());
- int32 bp = int32(count * caster->CountPctFromMaxHealth(int32(GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier)));
- // Improved Death Strike
- if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_DEATHKNIGHT, DK_ICON_ID_IMPROVED_DEATH_STRIKE, 0))
- AddPct(bp, caster->CalculateSpellDamage(caster, aurEff->GetSpellInfo(), 2));
- caster->CastCustomSpell(caster, SPELL_DK_DEATH_STRIKE_HEAL, &bp, NULL, NULL, false);
+ // Call CalculateAmount() to constantly fire the AuraEffect's HandleCalcAmount method
+ int32 heal = CalculatePct(enabler->CalculateAmount(GetCaster()), GetSpellInfo()->Effects[EFFECT_0].DamageMultiplier);
+
+ if (AuraEffect const* aurEff = GetCaster()->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_DEATH_STRIKE, EFFECT_2))
+ heal = AddPct(heal, aurEff->GetAmount());
+
+ heal = std::max(heal, int32(GetCaster()->CountPctFromMaxHealth(GetEffectValue())));
+ GetCaster()->CastCustomSpell(SPELL_DK_DEATH_STRIKE_HEAL, SPELLVALUE_BASE_POINT0, heal, GetCaster(), true);
}
+
+ if (!GetCaster()->HasAura(SPELL_DK_BLOOD_PRESENCE))
+ return;
+
+ if (AuraEffect const* aurEff = GetCaster()->GetAuraEffect(SPELL_DK_BLOOD_SHIELD_MASTERY, EFFECT_0))
+ GetCaster()->CastCustomSpell(SPELL_DK_BLOOD_SHIELD_ABSORB, SPELLVALUE_BASE_POINT0, GetCaster()->CountPctFromMaxHealth(aurEff->GetAmount()), GetCaster());
}
void Register() OVERRIDE
{
OnEffectHitTarget += SpellEffectFn(spell_dk_death_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY);
}
-
};
SpellScript* GetSpellScript() const OVERRIDE
@@ -606,6 +594,80 @@ class spell_dk_death_strike : public SpellScriptLoader
}
};
+// 89832 - Death Strike (Save damage taken in last 5 sec)
+class spell_dk_death_strike_enabler : public SpellScriptLoader
+{
+ public:
+ spell_dk_death_strike_enabler() : SpellScriptLoader("spell_dk_death_strike_enabler") { }
+
+ class spell_dk_death_strike_enabler_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_death_strike_enabler_AuraScript);
+
+ bool Load() OVERRIDE
+ {
+ for (uint8 i = 0; i < 5; ++i)
+ _damagePerSecond[i] = 0;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetDamageInfo();
+ }
+
+ void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
+ {
+ if (!GetUnitOwner()->HasAura(SPELL_DK_BLOOD_PRESENCE))
+ {
+ for (uint8 i = 0; i < 5; ++i)
+ _damagePerSecond[i] = 0;
+ }
+ else
+ _damagePerSecond[0] += eventInfo.GetDamageInfo()->GetDamage();
+ }
+
+ // Cheap hack to have update calls
+ void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude)
+ {
+ isPeriodic = true;
+ amplitude = 1000;
+ }
+
+ void Update(AuraEffect* /*aurEff*/)
+ {
+ // Move backwards all datas by one
+ for (uint8 i = 4; i > 0; --i)
+ _damagePerSecond[i] = _damagePerSecond[i - 1];
+ _damagePerSecond[0] = 0;
+ }
+
+ void HandleCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ {
+ canBeRecalculated = true;
+ amount = 0;
+ for (uint8 i = 0; i < 5; ++i)
+ amount += int32(_damagePerSecond[i]);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_dk_death_strike_enabler_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_dk_death_strike_enabler_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_dk_death_strike_enabler_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_dk_death_strike_enabler_AuraScript::Update, EFFECT_0, SPELL_AURA_DUMMY);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_death_strike_enabler_AuraScript::HandleCalcAmount, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+
+ uint32 _damagePerSecond[5];
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dk_death_strike_enabler_AuraScript();
+ }
+};
+
// 47496 - Explode, Ghoul spell for Corpse Explosion
class spell_dk_ghoul_explode : public SpellScriptLoader
{
@@ -708,29 +770,44 @@ class spell_dk_improved_blood_presence : public SpellScriptLoader
if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE_TRIGGERED))
return false;
return true;
}
- void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ void HandleModDamagePctTaken(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ if ((target->HasAura(SPELL_DK_FROST_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, -aurEff->GetAmount(), target, true, NULL, aurEff);
+ }
+
+ void HandleModAttackerMeleeCritChance(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- if ((target->HasAura(SPELL_DK_FROST_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT1, aurEff->GetAmount(), target, true, NULL, aurEff);
+ if (target->HasAura(SPELL_DK_BLOOD_PRESENCE))
+ if (AuraEffect* triggeredEff = target->GetAuraEffect(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, EFFECT_1))
+ triggeredEff->SetAmount(aurEff->GetAmount());
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE))
- target->RemoveAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED);
+
+ if (target->HasAura(SPELL_DK_BLOOD_PRESENCE))
+ {
+ if (AuraEffect* triggeredEff = target->GetAuraEffect(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, EFFECT_1))
+ triggeredEff->SetAmount(0);
+ }
+ else
+ target->RemoveAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED);
}
void Register() OVERRIDE
{
- AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleModDamagePctTaken, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_improved_blood_presence_AuraScript::HandleModAttackerMeleeCritChance, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dk_improved_blood_presence_AuraScript::HandleEffectRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -753,9 +830,8 @@ class spell_dk_improved_frost_presence : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE_TRIGGERED))
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED))
return false;
return true;
}
@@ -763,15 +839,13 @@ class spell_dk_improved_frost_presence : public SpellScriptLoader
void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_FROST_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff);
+ if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_UNHOLY_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- Unit* target = GetTarget();
- if (!target->HasAura(SPELL_DK_FROST_PRESENCE))
- target->RemoveAura(SPELL_DK_FROST_PRESENCE_TRIGGERED);
+ GetTarget()->RemoveAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED);
}
void Register() OVERRIDE
@@ -801,9 +875,7 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader
{
if (!sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED))
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED))
return false;
return true;
}
@@ -811,25 +883,13 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader
void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- if (target->HasAura(SPELL_DK_UNHOLY_PRESENCE) && !target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED))
- {
- // Not listed as any effect, only base points set in dbc
- int32 basePoints = GetSpellInfo()->Effects[EFFECT_1].CalcValue();
- target->CastCustomSpell(target, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &basePoints, &basePoints, &basePoints, true, NULL, aurEff);
- }
-
- if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_FROST_PRESENCE)) && !target->HasAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff);
+ if ((target->HasAura(SPELL_DK_BLOOD_PRESENCE) || target->HasAura(SPELL_DK_FROST_PRESENCE)) && !target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), target, true, NULL, aurEff);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- Unit* target = GetTarget();
-
- target->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED);
-
- if (!target->HasAura(SPELL_DK_UNHOLY_PRESENCE))
- target->RemoveAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED);
+ GetTarget()->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED);
}
void Register() OVERRIDE
@@ -845,6 +905,34 @@ class spell_dk_improved_unholy_presence : public SpellScriptLoader
}
};
+// 73975 - Necrotic Strike
+class spell_dk_necrotic_strike : public SpellScriptLoader
+{
+ public:
+ spell_dk_necrotic_strike() : SpellScriptLoader("spell_dk_necrotic_strike") { }
+
+ class spell_dk_necrotic_strike_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_necrotic_strike_AuraScript);
+
+ void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool & /*canBeRecalculated*/)
+ {
+ if (Unit* caster = GetCaster())
+ amount = int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.7f);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_necrotic_strike_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_HEAL_ABSORB);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dk_necrotic_strike_AuraScript();
+ }
+};
+
// 48266 - Blood Presence
// 48263 - Frost Presence
// 48265 - Unholy Presence
@@ -865,10 +953,9 @@ class spell_dk_presence : public SpellScriptLoader
|| !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_R1)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED)
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_BLOOD_PRESENCE_TRIGGERED)
|| !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_FROST_PRESENCE_TRIGGERED)
- || !sSpellMgr->GetSpellInfo(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED))
+ || !sSpellMgr->GetSpellInfo(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED))
return false;
return true;
@@ -876,53 +963,57 @@ class spell_dk_presence : public SpellScriptLoader
void HandleImprovedBloodPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
+ /// @todo: rune regg (effect 2)
Unit* target = GetTarget();
+ if (Aura const* aura = target->GetAuraOfRankedSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1))
+ {
+ CustomSpellValues val;
+ if (GetSpellInfo()->Id == SPELL_DK_BLOOD_PRESENCE)
+ {
+ if (AuraEffect const* impAurEff = aura->GetEffect(EFFECT_1))
+ val.AddSpellMod(SPELLVALUE_BASE_POINT1, impAurEff->GetAmount());
+ }
+ else
+ {
+ if (AuraEffect const* impAurEff = aura->GetEffect(EFFECT_0))
+ val.AddSpellMod(SPELLVALUE_BASE_POINT0, -impAurEff->GetAmount());
+ }
- if (GetId() == SPELL_DK_BLOOD_PRESENCE)
- target->CastSpell(target, SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, true);
- else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_R1, EFFECT_0))
- if (!target->HasAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT1, impAurEff->GetAmount(), target, true, NULL, aurEff);
+ if (!target->HasAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_BLOOD_PRESENCE_TRIGGERED, val, target, TRIGGERED_FULL_MASK, NULL, aurEff);
+ }
+ else if (GetSpellInfo()->Id == SPELL_DK_BLOOD_PRESENCE)
+ target->CastSpell(target, SPELL_DK_BLOOD_PRESENCE_TRIGGERED, true, NULL, aurEff);
}
void HandleImprovedFrostPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
- Unit* target = GetTarget();
+ if (GetSpellInfo()->Id != SPELL_DK_BLOOD_PRESENCE && GetSpellInfo()->Id != SPELL_DK_UNHOLY_PRESENCE)
+ return;
- if (GetId() == SPELL_DK_FROST_PRESENCE)
- target->CastSpell(target, SPELL_DK_FROST_PRESENCE_TRIGGERED, true);
- else if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_R1, EFFECT_0))
- if (!target->HasAura(SPELL_DK_FROST_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff);
+ Unit* target = GetTarget();
+ if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_R1, EFFECT_0))
+ if (!target->HasAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff);
}
void HandleImprovedUnholyPresence(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
{
- Unit* target = GetTarget();
-
- if (GetId() == SPELL_DK_UNHOLY_PRESENCE)
- target->CastSpell(target, SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, true);
+ if (GetSpellInfo()->Id != SPELL_DK_BLOOD_PRESENCE && GetSpellInfo()->Id != SPELL_DK_FROST_PRESENCE)
+ return;
+ Unit* target = GetTarget();
if (AuraEffect const* impAurEff = target->GetAuraEffectOfRankedSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_R1, EFFECT_0))
- {
- if (GetId() == SPELL_DK_UNHOLY_PRESENCE)
- {
- // Not listed as any effect, only base points set
- int32 bp = impAurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue();
- target->CastCustomSpell(target, SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, &bp, &bp, &bp, true, NULL, aurEff);
- }
- else if (!target->HasAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED))
- target->CastCustomSpell(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff);
- }
+ if (!target->HasAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED))
+ target->CastCustomSpell(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED, SPELLVALUE_BASE_POINT0, impAurEff->GetAmount(), target, true, NULL, aurEff);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
- target->RemoveAura(SPELL_DK_IMPROVED_BLOOD_PRESENCE_TRIGGERED);
+ target->RemoveAura(SPELL_DK_BLOOD_PRESENCE_TRIGGERED);
+ target->RemoveAura(SPELL_DK_IMPROVED_FROST_PRESENCE_TRIGGERED);
target->RemoveAura(SPELL_DK_IMPROVED_UNHOLY_PRESENCE_TRIGGERED);
- target->RemoveAura(SPELL_DK_FROST_PRESENCE_TRIGGERED);
- target->RemoveAura(SPELL_DK_UNHOLY_PRESENCE_TRIGGERED);
}
void Register() OVERRIDE
@@ -984,16 +1075,16 @@ class spell_dk_scent_of_blood : public SpellScriptLoader
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(GetTarget(), SPELL_DK_SCENT_OF_BLOOD, true, NULL, aurEff);
- GetTarget()->RemoveAuraFromStack(GetSpellInfo()->Id);
+ GetTarget()->RemoveAuraFromStack(GetId());
}
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_dk_scent_of_blood_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectProc += AuraEffectProcFn(spell_dk_scent_of_blood_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -1066,50 +1157,6 @@ class spell_dk_scourge_strike : public SpellScriptLoader
}
};
-// 49145 - Spell Deflection
-class spell_dk_spell_deflection : public SpellScriptLoader
-{
- public:
- spell_dk_spell_deflection() : SpellScriptLoader("spell_dk_spell_deflection") { }
-
- class spell_dk_spell_deflection_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_dk_spell_deflection_AuraScript);
-
- 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)
- {
- // You have a chance equal to your Parry chance
- if ((dmgInfo.GetDamageType() == SPELL_DIRECT_DAMAGE) && roll_chance_f(GetTarget()->GetUnitParryChance()))
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
- }
-
- void Register() OVERRIDE
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_spell_deflection_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_spell_deflection_AuraScript::Absorb, EFFECT_0);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_dk_spell_deflection_AuraScript();
- }
-};
-
// 55233 - Vampiric Blood
class spell_dk_vampiric_blood : public SpellScriptLoader
{
@@ -1137,7 +1184,7 @@ class spell_dk_vampiric_blood : public SpellScriptLoader
}
};
-// 52284 - Will of the Necropolis
+// -52284 - Will of the Necropolis
class spell_dk_will_of_the_necropolis : public SpellScriptLoader
{
public:
@@ -1147,55 +1194,38 @@ class spell_dk_will_of_the_necropolis : public SpellScriptLoader
{
PrepareAuraScript(spell_dk_will_of_the_necropolis_AuraScript);
- bool Validate(SpellInfo const* spellInfo) OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- SpellInfo const* firstRankSpellInfo = sSpellMgr->GetSpellInfo(SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1);
- if (!firstRankSpellInfo)
+ if (!sSpellMgr->GetSpellInfo(SPELL_DK_WILL_OF_THE_NECROPOLIS))
return false;
-
- // can't use other spell than will of the necropolis due to spell_ranks dependency
- if (!spellInfo->IsRankOf(firstRankSpellInfo))
- return false;
-
- uint8 rank = spellInfo->GetRank();
- if (!sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank, true))
- return false;
-
return true;
}
- uint32 absorbPct;
-
- bool Load() OVERRIDE
+ bool CheckProc(ProcEventInfo& eventInfo)
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
- return true;
- }
+ //! HACK due to currenct proc system implementation
+ if (Player* player = GetTarget()->ToPlayer())
+ if (player->HasSpellCooldown(GetId()))
+ return false;
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
- {
- // Set absorbtion amount to unlimited
- amount = -1;
+ return GetTarget()->HealthBelowPctDamaged(30, eventInfo.GetDamageInfo()->GetDamage());
}
- void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
- // min pct of hp is stored in effect 0 of talent spell
- uint8 rank = GetSpellInfo()->GetRank();
- SpellInfo const* talentProto = sSpellMgr->GetSpellInfo(sSpellMgr->GetSpellWithRank(SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1, rank));
-
- int32 remainingHp = int32(GetTarget()->GetHealth() - dmgInfo.GetDamage());
- int32 minHp = int32(GetTarget()->CountPctFromMaxHealth(talentProto->Effects[EFFECT_0].CalcValue(GetCaster())));
+ GetTarget()->CastSpell(GetTarget(), SPELL_DK_WILL_OF_THE_NECROPOLIS, true, NULL, aurEff);
- // Damage that would take you below [effect0] health or taken while you are at [effect0]
- if (remainingHp < minHp)
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
+ if (Player* player = GetTarget()->ToPlayer())
+ {
+ player->RemoveSpellCooldown(SPELL_DK_RUNE_TAP, true);
+ player->AddSpellCooldown(GetId(), 0, time(NULL) + 45);
+ }
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_will_of_the_necropolis_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_dk_will_of_the_necropolis_AuraScript::Absorb, EFFECT_0);
+ DoCheckProc += AuraCheckProcFn(spell_dk_will_of_the_necropolis_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_dk_will_of_the_necropolis_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE);
}
};
@@ -1212,22 +1242,23 @@ void AddSC_deathknight_spell_scripts()
new spell_dk_anti_magic_zone();
new spell_dk_blood_boil();
new spell_dk_blood_gorged();
- new spell_dk_corpse_explosion();
+ new spell_dk_butchery();
new spell_dk_death_coil();
new spell_dk_death_gate();
new spell_dk_death_grip();
new spell_dk_death_pact();
new spell_dk_death_strike();
+ new spell_dk_death_strike_enabler();
new spell_dk_ghoul_explode();
new spell_dk_icebound_fortitude();
new spell_dk_improved_blood_presence();
new spell_dk_improved_frost_presence();
new spell_dk_improved_unholy_presence();
+ new spell_dk_necrotic_strike();
new spell_dk_presence();
new spell_dk_rune_tap_party();
new spell_dk_scent_of_blood();
new spell_dk_scourge_strike();
- new spell_dk_spell_deflection();
new spell_dk_vampiric_blood();
new spell_dk_will_of_the_necropolis();
}
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 5e56d4b8d92..20448e79fb7 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -29,24 +29,41 @@
enum DruidSpells
{
+ SPELL_DRUID_WRATH = 5176,
+ SPELL_DRUID_STARFIRE = 2912,
+ SPELL_DRUID_STARSURGE = 78674,
+ SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE = 89265,
+ SPELL_DRUID_STARSURGE_ENERGIZE = 86605,
+ SPELL_DRUID_LUNAR_ECLIPSE_MARKER = 67484, // Will make the yellow arrow on eclipse bar point to the blue side (lunar)
+ SPELL_DRUID_SOLAR_ECLIPSE_MARKER = 67483, // Will make the yellow arrow on eclipse bar point to the yellow side (solar)
+ SPELL_DRUID_SOLAR_ECLIPSE = 48517,
+ SPELL_DRUID_LUNAR_ECLIPSE = 48518,
SPELL_DRUID_ENRAGE_MOD_DAMAGE = 51185,
+ SPELL_DRUID_FERAL_CHARGE_BEAR = 16979,
+ SPELL_DRUID_FERAL_CHARGE_CAT = 49376,
+ SPELL_DRUID_GLYPH_OF_INNERVATE = 54833,
+ SPELL_DRUID_GLYPH_OF_STARFIRE = 54846,
SPELL_DRUID_GLYPH_OF_TYPHOON = 62135,
SPELL_DRUID_IDOL_OF_FERAL_SHADOWS = 34241,
SPELL_DRUID_IDOL_OF_WORSHIP = 60774,
SPELL_DRUID_INCREASED_MOONFIRE_DURATION = 38414,
+ SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950,
SPELL_DRUID_KING_OF_THE_JUNGLE = 48492,
SPELL_DRUID_LIFEBLOOM_ENERGIZE = 64372,
SPELL_DRUID_LIFEBLOOM_FINAL_HEAL = 33778,
SPELL_DRUID_LIVING_SEED_HEAL = 48503,
SPELL_DRUID_LIVING_SEED_PROC = 48504,
- SPELL_DRUID_NATURES_SPLENDOR = 57865,
+ SPELL_DRUID_NATURES_GRACE = 16880,
+ SPELL_DRUID_NATURES_GRACE_TRIGGER = 16886,
SPELL_DRUID_SURVIVAL_INSTINCTS = 50322,
SPELL_DRUID_SAVAGE_ROAR = 62071,
- SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178,
- SPELL_DRUID_ITEM_T8_BALANCE_RELIC = 64950,
+ SPELL_DRUID_STAMPEDE_BAER_RANK_1 = 81016,
+ SPELL_DRUID_STAMPEDE_CAT_RANK_1 = 81021,
+ SPELL_DRUID_STAMPEDE_CAT_STATE = 109881,
+ SPELL_DRUID_TIGER_S_FURY_ENERGIZE = 51178
};
-// -1850 - Dash
+// 1850 - Dash
class spell_dru_dash : public SpellScriptLoader
{
public:
@@ -75,6 +92,162 @@ class spell_dru_dash : public SpellScriptLoader
}
};
+// 48517 - Eclipse (Solar)
+// 48518 - Eclipse (Lunar)
+class spell_dru_eclipse : public SpellScriptLoader
+{
+ public:
+ spell_dru_eclipse(char const* scriptName) : SpellScriptLoader(scriptName) { }
+
+ class spell_dru_eclipse_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_eclipse_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_GRACE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_GRACE_TRIGGER))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void ApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+
+ if (caster->ToPlayer()->GetAuraOfRankedSpell(SPELL_DRUID_NATURES_GRACE))
+ caster->ToPlayer()->RemoveSpellCooldown(SPELL_DRUID_NATURES_GRACE_TRIGGER, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_dru_eclipse_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dru_eclipse_AuraScript();
+ }
+};
+
+// 2912, 5176, 78674 - Starfire, Wrath, and Starsurge
+class spell_dru_eclipse_energize : public SpellScriptLoader
+{
+ public:
+ spell_dru_eclipse_energize() : SpellScriptLoader("spell_dru_eclipse_energize") { }
+
+ class spell_dru_eclipse_energize_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dru_eclipse_energize_SpellScript);
+
+ int32 energizeAmount;
+
+ bool Load() OVERRIDE
+ {
+ if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+
+ if (GetCaster()->ToPlayer()->getClass() != CLASS_DRUID)
+ return false;
+
+ energizeAmount = 0;
+
+ return true;
+ }
+
+ void HandleEnergize(SpellEffIndex effIndex)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+
+ // No boomy, no deal.
+ if (caster->GetPrimaryTalentTree(caster->GetActiveSpec()) != TALENT_TREE_DRUID_BALANCE)
+ return;
+
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_DRUID_WRATH:
+ {
+ energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -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)
+ {
+ caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true);
+ // If the energize was due to 0 power, cast the eclipse marker aura
+ if (!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER))
+ caster->CastSpell(caster, SPELL_DRUID_LUNAR_ECLIPSE_MARKER, true);
+ }
+ // The energizing effect brought us out of the solar eclipse, remove the aura
+ if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0)
+ caster->RemoveAurasDueToSpell(SPELL_DRUID_SOLAR_ECLIPSE);
+ break;
+ }
+ case SPELL_DRUID_STARFIRE:
+ {
+ energizeAmount = GetSpellInfo()->Effects[effIndex].BasePoints; // 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)
+ {
+ caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true);
+ // If the energize was due to 0 power, cast the eclipse marker aura
+ if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
+ caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true);
+ }
+ // The energizing effect brought us out of the lunar eclipse, remove the aura
+ if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0)
+ caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE);
+ break;
+ }
+ case SPELL_DRUID_STARSURGE:
+ {
+ // If we are set to fill the solar side or we've just logged in with 0 power (confirmed with sniffs)
+ 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
+ caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true);
+
+ // If the energize was due to 0 power, cast the eclipse marker aura
+ if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
+ caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true);
+ }
+ else if (!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER))
+ {
+ energizeAmount = -GetSpellInfo()->Effects[effIndex].BasePoints; // -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
+ if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0)
+ caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE);
+ // The energizing effect brought us out of the solar eclipse, remove the aura
+ else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0)
+ caster->RemoveAura(SPELL_DRUID_SOLAR_ECLIPSE);
+ break;
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_dru_eclipse_energize_SpellScript::HandleEnergize, EFFECT_1, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_dru_eclipse_energize_SpellScript;
+ }
+};
+
// 5229 - Enrage
class spell_dru_enrage : public SpellScriptLoader
{
@@ -111,6 +284,48 @@ class spell_dru_enrage : public SpellScriptLoader
}
};
+// 54832 - Glyph of Innervate
+class spell_dru_glyph_of_innervate : public SpellScriptLoader
+{
+ public:
+ spell_dru_glyph_of_innervate() : SpellScriptLoader("spell_dru_glyph_of_innervate") { }
+
+ class spell_dru_glyph_of_innervate_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_glyph_of_innervate_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_GLYPH_OF_INNERVATE))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ // Not proc from self Innervate
+ return GetTarget() != eventInfo.GetProcTarget();
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), SPELL_DRUID_GLYPH_OF_INNERVATE, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_dru_glyph_of_innervate_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_innervate_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dru_glyph_of_innervate_AuraScript();
+ }
+};
+
// 54846 - Glyph of Starfire
class spell_dru_glyph_of_starfire : public SpellScriptLoader
{
@@ -123,7 +338,7 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_INCREASED_MOONFIRE_DURATION) || !sSpellMgr->GetSpellInfo(SPELL_DRUID_NATURES_SPLENDOR))
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_INCREASED_MOONFIRE_DURATION))
return false;
return true;
}
@@ -132,7 +347,7 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
- if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0, caster->GetGUID()))
+ if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x2, 0, 0, caster->GetGUID()))
{
Aura* aura = aurEff->GetBase();
@@ -140,8 +355,6 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader
uint32 countMax = aura->GetSpellInfo()->GetMaxDuration() + 9000;
if (caster->HasAura(SPELL_DRUID_INCREASED_MOONFIRE_DURATION))
countMax += 3000;
- if (caster->HasAura(SPELL_DRUID_NATURES_SPLENDOR))
- countMax += 3000;
if (countMin < countMax)
{
@@ -163,6 +376,41 @@ class spell_dru_glyph_of_starfire : public SpellScriptLoader
}
};
+// 54845 - Glyph of Starfire
+class spell_dru_glyph_of_starfire_proc : public SpellScriptLoader
+{
+ public:
+ spell_dru_glyph_of_starfire_proc() : SpellScriptLoader("spell_dru_glyph_of_starfire_proc") { }
+
+ class spell_dru_glyph_of_starfire_proc_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_glyph_of_starfire_proc_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_GLYPH_OF_STARFIRE))
+ return false;
+ return true;
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_DRUID_GLYPH_OF_STARFIRE, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_dru_glyph_of_starfire_proc_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dru_glyph_of_starfire_proc_AuraScript();
+ }
+};
+
// 34246 - Idol of the Emerald Queen
// 60779 - Idol of Lush Moss
class spell_dru_idol_lifebloom : public SpellScriptLoader
@@ -226,7 +474,7 @@ class spell_dru_innervate : public SpellScriptLoader
}
};
-// -5570 - Insect Swarm
+// 5570 - Insect Swarm
class spell_dru_insect_swarm : public SpellScriptLoader
{
public:
@@ -255,7 +503,7 @@ class spell_dru_insect_swarm : public SpellScriptLoader
}
};
-// -33763 - Lifebloom
+// 33763 - Lifebloom
class spell_dru_lifebloom : public SpellScriptLoader
{
public:
@@ -408,77 +656,6 @@ class spell_dru_living_seed_proc : public SpellScriptLoader
}
};
-// 69366 - Moonkin Form passive
-class spell_dru_moonkin_form_passive : public SpellScriptLoader
-{
- public:
- spell_dru_moonkin_form_passive() : SpellScriptLoader("spell_dru_moonkin_form_passive") { }
-
- class spell_dru_moonkin_form_passive_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_dru_moonkin_form_passive_AuraScript);
-
- 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 Stunned in Moonkin Form
- if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
- }
-
- void Register() OVERRIDE
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_moonkin_form_passive_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_moonkin_form_passive_AuraScript::Absorb, EFFECT_0);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_dru_moonkin_form_passive_AuraScript();
- }
-};
-
-// 48391 - Owlkin Frenzy
-class spell_dru_owlkin_frenzy : public SpellScriptLoader
-{
- public:
- spell_dru_owlkin_frenzy() : SpellScriptLoader("spell_dru_owlkin_frenzy") { }
-
- class spell_dru_owlkin_frenzy_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_dru_owlkin_frenzy_AuraScript);
-
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
- {
- amount = CalculatePct(GetUnitOwner()->GetCreatePowers(POWER_MANA), amount);
- }
-
- void Register() OVERRIDE
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_owlkin_frenzy_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_PERIODIC_ENERGIZE);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_dru_owlkin_frenzy_AuraScript();
- }
-};
-
// -16972 - Predatory Strikes
class spell_dru_predatory_strikes : public SpellScriptLoader
{
@@ -508,51 +685,7 @@ class spell_dru_predatory_strikes : public SpellScriptLoader
}
};
-// 33851 - Primal Tenacity
-class spell_dru_primal_tenacity : public SpellScriptLoader
-{
- public:
- spell_dru_primal_tenacity() : SpellScriptLoader("spell_dru_primal_tenacity") { }
-
- class spell_dru_primal_tenacity_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_dru_primal_tenacity_AuraScript);
-
- uint32 absorbPct;
-
- bool Load() OVERRIDE
- {
- absorbPct = GetSpellInfo()->Effects[EFFECT_1].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 Stunned in Cat Form
- if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
- }
-
- void Register() OVERRIDE
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_primal_tenacity_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_dru_primal_tenacity_AuraScript::Absorb, EFFECT_1);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_dru_primal_tenacity_AuraScript();
- }
-};
-
-// -1079 - Rip
+// 1079 - Rip
class spell_dru_rip : public SpellScriptLoader
{
public:
@@ -672,7 +805,7 @@ class spell_dru_savage_roar : public SpellScriptLoader
{
PrepareAuraScript(spell_dru_savage_roar_AuraScript);
- bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_SAVAGE_ROAR))
return false;
@@ -708,34 +841,7 @@ class spell_dru_savage_roar : public SpellScriptLoader
}
};
-// -50294 - Starfall (AOE)
-class spell_dru_starfall_aoe : public SpellScriptLoader
-{
- public:
- spell_dru_starfall_aoe() : SpellScriptLoader("spell_dru_starfall_aoe") { }
-
- class spell_dru_starfall_aoe_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_dru_starfall_aoe_SpellScript);
-
- void FilterTargets(std::list<WorldObject*>& targets)
- {
- targets.remove(GetExplTargetUnit());
- }
-
- void Register() OVERRIDE
- {
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_dru_starfall_aoe_SpellScript();
- }
-};
-
-// -50286 - Starfall (Dummy)
+// 50286 - Starfall (Dummy)
class spell_dru_starfall_dummy : public SpellScriptLoader
{
public:
@@ -781,6 +887,59 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
}
};
+// -78892 - Stampede
+class spell_dru_stampede : public SpellScriptLoader
+{
+ public:
+ spell_dru_stampede() : SpellScriptLoader("spell_dru_stampede") { }
+
+ class spell_dru_stampede_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_stampede_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_BAER_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_CAT_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DRUID_STAMPEDE_CAT_STATE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DRUID_FERAL_CHARGE_CAT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_DRUID_FERAL_CHARGE_BEAR))
+ return false;
+ return true;
+ }
+
+ void HandleEffectCatProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ if (GetTarget()->GetShapeshiftForm() != FORM_CAT || eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_DRUID_FERAL_CHARGE_CAT)
+ return;
+
+ GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_DRUID_STAMPEDE_CAT_RANK_1, GetSpellInfo()->GetRank()), true, NULL, aurEff);
+ GetTarget()->CastSpell(GetTarget(), SPELL_DRUID_STAMPEDE_CAT_STATE, true, NULL, aurEff);
+ }
+
+ void HandleEffectBearProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ if (GetTarget()->GetShapeshiftForm() != FORM_BEAR || eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_DRUID_FERAL_CHARGE_BEAR)
+ return;
+
+ GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_DRUID_STAMPEDE_BAER_RANK_1, GetSpellInfo()->GetRank()), true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_dru_stampede_AuraScript::HandleEffectCatProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_dru_stampede_AuraScript::HandleEffectBearProc, EFFECT_1, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_dru_stampede_AuraScript();
+ }
+};
+
// 61336 - Survival Instincts
class spell_dru_survival_instincts : public SpellScriptLoader
{
@@ -865,7 +1024,7 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
if (Player* caster = GetCaster()->ToPlayer())
- if (caster->Has310Flyer(false))
+ if (caster->GetSkillValue(SKILL_RIDING) >= 375)
amount = 310;
}
@@ -881,7 +1040,7 @@ class spell_dru_swift_flight_passive : public SpellScriptLoader
}
};
-// -5217 - Tiger's Fury
+// 5217 - Tiger's Fury
class spell_dru_tiger_s_fury : public SpellScriptLoader
{
public:
@@ -909,7 +1068,7 @@ class spell_dru_tiger_s_fury : public SpellScriptLoader
}
};
-// -61391 - Typhoon
+// 61391 - Typhoon
class spell_dru_typhoon : public SpellScriptLoader
{
public:
@@ -1066,23 +1225,25 @@ class spell_dru_wild_growth : public SpellScriptLoader
void AddSC_druid_spell_scripts()
{
new spell_dru_dash();
+ new spell_dru_eclipse("spell_dru_eclipse_lunar");
+ new spell_dru_eclipse("spell_dru_eclipse_solar");
+ new spell_dru_eclipse_energize();
new spell_dru_enrage();
+ new spell_dru_glyph_of_innervate();
new spell_dru_glyph_of_starfire();
+ new spell_dru_glyph_of_starfire_proc();
new spell_dru_idol_lifebloom();
new spell_dru_innervate();
new spell_dru_insect_swarm();
new spell_dru_lifebloom();
new spell_dru_living_seed();
new spell_dru_living_seed_proc();
- new spell_dru_moonkin_form_passive();
- new spell_dru_owlkin_frenzy();
new spell_dru_predatory_strikes();
- new spell_dru_primal_tenacity();
new spell_dru_rip();
new spell_dru_savage_defense();
new spell_dru_savage_roar();
- new spell_dru_starfall_aoe();
new spell_dru_starfall_dummy();
+ new spell_dru_stampede();
new spell_dru_survival_instincts();
new spell_dru_swift_flight_passive();
new spell_dru_tiger_s_fury();
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 1e9a8713019..891f578e73e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -163,6 +163,67 @@ class spell_gen_adaptive_warding : public SpellScriptLoader
}
};
+enum AlchemistStone
+{
+ ALECHEMIST_STONE_HEAL = 21399,
+ ALECHEMIST_STONE_MANA = 21400,
+};
+
+// 17619 - Alchemist Stone
+class spell_gen_alchemist_stone : public SpellScriptLoader
+{
+ public:
+ spell_gen_alchemist_stone() : SpellScriptLoader("spell_gen_alchemist_stone") { }
+
+ class spell_gen_alchemist_stone_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_alchemist_stone_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_HEAL) ||
+ !sSpellMgr->GetSpellInfo(ALECHEMIST_STONE_MANA))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_POTION;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+
+ uint32 spellId = 0;
+ int32 bp = int32(eventInfo.GetDamageInfo()->GetDamage() * 0.4f);
+
+ if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_HEAL))
+ spellId = ALECHEMIST_STONE_HEAL;
+ else if (eventInfo.GetDamageInfo()->GetSpellInfo()->HasEffect(SPELL_EFFECT_ENERGIZE))
+ spellId = ALECHEMIST_STONE_MANA;
+
+ if (!spellId)
+ return;
+
+ GetTarget()->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, bp, GetTarget(), true, NULL, aurEff);
+ }
+
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_gen_alchemist_stone_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_gen_alchemist_stone_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_gen_alchemist_stone_AuraScript();
+ }
+};
+
class spell_gen_allow_cast_from_item_only : public SpellScriptLoader
{
public:
@@ -698,6 +759,11 @@ class spell_gen_chaos_blast : public SpellScriptLoader
}
};
+enum Clone
+{
+ SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE = 57528
+};
+
class spell_gen_clone : public SpellScriptLoader
{
public:
@@ -715,8 +781,16 @@ class spell_gen_clone : public SpellScriptLoader
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
- OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
+ if (m_scriptSpellId == SPELL_NIGHTMARE_FIGMENT_MIRROR_IMAGE)
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_DUMMY);
+ }
+ else
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHitTarget += SpellEffectFn(spell_gen_clone_SpellScript::HandleScriptEffect, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
}
};
@@ -1076,63 +1150,6 @@ class spell_gen_dalaran_disguise : public SpellScriptLoader
}
};
-enum DamageReductionAura
-{
- SPELL_BLESSING_OF_SANCTUARY = 20911,
- SPELL_GREATER_BLESSING_OF_SANCTUARY = 25899,
- SPELL_RENEWED_HOPE = 63944,
- SPELL_VIGILANCE = 50720,
- SPELL_DAMAGE_REDUCTION_AURA = 68066
-};
-
-class spell_gen_damage_reduction_aura : public SpellScriptLoader
-{
- public:
- spell_gen_damage_reduction_aura() : SpellScriptLoader("spell_gen_damage_reduction_aura") { }
-
- class spell_gen_damage_reduction_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_gen_damage_reduction_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_DAMAGE_REDUCTION_AURA))
- return false;
- return true;
- }
-
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- Unit* target = GetTarget();
- target->CastSpell(target, SPELL_DAMAGE_REDUCTION_AURA, true);
- }
-
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- Unit* target = GetTarget();
- if (target->HasAura(SPELL_DAMAGE_REDUCTION_AURA) && !(target->HasAura(SPELL_BLESSING_OF_SANCTUARY) ||
- target->HasAura(SPELL_GREATER_BLESSING_OF_SANCTUARY) ||
- target->HasAura(SPELL_RENEWED_HOPE) ||
- target->HasAura(SPELL_VIGILANCE)))
- {
- target->RemoveAurasDueToSpell(SPELL_DAMAGE_REDUCTION_AURA);
- }
- }
-
- void Register() OVERRIDE
- {
- OnEffectApply += AuraEffectApplyFn(spell_gen_damage_reduction_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- OnEffectRemove += AuraEffectRemoveFn(spell_gen_damage_reduction_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- }
-
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_gen_damage_reduction_AuraScript();
- }
-};
-
enum DefendVisuals
{
SPELL_VISUAL_SHIELD_1 = 63130,
@@ -1669,6 +1686,48 @@ class spell_gen_gunship_portal : public SpellScriptLoader
}
};
+
+enum Interrupt
+{
+ SPELL_GEN_THROW_INTERRUPT = 32747
+};
+
+// 32748 - Deadly Throw Interrupt
+// 44835 - Maim Interrupt
+class spell_gen_interrupt : public SpellScriptLoader
+{
+ public:
+ spell_gen_interrupt() : SpellScriptLoader("spell_gen_interrupt") { }
+
+ class spell_gen_interrupt_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_interrupt_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_GEN_THROW_INTERRUPT))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_GEN_THROW_INTERRUPT, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_gen_interrupt_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_gen_interrupt_AuraScript();
+ }
+};
+
enum Launch
{
SPELL_LAUNCH_NO_FALLING_DAMAGE = 66251
@@ -1721,31 +1780,32 @@ class spell_gen_launch : public SpellScriptLoader
}
};
-
-class spell_gen_lifeblood : public SpellScriptLoader
+class spell_gen_increase_stats_buff : public SpellScriptLoader
{
public:
- spell_gen_lifeblood() : SpellScriptLoader("spell_gen_lifeblood") { }
+ spell_gen_increase_stats_buff(char const* scriptName) : SpellScriptLoader(scriptName) { }
- class spell_gen_lifeblood_AuraScript : public AuraScript
+ class spell_gen_increase_stats_buff_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_gen_lifeblood_AuraScript);
+ PrepareSpellScript(spell_gen_increase_stats_buff_SpellScript);
- void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
- if (Unit* owner = GetUnitOwner())
- amount += int32(CalculatePct(owner->GetMaxHealth(), 1.5f / aurEff->GetTotalTicks()));
+ if (GetHitUnit()->IsInRaidWith(GetCaster()))
+ GetCaster()->CastSpell(GetCaster(), GetEffectValue() + 1, true); // raid buff
+ else
+ GetCaster()->CastSpell(GetHitUnit(), GetEffectValue(), true); // single-target buff
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_lifeblood_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ OnEffectHitTarget += SpellEffectFn(spell_gen_increase_stats_buff_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_gen_lifeblood_AuraScript();
+ return new spell_gen_increase_stats_buff_SpellScript();
}
};
@@ -1805,233 +1865,6 @@ class spell_gen_lifebloom : public SpellScriptLoader
uint32 _spellId;
};
-enum MagicRoosterSpells
-{
- SPELL_MAGIC_ROOSTER_NORMAL = 66122,
- SPELL_MAGIC_ROOSTER_DRAENEI_MALE = 66123,
- SPELL_MAGIC_ROOSTER_TAUREN_MALE = 66124
-};
-
-class spell_gen_magic_rooster : public SpellScriptLoader
-{
- public:
- spell_gen_magic_rooster() : SpellScriptLoader("spell_gen_magic_rooster") { }
-
- class spell_gen_magic_rooster_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_gen_magic_rooster_SpellScript);
-
- void HandleScript(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
- if (Player* target = GetHitPlayer())
- {
- // prevent client crashes from stacking mounts
- target->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- uint32 spellId = SPELL_MAGIC_ROOSTER_NORMAL;
- switch (target->getRace())
- {
- case RACE_DRAENEI:
- if (target->getGender() == GENDER_MALE)
- spellId = SPELL_MAGIC_ROOSTER_DRAENEI_MALE;
- break;
- case RACE_TAUREN:
- if (target->getGender() == GENDER_MALE)
- spellId = SPELL_MAGIC_ROOSTER_TAUREN_MALE;
- break;
- default:
- break;
- }
-
- target->CastSpell(target, spellId, true);
- }
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_gen_magic_rooster_SpellScript::HandleScript, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_gen_magic_rooster_SpellScript();
- }
-};
-
-enum Mounts
-{
- SPELL_COLD_WEATHER_FLYING = 54197,
-
- // Magic Broom
- SPELL_MAGIC_BROOM_60 = 42680,
- SPELL_MAGIC_BROOM_100 = 42683,
- SPELL_MAGIC_BROOM_150 = 42667,
- SPELL_MAGIC_BROOM_280 = 42668,
-
- // Headless Horseman's Mount
- SPELL_HEADLESS_HORSEMAN_MOUNT_60 = 51621,
- SPELL_HEADLESS_HORSEMAN_MOUNT_100 = 48024,
- SPELL_HEADLESS_HORSEMAN_MOUNT_150 = 51617,
- SPELL_HEADLESS_HORSEMAN_MOUNT_280 = 48023,
-
- // Winged Steed of the Ebon Blade
- SPELL_WINGED_STEED_150 = 54726,
- SPELL_WINGED_STEED_280 = 54727,
-
- // Big Love Rocket
- SPELL_BIG_LOVE_ROCKET_0 = 71343,
- SPELL_BIG_LOVE_ROCKET_60 = 71344,
- SPELL_BIG_LOVE_ROCKET_100 = 71345,
- SPELL_BIG_LOVE_ROCKET_150 = 71346,
- SPELL_BIG_LOVE_ROCKET_310 = 71347,
-
- // Invincible
- SPELL_INVINCIBLE_60 = 72281,
- SPELL_INVINCIBLE_100 = 72282,
- SPELL_INVINCIBLE_150 = 72283,
- SPELL_INVINCIBLE_310 = 72284,
-
- // Blazing Hippogryph
- SPELL_BLAZING_HIPPOGRYPH_150 = 74854,
- SPELL_BLAZING_HIPPOGRYPH_280 = 74855,
-
- // Celestial Steed
- SPELL_CELESTIAL_STEED_60 = 75619,
- SPELL_CELESTIAL_STEED_100 = 75620,
- SPELL_CELESTIAL_STEED_150 = 75617,
- SPELL_CELESTIAL_STEED_280 = 75618,
- SPELL_CELESTIAL_STEED_310 = 76153,
-
- // X-53 Touring Rocket
- SPELL_X53_TOURING_ROCKET_150 = 75957,
- SPELL_X53_TOURING_ROCKET_280 = 75972,
- SPELL_X53_TOURING_ROCKET_310 = 76154
-};
-
-class spell_gen_mount : public SpellScriptLoader
-{
- public:
- spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name),
- _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
-
- class spell_gen_mount_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_gen_mount_SpellScript);
-
- public:
- spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(),
- _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0))
- return false;
- if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60))
- return false;
- if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100))
- return false;
- if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150))
- return false;
- if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280))
- return false;
- if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310))
- return false;
- return true;
- }
-
- void HandleMount(SpellEffIndex effIndex)
- {
- PreventHitDefaultEffect(effIndex);
-
- if (Player* target = GetHitPlayer())
- {
- // Prevent stacking of mounts and client crashes upon dismounting
- target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura());
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = false;
- uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId());
- if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING)))
- canFly = true;
-
- float x, y, z;
- target->GetPosition(x, y, z);
- uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag);
- if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- uint32 mount = 0;
- switch (target->GetBaseSkillValue(SKILL_RIDING))
- {
- case 0:
- mount = _mount0;
- break;
- case 75:
- mount = _mount60;
- break;
- case 150:
- mount = _mount100;
- break;
- case 225:
- if (canFly)
- mount = _mount150;
- else
- mount = _mount100;
- break;
- case 300:
- if (canFly)
- {
- if (_mount310 && target->Has310Flyer(false))
- mount = _mount310;
- else
- mount = _mount280;
- }
- else
- mount = _mount100;
- break;
- default:
- break;
- }
-
- if (mount)
- {
- PreventHitAura();
- target->CastSpell(target, mount, true);
- }
- }
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
- }
-
- private:
- uint32 _mount0;
- uint32 _mount60;
- uint32 _mount100;
- uint32 _mount150;
- uint32 _mount280;
- uint32 _mount310;
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310);
- }
-
- private:
- uint32 _mount0;
- uint32 _mount60;
- uint32 _mount100;
- uint32 _mount150;
- uint32 _mount280;
- uint32 _mount310;
-};
-
/* DOCUMENTATION: Charge spells
Charge spells can be classified in four groups:
@@ -2795,7 +2628,7 @@ class spell_gen_parachute_ic : public SpellScriptLoader
void HandleTriggerSpell(AuraEffect const* /*aurEff*/)
{
if (Player* target = GetTarget()->ToPlayer())
- if (target->m_movementInfo.fallTime > 2000)
+ if (target->m_movementInfo.jump.fallTime > 2000)
target->CastSpell(target, SPELL_PARACHUTE_IC, true);
}
@@ -3055,6 +2888,160 @@ class spell_gen_replenishment : public SpellScriptLoader
}
};
+
+enum RunningWildMountIds
+{
+ RUNNING_WILD_MODEL_MALE = 29422,
+ RUNNING_WILD_MODEL_FEMALE = 29423,
+ SPELL_ALTERED_FORM = 97709
+};
+
+class spell_gen_running_wild : public SpellScriptLoader
+{
+ public:
+ spell_gen_running_wild() : SpellScriptLoader("spell_gen_running_wild") { }
+
+ class spell_gen_running_wild_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_running_wild_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ {
+ if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_MALE))
+ return false;
+ if (!sCreatureDisplayInfoStore.LookupEntry(RUNNING_WILD_MODEL_FEMALE))
+ return false;
+ return true;
+ }
+
+ void HandleMount(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ PreventDefaultAction();
+
+ target->Mount(target->getGender() == GENDER_FEMALE ? RUNNING_WILD_MODEL_FEMALE : RUNNING_WILD_MODEL_MALE, 0, 0);
+
+ // cast speed aura
+ if (MountCapabilityEntry const* mountCapability = sMountCapabilityStore.LookupEntry(aurEff->GetAmount()))
+ target->CastSpell(target, mountCapability->SpeedModSpell, TRIGGERED_FULL_MASK);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_gen_running_wild_AuraScript::HandleMount, EFFECT_1, SPELL_AURA_MOUNTED, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ class spell_gen_running_wild_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_running_wild_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ALTERED_FORM))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ // Definitely not a good thing, but currently the only way to do something at cast start
+ // Should be replaced as soon as possible with a new hook: BeforeCastStart
+ GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK);
+ return false;
+ }
+
+ void Register() OVERRIDE
+ {
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_gen_running_wild_AuraScript();
+ }
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_gen_running_wild_SpellScript();
+ }
+};
+
+class spell_gen_two_forms : public SpellScriptLoader
+{
+ public:
+ spell_gen_two_forms() : SpellScriptLoader("spell_gen_two_forms") { }
+
+ class spell_gen_two_forms_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_two_forms_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ if (GetCaster()->IsInCombat())
+ {
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ // Player cannot transform to human form if he is forced to be worgen for some reason (Darkflight)
+ if (GetCaster()->GetAuraEffectsByType(SPELL_AURA_WORGEN_ALTERED_FORM).size() > 1)
+ {
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_CANT_TRANSFORM);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ return SPELL_CAST_OK;
+ }
+
+ void HandleTransform(SpellEffIndex effIndex)
+ {
+ Unit* target = GetHitUnit();
+ PreventHitDefaultEffect(effIndex);
+ if (target->HasAuraType(SPELL_AURA_WORGEN_ALTERED_FORM))
+ target->RemoveAurasByType(SPELL_AURA_WORGEN_ALTERED_FORM);
+ else // Basepoints 1 for this aura control whether to trigger transform transition animation or not.
+ target->CastCustomSpell(SPELL_ALTERED_FORM, SPELLVALUE_BASE_POINT0, 1, target, TRIGGERED_FULL_MASK);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnCheckCast += SpellCheckCastFn(spell_gen_two_forms_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_gen_two_forms_SpellScript::HandleTransform, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_gen_two_forms_SpellScript();
+ }
+};
+
+class spell_gen_darkflight : public SpellScriptLoader
+{
+ public:
+ spell_gen_darkflight() : SpellScriptLoader("spell_gen_darkflight") { }
+
+ class spell_gen_darkflight_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_darkflight_SpellScript);
+
+ void TriggerTransform()
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_ALTERED_FORM, TRIGGERED_FULL_MASK);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterCast += SpellCastFn(spell_gen_darkflight_SpellScript::TriggerTransform);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_gen_darkflight_SpellScript();
+ }
+};
enum SeaforiumSpells
{
SPELL_PLANT_CHARGES_CREDIT_ACHIEVEMENT = 60937
@@ -3677,6 +3664,7 @@ void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
new spell_gen_adaptive_warding();
+ new spell_gen_alchemist_stone();
new spell_gen_allow_cast_from_item_only();
new spell_gen_animal_blood();
new spell_gen_aura_of_anger();
@@ -3698,7 +3686,6 @@ void AddSC_generic_spell_scripts()
new spell_gen_creature_permanent_feign_death();
new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise");
new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise");
- new spell_gen_damage_reduction_aura();
new spell_gen_defend();
new spell_gen_despawn_self();
new spell_gen_divine_storm_cd_reset();
@@ -3710,25 +3697,22 @@ void AddSC_generic_spell_scripts()
new spell_gen_gift_of_naaru();
new spell_gen_gnomish_transporter();
new spell_gen_gunship_portal();
+ new spell_gen_increase_stats_buff("spell_pal_blessing_of_kings");
+ new spell_gen_increase_stats_buff("spell_pal_blessing_of_might");
+ new spell_gen_increase_stats_buff("spell_dru_mark_of_the_wild");
+ new spell_gen_increase_stats_buff("spell_pri_power_word_fortitude");
+ new spell_gen_increase_stats_buff("spell_pri_shadow_protection");
+ new spell_gen_increase_stats_buff("spell_mage_arcane_brilliance");
+ new spell_gen_increase_stats_buff("spell_mage_dalaran_brilliance");
+ new spell_gen_interrupt();
new spell_gen_launch();
- new spell_gen_lifeblood();
new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL);
new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL);
- new spell_gen_magic_rooster();
- new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280);
- new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280);
- new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280);
- new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310);
- new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310);
- new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280);
- new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310);
- new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310);
new spell_gen_mounted_charge();
new spell_gen_netherbloom();
- new spell_gen_nightmare_vine();
new spell_gen_obsidian_armor();
new spell_gen_on_tournament_mount();
new spell_gen_oracle_wolvar_reputation();
@@ -3739,6 +3723,11 @@ void AddSC_generic_spell_scripts()
new spell_gen_profession_research();
new spell_gen_remove_flight_auras();
new spell_gen_replenishment();
+ // Running Wild
+ new spell_gen_running_wild();
+ new spell_gen_two_forms();
+ new spell_gen_darkflight();
+ /* */
new spell_gen_seaforium_blast();
new spell_gen_spectator_cheer_trigger();
new spell_gen_spirit_healer_res();
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 2f8a5daae84..b1f8b536c98 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -32,16 +32,13 @@
enum HunterSpells
{
- SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET = 61669,
- SPELL_HUNTER_ASPECT_OF_THE_VIPER = 34074,
- SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE = 34075,
SPELL_HUNTER_BESTIAL_WRATH = 19574,
- SPELL_HUNTER_CHIMERA_SHOT_SERPENT = 53353,
- SPELL_HUNTER_CHIMERA_SHOT_VIPER = 53358,
- SPELL_HUNTER_CHIMERA_SHOT_SCORPID = 53359,
- SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER = 56851,
+ SPELL_HUNTER_CHIMERA_SHOT_HEAL = 53353,
+ SPELL_HUNTER_FIRE = 82926,
+ SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS = 91954,
SPELL_HUNTER_IMPROVED_MEND_PET = 24406,
SPELL_HUNTER_INVIGORATION_TRIGGERED = 53398,
+ SPELL_HUNTER_LOCK_AND_LOAD = 56453,
SPELL_HUNTER_MASTERS_CALL_TRIGGERED = 62305,
SPELL_HUNTER_MISDIRECTION_PROC = 35079,
SPELL_HUNTER_PET_LAST_STAND_TRIGGERED = 53479,
@@ -49,245 +46,169 @@ enum HunterSpells
SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_TRIGGERED = 54114,
SPELL_HUNTER_PET_HEART_OF_THE_PHOENIX_DEBUFF = 55711,
SPELL_HUNTER_PET_CARRION_FEEDER_TRIGGERED = 54045,
+ SPELL_HUNTER_RAPID_RECUPERATION = 58883,
SPELL_HUNTER_READINESS = 23989,
+ SPELL_HUNTER_SERPENT_STING = 1978,
SPELL_HUNTER_SNIPER_TRAINING_R1 = 53302,
SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 = 64418,
- SPELL_HUNTER_VICIOUS_VIPER = 61609,
- SPELL_HUNTER_VIPER_ATTACK_SPEED = 60144,
- SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543
+ SPELL_HUNTER_STEADY_SHOT_FOCUS = 77443,
+ SPELL_HUNTER_THRILL_OF_THE_HUNT = 34720,
+ SPELL_DRAENEI_GIFT_OF_THE_NAARU = 59543,
};
-// 13161 - Aspect of the Beast
-class spell_hun_aspect_of_the_beast : public SpellScriptLoader
+// 53209 - Chimera Shot
+class spell_hun_chimera_shot : public SpellScriptLoader
{
public:
- spell_hun_aspect_of_the_beast() : SpellScriptLoader("spell_hun_aspect_of_the_beast") { }
+ spell_hun_chimera_shot() : SpellScriptLoader("spell_hun_chimera_shot") { }
- class spell_hun_aspect_of_the_beast_AuraScript : public AuraScript
+ class spell_hun_chimera_shot_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_hun_aspect_of_the_beast_AuraScript);
-
- bool Load() OVERRIDE
- {
- return GetCaster()->GetTypeId() == TYPEID_PLAYER;
- }
+ PrepareSpellScript(spell_hun_chimera_shot_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET))
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_HEAL) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING))
return false;
return true;
}
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ bool Load() OVERRIDE
{
- if (Player* caster = GetCaster()->ToPlayer())
- if (Pet* pet = caster->GetPet())
- pet->RemoveAurasDueToSpell(SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET);
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (Player* caster = GetCaster()->ToPlayer())
- if (caster->GetPet())
- caster->CastSpell(caster, SPELL_HUNTER_ASPECT_OF_THE_BEAST_PET, true);
+ GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_CHIMERA_SHOT_HEAL, true);
+
+ if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID()))
+ aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
}
void Register() OVERRIDE
{
- AfterEffectApply += AuraEffectApplyFn(spell_hun_aspect_of_the_beast_AuraScript::OnApply, EFFECT_0, SPELL_AURA_UNTRACKABLE, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_hun_aspect_of_the_beast_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_UNTRACKABLE, AURA_EFFECT_HANDLE_REAL);
+ OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_hun_aspect_of_the_beast_AuraScript();
+ return new spell_hun_chimera_shot_SpellScript();
}
};
-// 34074 - Aspect of the Viper
-class spell_hun_ascpect_of_the_viper : public SpellScriptLoader
+// 77767 - Cobra Shot
+class spell_hun_cobra_shot : public SpellScriptLoader
{
public:
- spell_hun_ascpect_of_the_viper() : SpellScriptLoader("spell_hun_ascpect_of_the_viper") { }
+ spell_hun_cobra_shot() : SpellScriptLoader("spell_hun_cobra_shot") { }
- class spell_hun_ascpect_of_the_viper_AuraScript : public AuraScript
+ class spell_hun_cobra_shot_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_hun_ascpect_of_the_viper_AuraScript);
+ PrepareSpellScript(spell_hun_cobra_shot_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE) ||
- !sSpellMgr->GetSpellInfo(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER) ||
- !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VIPER_ATTACK_SPEED) ||
- !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VICIOUS_VIPER))
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SERPENT_STING))
return false;
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ bool Load() OVERRIDE
{
- PreventDefaultAction();
-
- uint32 maxMana = GetTarget()->GetMaxPower(POWER_MANA);
- int32 mana = CalculatePct(maxMana, GetTarget()->GetAttackTime(RANGED_ATTACK) / 1000.0f);
-
- if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_HUNTER_GLYPH_OF_ASPECT_OF_THE_VIPER, EFFECT_0))
- AddPct(mana, glyph->GetAmount());
-
- GetTarget()->CastCustomSpell(SPELL_HUNTER_ASPECT_OF_THE_VIPER_ENERGIZE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff);
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- // Hunter T7 4P Bonus
- if (GetTarget()->HasAura(SPELL_HUNTER_VIPER_ATTACK_SPEED))
- GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_VICIOUS_VIPER, true, NULL, aurEff);
- }
+ GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_GENERIC_ENERGIZE_FOCUS, true);
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- // Hunter T7 4P Bonus
- if (GetTarget()->HasAura(SPELL_HUNTER_VIPER_ATTACK_SPEED))
- GetTarget()->RemoveAurasDueToSpell(SPELL_HUNTER_VICIOUS_VIPER);
+ if (Aura* aur = GetHitUnit()->GetAura(SPELL_HUNTER_SERPENT_STING, GetCaster()->GetGUID()))
+ {
+ int32 newDuration = aur->GetDuration() + GetEffectValue() * IN_MILLISECONDS;
+ aur->SetDuration(std::min(newDuration, aur->GetMaxDuration()), true);
+ }
}
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_hun_ascpect_of_the_viper_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_OBS_MOD_POWER);
- AfterEffectApply += AuraEffectApplyFn(spell_hun_ascpect_of_the_viper_AuraScript::OnApply, EFFECT_0, SPELL_AURA_OBS_MOD_POWER, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_hun_ascpect_of_the_viper_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_OBS_MOD_POWER, AURA_EFFECT_HANDLE_REAL);
+ OnEffectHitTarget += SpellEffectFn(spell_hun_cobra_shot_SpellScript::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_hun_ascpect_of_the_viper_AuraScript();
+ return new spell_hun_cobra_shot_SpellScript();
}
};
-// 53209 - Chimera Shot
-class spell_hun_chimera_shot : public SpellScriptLoader
+// 781 - Disengage
+class spell_hun_disengage : public SpellScriptLoader
{
public:
- spell_hun_chimera_shot() : SpellScriptLoader("spell_hun_chimera_shot") { }
+ spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { }
- class spell_hun_chimera_shot_SpellScript : public SpellScript
+ class spell_hun_disengage_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_hun_chimera_shot_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SERPENT) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_VIPER) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_CHIMERA_SHOT_SCORPID))
- return false;
- return true;
- }
+ PrepareSpellScript(spell_hun_disengage_SpellScript);
- void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ SpellCastResult CheckCast()
{
Unit* caster = GetCaster();
- if (Unit* unitTarget = GetHitUnit())
- {
- uint32 spellId = 0;
- int32 basePoint = 0;
- Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
- for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
- {
- Aura* aura = i->second->GetBase();
- if (aura->GetCasterGUID() != caster->GetGUID())
- continue;
-
- // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
- flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags;
- if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
- continue;
- if (AuraEffect const* aurEff = aura->GetEffect(0))
- {
- // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
- if (familyFlag[0] & 0x4000)
- {
- int32 TickCount = aurEff->GetTotalTicks();
- spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT;
- basePoint = caster->SpellDamageBonusDone(unitTarget, aura->GetSpellInfo(), aurEff->GetAmount(), DOT, aura->GetStackAmount());
- ApplyPct(basePoint, TickCount * 40);
- basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount());
- }
- // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
- else if (familyFlag[1] & 0x00000080)
- {
- int32 TickCount = aura->GetEffect(0)->GetTotalTicks();
- spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER;
-
- // Amount of one aura tick
- basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount()));
- int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50; /// @todo WTF? caster uses unitTarget?
- if (basePoint > casterBasePoint)
- basePoint = casterBasePoint;
- ApplyPct(basePoint, TickCount * 60);
- }
- // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
- else if (familyFlag[0] & 0x00008000)
- spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID;
- // ?? nothing say in spell desc (possibly need addition check)
- //if (familyFlag & 0x0000010000000000LL || // dot
- // familyFlag & 0x0000100000000000LL) // stun
- //{
- // spellId = 53366; // 53366 Chimera Shot - Wyvern
- //}
-
- // Refresh aura duration
- aura->RefreshDuration();
- }
- break;
- }
- if (spellId)
- caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true);
- if (spellId == SPELL_HUNTER_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown
- caster->ToPlayer()->AddSpellCooldown(spellId, 0, uint32(time(NULL) + 60));
- }
+ if (caster->GetTypeId() == TYPEID_PLAYER && !caster->IsInCombat())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
+ return SPELL_CAST_OK;
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_hun_chimera_shot_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_hun_chimera_shot_SpellScript();
+ return new spell_hun_disengage_SpellScript();
}
};
-// 781 - Disengage
-class spell_hun_disengage : public SpellScriptLoader
+// 82926 - Fire!
+class spell_hun_fire : public SpellScriptLoader
{
public:
- spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { }
+ spell_hun_fire() : SpellScriptLoader("spell_hun_fire") { }
- class spell_hun_disengage_SpellScript : public SpellScript
+ class spell_hun_fire_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_hun_disengage_SpellScript);
+ PrepareAuraScript(spell_hun_fire_AuraScript);
- SpellCastResult CheckCast()
+ void HandleEffectCalcSpellMod(AuraEffect const* aurEff, SpellModifier*& spellMod)
{
- Unit* caster = GetCaster();
- if (caster->GetTypeId() == TYPEID_PLAYER && !caster->IsInCombat())
- return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+ 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;
+ }
- return SPELL_CAST_OK;
+ spellMod->value = -aurEff->GetAmount();
}
void Register() OVERRIDE
{
- OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast);
+ DoEffectCalcSpellMod += AuraEffectCalcSpellModFn(spell_hun_fire_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
}
};
- SpellScript* GetSpellScript() const OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_hun_disengage_SpellScript();
+ return new spell_hun_fire_AuraScript();
}
};
@@ -331,6 +252,43 @@ class spell_hun_improved_mend_pet : public SpellScriptLoader
return new spell_hun_improved_mend_pet_AuraScript();
}
};
+
+// -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
{
@@ -416,7 +374,8 @@ 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->Effects[EFFECT_1].CalcValue()))
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_MASTERS_CALL_TRIGGERED) ||
+ !sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].CalcValue()))
return false;
return true;
}
@@ -429,7 +388,6 @@ class spell_hun_masters_call : public SpellScriptLoader
{
TriggerCastFlags castMask = TriggerCastFlags(TRIGGERED_FULL_MASK & ~TRIGGERED_IGNORE_CASTER_AURASTATE);
target->CastSpell(ally, GetEffectValue(), castMask);
- target->CastSpell(ally, GetSpellInfo()->Effects[EFFECT_0].CalcValue(), castMask);
}
}
@@ -635,6 +593,54 @@ class spell_hun_pet_heart_of_the_phoenix : public SpellScriptLoader
}
};
+// -53228 - Rapid Recuperation
+class spell_hun_rapid_recuperation : public SpellScriptLoader
+{
+ public:
+ spell_hun_rapid_recuperation() : SpellScriptLoader("spell_hun_rapid_recuperation") { }
+
+ class spell_hun_rapid_recuperation_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_rapid_recuperation_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_RAPID_RECUPERATION))
+ return false;
+ return true;
+ }
+
+ void HandleAbilityCast(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
+ {
+ // This effect only from Rapid Fire (ability cast)
+ if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x20))
+ PreventDefaultAction();
+ }
+
+ void HandleFocusRegen(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ // This effect only from Rapid Killing (focus regen)
+ if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x01000000))
+ return;
+
+ int32 focus = aurEff->GetAmount();
+ GetTarget()->CastCustomSpell(SPELL_HUNTER_RAPID_RECUPERATION, SPELLVALUE_BASE_POINT0, focus, GetTarget(), true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleAbilityCast, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectProc += AuraEffectProcFn(spell_hun_rapid_recuperation_AuraScript::HandleFocusRegen, EFFECT_1, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_hun_rapid_recuperation_AuraScript();
+ }
+};
+
// 23989 - Readiness
class spell_hun_readiness : public SpellScriptLoader
{
@@ -684,6 +690,44 @@ class spell_hun_readiness : public SpellScriptLoader
}
};
+// 82925 - Ready, Set, Aim...
+class spell_hun_ready_set_aim : public SpellScriptLoader
+{
+ public:
+ spell_hun_ready_set_aim() : SpellScriptLoader("spell_hun_ready_set_aim") { }
+
+ class spell_hun_ready_set_aim_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_ready_set_aim_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_FIRE))
+ return false;
+ return true;
+ }
+
+ void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetStackAmount() == 5)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_FIRE, true, NULL, aurEff);
+ GetTarget()->RemoveAura(GetId());
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_hun_ready_set_aim_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_hun_ready_set_aim_AuraScript();
+ }
+};
+
// 37506 - Scatter Shot
class spell_hun_scatter_shot : public SpellScriptLoader
{
@@ -732,7 +776,8 @@ class spell_hun_sniper_training : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) || !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1))
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_R1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1))
return false;
return true;
}
@@ -742,10 +787,15 @@ class spell_hun_sniper_training : public SpellScriptLoader
PreventDefaultAction();
if (aurEff->GetAmount() <= 0)
{
- Unit* target = GetTarget();
+ Unit* caster = GetCaster();
uint32 spellId = SPELL_HUNTER_SNIPER_TRAINING_BUFF_R1 + GetId() - SPELL_HUNTER_SNIPER_TRAINING_R1;
- if (!target->HasAura(spellId))
- target->CastSpell(target, spellId, true, 0, aurEff);
+ if (Unit* target = GetTarget())
+ if (!target->HasAura(spellId))
+ {
+ SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(spellId);
+ Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(GetSpellInfo()) ? caster : target;
+ triggerCaster->CastSpell(target, triggeredSpellInfo, true, 0, aurEff);
+ }
}
}
@@ -774,6 +824,45 @@ class spell_hun_sniper_training : public SpellScriptLoader
}
};
+// 56641 - Steady Shot
+class spell_hun_steady_shot : public SpellScriptLoader
+{
+ public:
+ spell_hun_steady_shot() : SpellScriptLoader("spell_hun_steady_shot") { }
+
+ class spell_hun_steady_shot_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_hun_steady_shot_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_STEADY_SHOT_FOCUS))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void HandleOnHit()
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_HUNTER_STEADY_SHOT_FOCUS, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnHit += SpellHitFn(spell_hun_steady_shot_SpellScript::HandleOnHit);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_hun_steady_shot_SpellScript();
+ }
+};
+
// 1515 - Tame Beast
class spell_hun_tame_beast : public SpellScriptLoader
{
@@ -826,7 +915,6 @@ class spell_hun_tame_beast : public SpellScriptLoader
}
};
-// -24604 - Furious Howl
// 53434 - Call of the Wild
class spell_hun_target_only_pet_and_owner : public SpellScriptLoader
{
@@ -858,56 +946,93 @@ class spell_hun_target_only_pet_and_owner : public SpellScriptLoader
}
};
-// 60144 - Viper Attack Speed
-class spell_hun_viper_attack_speed : public SpellScriptLoader
+// 34497 - Thrill of the Hunt
+class spell_hun_thrill_of_the_hunt : public SpellScriptLoader
{
public:
- spell_hun_viper_attack_speed() : SpellScriptLoader("spell_hun_viper_attack_speed") { }
+ spell_hun_thrill_of_the_hunt() : SpellScriptLoader("spell_hun_thrill_of_the_hunt") { }
- class spell_hun_viper_attack_speed_AuraScript : public AuraScript
+ class spell_hun_thrill_of_the_hunt_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_hun_viper_attack_speed_AuraScript);
+ PrepareAuraScript(spell_hun_thrill_of_the_hunt_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_ASPECT_OF_THE_VIPER) ||
- !sSpellMgr->GetSpellInfo(SPELL_HUNTER_VICIOUS_VIPER))
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_THRILL_OF_THE_HUNT))
return false;
return true;
}
- void OnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 focus = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), SpellSchoolMask(eventInfo.GetDamageInfo()->GetSchoolMask()));
+ focus = CalculatePct(focus, aurEff->GetAmount());
+
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_HUNTER_THRILL_OF_THE_HUNT, &focus, NULL, NULL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
{
- if (GetTarget()->HasAura(SPELL_HUNTER_ASPECT_OF_THE_VIPER))
- GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_VICIOUS_VIPER, true, NULL, aurEff);
+ OnEffectProc += AuraEffectProcFn(spell_hun_thrill_of_the_hunt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
+ };
- void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_hun_thrill_of_the_hunt_AuraScript();
+ }
+};
+
+// -56333 - T.N.T.
+class spell_hun_tnt : public SpellScriptLoader
+{
+ public:
+ spell_hun_tnt() : SpellScriptLoader("spell_hun_tnt") { }
+
+ class spell_hun_tnt_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_tnt_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_HUNTER_LOCK_AND_LOAD))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& /*eventInfo*/)
{
- // possible exploit
- GetTarget()->RemoveAurasDueToSpell(SPELL_HUNTER_VICIOUS_VIPER);
+ return roll_chance_i(GetEffect(EFFECT_0)->GetAmount());
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), SPELL_HUNTER_LOCK_AND_LOAD, true, NULL, aurEff);
}
void Register() OVERRIDE
{
- AfterEffectApply += AuraEffectApplyFn(spell_hun_viper_attack_speed_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_hun_viper_attack_speed_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ DoCheckProc += AuraCheckProcFn(spell_hun_tnt_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_hun_tnt_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_hun_viper_attack_speed_AuraScript();
+ return new spell_hun_tnt_AuraScript();
}
};
void AddSC_hunter_spell_scripts()
{
- new spell_hun_aspect_of_the_beast();
- new spell_hun_ascpect_of_the_viper();
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();
@@ -915,10 +1040,14 @@ void AddSC_hunter_spell_scripts()
new spell_hun_misdirection_proc();
new spell_hun_pet_carrion_feeder();
new spell_hun_pet_heart_of_the_phoenix();
+ new spell_hun_rapid_recuperation();
new spell_hun_readiness();
+ new spell_hun_ready_set_aim();
new spell_hun_scatter_shot();
new spell_hun_sniper_training();
+ new spell_hun_steady_shot();
new spell_hun_tame_beast();
new spell_hun_target_only_pet_and_owner();
- new spell_hun_viper_attack_speed();
+ new spell_hun_thrill_of_the_hunt();
+ new spell_hun_tnt();
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 837023f3bdd..d8d70246e99 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -2482,51 +2482,6 @@ class spell_item_chicken_cover : public SpellScriptLoader
}
};
-enum Refocus
-{
- SPELL_AIMED_SHOT = 19434,
- SPELL_MULTISHOT = 2643,
- SPELL_VOLLEY = 42243,
-};
-
-class spell_item_refocus : public SpellScriptLoader
-{
- public:
- spell_item_refocus() : SpellScriptLoader("spell_item_refocus") { }
-
- class spell_item_refocus_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_item_refocus_SpellScript);
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- Player* caster = GetCaster()->ToPlayer();
-
- if (!caster || caster->getClass() != CLASS_HUNTER)
- return;
-
- if (caster->HasSpellCooldown(SPELL_AIMED_SHOT))
- caster->RemoveSpellCooldown(SPELL_AIMED_SHOT, true);
-
- if (caster->HasSpellCooldown(SPELL_MULTISHOT))
- caster->RemoveSpellCooldown(SPELL_MULTISHOT, true);
-
- if (caster->HasSpellCooldown(SPELL_VOLLEY))
- caster->RemoveSpellCooldown(SPELL_VOLLEY, true);
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_item_refocus_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_item_refocus_SpellScript();
- }
-};
-
class spell_item_muisek_vessel : public SpellScriptLoader
{
public:
@@ -2633,7 +2588,6 @@ void AddSC_item_spell_scripts()
new spell_item_ashbringer();
new spell_magic_eater_food();
- new spell_item_refocus();
new spell_item_shimmering_vessel();
new spell_item_purify_helboar_meat();
new spell_item_crystal_prison_dummy_dnd();
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index ba59f701445..83f594fd7b1 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -25,18 +25,30 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "Pet.h"
enum MageSpells
{
+ SPELL_ARCANCE_POTENCY_RANK_1 = 31571,
+ SPELL_ARCANCE_POTENCY_RANK_2 = 31572,
+ SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1 = 57529,
+ SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2 = 57531,
+ SPELL_MAGE_BLAZING_SPEED = 31643,
SPELL_MAGE_BURNOUT = 29077,
SPELL_MAGE_COLD_SNAP = 11958,
SPELL_MAGE_FOCUS_MAGIC_PROC = 54648,
+ SPELL_MAGE_FROST_NOVA = 122,
SPELL_MAGE_FROST_WARDING_R1 = 11189,
SPELL_MAGE_FROST_WARDING_TRIGGERED = 57776,
+ SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1 = 11210,
+ SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1 = 83046,
+ SPELL_MAGE_IMPROVED_POLYMORPH_MARKER = 87515,
SPELL_MAGE_INCANTERS_ABSORBTION_R1 = 44394,
SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED = 44413,
SPELL_MAGE_IGNITE = 12654,
SPELL_MAGE_MASTER_OF_ELEMENTS_ENERGIZE = 29077,
+ SPELL_MAGE_PERMAFROST = 91394,
+ SPELL_MAGE_SLOW = 31589,
SPELL_MAGE_SQUIRREL_FORM = 32813,
SPELL_MAGE_GIRAFFE_FORM = 32816,
SPELL_MAGE_SERPENT_FORM = 32817,
@@ -47,6 +59,91 @@ enum MageSpells
SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT = 70908,
SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY = 70907,
SPELL_MAGE_GLYPH_OF_BLAST_WAVE = 62126,
+
+ SPELL_MAGE_FLAMESTRIKE = 2120,
+
+ SPELL_MAGE_CHILLED_R1 = 12484,
+ SPELL_MAGE_CHILLED_R2 = 12485,
+
+ SPELL_MAGE_CONE_OF_COLD_AURA_R1 = 11190,
+ SPELL_MAGE_CONE_OF_COLD_AURA_R2 = 12489,
+ SPELL_MAGE_CONE_OF_COLD_TRIGGER_R1 = 83301,
+ SPELL_MAGE_CONE_OF_COLD_TRIGGER_R2 = 83302,
+
+ SPELL_MAGE_SHATTERED_BARRIER_R1 = 44745,
+ SPELL_MAGE_SHATTERED_BARRIER_R2 = 54787,
+ SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R1 = 55080,
+ SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R2 = 83073,
+
+ SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED = 83098,
+
+ SPELL_MAGE_RING_OF_FROST_SUMMON = 82676,
+ SPELL_MAGE_RING_OF_FROST_FREEZE = 82691,
+ SPELL_MAGE_RING_OF_FROST_DUMMY = 91264,
+
+ SPELL_MAGE_FINGERS_OF_FROST = 44544
+};
+
+enum MageIcons
+{
+ ICON_MAGE_SHATTER = 976,
+ ICON_MAGE_IMPROVED_FLAMESTRIKE = 37,
+ ICON_MAGE_IMPROVED_FREEZE = 94,
+ ICON_MAGE_INCANTER_S_ABSORPTION = 2941,
+ ICON_MAGE_IMPROVED_MANA_GEM = 1036
+};
+
+enum MiscSpells
+{
+ SPELL_PRIEST_SHADOW_WORD_DEATH = 32409
+};
+
+// -31571 - Arcane Potency
+class spell_mage_arcane_potency : public SpellScriptLoader
+{
+ public:
+ spell_mage_arcane_potency () : SpellScriptLoader("spell_mage_arcane_potency") { }
+
+ class spell_mage_arcane_potency_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_arcane_potency_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_RANK_2) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ uint32 spellId = 0;
+
+ if (GetSpellInfo()->Id == SPELL_ARCANCE_POTENCY_RANK_1)
+ spellId = SPELL_ARCANCE_POTENCY_TRIGGER_RANK_1;
+ else if (GetSpellInfo()->Id == SPELL_ARCANCE_POTENCY_RANK_2)
+ spellId = SPELL_ARCANCE_POTENCY_TRIGGER_RANK_2;
+ if (!spellId)
+ return;
+
+ GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff);
+
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_mage_arcane_potency_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_arcane_potency_AuraScript();
+ }
};
// Incanter's Absorbtion
@@ -74,7 +171,7 @@ class spell_mage_incanters_absorbtion_base_AuraScript : public AuraScript
}
};
-// -11113 - Blast Wave
+// 11113 - Blast Wave
class spell_mage_blast_wave : public SpellScriptLoader
{
public:
@@ -86,21 +183,40 @@ class spell_mage_blast_wave : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_GLYPH_OF_BLAST_WAVE))
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FLAMESTRIKE))
return false;
return true;
}
- void HandleKnockBack(SpellEffIndex effIndex)
+ void CountTargets(std::list<WorldObject*>& targetList)
+ {
+ _targetCount = targetList.size();
+ }
+
+ void HandleImprovedFlamestrike()
{
- if (GetCaster()->HasAura(SPELL_MAGE_GLYPH_OF_BLAST_WAVE))
- PreventHitDefaultEffect(effIndex);
+ if (_targetCount >= 2)
+ if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_FLAMESTRIKE, EFFECT_0))
+ if (roll_chance_i(aurEff->GetAmount()))
+ {
+ float x, y, z;
+ WorldLocation const* loc = GetExplTargetDest();
+ if (!loc)
+ return;
+
+ loc->GetPosition(x, y, z);
+ GetCaster()->CastSpell(x, y, z, SPELL_MAGE_FLAMESTRIKE, true);
+ }
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_mage_blast_wave_SpellScript::HandleKnockBack, EFFECT_2, SPELL_EFFECT_KNOCK_BACK);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_blast_wave_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ AfterCast += SpellCastFn(spell_mage_blast_wave_SpellScript::HandleImprovedFlamestrike);
}
+
+ private:
+ uint32 _targetCount;
};
SpellScript* GetSpellScript() const OVERRIDE
@@ -109,51 +225,85 @@ class spell_mage_blast_wave : public SpellScriptLoader
}
};
-// -44449 - Burnout
-class spell_mage_burnout : public SpellScriptLoader
+// -31641 - Blazing Speed
+class spell_mage_blazing_speed : public SpellScriptLoader
{
public:
- spell_mage_burnout() : SpellScriptLoader("spell_mage_burnout") { }
+ spell_mage_blazing_speed() : SpellScriptLoader("spell_mage_blazing_speed") { }
- class spell_mage_burnout_AuraScript : public AuraScript
+ class spell_mage_blazing_speed_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_mage_burnout_AuraScript);
+ PrepareAuraScript(spell_mage_blazing_speed_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BURNOUT))
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_BLAZING_SPEED))
return false;
return true;
}
- bool CheckProc(ProcEventInfo& eventInfo)
- {
- return eventInfo.GetDamageInfo()->GetSpellInfo(); // eventInfo.GetSpellInfo()
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
-
- int32 mana = int32(eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetDamageInfo()->GetSchoolMask()));
- mana = CalculatePct(mana, aurEff->GetAmount());
-
- GetTarget()->CastCustomSpell(SPELL_MAGE_BURNOUT, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff);
+ GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_BLAZING_SPEED, true, NULL, aurEff);
}
void Register() OVERRIDE
{
- DoCheckProc += AuraCheckProcFn(spell_mage_burnout_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_mage_burnout_AuraScript::HandleProc, EFFECT_1, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_mage_blazing_speed_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_mage_burnout_AuraScript();
+ return new spell_mage_blazing_speed_AuraScript();
}
};
+// 42208 - Blizzard
+/// Updated 4.3.4
+class spell_mage_blizzard : public SpellScriptLoader
+{
+ public:
+ spell_mage_blizzard() : SpellScriptLoader("spell_mage_blizzard") { }
+
+ class spell_mage_blizzard_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_blizzard_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_CHILLED_R1))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_CHILLED_R2))
+ return false;
+ return true;
+ }
+
+ void AddChillEffect(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Unit* unitTarget = GetHitUnit())
+ {
+ if (caster->IsScriptOverriden(GetSpellInfo(), 836))
+ caster->CastSpell(unitTarget, SPELL_MAGE_CHILLED_R1, true);
+ else if (caster->IsScriptOverriden(GetSpellInfo(), 988))
+ caster->CastSpell(unitTarget, SPELL_MAGE_CHILLED_R2, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mage_blizzard_SpellScript::AddChillEffect, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mage_blizzard_SpellScript();
+ }
+};
+
// 11958 - Cold Snap
class spell_mage_cold_snap : public SpellScriptLoader
{
@@ -201,8 +351,113 @@ class spell_mage_cold_snap : public SpellScriptLoader
}
};
-// -543 - Fire Ward
-// -6143 - Frost Ward
+// 120 - Cone of Cold
+/// Updated 4.3.4
+class spell_mage_cone_of_cold : public SpellScriptLoader
+{
+ public:
+ spell_mage_cone_of_cold() : SpellScriptLoader("spell_mage_cone_of_cold") { }
+
+ class spell_mage_cone_of_cold_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_cone_of_cold_SpellScript);
+
+ void HandleConeOfColdScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Unit* unitTarget = GetHitUnit())
+ {
+ if (caster->HasAura(SPELL_MAGE_CONE_OF_COLD_AURA_R1)) // Improved Cone of Cold Rank 1
+ unitTarget->CastSpell(unitTarget, SPELL_MAGE_CONE_OF_COLD_TRIGGER_R1, true);
+ else if (caster->HasAura(SPELL_MAGE_CONE_OF_COLD_AURA_R2)) // Improved Cone of Cold Rank 2
+ unitTarget->CastSpell(unitTarget, SPELL_MAGE_CONE_OF_COLD_TRIGGER_R2, true);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mage_cone_of_cold_SpellScript::HandleConeOfColdScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mage_cone_of_cold_SpellScript();
+ }
+};
+
+// 42955 Conjure Refreshment
+/// Updated 4.3.4
+struct ConjureRefreshmentData
+{
+ uint32 minLevel;
+ uint32 maxLevel;
+ uint32 spellId;
+};
+
+uint8 const MAX_CONJURE_REFRESHMENT_SPELLS = 7;
+ConjureRefreshmentData const _conjureData[MAX_CONJURE_REFRESHMENT_SPELLS] =
+{
+ { 33, 43, 92739 },
+ { 44, 53, 92799 },
+ { 54, 63, 92802 },
+ { 64, 73, 92805 },
+ { 74, 79, 74625 },
+ { 80, 84, 92822 },
+ { 85, 85, 92727 }
+};
+
+// 42955 - Conjure Refreshment
+class spell_mage_conjure_refreshment : public SpellScriptLoader
+{
+ public:
+ spell_mage_conjure_refreshment() : SpellScriptLoader("spell_mage_conjure_refreshment") { }
+
+ class spell_mage_conjure_refreshment_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_conjure_refreshment_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ for (uint8 i = 0; i < MAX_CONJURE_REFRESHMENT_SPELLS; ++i)
+ if (!sSpellMgr->GetSpellInfo(_conjureData[i].spellId))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint8 level = GetHitUnit()->getLevel();
+ for (uint8 i = 0; i < MAX_CONJURE_REFRESHMENT_SPELLS; ++i)
+ {
+ ConjureRefreshmentData const& spellData = _conjureData[i];
+ if (level < spellData.minLevel || level > spellData.maxLevel)
+ continue;
+ GetHitUnit()->CastSpell(GetHitUnit(), spellData.spellId);
+ break;
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mage_conjure_refreshment_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_mage_conjure_refreshment_SpellScript();
+ }
+};
+
+// 543 - Fire War
class spell_mage_fire_frost_ward : public SpellScriptLoader
{
public:
@@ -214,9 +469,8 @@ class spell_mage_fire_frost_ward : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1))
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_TRIGGERED) ||
+ !sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_WARDING_R1))
return false;
return true;
}
@@ -319,97 +573,154 @@ class spell_mage_focus_magic : public SpellScriptLoader
}
};
-// -11426 - Ice Barrier
-class spell_mage_ice_barrier : public SpellScriptLoader
+// 116 - Frostbolt
+/// Updated 4.3.4
+class spell_mage_frostbolt : public SpellScriptLoader
+{
+ public:
+ spell_mage_frostbolt() : SpellScriptLoader("spell_mage_frostbolt") { }
+
+ class spell_mage_frostbolt_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_frostbolt_SpellScript);
+
+ void RecalculateDamage(SpellEffIndex /*effIndex*/)
+ {
+ if (GetHitUnit() && GetHitUnit()->HasAuraState(AURA_STATE_FROZEN, GetSpellInfo(), GetCaster()))
+ {
+ if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_SHATTER, EFFECT_1))
+ {
+ int32 damage = GetHitDamage();
+ AddPct(damage, aurEff->GetAmount());
+ SetHitDamage(damage);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_mage_frostbolt_SpellScript::RecalculateDamage, EFFECT_1, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mage_frostbolt_SpellScript();
+ }
+};
+
+// 56372 - Glyph of Ice Block
+class spell_mage_glyph_of_ice_block : public SpellScriptLoader
{
public:
- spell_mage_ice_barrier() : SpellScriptLoader("spell_mage_ice_barrier") { }
+ spell_mage_glyph_of_ice_block() : SpellScriptLoader("spell_mage_glyph_of_ice_block") { }
- class spell_mage_ice_barrier_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript
+ class spell_mage_glyph_of_ice_block_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_mage_ice_barrier_AuraScript);
+ PrepareAuraScript(spell_mage_glyph_of_ice_block_AuraScript);
- void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& canBeRecalculated)
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- canBeRecalculated = false;
- if (Unit* caster = GetCaster())
- {
- // +80.68% from sp bonus
- float bonus = 0.8068f;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FROST_NOVA))
+ return false;
+ return true;
+ }
- bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask());
+ bool CheckProc(ProcEventInfo& /*eventInfo*/)
+ {
+ return GetTarget()->GetTypeId() == TYPEID_PLAYER;
+ }
- // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :)
- // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage
- bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus);
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ // Remove Frost Nova cooldown
+ GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_MAGE_FROST_NOVA, true);
+ }
- bonus *= caster->CalculateLevelPenalty(GetSpellInfo());
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_mage_glyph_of_ice_block_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_ice_block_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
- amount += int32(bonus);
- }
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_glyph_of_ice_block_AuraScript();
+ }
+};
+
+// 56374 - Glyph of Icy Veins
+class spell_mage_glyph_of_icy_veins : public SpellScriptLoader
+{
+ public:
+ spell_mage_glyph_of_icy_veins() : SpellScriptLoader("spell_mage_glyph_of_icy_veins") { }
+
+ class spell_mage_glyph_of_icy_veins_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_glyph_of_icy_veins_AuraScript);
+
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+
+ GetTarget()->RemoveAurasByType(SPELL_AURA_HASTE_SPELLS, 0, 0, true, false);
+ GetTarget()->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_ice_barrier_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_ice_barrier_AuraScript::Trigger, EFFECT_0);
+ OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_icy_veins_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_mage_ice_barrier_AuraScript();
+ return new spell_mage_glyph_of_icy_veins_AuraScript();
}
};
-// -11119 - Ignite
-class spell_mage_ignite : public SpellScriptLoader
+// 56375 - Glyph of Polymorph
+class spell_mage_glyph_of_polymorph : public SpellScriptLoader
{
public:
- spell_mage_ignite() : SpellScriptLoader("spell_mage_ignite") { }
+ spell_mage_glyph_of_polymorph() : SpellScriptLoader("spell_mage_glyph_of_polymorph") { }
- class spell_mage_ignite_AuraScript : public AuraScript
+ class spell_mage_glyph_of_polymorph_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_mage_ignite_AuraScript);
+ PrepareAuraScript(spell_mage_glyph_of_polymorph_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE))
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH))
return false;
return true;
}
- bool CheckProc(ProcEventInfo& eventInfo)
- {
- return eventInfo.GetProcTarget();
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
+ Unit* target = eventInfo.GetProcTarget();
- SpellInfo const* igniteDot = sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE);
- int32 pct = 8 * GetSpellInfo()->GetRank();
-
- int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks());
- 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);
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(SPELL_PRIEST_SHADOW_WORD_DEATH)); // SW:D shall not be removed.
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
}
void Register() OVERRIDE
{
- DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_mage_glyph_of_polymorph_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_mage_ignite_AuraScript();
+ return new spell_mage_glyph_of_polymorph_AuraScript();
}
};
-// -44457 - Living Bomb
+// 44457 - Living Bomb
class spell_mage_living_bomb : public SpellScriptLoader
{
public:
@@ -419,9 +730,9 @@ class spell_mage_living_bomb : public SpellScriptLoader
{
PrepareAuraScript(spell_mage_living_bomb_AuraScript);
- bool Validate(SpellInfo const* spell) OVERRIDE
+ bool Validate(SpellInfo const* spellInfo)
{
- if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue())))
+ if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->Effects[EFFECT_1].CalcValue())))
return false;
return true;
}
@@ -448,44 +759,158 @@ class spell_mage_living_bomb : public SpellScriptLoader
}
};
-// -1463 - Mana Shield
-class spell_mage_mana_shield : public SpellScriptLoader
+// 11426 - Ice Barrier
+/// Updated 4.3.4
+class spell_mage_ice_barrier : public SpellScriptLoader
+{
+ public:
+ spell_mage_ice_barrier() : SpellScriptLoader("spell_mage_ice_barrier") { }
+
+ class spell_mage_ice_barrier_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_ice_barrier_AuraScript);
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ if (GetTarget()->HasAura(SPELL_MAGE_SHATTERED_BARRIER_R1))
+ GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R1, true);
+ else if (GetTarget()->HasAura(SPELL_MAGE_SHATTERED_BARRIER_R2))
+ GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_SHATTERED_BARRIER_FREEZE_R2, true);
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_mage_ice_barrier_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_ice_barrier_AuraScript();
+ }
+};
+
+// -11119 - Ignite
+class spell_mage_ignite : public SpellScriptLoader
{
public:
- spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { }
+ spell_mage_ignite() : SpellScriptLoader("spell_mage_ignite") { }
- class spell_mage_mana_shield_AuraScript : public spell_mage_incanters_absorbtion_base_AuraScript
+ class spell_mage_ignite_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_mage_mana_shield_AuraScript);
+ PrepareAuraScript(spell_mage_ignite_AuraScript);
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- canBeRecalculated = false;
- if (Unit* caster = GetCaster())
- {
- // +80.53% from sp bonus
- float bonus = 0.8053f;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE))
+ return false;
+ return true;
+ }
- bonus *= caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask());
- bonus *= caster->CalculateLevelPenalty(GetSpellInfo());
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetProcTarget();
+ }
- amount += int32(bonus);
- }
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+
+ SpellInfo const* igniteDot = sSpellMgr->GetSpellInfo(SPELL_MAGE_IGNITE);
+ int32 pct = 8 * GetSpellInfo()->GetRank();
+
+ int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), pct) / igniteDot->GetMaxTicks());
+ 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);
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mage_mana_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MANA_SHIELD);
- AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_mana_shield_AuraScript::Trigger, EFFECT_0);
+ DoCheckProc += AuraCheckProcFn(spell_mage_ignite_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_mage_ignite_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_mage_mana_shield_AuraScript();
+ return new spell_mage_ignite_AuraScript();
}
};
+// 543 - Mage Ward
+/// Updated 4.3.4
+class spell_mage_mage_ward : public SpellScriptLoader
+{
+ public:
+ spell_mage_mage_ward() : SpellScriptLoader("spell_mage_mage_ward") { }
+
+ class spell_mage_mage_ward_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_mage_ward_AuraScript);
+
+ void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount)
+ {
+ if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0))
+ {
+ int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount());
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectAbsorb += AuraEffectAbsorbFn(spell_mage_mage_ward_AuraScript::HandleAbsorb, EFFECT_0);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_mage_ward_AuraScript();
+ }
+};
+
+// 1463 - Mana Shield
+/// Updated 4.3.4
+class spell_mage_mana_shield : public SpellScriptLoader
+{
+ public:
+ spell_mage_mana_shield() : SpellScriptLoader("spell_mage_mana_shield") { }
+
+ class spell_mage_mana_shield_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_mana_shield_AuraScript);
+
+ void HandleAbsorb(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & absorbAmount)
+ {
+ if (AuraEffect* aurEff = GetTarget()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_GENERIC, ICON_MAGE_INCANTER_S_ABSORPTION, EFFECT_0))
+ {
+ int32 bp = CalculatePct(absorbAmount, aurEff->GetAmount());
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_TRIGGERED, &bp, NULL, NULL, true);
+ }
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL)
+ GetTarget()->CastSpell(GetTarget(), SPELL_MAGE_INCANTERS_ABSORBTION_R1, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectManaShield += AuraEffectManaShieldFn(spell_mage_mana_shield_AuraScript::HandleAbsorb, EFFECT_0);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_mage_mana_shield_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_MANA_SHIELD, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_mana_shield_AuraScript();
+ }
+};
+
// -29074 - Master of Elements
class spell_mage_master_of_elements : public SpellScriptLoader
{
@@ -532,9 +957,158 @@ class spell_mage_master_of_elements : public SpellScriptLoader
}
};
+// 86181 - Nether Vortex
+class spell_mage_nether_vortex : public SpellScriptLoader
+{
+ public:
+ spell_mage_nether_vortex() : SpellScriptLoader("spell_mage_nether_vortex") { }
+
+ class spell_mage_nether_vortex_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_nether_vortex_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_SLOW))
+ return false;
+ return true;
+ }
+
+ bool DoCheck(ProcEventInfo& eventInfo)
+ {
+ if (Aura* aura = eventInfo.GetProcTarget()->GetAura(SPELL_MAGE_SLOW))
+ if (aura->GetCasterGUID() != GetTarget()->GetGUID())
+ return false;
+
+ return true;
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_MAGE_SLOW, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_mage_nether_vortex_AuraScript::DoCheck);
+ OnEffectProc += AuraEffectProcFn(spell_mage_nether_vortex_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_nether_vortex_AuraScript();
+ }
+};
+
+// -11175 - Permafrost
+class spell_mage_permafrost : public SpellScriptLoader
+{
+ public:
+ spell_mage_permafrost() : SpellScriptLoader("spell_mage_permafrost") { }
+
+ class spell_mage_permafrost_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_permafrost_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_PERMAFROST))
+ return false;
+ return true;
+ }
+
+ bool DoCheck(ProcEventInfo& eventInfo)
+ {
+ return GetTarget()->GetGuardianPet() && eventInfo.GetDamageInfo()->GetDamage();
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+
+ int32 heal = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()));
+ GetTarget()->CastCustomSpell(SPELL_MAGE_PERMAFROST, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_mage_permafrost_AuraScript::DoCheck);
+ OnEffectProc += AuraEffectProcFn(spell_mage_permafrost_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_permafrost_AuraScript();
+ }
+};
+
+// 118 - Polymorph
+class spell_mage_polymorph : public SpellScriptLoader
+{
+ public:
+ spell_mage_polymorph() : SpellScriptLoader("spell_mage_polymorph") { }
+
+ class spell_mage_polymorph_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_polymorph_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_POLYMORPH_MARKER))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ _caster = NULL;
+ return true;
+ }
+
+ bool DoCheck(ProcEventInfo& eventInfo)
+ {
+ _caster = GetCaster();
+ return _caster && eventInfo.GetDamageInfo();
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ // Improved Polymorph
+ if (AuraEffect const* improvedPolymorph = _caster->GetAuraEffectOfRankedSpell(SPELL_MAGE_IMPROVED_POLYMORPH_RANK_1, EFFECT_0))
+ {
+ if (_caster->HasAura(SPELL_MAGE_IMPROVED_POLYMORPH_MARKER))
+ return;
+
+ GetTarget()->CastSpell(GetTarget(), sSpellMgr->GetSpellWithRank(SPELL_MAGE_IMPROVED_POLYMORPH_STUN_RANK_1, improvedPolymorph->GetSpellInfo()->GetRank()), true, NULL, aurEff);
+ _caster->CastSpell(_caster, SPELL_MAGE_IMPROVED_POLYMORPH_MARKER, true, NULL, aurEff);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_mage_polymorph_AuraScript::DoCheck);
+ OnEffectProc += AuraEffectProcFn(spell_mage_polymorph_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_MOD_CONFUSE);
+ }
+
+ private:
+ Unit* _caster;
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_polymorph_AuraScript();
+ }
+};
+
enum SilvermoonPolymorph
{
- NPC_AUROSALIA = 18744,
+ NPC_AUROSALIA = 18744
};
/// @todo move out of here and rename - not a mage spell
@@ -553,7 +1127,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
// check if spell ids exist in dbc
- for (uint32 i = 0; i < 6; ++i)
+ for (uint32 i = 0; i < 6; i++)
if (!sSpellMgr->GetSpellInfo(PolymorhForms[i]))
return false;
return true;
@@ -568,6 +1142,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader
void Register() OVERRIDE
{
+ // add dummy effect spell handler to Polymorph visual
OnEffectHitTarget += SpellEffectFn(spell_mage_polymorph_cast_visual_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -578,7 +1153,7 @@ class spell_mage_polymorph_cast_visual : public SpellScriptLoader
}
};
-const uint32 spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_SpellScript::PolymorhForms[6] =
+uint32 const spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_SpellScript::PolymorhForms[6] =
{
SPELL_MAGE_SQUIRREL_FORM,
SPELL_MAGE_GIRAFFE_FORM,
@@ -588,57 +1163,274 @@ const uint32 spell_mage_polymorph_cast_visual::spell_mage_polymorph_cast_visual_
SPELL_MAGE_SHEEP_FORM
};
-// 31687 - Summon Water Elemental
-class spell_mage_summon_water_elemental : public SpellScriptLoader
+// 5405 - Replenish Mana (Mana Gem)
+/// Updated 4.3.4
+class spell_mage_replenish_mana : public SpellScriptLoader
+{
+ public:
+ spell_mage_replenish_mana() : SpellScriptLoader("spell_mage_replenish_mana") { }
+
+ class spell_mage_replenish_mana_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_replenish_mana_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED))
+ return false;
+ return true;
+ }
+
+ void HandleImprovedManaGem()
+ {
+ if (AuraEffect* aurEff = GetCaster()->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_MANA_GEM, EFFECT_0))
+ {
+ int32 bp = CalculatePct(GetCaster()->GetMaxPower(POWER_MANA), aurEff->GetAmount());
+ GetCaster()->CastCustomSpell(GetCaster(), SPELL_MAGE_IMPROVED_MANA_GEM_TRIGGERED, &bp, &bp, NULL, true);
+ }
+ }
+
+ void Register()
+ {
+ AfterCast += SpellCastFn(spell_mage_replenish_mana_SpellScript::HandleImprovedManaGem);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mage_replenish_mana_SpellScript();
+ }
+};
+
+// 82676 - Ring of Frost
+/// Updated 4.3.4
+class spell_mage_ring_of_frost : public SpellScriptLoader
{
public:
- spell_mage_summon_water_elemental() : SpellScriptLoader("spell_mage_summon_water_elemental") { }
+ spell_mage_ring_of_frost() : SpellScriptLoader("spell_mage_ring_of_frost") { }
- class spell_mage_summon_water_elemental_SpellScript : public SpellScript
+ class spell_mage_ring_of_frost_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_mage_summon_water_elemental_SpellScript);
+ PrepareAuraScript(spell_mage_ring_of_frost_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY) || !sSpellMgr->GetSpellInfo(SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT))
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_FREEZE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY))
return false;
return true;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ bool Load() OVERRIDE
{
- Unit* caster = GetCaster();
- // Glyph of Eternal Water
- if (caster->HasAura(SPELL_MAGE_GLYPH_OF_ETERNAL_WATER))
- caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_PERMANENT, true);
- else
- caster->CastSpell(caster, SPELL_MAGE_SUMMON_WATER_ELEMENTAL_TEMPORARY, true);
+ ringOfFrost = NULL;
+ return true;
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (ringOfFrost)
+ if (GetMaxDuration() - (int32)ringOfFrost->GetTimer() >= sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY)->GetDuration())
+ GetTarget()->CastSpell(ringOfFrost->GetPositionX(), ringOfFrost->GetPositionY(), ringOfFrost->GetPositionZ(), SPELL_MAGE_RING_OF_FROST_FREEZE, true);
+ }
+
+ void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ std::list<Creature*> MinionList;
+ GetTarget()->GetAllMinionsByEntry(MinionList, GetSpellInfo()->Effects[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++)
+ {
+ TempSummon* summon = (*itr)->ToTempSummon();
+
+ if (ringOfFrost && summon)
+ {
+ if (summon->GetTimer() > ringOfFrost->GetTimer())
+ {
+ ringOfFrost->DespawnOrUnsummon();
+ ringOfFrost = summon;
+ }
+ else
+ summon->DespawnOrUnsummon();
+ }
+ else if (summon)
+ ringOfFrost = summon;
+ }
+ }
+
+ TempSummon* ringOfFrost;
+
+ void Register() OVERRIDE
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mage_ring_of_frost_AuraScript::HandleEffectPeriodic, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ OnEffectApply += AuraEffectApplyFn(spell_mage_ring_of_frost_AuraScript::Apply, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_ring_of_frost_AuraScript();
+ }
+};
+
+// 82691 - Ring of Frost (freeze efect)
+/// Updated 4.3.4
+class spell_mage_ring_of_frost_freeze : public SpellScriptLoader
+{
+ public:
+ spell_mage_ring_of_frost_freeze() : SpellScriptLoader("spell_mage_ring_of_frost_freeze") { }
+
+ class spell_mage_ring_of_frost_freeze_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_ring_of_frost_freeze_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_FREEZE))
+ return false;
+ return true;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ float outRadius = sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_SUMMON)->Effects[EFFECT_0].CalcRadius();
+ float inRadius = 4.7f;
+
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ if (Unit* unit = (*itr)->ToUnit())
+ if (unit->HasAura(SPELL_MAGE_RING_OF_FROST_DUMMY) || unit->HasAura(SPELL_MAGE_RING_OF_FROST_FREEZE) || unit->GetExactDist(GetExplTargetDest()) > outRadius || unit->GetExactDist(GetExplTargetDest()) < inRadius)
+ targets.erase(itr--);
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_mage_summon_water_elemental_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_ring_of_frost_freeze_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_mage_summon_water_elemental_SpellScript();
+ return new spell_mage_ring_of_frost_freeze_SpellScript();
}
+
+ class spell_mage_ring_of_frost_freeze_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_ring_of_frost_freeze_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_RING_OF_FROST_DUMMY))
+ return false;
+ return true;
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
+ if (GetCaster())
+ GetCaster()->CastSpell(GetTarget(), SPELL_MAGE_RING_OF_FROST_DUMMY, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_mage_ring_of_frost_freeze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_mage_ring_of_frost_freeze_AuraScript();
+ }
+};
+
+// 33395 Water Elemental's Freeze
+/// Updated 4.3.4
+class spell_mage_water_elemental_freeze : public SpellScriptLoader
+{
+ public:
+ spell_mage_water_elemental_freeze() : SpellScriptLoader("spell_mage_water_elemental_freeze") { }
+
+ class spell_mage_water_elemental_freeze_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mage_water_elemental_freeze_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGE_FINGERS_OF_FROST))
+ return false;
+ return true;
+ }
+
+ void CountTargets(std::list<WorldObject*>& targetList)
+ {
+ _didHit = !targetList.empty();
+ }
+
+ void HandleImprovedFreeze()
+ {
+ if (!_didHit)
+ return;
+
+ Unit* owner = GetCaster()->GetOwner();
+ if (!owner)
+ return;
+
+ if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, ICON_MAGE_IMPROVED_FREEZE, EFFECT_0))
+ {
+ if (roll_chance_i(aurEff->GetAmount()))
+ owner->CastCustomSpell(SPELL_MAGE_FINGERS_OF_FROST, SPELLVALUE_AURA_STACK, 2, owner, true);
+ }
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mage_water_elemental_freeze_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ AfterCast += SpellCastFn(spell_mage_water_elemental_freeze_SpellScript::HandleImprovedFreeze);
+ }
+
+ private:
+ bool _didHit;
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mage_water_elemental_freeze_SpellScript();
+ }
};
void AddSC_mage_spell_scripts()
{
+ new spell_mage_arcane_potency();
new spell_mage_blast_wave();
- new spell_mage_burnout();
+ new spell_mage_blazing_speed();
+ new spell_mage_blizzard();
new spell_mage_cold_snap();
+ new spell_mage_cone_of_cold();
+ new spell_mage_conjure_refreshment();
new spell_mage_fire_frost_ward();
new spell_mage_focus_magic();
+ new spell_mage_frostbolt();
new spell_mage_ice_barrier();
new spell_mage_ignite();
+ new spell_mage_glyph_of_ice_block();
+ new spell_mage_glyph_of_icy_veins();
+ new spell_mage_glyph_of_polymorph();
new spell_mage_living_bomb();
+ new spell_mage_mage_ward();
new spell_mage_mana_shield();
new spell_mage_master_of_elements();
+ new spell_mage_nether_vortex();
+ new spell_mage_permafrost();
+ new spell_mage_polymorph();
new spell_mage_polymorph_cast_visual();
- new spell_mage_summon_water_elemental();
+ new spell_mage_replenish_mana();
+ new spell_mage_ring_of_frost();
+ new spell_mage_ring_of_frost_freeze();
+ new spell_mage_water_elemental_freeze();
}
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index b5265561d85..abb14a9cc5d 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -29,54 +29,43 @@
enum PaladinSpells
{
- SPELL_PALADIN_DIVINE_PLEA = 54428,
- SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF = 67480,
- SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE = 57319,
-
- SPELL_PALADIN_HOLY_SHOCK_R1 = 20473,
- SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912,
- SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914,
-
+ SPELL_PALADIN_AVENGERS_SHIELD = 31935,
+ SPELL_PALADIN_AURA_MASTERY_IMMUNE = 64364,
+ SPELL_PALADIN_BEACON_OF_LIGHT_MARKER = 53563,
+ SPELL_PALADIN_BEACON_OF_LIGHT_HEAL = 53652,
SPELL_PALADIN_BLESSING_OF_LOWER_CITY_DRUID = 37878,
SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PALADIN = 37879,
SPELL_PALADIN_BLESSING_OF_LOWER_CITY_PRIEST = 37880,
SPELL_PALADIN_BLESSING_OF_LOWER_CITY_SHAMAN = 37881,
-
+ SPELL_PALADIN_CONCENTRACTION_AURA = 19746,
+ SPELL_PALADIN_DIVINE_PURPOSE_PROC = 90174,
+ SPELL_PALADIN_DIVINE_SACRIFICE = 64205,
SPELL_PALADIN_DIVINE_STORM = 53385,
SPELL_PALADIN_DIVINE_STORM_DUMMY = 54171,
SPELL_PALADIN_DIVINE_STORM_HEAL = 54172,
-
+ SPELL_PALADIN_EYE_FOR_AN_EYE_RANK_1 = 9799,
SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE = 25997,
-
SPELL_PALADIN_FORBEARANCE = 25771,
- SPELL_PALADIN_AVENGING_WRATH_MARKER = 61987,
- SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988,
-
+ SPELL_PALADIN_GLYPH_OF_SALVATION = 63225,
SPELL_PALADIN_HAND_OF_SACRIFICE = 6940,
- SPELL_PALADIN_DIVINE_SACRIFICE = 64205,
-
+ SPELL_PALADIN_HOLY_LIGHT = 635,
+ SPELL_PALADIN_HOLY_SHOCK_R1 = 20473,
+ SPELL_PALADIN_HOLY_SHOCK_R1_DAMAGE = 25912,
+ SPELL_PALADIN_HOLY_SHOCK_R1_HEALING = 25914,
+ SPELL_PALADIN_IMMUNE_SHIELD_MARKER = 61988,
+ SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA = 63510,
+ SPELL_PALADIN_IMPROVED_DEVOTION_AURA = 63514,
SPELL_PALADIN_ITEM_HEALING_TRANCE = 37706,
-
SPELL_PALADIN_JUDGEMENT_DAMAGE = 54158,
- SPELL_PALADIN_JUDGEMENT_OF_JUSTICE = 20184,
- SPELL_PALADIN_JUDGEMENT_OF_LIGHT = 20185,
- SPELL_PALADIN_JUDGEMENT_OF_WISDOM = 20186,
-
- SPELL_PALADIN_GLYPH_OF_SALVATION = 63225,
-
SPELL_PALADIN_RIGHTEOUS_DEFENSE_TAUNT = 31790,
-
- SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742,
-
- SPELL_PALADIN_CONCENTRACTION_AURA = 19746,
- SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869,
- SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379,
-
- SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA = 63510,
- SPELL_PALADIN_IMPROVED_DEVOTION_AURA = 63514,
SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA = 63531,
- SPELL_PALADIN_AURA_MASTERY_IMMUNE = 64364,
+ SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 = 31869,
+ SPELL_PALADIN_SEAL_OF_RIGHTEOUSNESS = 25742,
+ SPELL_PALADIN_SWIFT_RETRIBUTION_R1 = 53379
+};
+enum MiscSpells
+{
SPELL_GENERIC_ARENA_DAMPENING = 74410,
SPELL_GENERIC_BATTLEGROUND_DAMPENING = 74411
};
@@ -86,6 +75,7 @@ enum PaladinSpellIcons
PALADIN_ICON_ID_RETRIBUTION_AURA = 555
};
+/*
// 31850 - Ardent Defender
class spell_pal_ardent_defender : public SpellScriptLoader
{
@@ -110,7 +100,7 @@ class spell_pal_ardent_defender : public SpellScriptLoader
return GetUnitOwner()->GetTypeId() == TYPEID_PLAYER;
}
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
+ void CalculateAmount(AuraEffect const* aurEff, int32 & amount, bool & canBeRecalculated)
{
// Set absorbtion amount to unlimited
amount = -1;
@@ -161,6 +151,7 @@ class spell_pal_ardent_defender : public SpellScriptLoader
return new spell_pal_ardent_defender_AuraScript();
}
};
+*/
// 31821 - Aura Mastery
class spell_pal_aura_mastery : public SpellScriptLoader
@@ -236,6 +227,67 @@ class spell_pal_aura_mastery_immune : public SpellScriptLoader
}
};
+// 53651 - Beacon of Light
+class spell_pal_beacon_of_light : public SpellScriptLoader
+{
+ public:
+ spell_pal_beacon_of_light() : SpellScriptLoader("spell_pal_beacon_of_light") { }
+
+ class spell_pal_beacon_of_light_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pal_beacon_of_light_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BEACON_OF_LIGHT_HEAL))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ if (eventInfo.GetActionTarget()->GetAura(SPELL_PALADIN_BEACON_OF_LIGHT_MARKER, GetCasterGUID()))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 heal = eventInfo.GetHealInfo()->GetHeal();
+
+ if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_PALADIN_HOLY_LIGHT)
+ heal = int32(CalculatePct(heal, aurEff->GetAmount()));
+
+ Unit::AuraList const& auras = GetCaster()->GetSingleCastAuras();
+ for (Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ if ((*itr)->GetId() == SPELL_PALADIN_BEACON_OF_LIGHT_MARKER)
+ {
+ std::list<AuraApplication*> applications;
+ (*itr)->GetApplicationList(applications);
+ if (applications.empty())
+ return;
+
+ GetCaster()->CastCustomSpell(SPELL_PALADIN_BEACON_OF_LIGHT_HEAL, SPELLVALUE_BASE_POINT0, heal, applications.front()->GetTarget(), true, NULL, aurEff);
+ return;
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_pal_beacon_of_light_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_pal_beacon_of_light_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pal_beacon_of_light_AuraScript();
+ }
+};
+
// 37877 - Blessing of Faith
class spell_pal_blessing_of_faith : public SpellScriptLoader
{
@@ -292,65 +344,6 @@ class spell_pal_blessing_of_faith : public SpellScriptLoader
}
};
-// 20911 - Blessing of Sanctuary
-// 25899 - Greater Blessing of Sanctuary
-class spell_pal_blessing_of_sanctuary : public SpellScriptLoader
-{
- public:
- spell_pal_blessing_of_sanctuary() : SpellScriptLoader("spell_pal_blessing_of_sanctuary") { }
-
- class spell_pal_blessing_of_sanctuary_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_pal_blessing_of_sanctuary_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE))
- return false;
- return true;
- }
-
- void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- Unit* target = GetTarget();
- if (Unit* caster = GetCaster())
- caster->CastSpell(target, SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, true);
- }
-
- void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- Unit* target = GetTarget();
- target->RemoveAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY_BUFF, GetCasterGUID());
- }
-
- bool CheckProc(ProcEventInfo& /*eventInfo*/)
- {
- return GetTarget()->getPowerType() == POWER_MANA;
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
- {
- PreventDefaultAction();
- GetTarget()->CastSpell(GetTarget(), SPELL_PALADIN_BLESSING_OF_SANCTUARY_ENERGIZE, true, NULL, aurEff);
- }
-
- void Register() OVERRIDE
- {
- AfterEffectApply += AuraEffectApplyFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- AfterEffectRemove += AuraEffectRemoveFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- DoCheckProc += AuraCheckProcFn(spell_pal_blessing_of_sanctuary_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_pal_blessing_of_sanctuary_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_pal_blessing_of_sanctuary_AuraScript();
- }
-};
-
// 64205 - Divine Sacrifice
class spell_pal_divine_sacrifice : public SpellScriptLoader
{
@@ -366,6 +359,7 @@ class spell_pal_divine_sacrifice : public SpellScriptLoader
bool Load() OVERRIDE
{
+
if (Unit* caster = GetCaster())
{
if (caster->GetTypeId() == TYPEID_PLAYER)
@@ -548,17 +542,16 @@ class spell_pal_eye_for_an_eye : public SpellScriptLoader
return true;
}
- void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
- // return damage % to attacker but < 50% own total health
- int32 damage = int32(std::min(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()), GetTarget()->GetMaxHealth() / 2));
+ int32 damage = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount());
GetTarget()->CastCustomSpell(SPELL_PALADIN_EYE_FOR_AN_EYE_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff);
}
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_pal_eye_for_an_eye_AuraScript::HandleEffectProc, EFFECT_0, m_scriptSpellId == SPELL_PALADIN_EYE_FOR_AN_EYE_RANK_1 ? SPELL_AURA_DUMMY : SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -568,72 +561,76 @@ class spell_pal_eye_for_an_eye : public SpellScriptLoader
}
};
-// 54968 - Glyph of Holy Light
-class spell_pal_glyph_of_holy_light : public SpellScriptLoader
+// -75806 - Grand Crusader
+class spell_pal_grand_crusader : public SpellScriptLoader
{
public:
- spell_pal_glyph_of_holy_light() : SpellScriptLoader("spell_pal_glyph_of_holy_light") { }
+ spell_pal_grand_crusader() : SpellScriptLoader("spell_pal_grand_crusader") { }
- class spell_pal_glyph_of_holy_light_SpellScript : public SpellScript
+ class spell_pal_grand_crusader_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_pal_glyph_of_holy_light_SpellScript);
+ PrepareAuraScript(spell_pal_grand_crusader_AuraScript);
- void FilterTargets(std::list<WorldObject*>& targets)
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- uint32 const maxTargets = GetSpellInfo()->MaxAffectedTargets;
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_AVENGERS_SHIELD))
+ return false;
+ return true;
+ }
- if (targets.size() > maxTargets)
- {
- targets.sort(Trinity::HealthPctOrderPred());
- targets.resize(maxTargets);
- }
+ bool CheckProc(ProcEventInfo& /*eventInfo*/)
+ {
+ return GetTarget()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ GetTarget()->ToPlayer()->RemoveSpellCooldown(SPELL_PALADIN_AVENGERS_SHIELD, true);
}
void Register() OVERRIDE
{
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_glyph_of_holy_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ DoCheckProc += AuraCheckProcFn(spell_pal_grand_crusader_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_pal_grand_crusader_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
- SpellScript* GetSpellScript() const OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_pal_glyph_of_holy_light_SpellScript();
+ return new spell_pal_grand_crusader_AuraScript();
}
};
-// 63521 - Guarded by The Light
-class spell_pal_guarded_by_the_light : public SpellScriptLoader
+// 54968 - Glyph of Holy Light
+class spell_pal_glyph_of_holy_light : public SpellScriptLoader
{
public:
- spell_pal_guarded_by_the_light() : SpellScriptLoader("spell_pal_guarded_by_the_light") { }
+ spell_pal_glyph_of_holy_light() : SpellScriptLoader("spell_pal_glyph_of_holy_light") { }
- class spell_pal_guarded_by_the_light_SpellScript : public SpellScript
+ class spell_pal_glyph_of_holy_light_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_pal_guarded_by_the_light_SpellScript);
+ PrepareSpellScript(spell_pal_glyph_of_holy_light_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_DIVINE_PLEA))
- return false;
- return true;
- }
+ uint32 const maxTargets = GetSpellInfo()->MaxAffectedTargets;
- void HandleScriptEffect(SpellEffIndex /*effIndex*/)
- {
- // Divine Plea
- if (Aura* aura = GetCaster()->GetAura(SPELL_PALADIN_DIVINE_PLEA))
- aura->RefreshDuration();
+ if (targets.size() > maxTargets)
+ {
+ targets.sort(Trinity::HealthPctOrderPred());
+ targets.resize(maxTargets);
+ }
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_pal_guarded_by_the_light_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_glyph_of_holy_light_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_pal_guarded_by_the_light_SpellScript();
+ return new spell_pal_glyph_of_holy_light_SpellScript();
}
};
@@ -681,40 +678,7 @@ class spell_pal_hand_of_sacrifice : public SpellScriptLoader
}
};
-// 1038 - Hand of Salvation
-class spell_pal_hand_of_salvation : public SpellScriptLoader
-{
- public:
- spell_pal_hand_of_salvation() : SpellScriptLoader("spell_pal_hand_of_salvation") { }
-
- class spell_pal_hand_of_salvation_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_pal_hand_of_salvation_AuraScript);
-
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
- {
- if (Unit* caster = GetCaster())
- {
- // Glyph of Salvation
- if (caster->GetGUID() == GetUnitOwner()->GetGUID())
- if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_PALADIN_GLYPH_OF_SALVATION, EFFECT_0))
- amount -= aurEff->GetAmount();
- }
- }
-
- void Register() OVERRIDE
- {
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_hand_of_salvation_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_pal_hand_of_salvation_AuraScript();
- }
-};
-
-// -20473 - Holy Shock
+// 20473 - Holy Shock
class spell_pal_holy_shock : public SpellScriptLoader
{
public:
@@ -786,71 +750,6 @@ class spell_pal_holy_shock : public SpellScriptLoader
}
};
-// Maybe this is incorrect
-// These spells should always be cast on login, regardless of whether the player has the talent or not
-
-// -20254 - Improved Concentration Aura
-// -20138 - Improved Devotion Aura
-// 31869 - Sanctified Retribution
-// -53379 - Swift Retribution
-class spell_pal_improved_aura : public SpellScriptLoader
-{
- public:
- spell_pal_improved_aura(char const* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
-
- class spell_pal_improved_aura_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_pal_improved_aura_AuraScript);
-
- public:
- spell_pal_improved_aura_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { }
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(_spellId)
- || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1)
- || !sSpellMgr->GetSpellInfo(SPELL_PALADIN_SWIFT_RETRIBUTION_R1))
- return false;
- return true;
- }
-
- void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- Unit* target = GetTarget();
- if (!target->GetOwnedAura(_spellId))
- target->CastSpell(target, _spellId, true);
- }
-
- void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
- {
- uint32 spellId = GetSpellInfo()->GetFirstRankSpell()->Id;
-
- if ((spellId == SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SWIFT_RETRIBUTION_R1))
- || (spellId == SPELL_PALADIN_SWIFT_RETRIBUTION_R1 && GetTarget()->GetAuraOfRankedSpell(SPELL_PALADIN_SANCTIFIED_RETRIBUTION_R1)))
- return;
-
- GetTarget()->RemoveOwnedAura(_spellId, GetCasterGUID());
- }
-
- void Register() OVERRIDE
- {
- AfterEffectApply += AuraEffectApplyFn(spell_pal_improved_aura_AuraScript::HandleEffectApply, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_pal_improved_aura_AuraScript::HandleEffectRemove, EFFECT_FIRST_FOUND, SPELL_AURA_ADD_FLAT_MODIFIER, AURA_EFFECT_HANDLE_REAL);
- }
-
- private:
- uint32 _spellId;
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_pal_improved_aura_AuraScript(_spellId);
- }
-
- private:
- uint32 _spellId;
-};
-
// 63510 - Improved Concentraction Aura (Area Aura)
// 63514 - Improved Devotion Aura (Area Aura)
// 63531 - Sanctified Retribution (Area Aura)
@@ -928,32 +827,27 @@ class spell_pal_item_healing_discount : public SpellScriptLoader
}
};
-// 53407 - Judgement of Justice
-// 20271 - Judgement of Light
-// 53408 - Judgement of Wisdom
+// 20271 - Judgement
+/// Updated 4.3.4
class spell_pal_judgement : public SpellScriptLoader
{
public:
- spell_pal_judgement(char const* scriptName, uint32 spellId) : SpellScriptLoader(scriptName), _spellId(spellId) { }
+ spell_pal_judgement() : SpellScriptLoader("spell_pal_judgement") { }
class spell_pal_judgement_SpellScript : public SpellScript
{
PrepareSpellScript(spell_pal_judgement_SpellScript);
- public:
- spell_pal_judgement_SpellScript(uint32 spellId) : SpellScript(), _spellId(spellId) { }
-
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_JUDGEMENT_DAMAGE)
- || !sSpellMgr->GetSpellInfo(_spellId))
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_JUDGEMENT_DAMAGE))
return false;
return true;
}
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- uint32 spellId2 = SPELL_PALADIN_JUDGEMENT_DAMAGE;
+ uint32 spellId = SPELL_PALADIN_JUDGEMENT_DAMAGE;
// some seals have SPELL_AURA_DUMMY in EFFECT_2
Unit::AuraEffectList const& auras = GetCaster()->GetAuraEffectsByType(SPELL_AURA_DUMMY);
@@ -962,63 +856,27 @@ class spell_pal_judgement : public SpellScriptLoader
if ((*i)->GetSpellInfo()->GetSpellSpecific() == SPELL_SPECIFIC_SEAL && (*i)->GetEffIndex() == EFFECT_2)
if (sSpellMgr->GetSpellInfo((*i)->GetAmount()))
{
- spellId2 = (*i)->GetAmount();
+ spellId = (*i)->GetAmount();
break;
}
}
- GetCaster()->CastSpell(GetHitUnit(), _spellId, true);
- GetCaster()->CastSpell(GetHitUnit(), spellId2, true);
+ GetCaster()->CastSpell(GetHitUnit(), spellId, true);
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
-
- private:
- uint32 const _spellId;
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_pal_judgement_SpellScript(_spellId);
+ return new spell_pal_judgement_SpellScript();
}
-
- private:
- uint32 const _spellId;
};
-// 20425 - Judgement of Command
-class spell_pal_judgement_of_command : public SpellScriptLoader
-{
- public:
- spell_pal_judgement_of_command() : SpellScriptLoader("spell_pal_judgement_of_command") { }
-
- class spell_pal_judgement_of_command_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_pal_judgement_of_command_SpellScript);
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- if (Unit* unitTarget = GetHitUnit())
- if (SpellInfo const* spell_proto = sSpellMgr->GetSpellInfo(GetEffectValue()))
- GetCaster()->CastSpell(unitTarget, spell_proto, true, NULL);
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_pal_judgement_of_command_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_pal_judgement_of_command_SpellScript();
- }
-};
-
-// -633 - Lay on Hands
+// 633 - Lay on Hands
class spell_pal_lay_on_hands : public SpellScriptLoader
{
public:
@@ -1030,11 +888,8 @@ class spell_pal_lay_on_hands : public SpellScriptLoader
bool Validate(SpellInfo const* /*spell*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_FORBEARANCE))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_AVENGING_WRATH_MARKER))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_IMMUNE_SHIELD_MARKER))
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_FORBEARANCE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_PALADIN_IMMUNE_SHIELD_MARKER))
return false;
return true;
}
@@ -1044,8 +899,11 @@ class spell_pal_lay_on_hands : public SpellScriptLoader
Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
if (caster == target)
- if (target->HasAura(SPELL_PALADIN_FORBEARANCE) || target->HasAura(SPELL_PALADIN_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER))
+ if (target->HasAura(SPELL_PALADIN_FORBEARANCE) ||
+ target->HasAura(SPELL_PALADIN_IMMUNE_SHIELD_MARKER))
+ {
return SPELL_FAILED_TARGET_AURASTATE;
+ }
return SPELL_CAST_OK;
}
@@ -1056,7 +914,6 @@ class spell_pal_lay_on_hands : public SpellScriptLoader
if (caster == GetHitUnit())
{
caster->CastSpell(caster, SPELL_PALADIN_FORBEARANCE, true);
- caster->CastSpell(caster, SPELL_PALADIN_AVENGING_WRATH_MARKER, true);
caster->CastSpell(caster, SPELL_PALADIN_IMMUNE_SHIELD_MARKER, true);
}
}
@@ -1138,47 +995,105 @@ class spell_pal_righteous_defense : public SpellScriptLoader
}
};
-// 58597 - Sacred Shield
+// 85285 - Sacred Shield
class spell_pal_sacred_shield : public SpellScriptLoader
{
public:
spell_pal_sacred_shield() : SpellScriptLoader("spell_pal_sacred_shield") { }
- class spell_pal_sacred_shield_AuraScript : public AuraScript
+ class spell_pal_sacred_shield_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_pal_sacred_shield_AuraScript);
+ PrepareSpellScript(spell_pal_sacred_shield_SpellScript);
- void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ SpellCastResult CheckCast()
{
- if (Unit* caster = GetCaster())
- {
- // +75.00% from sp bonus
- float bonus = CalculatePct(caster->SpellBaseHealingBonusDone(GetSpellInfo()->GetSchoolMask()), 75.0f);
+ Unit* caster = GetCaster();
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_DONT_REPORT;
- // Divine Guardian is only applied at the spell healing bonus because it was already applied to the base value in CalculateSpellDamage
- bonus = caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), bonus);
- bonus *= caster->CalculateLevelPenalty(GetSpellInfo());
+ if (!caster->HealthBelowPct(30))
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
- amount += int32(bonus);
+ return SPELL_CAST_OK;
+ }
- // Arena - Dampening
- if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_ARENA_DAMPENING, EFFECT_0))
- AddPct(amount, dampening->GetAmount());
- // Battleground - Dampening
- else if (AuraEffect const* dampening = caster->GetAuraEffect(SPELL_GENERIC_BATTLEGROUND_DAMPENING, EFFECT_0))
- AddPct(amount, dampening->GetAmount());
+ void Register() OVERRIDE
+ {
+ OnCheckCast += SpellCheckCastFn(spell_pal_sacred_shield_SpellScript::CheckCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pal_sacred_shield_SpellScript();
+ }
+};
+
+// 85256 - Templar's Verdict
+/// Updated 4.3.4
+class spell_pal_templar_s_verdict : public SpellScriptLoader
+{
+ public:
+ spell_pal_templar_s_verdict() : SpellScriptLoader("spell_pal_templar_s_verdict") { }
+
+ class spell_pal_templar_s_verdict_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pal_templar_s_verdict_SpellScript);
+
+ bool Validate (SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PALADIN_DIVINE_PURPOSE_PROC))
+ return false;
+
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ if (GetCaster()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+
+ if (GetCaster()->ToPlayer()->getClass() != CLASS_PALADIN)
+ return false;
+
+ return true;
+ }
+
+ void ChangeDamage(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ int32 damage = GetHitDamage();
+
+ if (caster->HasAura(SPELL_PALADIN_DIVINE_PURPOSE_PROC))
+ damage *= 7.5; // 7.5*30% = 225%
+ else
+ {
+ switch (caster->GetPower(POWER_HOLY_POWER))
+ {
+ case 0: // 1 Holy Power
+ damage = damage;
+ break;
+ case 1: // 2 Holy Power
+ damage *= 3; // 3*30 = 90%
+ break;
+ case 2: // 3 Holy Power
+ damage *= 7.5; // 7.5*30% = 225%
+ break;
+ }
}
+
+ SetHitDamage(damage);
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pal_sacred_shield_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
+ OnEffectHitTarget += SpellEffectFn(spell_pal_templar_s_verdict_SpellScript::ChangeDamage, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_pal_sacred_shield_AuraScript();
+ return new spell_pal_templar_s_verdict_SpellScript();
}
};
@@ -1228,37 +1143,31 @@ class spell_pal_seal_of_righteousness : public SpellScriptLoader
}
};
+
void AddSC_paladin_spell_scripts()
{
- new spell_pal_ardent_defender();
+ //new spell_pal_ardent_defender();
new spell_pal_aura_mastery();
new spell_pal_aura_mastery_immune();
+ new spell_pal_beacon_of_light();
new spell_pal_blessing_of_faith();
- new spell_pal_blessing_of_sanctuary();
new spell_pal_divine_sacrifice();
new spell_pal_divine_storm();
new spell_pal_divine_storm_dummy();
new spell_pal_exorcism_and_holy_wrath_damage();
new spell_pal_eye_for_an_eye();
new spell_pal_glyph_of_holy_light();
- new spell_pal_guarded_by_the_light();
+ new spell_pal_grand_crusader();
new spell_pal_hand_of_sacrifice();
- new spell_pal_hand_of_salvation();
new spell_pal_holy_shock();
- new spell_pal_improved_aura("spell_pal_improved_concentraction_aura", SPELL_PALADIN_IMPROVED_CONCENTRACTION_AURA);
- new spell_pal_improved_aura("spell_pal_improved_devotion_aura", SPELL_PALADIN_IMPROVED_DEVOTION_AURA);
- new spell_pal_improved_aura("spell_pal_sanctified_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA);
- new spell_pal_improved_aura("spell_pal_swift_retribution", SPELL_PALADIN_SANCTIFIED_RETRIBUTION_AURA);
new spell_pal_improved_aura_effect("spell_pal_improved_concentraction_aura_effect");
new spell_pal_improved_aura_effect("spell_pal_improved_devotion_aura_effect");
new spell_pal_improved_aura_effect("spell_pal_sanctified_retribution_effect");
new spell_pal_item_healing_discount();
- new spell_pal_judgement("spell_pal_judgement_of_justice", SPELL_PALADIN_JUDGEMENT_OF_JUSTICE);
- new spell_pal_judgement("spell_pal_judgement_of_light", SPELL_PALADIN_JUDGEMENT_OF_LIGHT);
- new spell_pal_judgement("spell_pal_judgement_of_wisdom", SPELL_PALADIN_JUDGEMENT_OF_WISDOM);
- new spell_pal_judgement_of_command();
+ new spell_pal_judgement();
new spell_pal_lay_on_hands();
new spell_pal_righteous_defense();
new spell_pal_sacred_shield();
+ new spell_pal_templar_s_verdict();
new spell_pal_seal_of_righteousness();
}
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
index a7742630ccd..7c8a725ca08 100644
--- a/src/server/scripts/Spells/spell_pet.cpp
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -536,7 +536,6 @@ public:
}
};
-
class spell_warl_pet_scaling_04 : public SpellScriptLoader
{
public:
@@ -813,7 +812,6 @@ public:
}
};
-
class spell_sha_pet_scaling_04 : public SpellScriptLoader
{
public:
@@ -1347,24 +1345,6 @@ public:
return;
if (GetCaster()->GetOwner()->ToPlayer())
{
- // Pet's base damage changes depending on happiness
- if (GetCaster()->IsPet() && GetCaster()->ToPet()->IsHunterPet())
- {
- switch (GetCaster()->ToPet()->GetHappinessState())
- {
- case HAPPY:
- // 125% of normal damage
- amount += 25.0f;
- break;
- case CONTENT:
- // 100% of normal damage, nothing to modify
- break;
- case UNHAPPY:
- // 75% of normal damage
- amount += -25.0f;
- break;
- }
- }
// Cobra Reflexes
if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0))
amount -= cobraReflexes->GetAmount();
@@ -1424,7 +1404,6 @@ public:
}
};
-
class spell_dk_avoidance_passive : public SpellScriptLoader
{
public:
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 71e5dac28ec..c92f9e30ac5 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -29,29 +29,51 @@
enum PriestSpells
{
+ SPELL_PRIEST_ABSOLUTION = 33167,
+ SPELL_PRIEST_BODY_AND_SOUL_DISPEL = 64136,
+ SPELL_PRIEST_BODY_AND_SOUL_SPEED = 65081,
+ SPELL_PRIEST_CURE_DISEASE = 528,
+ SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY = 97690,
+ SPELL_PRIEST_DISPEL_MAGIC_HOSTILE = 97691,
SPELL_PRIEST_DIVINE_AEGIS = 47753,
- SPELL_PRIEST_EMPOWERED_RENEW = 63544,
+ SPELL_PRIEST_DIVINE_TOUCH = 63544,
SPELL_PRIEST_GLYPH_OF_CIRCLE_OF_HEALING = 55675,
+ SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC = 55677,
+ SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL = 56131,
SPELL_PRIEST_GLYPH_OF_LIGHTWELL = 55673,
SPELL_PRIEST_GLYPH_OF_PRAYER_OF_HEALING_HEAL = 56161,
+ SPELL_PRIEST_GLYPH_OF_SHADOW = 107906,
SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153,
SPELL_PRIEST_ITEM_EFFICIENCY = 37595,
+ SPELL_PRIEST_LEAP_OF_FAITH = 73325,
+ SPELL_PRIEST_LEAP_OF_FAITH_EFFECT = 92832,
+ SPELL_PRIEST_LEAP_OF_FAITH_EFFECT_TRIGGER = 92833,
+ SPELL_PRIEST_LEAP_OF_FAITH_TRIGGERED = 92572,
SPELL_PRIEST_MANA_LEECH_PROC = 34650,
SPELL_PRIEST_PENANCE_R1 = 47540,
SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758,
SPELL_PRIEST_PENANCE_R1_HEAL = 47757,
- SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619,
SPELL_PRIEST_REFLECTIVE_SHIELD_R1 = 33201,
+ SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED = 33619,
+ SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH = 107903,
+ SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH = 107904,
SPELL_PRIEST_SHADOW_WORD_DEATH = 32409,
+ SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1 = 47586,
SPELL_PRIEST_T9_HEALING_2P = 67201,
- SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085,
+ SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL = 15290,
+ SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL = 64085
};
enum PriestSpellIcons
{
PRIEST_ICON_ID_BORROWED_TIME = 2899,
- PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021,
- PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874,
+ PRIEST_ICON_ID_DIVINE_TOUCH_TALENT = 3021,
+ PRIEST_ICON_ID_PAIN_AND_SUFFERING = 2874
+};
+
+enum MiscSpells
+{
+ SPELL_GEN_REPLENISHMENT = 57669
};
class PowerCheck
@@ -88,7 +110,58 @@ class RaidCheck
Unit const* _caster;
};
-// -34861 - Circle of Healing
+class spell_pri_body_and_soul : public SpellScriptLoader
+{
+ public:
+ spell_pri_body_and_soul() : SpellScriptLoader("spell_pri_body_and_soul") { }
+
+ class spell_pri_body_and_soul_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_body_and_soul_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_CURE_DISEASE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_PRIEST_BODY_AND_SOUL_DISPEL))
+ return false;
+ return true;
+ }
+
+ void HandleEffectSpeedProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ // Proc only with Power Word: Shield or Leap of Faith
+ if (!(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[0] & 0x1 || eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[2] & 0x80000))
+ return;
+
+ GetTarget()->CastCustomSpell(SPELL_PRIEST_BODY_AND_SOUL_SPEED, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), eventInfo.GetProcTarget(), true, NULL, aurEff);
+ }
+
+ void HandleEffectDispelProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ // Proc only with Cure Disease
+ if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id != SPELL_PRIEST_CURE_DISEASE || eventInfo.GetProcTarget() != GetTarget())
+ return;
+
+ if (roll_chance_i(aurEff->GetAmount()))
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_BODY_AND_SOUL_DISPEL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectSpeedProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_pri_body_and_soul_AuraScript::HandleEffectDispelProc, EFFECT_1, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_body_and_soul_AuraScript();
+ }
+};
+
+// 34861 - Circle of Healing
class spell_pri_circle_of_healing : public SpellScriptLoader
{
public:
@@ -130,6 +203,65 @@ class spell_pri_circle_of_healing : public SpellScriptLoader
}
};
+// 527 - Dispel magic
+class spell_pri_dispel_magic : public SpellScriptLoader
+{
+public:
+ spell_pri_dispel_magic() : SpellScriptLoader("spell_pri_dispel_magic") { }
+
+ class spell_pri_dispel_magic_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pri_dispel_magic_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ABSOLUTION))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetExplTargetUnit();
+
+ if (!target || (!caster->HasAura(SPELL_PRIEST_ABSOLUTION) && caster != target && target->IsFriendlyTo(caster)))
+ return SPELL_FAILED_BAD_TARGETS;
+ return SPELL_CAST_OK;
+ }
+
+ void AfterEffectHit(SpellEffIndex /*effIndex*/)
+ {
+ if (GetHitUnit()->IsFriendlyTo(GetCaster()))
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_FRIENDLY, true);
+ if (AuraEffect const* aurEff = GetHitUnit()->GetAuraEffect(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC, EFFECT_0))
+ {
+ int32 heal = GetHitUnit()->CountPctFromMaxHealth(aurEff->GetAmount());
+ GetCaster()->CastCustomSpell(SPELL_PRIEST_GLYPH_OF_DISPEL_MAGIC_HEAL, SPELLVALUE_BASE_POINT0, heal, GetHitUnit());
+ }
+ }
+ else
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_PRIEST_DISPEL_MAGIC_HOSTILE, true);
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_pri_dispel_magic_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_pri_dispel_magic_SpellScript::AfterEffectHit, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_pri_dispel_magic_SpellScript();
+ }
+};
+
// -47509 - Divine Aegis
class spell_pri_divine_aegis : public SpellScriptLoader
{
@@ -253,6 +385,76 @@ class spell_pri_glyph_of_prayer_of_healing : public SpellScriptLoader
}
};
+class spell_pri_improved_power_word_shield : public SpellScriptLoader
+{
+ public:
+ spell_pri_improved_power_word_shield() : SpellScriptLoader("spell_pri_improved_power_word_shield") { }
+
+ class spell_pri_improved_power_word_shield_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_improved_power_word_shield_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_pri_improved_power_word_shield_AuraScript::HandleEffectCalcSpellMod, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_improved_power_word_shield_AuraScript();
+ }
+};
+
+// 37594 - Greater Heal Refund
+class spell_pri_item_greater_heal_refund : public SpellScriptLoader
+{
+ public:
+ spell_pri_item_greater_heal_refund() : SpellScriptLoader("spell_pri_item_greater_heal_refund") { }
+
+ class spell_pri_item_greater_heal_refund_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_item_greater_heal_refund_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ITEM_EFFICIENCY))
+ return false;
+ return true;
+ }
+
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_item_greater_heal_refund_AuraScript();
+ }
+};
+
// 47788 - Guardian Spirit
class spell_pri_guardian_spirit : public SpellScriptLoader
{
@@ -346,42 +548,47 @@ class spell_pri_hymn_of_hope : public SpellScriptLoader
}
};
-// 37594 - Greater Heal Refund
-class spell_pri_item_greater_heal_refund : public SpellScriptLoader
+// 92833 - Leap of Faith
+class spell_pri_leap_of_faith_effect_trigger : public SpellScriptLoader
{
public:
- spell_pri_item_greater_heal_refund() : SpellScriptLoader("spell_pri_item_greater_heal_refund") { }
+ spell_pri_leap_of_faith_effect_trigger() : SpellScriptLoader("spell_pri_leap_of_faith_effect_trigger") { }
- class spell_pri_item_greater_heal_refund_AuraScript : public AuraScript
+ class spell_pri_leap_of_faith_effect_trigger_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_pri_item_greater_heal_refund_AuraScript);
+ PrepareSpellScript(spell_pri_leap_of_faith_effect_trigger_SpellScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_ITEM_EFFICIENCY))
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_LEAP_OF_FAITH_EFFECT))
return false;
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ void HandleEffectDummy(SpellEffIndex /*effIndex*/)
{
- PreventDefaultAction();
- GetTarget()->CastSpell(GetTarget(), SPELL_PRIEST_ITEM_EFFICIENCY, true, NULL, aurEff);
+ Position destPos;
+ GetHitDest()->GetPosition(&destPos);
+
+ SpellCastTargets targets;
+ targets.SetDst(destPos);
+ targets.SetUnitTarget(GetCaster());
+ GetHitUnit()->CastSpell(targets, sSpellMgr->GetSpellInfo(GetEffectValue()), NULL);
}
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_pri_item_greater_heal_refund_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectHitTarget += SpellEffectFn(spell_pri_leap_of_faith_effect_trigger_SpellScript::HandleEffectDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_pri_item_greater_heal_refund_AuraScript();
+ return new spell_pri_leap_of_faith_effect_trigger_SpellScript();
}
};
-// -7001 - Lightwell Renew
+// 7001 - Lightwell Renew
class spell_pri_lightwell_renew : public SpellScriptLoader
{
public:
@@ -492,7 +699,7 @@ class spell_pri_mana_leech : public SpellScriptLoader
}
};
-// -49821 - Mind Sear
+// 49821 - Mind Sear
class spell_pri_mind_sear : public SpellScriptLoader
{
public:
@@ -549,7 +756,7 @@ class spell_pri_pain_and_suffering_proc : public SpellScriptLoader
}
};
-// -47540 - Penance
+// 47540 - Penance
class spell_pri_penance : public SpellScriptLoader
{
public:
@@ -622,7 +829,41 @@ class spell_pri_penance : public SpellScriptLoader
}
};
-// -17 - Power Word: Shield
+// -47569 - Phantasm
+class spell_pri_phantasm : public SpellScriptLoader
+{
+ public:
+ spell_pri_phantasm() : SpellScriptLoader("spell_pri_phantasm") { }
+
+ class spell_pri_phantasm_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_phantasm_AuraScript);
+
+ bool CheckProc(ProcEventInfo& /*eventInfo*/)
+ {
+ return roll_chance_i(GetEffect(EFFECT_0)->GetAmount());
+ }
+
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->RemoveMovementImpairingAuras();
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_pri_phantasm_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_pri_phantasm_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_phantasm_AuraScript();
+ }
+};
+
+// 17 - Power Word: Shield
class spell_pri_power_word_shield : public SpellScriptLoader
{
public:
@@ -646,8 +887,8 @@ class spell_pri_power_word_shield : public SpellScriptLoader
canBeRecalculated = false;
if (Unit* caster = GetCaster())
{
- // +80.68% from sp bonus
- float bonus = 0.8068f;
+ // +87% from sp bonus
+ float bonus = 0.87f;
// Borrowed Time
if (AuraEffect const* borrowedTime = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_BORROWED_TIME, EFFECT_1))
@@ -663,7 +904,7 @@ class spell_pri_power_word_shield : public SpellScriptLoader
amount += int32(bonus);
// Twin Disciplines
- if (AuraEffect const* twinDisciplines = caster->GetAuraEffect(SPELL_AURA_ADD_PCT_MODIFIER, SPELLFAMILY_PRIEST, 0x400000, 0, 0, GetCasterGUID()))
+ if (AuraEffect const* twinDisciplines = caster->GetAuraEffectOfRankedSpell(SPELL_PRIEST_TWIN_DISCIPLINES_RANK_1, EFFECT_1))
AddPct(amount, twinDisciplines->GetAmount());
// Focused Power
@@ -677,7 +918,7 @@ class spell_pri_power_word_shield : public SpellScriptLoader
if (dmgInfo.GetAttacker() == target)
return;
- if (AuraEffect* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0))
+ if (AuraEffect const* talentAurEff = target->GetAuraEffectOfRankedSpell(SPELL_PRIEST_REFLECTIVE_SHIELD_R1, EFFECT_0))
{
int32 bp = CalculatePct(absorbAmount, talentAurEff->GetAmount());
target->CastCustomSpell(dmgInfo.GetAttacker(), SPELL_PRIEST_REFLECTIVE_SHIELD_TRIGGERED, &bp, NULL, NULL, true, NULL, aurEff);
@@ -732,7 +973,7 @@ class spell_pri_prayer_of_mending_heal : public SpellScriptLoader
}
};
-// -139 - Renew
+// 139 - Renew
class spell_pri_renew : public SpellScriptLoader
{
public:
@@ -742,6 +983,13 @@ class spell_pri_renew : public SpellScriptLoader
{
PrepareAuraScript(spell_pri_renew_AuraScript);
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_DIVINE_TOUCH))
+ return false;
+ return true;
+ }
+
bool Load() OVERRIDE
{
return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER;
@@ -751,14 +999,13 @@ class spell_pri_renew : public SpellScriptLoader
{
if (Unit* caster = GetCaster())
{
- // Empowered Renew
- if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1))
+ // Divine Touch
+ if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_DIVINE_TOUCH_TALENT, EFFECT_0))
{
- uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT);
+ uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), aurEff->GetAmount(), DOT);
heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
-
- int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100;
- caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff);
+ int32 basepoints0 = CalculatePct(int32(heal) * aurEff->GetTotalTicks(), empoweredRenewAurEff->GetAmount());
+ caster->CastCustomSpell(GetTarget(), SPELL_PRIEST_DIVINE_TOUCH, &basepoints0, NULL, NULL, true, NULL, aurEff);
}
}
}
@@ -775,7 +1022,7 @@ class spell_pri_renew : public SpellScriptLoader
}
};
-// -32379 - Shadow Word Death
+// 32379 - Shadow Word Death
class spell_pri_shadow_word_death : public SpellScriptLoader
{
public:
@@ -808,7 +1055,120 @@ class spell_pri_shadow_word_death : public SpellScriptLoader
}
};
-// -34914 - Vampiric Touch
+// 15473 - Shadowform
+class spell_pri_shadowform : public SpellScriptLoader
+{
+ public:
+ spell_pri_shadowform() : SpellScriptLoader("spell_pri_shadowform") { }
+
+ class spell_pri_shadowform_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_shadowform_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH) ||
+ !sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH))
+ return false;
+ return true;
+ }
+
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH, true);
+ }
+
+ void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(GetTarget()->HasAura(SPELL_PRIEST_GLYPH_OF_SHADOW) ? SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH : SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_pri_shadowform_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_pri_shadowform_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_shadowform_AuraScript();
+ }
+};
+
+// 15286 - Vampiric Embrace
+class spell_pri_vampiric_embrace : public SpellScriptLoader
+{
+ public:
+ spell_pri_vampiric_embrace() : SpellScriptLoader("spell_pri_vampiric_embrace") { }
+
+ class spell_pri_vampiric_embrace_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_vampiric_embrace_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ // Not proc from Mind Sear
+ return !(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x80000);
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 self = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()));
+ int32 team = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount() / 2));
+
+ GetTarget()->CastCustomSpell((Unit*)NULL, SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL, &team, &self, NULL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_embrace_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_embrace_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_pri_vampiric_embrace_AuraScript();
+ }
+};
+
+// 15290 - Vampiric Embrace (heal)
+class spell_pri_vampiric_embrace_target : public SpellScriptLoader
+{
+ public:
+ spell_pri_vampiric_embrace_target() : SpellScriptLoader("spell_pri_vampiric_embrace_target") { }
+
+ class spell_pri_vampiric_embrace_target_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pri_vampiric_embrace_target_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
+ {
+ unitList.remove(GetCaster());
+ }
+
+ void Register() OVERRIDE
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_vampiric_embrace_target_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_pri_vampiric_embrace_target_SpellScript();
+ }
+};
+
+// 34914 - Vampiric Touch
class spell_pri_vampiric_touch : public SpellScriptLoader
{
public:
@@ -820,7 +1180,8 @@ class spell_pri_vampiric_touch : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL))
+ if (!sSpellMgr->GetSpellInfo(SPELL_PRIEST_VAMPIRIC_TOUCH_DISPEL) ||
+ !sSpellMgr->GetSpellInfo(SPELL_GEN_REPLENISHMENT))
return false;
return true;
}
@@ -837,9 +1198,21 @@ class spell_pri_vampiric_touch : public SpellScriptLoader
}
}
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ return eventInfo.GetProcTarget() == GetCaster();
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ eventInfo.GetProcTarget()->CastSpell((Unit*)NULL, SPELL_GEN_REPLENISHMENT, true, NULL, aurEff);
+ }
+
void Register() OVERRIDE
{
AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel);
+ DoCheckProc += AuraCheckProcFn(spell_pri_vampiric_touch_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_pri_vampiric_touch_AuraScript::HandleEffectProc, EFFECT_2, SPELL_AURA_DUMMY);
}
};
@@ -851,22 +1224,30 @@ class spell_pri_vampiric_touch : public SpellScriptLoader
void AddSC_priest_spell_scripts()
{
+ new spell_pri_body_and_soul();
new spell_pri_circle_of_healing();
+ new spell_pri_dispel_magic();
new spell_pri_divine_aegis();
new spell_pri_divine_hymn();
new spell_pri_glyph_of_prayer_of_healing();
- new spell_pri_guardian_spirit();
new spell_pri_hymn_of_hope();
+ new spell_pri_improved_power_word_shield();
new spell_pri_item_greater_heal_refund();
+ new spell_pri_guardian_spirit();
+ new spell_pri_leap_of_faith_effect_trigger();
new spell_pri_lightwell_renew();
new spell_pri_mana_burn();
new spell_pri_mana_leech();
new spell_pri_mind_sear();
new spell_pri_pain_and_suffering_proc();
new spell_pri_penance();
+ new spell_pri_phantasm();
new spell_pri_power_word_shield();
new spell_pri_prayer_of_mending_heal();
new spell_pri_renew();
new spell_pri_shadow_word_death();
+ new spell_pri_shadowform();
+ new spell_pri_vampiric_embrace();
+ new spell_pri_vampiric_embrace_target();
new spell_pri_vampiric_touch();
}
diff --git a/src/server/scripts/Spells/spell_rogue.cpp b/src/server/scripts/Spells/spell_rogue.cpp
index d1d43684f3e..7768ad7596c 100644
--- a/src/server/scripts/Spells/spell_rogue.cpp
+++ b/src/server/scripts/Spells/spell_rogue.cpp
@@ -29,17 +29,31 @@
enum RogueSpells
{
- SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482,
- SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231,
- SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819,
- SPELL_ROGUE_KILLING_SPREE = 51690,
- SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840,
- SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841,
- SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851,
- SPELL_ROGUE_PREY_ON_THE_WEAK = 58670,
- SPELL_ROGUE_SHIV_TRIGGERED = 5940,
- SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933,
- SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628,
+ SPELL_ROGUE_BLADE_FLURRY = 13877,
+ SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK = 22482,
+ SPELL_ROGUE_CHEAT_DEATH_COOLDOWN = 31231,
+ SPELL_ROGUE_CRIPPLING_POISON = 3409,
+ SPELL_ROGUE_GLYPH_OF_PREPARATION = 56819,
+ SPELL_ROGUE_KILLING_SPREE = 51690,
+ SPELL_ROGUE_KILLING_SPREE_TELEPORT = 57840,
+ SPELL_ROGUE_KILLING_SPREE_WEAPON_DMG = 57841,
+ SPELL_ROGUE_KILLING_SPREE_DMG_BUFF = 61851,
+ SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT = 31665,
+ SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE = 31223,
+ SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC = 31666,
+ SPELL_ROGUE_OVERKILL_TALENT = 58426,
+ SPELL_ROGUE_OVERKILL_PERIODIC = 58428,
+ SPELL_ROGUE_OVERKILL_POWER_REGEN = 58427,
+ SPELL_ROGUE_PREY_ON_THE_WEAK = 58670,
+ SPELL_ROGUE_SHIV_TRIGGERED = 5940,
+ SPELL_ROGUE_SILCE_AND_DICE = 5171,
+ SPELL_ROGUE_TRICKS_OF_THE_TRADE_DMG_BOOST = 57933,
+ SPELL_ROGUE_TRICKS_OF_THE_TRADE_PROC = 59628
+};
+
+enum RogueSpellIcons
+{
+ ICON_ROGUE_IMPROVED_RECUPERATE = 4819
};
// 13877, 33735, (check 51211, 65956) - Blade Flurry
@@ -67,24 +81,27 @@ class spell_rog_blade_flurry : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
- _procTarget = eventInfo.GetActor()->SelectNearbyTarget(eventInfo.GetProcTarget());
- return _procTarget;
+ _procTarget = GetTarget()->SelectNearbyTarget(eventInfo.GetProcTarget());
+ return _procTarget && eventInfo.GetDamageInfo();
}
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
- if (eventInfo.GetDamageInfo())
- {
- int32 damage = eventInfo.GetDamageInfo()->GetDamage();
- GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, SPELLVALUE_BASE_POINT0, damage, _procTarget, true, NULL, aurEff);
- }
+
+ TC_LOG_ERROR("misc", "damage: %u procSpell: %u",
+ eventInfo.GetDamageInfo()->GetDamage(), eventInfo.GetDamageInfo()->GetSpellInfo() ? eventInfo.GetDamageInfo()->GetSpellInfo()->Id : 0);
+
+ GetTarget()->CastCustomSpell(SPELL_ROGUE_BLADE_FLURRY_EXTRA_ATTACK, SPELLVALUE_BASE_POINT0, eventInfo.GetDamageInfo()->GetDamage(), _procTarget, true, NULL, aurEff);
}
void Register() OVERRIDE
{
DoCheckProc += AuraCheckProcFn(spell_rog_blade_flurry_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE);
+ if (m_scriptSpellId == SPELL_ROGUE_BLADE_FLURRY)
+ OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ else
+ OnEffectProc += AuraEffectProcFn(spell_rog_blade_flurry_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_MOD_MELEE_HASTE);
}
private:
@@ -97,7 +114,7 @@ class spell_rog_blade_flurry : public SpellScriptLoader
}
};
-// -31228 - Cheat Death
+// 31228 - Cheat Death
class spell_rog_cheat_death : public SpellScriptLoader
{
public:
@@ -160,7 +177,71 @@ class spell_rog_cheat_death : public SpellScriptLoader
}
};
-// -2818 - Deadly Poison
+// -51625 - Deadly Brew
+class spell_rog_crippling_poison : public SpellScriptLoader
+{
+ public:
+ spell_rog_crippling_poison() : SpellScriptLoader("spell_rog_crippling_poison") { }
+
+ class spell_rog_crippling_poison_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_crippling_poison_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_CRIPPLING_POISON))
+ return false;
+ return true;
+ }
+
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_ROGUE_CRIPPLING_POISON, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_rog_crippling_poison_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_rog_crippling_poison_AuraScript();
+ }
+};
+
+// -51664 - Cut to the Chase
+class spell_rog_cut_to_the_chase : public SpellScriptLoader
+{
+ public:
+ spell_rog_cut_to_the_chase () : SpellScriptLoader("spell_rog_cut_to_the_chase") { }
+
+ class spell_rog_cut_to_the_chase_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_cut_to_the_chase_AuraScript);
+
+ void HandleProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ if (Aura* aur = GetTarget()->GetAura(SPELL_ROGUE_SILCE_AND_DICE))
+ aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_rog_cut_to_the_chase_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_rog_cut_to_the_chase_AuraScript();
+ }
+};
+
+// 2818 - Deadly Poison
class spell_rog_deadly_poison : public SpellScriptLoader
{
public:
@@ -206,6 +287,9 @@ class spell_rog_deadly_poison : public SpellScriptLoader
// item combat enchantments
for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
{
+ if (slot > PRISMATIC_ENCHANTMENT_SLOT && slot < PROP_ENCHANTMENT_SLOT_0) // not holding enchantment id
+ continue;
+
SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot)));
if (!enchant)
continue;
@@ -354,7 +438,44 @@ class spell_rog_killing_spree : public SpellScriptLoader
}
};
-// -31130 - Nerves of Steel
+// 31666 - Master of Subtlety
+class spell_rog_master_of_subtlety : public SpellScriptLoader
+{
+ public:
+ spell_rog_master_of_subtlety() : SpellScriptLoader("spell_rog_master_of_subtlety") { }
+
+ class spell_rog_master_of_subtlety_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_master_of_subtlety_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT))
+ return false;
+ return true;
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ Unit* target = GetTarget();
+
+ if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ target->RemoveAurasDueToSpell(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_master_of_subtlety_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_rog_master_of_subtlety_AuraScript();
+ }
+};
+
+// 31130 - Nerves of Steel
class spell_rog_nerves_of_steel : public SpellScriptLoader
{
public:
@@ -398,6 +519,43 @@ class spell_rog_nerves_of_steel : public SpellScriptLoader
}
};
+// 58428 - Overkill
+class spell_rog_overkill : public SpellScriptLoader
+{
+ public:
+ spell_rog_overkill() : SpellScriptLoader("spell_rog_overkill") { }
+
+ class spell_rog_overkill_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_overkill_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_POWER_REGEN))
+ return false;
+ return true;
+ }
+
+ void HandleEffectPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ Unit* target = GetTarget();
+
+ if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ target->RemoveAurasDueToSpell(SPELL_ROGUE_OVERKILL_POWER_REGEN);
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_overkill_AuraScript::HandleEffectPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_rog_overkill_AuraScript();
+ }
+};
+
// 14185 - Preparation
class spell_rog_preparation : public SpellScriptLoader
{
@@ -424,29 +582,25 @@ class spell_rog_preparation : public SpellScriptLoader
{
Player* caster = GetCaster()->ToPlayer();
- //immediately finishes the cooldown on certain Rogue abilities
- const SpellCooldowns& cm = caster->GetSpellCooldownMap();
+ // immediately finishes the cooldown on certain Rogue abilities
+ SpellCooldowns const& cm = caster->GetSpellCooldownMap();
for (SpellCooldowns::const_iterator itr = cm.begin(); itr != cm.end();)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo || spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE)
+ {
+ ++itr;
+ continue;
+ }
- if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE)
+ if ((spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_SHADOWSTEP || // Shadowstep
+ spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_VAN_SPRINT) || // Vanish, Sprint
+ // Glyph of Preparation
+ (caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION) &&
+ (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE_SMOKE_BOMB || // Dismantle, Smoke Bomb
+ spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG0_ROGUE_KICK))) // Kick
{
- if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_COLDB_SHADOWSTEP || // Cold Blood, Shadowstep
- spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_VAN_EVAS_SPRINT) // Vanish, Evasion, Sprint
- caster->RemoveSpellCooldown((itr++)->first, true);
- else if (caster->HasAura(SPELL_ROGUE_GLYPH_OF_PREPARATION))
- {
- if (spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_DISMANTLE || // Dismantle
- spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_KICK || // Kick
- (spellInfo->SpellFamilyFlags[0] & SPELLFAMILYFLAG_ROGUE_BLADE_FLURRY && // Blade Flurry
- spellInfo->SpellFamilyFlags[1] & SPELLFAMILYFLAG1_ROGUE_BLADE_FLURRY))
- caster->RemoveSpellCooldown((itr++)->first, true);
- else
- ++itr;
- }
- else
- ++itr;
+ caster->RemoveSpellCooldown((itr++)->first, true);
}
else
++itr;
@@ -465,7 +619,7 @@ class spell_rog_preparation : public SpellScriptLoader
}
};
-// -51685 - Prey on the Weak
+// 51685 - Prey on the Weak
class spell_rog_prey_on_the_weak : public SpellScriptLoader
{
public:
@@ -510,7 +664,56 @@ class spell_rog_prey_on_the_weak : public SpellScriptLoader
}
};
-// -1943 - Rupture
+// 73651 - Recuperate
+class spell_rog_recuperate : public SpellScriptLoader
+{
+ public:
+ spell_rog_recuperate() : SpellScriptLoader("spell_rog_recuperate") { }
+
+ class spell_rog_recuperate_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_recuperate_AuraScript);
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void OnPeriodic(AuraEffect const* /*aurEff*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (AuraEffect* effect = GetAura()->GetEffect(EFFECT_0))
+ effect->RecalculateAmount(caster);
+ }
+
+ void CalculateBonus(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ {
+ canBeRecalculated = false;
+ if (Unit* caster = GetCaster())
+ {
+ int32 baseAmount = GetSpellInfo()->Effects[EFFECT_0].CalcValue(caster) * 1000;
+ // Improved Recuperate
+ if (AuraEffect const* auraEffect = caster->GetDummyAuraEffect(SPELLFAMILY_ROGUE, ICON_ROGUE_IMPROVED_RECUPERATE, EFFECT_0))
+ baseAmount += auraEffect->GetAmount();
+
+ amount = CalculatePct(caster->GetMaxHealth(), float(baseAmount) / 1000.0f);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_rog_recuperate_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_rog_recuperate_AuraScript::CalculateBonus, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_rog_recuperate_AuraScript();
+ }
+};
+
+// 1943 - Rupture
class spell_rog_rupture : public SpellScriptLoader
{
public:
@@ -603,6 +806,70 @@ class spell_rog_shiv : public SpellScriptLoader
}
};
+// 1784 - Stealth
+class spell_rog_stealth : public SpellScriptLoader
+{
+ public:
+ spell_rog_stealth() : SpellScriptLoader("spell_rog_stealth") { }
+
+ class spell_rog_stealth_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_rog_stealth_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_TALENT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_POWER_REGEN) ||
+ !sSpellMgr->GetSpellInfo(SPELL_ROGUE_OVERKILL_PERIODIC))
+ return false;
+ return true;
+ }
+
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+
+ // Master of Subtlety
+ if (AuraEffect const* aurEff = target->GetAuraEffect(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE, EFFECT_0))
+ {
+ int32 basepoints0 = aurEff->GetAmount();
+ target->CastCustomSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_DAMAGE_PERCENT, &basepoints0, NULL, NULL, true);
+ }
+
+ // Overkill
+ if (target->HasAura(SPELL_ROGUE_OVERKILL_TALENT))
+ target->CastSpell(target, SPELL_ROGUE_OVERKILL_POWER_REGEN, true);
+ }
+
+ void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+
+ // Master of subtlety
+ if (target->HasAura(SPELL_ROGUE_MASTER_OF_SUBTLETY_PASSIVE))
+ target->CastSpell(target, SPELL_ROGUE_MASTER_OF_SUBTLETY_PERIODIC, true);
+
+ // Overkill
+ if (target->HasAura(SPELL_ROGUE_OVERKILL_TALENT))
+ target->CastSpell(target, SPELL_ROGUE_OVERKILL_PERIODIC, true);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_rog_stealth_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_rog_stealth_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_MOD_SHAPESHIFT, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_rog_stealth_AuraScript();
+ }
+};
+
// 57934 - Tricks of the Trade
class spell_rog_tricks_of_the_trade : public SpellScriptLoader
{
@@ -698,13 +965,19 @@ void AddSC_rogue_spell_scripts()
{
new spell_rog_blade_flurry();
new spell_rog_cheat_death();
+ new spell_rog_crippling_poison();
+ new spell_rog_cut_to_the_chase();
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();
+ new spell_rog_stealth();
new spell_rog_tricks_of_the_trade();
new spell_rog_tricks_of_the_trade_proc();
}
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index 707c8a0985f..c3ea8ca2d62 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -30,132 +30,134 @@
enum ShamanSpells
{
+ SPELL_HUNTER_INSANITY = 95809,
+ SPELL_MAGE_TEMPORAL_DISPLACEMENT = 80354,
+ SPELL_SHAMAN_ANCESTRAL_AWAKENING = 52759,
SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC = 52752,
SPELL_SHAMAN_BIND_SIGHT = 6277,
- SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT = 52025,
SPELL_SHAMAN_EARTH_SHIELD_HEAL = 379,
+ SPELL_SHAMAN_ELEMENTAL_MASTERY = 16166,
SPELL_SHAMAN_EXHAUSTION = 57723,
- SPELL_SHAMAN_FIRE_NOVA_R1 = 1535,
SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1 = 8349,
+ SPELL_SHAMAN_FLAME_SHOCK = 8050,
+ SPELL_SHAMAN_FOCUSED_INSIGHT = 77800,
SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD = 63279,
SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM = 55456,
+ SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE = 55533,
SPELL_SHAMAN_GLYPH_OF_MANA_TIDE = 55441,
SPELL_SHAMAN_GLYPH_OF_THUNDERSTORM = 62132,
+ SPELL_SHAMAN_LAVA_BURST = 51505,
+ SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480,
+ SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 65264,
+ SPELL_SHAMAN_LAVA_SURGE = 77762,
SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD = 23552,
SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE = 27635,
SPELL_SHAMAN_ITEM_MANA_SURGE = 23571,
- SPELL_SHAMAN_LAVA_FLOWS_R1 = 51480,
- SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694,
- SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE = 52032,
- SPELL_SHAMAN_MANA_TIDE_TOTEM = 39609,
+ SPELL_SHAMAN_LIGHTNING_SHIELD = 324,
+ SPELL_SHAMAN_NATURE_GUARDIAN = 31616,
SPELL_SHAMAN_SATED = 57724,
SPELL_SHAMAN_STORM_EARTH_AND_FIRE = 51483,
+ SPELL_SHAMAN_TELLURIC_CURRENTS = 82987,
SPELL_SHAMAN_TOTEM_EARTHBIND_EARTHGRAB = 64695,
SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM = 6474,
SPELL_SHAMAN_TOTEM_EARTHEN_POWER = 59566,
- SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042
+ SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL = 52042,
+ SPELL_SHAMAN_TIDAL_WAVES = 53390
};
enum ShamanSpellIcons
{
- SHAMAN_ICON_ID_RESTORATIVE_TOTEMS = 338,
+ SHAMAN_ICON_ID_SOOTHING_RAIN = 2011,
SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW = 3087
};
-// 52759 - Ancestral Awakening (Proc)
-class spell_sha_ancestral_awakening_proc : public SpellScriptLoader
+// -51556 - Ancestral Awakening
+class spell_sha_ancestral_awakening : public SpellScriptLoader
{
public:
- spell_sha_ancestral_awakening_proc() : SpellScriptLoader("spell_sha_ancestral_awakening_proc") { }
+ spell_sha_ancestral_awakening() : SpellScriptLoader("spell_sha_ancestral_awakening") { }
- class spell_sha_ancestral_awakening_proc_SpellScript : public SpellScript
+ class spell_sha_ancestral_awakening_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_sha_ancestral_awakening_proc_SpellScript);
+ PrepareAuraScript(spell_sha_ancestral_awakening_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TIDAL_WAVES))
return false;
return true;
}
- void FilterTargets(std::list<WorldObject*>& targets)
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
- if (targets.size() < 2)
- return;
-
- targets.sort(Trinity::HealthPctOrderPred());
+ PreventDefaultAction();
+ int32 heal = int32(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount()));
- WorldObject* target = targets.front();
- targets.clear();
- targets.push_back(target);
- }
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- int32 damage = GetEffectValue();
- if (GetHitUnit())
- GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC, &damage, NULL, NULL, true);
+ GetTarget()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff);
}
void Register() OVERRIDE
{
- OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_ancestral_awakening_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
- OnEffectHitTarget += SpellEffectFn(spell_sha_ancestral_awakening_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_sha_ancestral_awakening_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
- SpellScript* GetSpellScript() const OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_sha_ancestral_awakening_proc_SpellScript();
+ return new spell_sha_ancestral_awakening_AuraScript();
}
};
-// 51474 - Astral Shift
-class spell_sha_astral_shift : public SpellScriptLoader
+// 52759 - Ancestral Awakening
+/// Updated 4.3.4
+class spell_sha_ancestral_awakening_proc : public SpellScriptLoader
{
public:
- spell_sha_astral_shift() : SpellScriptLoader("spell_sha_astral_shift") { }
+ spell_sha_ancestral_awakening_proc() : SpellScriptLoader("spell_sha_ancestral_awakening_proc") { }
- class spell_sha_astral_shift_AuraScript : public AuraScript
+ class spell_sha_ancestral_awakening_proc_SpellScript : public SpellScript
{
- PrepareAuraScript(spell_sha_astral_shift_AuraScript);
-
- uint32 absorbPct;
+ PrepareSpellScript(spell_sha_ancestral_awakening_proc_SpellScript);
- bool Load() OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- absorbPct = GetSpellInfo()->Effects[EFFECT_0].CalcValue(GetCaster());
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC))
+ return false;
return true;
}
- void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- // Set absorbtion amount to unlimited
- amount = -1;
- }
+ if (targets.size() < 2)
+ return;
- void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
+ targets.sort(Trinity::HealthPctOrderPred());
+
+ WorldObject* target = targets.front();
+ targets.clear();
+ targets.push_back(target);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
- // reduces all damage taken while stun, fear or silence
- if (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_FLEEING | UNIT_FLAG_SILENCED) || (GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN)))
- absorbAmount = CalculatePct(dmgInfo.GetDamage(), absorbPct);
+ GetCaster()->CastCustomSpell(SPELL_SHAMAN_ANCESTRAL_AWAKENING_PROC, SPELLVALUE_BASE_POINT0, GetEffectValue(), GetHitUnit(), true);
}
void Register() OVERRIDE
{
- DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_astral_shift_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB);
- OnEffectAbsorb += AuraEffectAbsorbFn(spell_sha_astral_shift_AuraScript::Absorb, EFFECT_0);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_ancestral_awakening_proc_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
+ OnEffectHitTarget += SpellEffectFn(spell_sha_ancestral_awakening_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
- AuraScript* GetAuraScript() const OVERRIDE
+ SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_sha_astral_shift_AuraScript();
+ return new spell_sha_ancestral_awakening_proc_SpellScript();
}
};
// 2825 - Bloodlust
+/// Updated 4.3.4
class spell_sha_bloodlust : public SpellScriptLoader
{
public:
@@ -175,6 +177,8 @@ class spell_sha_bloodlust : public SpellScriptLoader
void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_SATED));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT));
}
void ApplyDebuff()
@@ -198,7 +202,8 @@ class spell_sha_bloodlust : public SpellScriptLoader
}
};
-// -1064 - Chain Heal
+// 1064 - Chain Heal
+/// Updated 4.3.4
class spell_sha_chain_heal : public SpellScriptLoader
{
public:
@@ -212,6 +217,7 @@ class spell_sha_chain_heal : public SpellScriptLoader
{
firstHeal = true;
riptide = false;
+ amount = 0;
return true;
}
@@ -223,6 +229,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();
// Consume it
GetHitUnit()->RemoveAura(aurEff->GetBase());
}
@@ -230,7 +237,10 @@ class spell_sha_chain_heal : public SpellScriptLoader
}
// Riptide increases the Chain Heal effect by 25%
if (riptide)
- SetHitHeal(GetHitHeal() * 1.25f);
+ {
+ uint32 bonus = CalculatePct(GetHitHeal(), amount);
+ SetHitHeal(GetHitHeal() + bonus);
+ }
}
void Register() OVERRIDE
@@ -240,6 +250,7 @@ class spell_sha_chain_heal : public SpellScriptLoader
bool firstHeal;
bool riptide;
+ uint32 amount;
};
SpellScript* GetSpellScript() const OVERRIDE
@@ -248,43 +259,7 @@ class spell_sha_chain_heal : public SpellScriptLoader
}
};
-// 8171 - Cleansing Totem (Pulse)
-class spell_sha_cleansing_totem_pulse : public SpellScriptLoader
-{
- public:
- spell_sha_cleansing_totem_pulse() : SpellScriptLoader("spell_sha_cleansing_totem_pulse") { }
-
- class spell_sha_cleansing_totem_pulse_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_sha_cleansing_totem_pulse_SpellScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT))
- return false;
- return true;
- }
-
- void HandleDummy(SpellEffIndex /*effIndex*/)
- {
- int32 bp = 1;
- if (GetCaster() && GetHitUnit() && GetOriginalCaster())
- GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_SHAMAN_CLEANSING_TOTEM_EFFECT, NULL, &bp, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID());
- }
-
- void Register() OVERRIDE
- {
- OnEffectHitTarget += SpellEffectFn(spell_sha_cleansing_totem_pulse_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const OVERRIDE
- {
- return new spell_sha_cleansing_totem_pulse_SpellScript();
- }
-};
-
-// -974 - Earth Shield
+// 974 - Earth Shield
class spell_sha_earth_shield : public SpellScriptLoader
{
public:
@@ -296,9 +271,8 @@ class spell_sha_earth_shield : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_EARTH_SHIELD_HEAL) ||
+ !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_EARTH_SHIELD))
return false;
return true;
}
@@ -352,7 +326,8 @@ class spell_sha_earth_shield : public SpellScriptLoader
}
};
-// 6474 - Earthbind Totem - Fix Talent: Earthen Power
+// 6474 - Earthbind Totem - Fix Talent:Earthen Power, Earth's Grasp
+/// Updated 4.3.4
class spell_sha_earthbind_totem : public SpellScriptLoader
{
public:
@@ -364,7 +339,8 @@ class spell_sha_earthbind_totem : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHEN_POWER))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHBIND_TOTEM) ||
+ !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_EARTHEN_POWER))
return false;
return true;
}
@@ -386,7 +362,7 @@ class spell_sha_earthbind_totem : public SpellScriptLoader
Player* owner = GetCaster()->GetCharmerOrOwnerPlayerOrPlayerItself();
if (!owner)
return;
- // Storm, Earth and Fire
+ // Earth's Grasp
if (AuraEffect* aurEff = owner->GetAuraEffectOfRankedSpell(SPELL_SHAMAN_STORM_EARTH_AND_FIRE, EFFECT_1))
{
if (roll_chance_i(aurEff->GetAmount()))
@@ -451,54 +427,68 @@ class spell_sha_earthen_power : public SpellScriptLoader
}
};
-// -1535 - Fire Nova
-class spell_sha_fire_nova : public SpellScriptLoader
+// 86185 Feedback
+class spell_sha_feedback : public SpellScriptLoader
{
public:
- spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { }
+ spell_sha_feedback() : SpellScriptLoader("spell_sha_feedback") { }
- class spell_sha_fire_nova_SpellScript : public SpellScript
+ class spell_sha_feedback_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_sha_fire_nova_SpellScript);
+ PrepareAuraScript(spell_sha_feedback_AuraScript);
- bool Validate(SpellInfo const* spellInfo) OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- SpellInfo const* firstRankSpellInfo = sSpellMgr->GetSpellInfo(SPELL_SHAMAN_FIRE_NOVA_R1);
- if (!firstRankSpellInfo || !spellInfo->IsRankOf(firstRankSpellInfo))
- return false;
-
- uint8 rank = spellInfo->GetRank();
- if (!sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, rank, true))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_ELEMENTAL_MASTERY))
return false;
return true;
}
- SpellCastResult CheckFireTotem()
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
- // fire totem
- if (!GetCaster()->m_SummonSlot[1])
- {
- SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_FIRE_TOTEM);
- return SPELL_FAILED_CUSTOM_ERROR;
- }
+ PreventDefaultAction(); // will prevent default effect execution
+ if (Player* target = GetTarget()->ToPlayer())
+ target->ModifySpellCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, aurEff->GetBaseAmount());
+ }
- return SPELL_CAST_OK;
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_sha_feedback_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_feedback_AuraScript();
+ }
+};
+
+// 1535 Fire Nova
+/// Updated 4.3.4
+class spell_sha_fire_nova : public SpellScriptLoader
+{
+ public:
+ spell_sha_fire_nova() : SpellScriptLoader("spell_sha_fire_nova") { }
+
+ class spell_sha_fire_nova_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_sha_fire_nova_SpellScript);
void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
- if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[1]))
+ if (Unit* target = GetHitUnit())
{
- uint8 rank = GetSpellInfo()->GetRank();
- if (totem->IsTotem())
- caster->CastSpell(totem, sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, rank), true);
+ if (target->HasAura(SPELL_SHAMAN_FLAME_SHOCK))
+ {
+ caster->CastSpell(target, SPELL_SHAMAN_FIRE_NOVA_TRIGGERED_R1, true);
+ target->RemoveAurasDueToSpell(SPELL_SHAMAN_FLAME_SHOCK);
+ }
}
}
void Register() OVERRIDE
{
- OnCheckCast += SpellCheckCastFn(spell_sha_fire_nova_SpellScript::CheckFireTotem);
OnEffectHitTarget += SpellEffectFn(spell_sha_fire_nova_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -509,7 +499,8 @@ class spell_sha_fire_nova : public SpellScriptLoader
}
};
-// -8050 - Flame Shock
+// 8050 -Flame Shock
+/// Updated 4.3.4
class spell_sha_flame_shock : public SpellScriptLoader
{
public:
@@ -521,9 +512,8 @@ class spell_sha_flame_shock : public SpellScriptLoader
bool Validate(SpellInfo const* /*spell*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_R1))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_R1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1))
return false;
return true;
}
@@ -531,6 +521,7 @@ class spell_sha_flame_shock : public SpellScriptLoader
void HandleDispel(DispelInfo* /*dispelInfo*/)
{
if (Unit* caster = GetCaster())
+ {
// Lava Flows
if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0))
{
@@ -538,9 +529,10 @@ class spell_sha_flame_shock : public SpellScriptLoader
if (!aurEff->GetSpellInfo()->IsRankOf(firstRankSpellInfo))
return;
- uint8 rank = aurEff->GetSpellInfo()->GetRank();
- caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true);
+ int32 basepoints = aurEff->GetAmount();
+ caster->CastCustomSpell(caster, SPELL_SHAMAN_LAVA_FLOWS_TRIGGERED_R1, &basepoints, NULL, NULL, true);
}
+ }
}
void Register() OVERRIDE
@@ -555,7 +547,90 @@ class spell_sha_flame_shock : public SpellScriptLoader
}
};
-// 52041, 52046, 52047, 52048, 52049, 52050, 58759, 58760, 58761 - Healing Stream Totem
+// 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
+{
+ public:
+ spell_sha_glyph_of_healing_wave() : SpellScriptLoader("spell_sha_glyph_of_healing_wave") { }
+
+ class spell_sha_glyph_of_healing_wave_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_glyph_of_healing_wave_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ // Not proc from self heals
+ return GetTarget() != eventInfo.GetProcTarget();
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 heal = CalculatePct(int32(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount());
+
+ GetTarget()->CastCustomSpell(SPELL_SHAMAN_GLYPH_OF_HEALING_WAVE, SPELLVALUE_BASE_POINT0, heal, (Unit*)NULL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_sha_glyph_of_healing_wave_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_sha_glyph_of_healing_wave_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_glyph_of_healing_wave_AuraScript();
+ }
+};
+
+// 52041 - Healing Stream Totem
+/// Updated 4.3.4
class spell_sha_healing_stream_totem : public SpellScriptLoader
{
public:
@@ -567,12 +642,10 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL))
- return false;
- return true;
+ return sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TOTEM_HEALING_STREAM_HEAL);
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ void HandleDummy(SpellEffIndex /* effIndex */)
{
int32 damage = GetEffectValue();
SpellInfo const* triggeringSpell = GetTriggeringSpell();
@@ -584,14 +657,10 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
if (triggeringSpell)
damage = int32(owner->SpellHealingBonusDone(target, triggeringSpell, damage, HEAL));
- // Restorative Totems
- if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_RESTORATIVE_TOTEMS, 1))
+ // Soothing Rains
+ if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, SHAMAN_ICON_ID_SOOTHING_RAIN, EFFECT_0))
AddPct(damage, dummy->GetAmount());
- // Glyph of Healing Stream Totem
- if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_HEALING_STREAM_TOTEM, EFFECT_0))
- AddPct(damage, aurEff->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());
@@ -611,6 +680,7 @@ class spell_sha_healing_stream_totem : public SpellScriptLoader
};
// 32182 - Heroism
+/// Updated 4.3.4
class spell_sha_heroism : public SpellScriptLoader
{
public:
@@ -630,6 +700,8 @@ class spell_sha_heroism : public SpellScriptLoader
void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SHAMAN_EXHAUSTION));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_HUNTER_INSANITY));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_MAGE_TEMPORAL_DISPLACEMENT));
}
void ApplyDebuff()
@@ -670,7 +742,7 @@ class spell_sha_item_lightning_shield : public SpellScriptLoader
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD, true, NULL, aurEff);
@@ -678,7 +750,7 @@ class spell_sha_item_lightning_shield : public SpellScriptLoader
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -705,7 +777,7 @@ class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
PreventDefaultAction();
GetTarget()->CastSpell(GetTarget(), SPELL_SHAMAN_ITEM_LIGHTNING_SHIELD_DAMAGE, true, NULL, aurEff);
@@ -713,7 +785,7 @@ class spell_sha_item_lightning_shield_trigger : public SpellScriptLoader
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_trigger_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectProc += AuraEffectProcFn(spell_sha_item_lightning_shield_trigger_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -740,24 +812,18 @@ class spell_sha_item_mana_surge : public SpellScriptLoader
return true;
}
- bool CheckProc(ProcEventInfo& eventInfo)
- {
- return eventInfo.GetDamageInfo()->GetSpellInfo();
- }
-
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
- int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), eventInfo.GetSchoolMask());
- int32 damage = CalculatePct(mana, 35);
+ int32 mana = eventInfo.GetDamageInfo()->GetSpellInfo()->CalcPowerCost(GetTarget(), SpellSchoolMask(eventInfo.GetDamageInfo()->GetSchoolMask()));
+ mana = int32(CalculatePct(mana, 35));
- GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, damage, GetTarget(), true, NULL, aurEff);
+ GetTarget()->CastCustomSpell(SPELL_SHAMAN_ITEM_MANA_SURGE, SPELLVALUE_BASE_POINT0, mana, GetTarget(), true, NULL, aurEff);
}
void Register() OVERRIDE
{
- DoCheckProc += AuraCheckProcFn(spell_sha_item_mana_surge_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectProc += AuraEffectProcFn(spell_sha_item_mana_surge_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
@@ -768,6 +834,7 @@ class spell_sha_item_mana_surge : public SpellScriptLoader
};
// 60103 - Lava Lash
+/// Updated 4.3.4
class spell_sha_lava_lash : public SpellScriptLoader
{
public:
@@ -811,139 +878,240 @@ class spell_sha_lava_lash : public SpellScriptLoader
}
};
-// 52031, 52033, 52034, 52035, 52036, 58778, 58779, 58780 - Mana Spring Totem
-class spell_sha_mana_spring_totem : public SpellScriptLoader
+class spell_sha_lava_surge : public SpellScriptLoader
+{
+ public:
+ spell_sha_lava_surge() : SpellScriptLoader("spell_sha_lava_surge") { }
+
+ class spell_sha_lava_surge_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_lava_surge_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_SURGE))
+ return false;
+ return true;
+ }
+
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), SPELL_SHAMAN_LAVA_SURGE, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_sha_lava_surge_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_lava_surge_AuraScript();
+ }
+};
+
+class spell_sha_lava_surge_proc : public SpellScriptLoader
{
public:
- spell_sha_mana_spring_totem() : SpellScriptLoader("spell_sha_mana_spring_totem") { }
+ spell_sha_lava_surge_proc() : SpellScriptLoader("spell_sha_lava_surge_proc") { }
- class spell_sha_mana_spring_totem_SpellScript : public SpellScript
+ class spell_sha_lava_surge_proc_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_sha_mana_spring_totem_SpellScript);
+ PrepareSpellScript(spell_sha_lava_surge_proc_SpellScript)
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LAVA_BURST))
return false;
return true;
}
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
void HandleDummy(SpellEffIndex /*effIndex*/)
{
- int32 damage = GetEffectValue();
- if (Unit* target = GetHitUnit())
- if (Unit* caster = GetCaster())
- if (target->getPowerType() == POWER_MANA)
- caster->CastCustomSpell(target, SPELL_SHAMAN_MANA_SPRING_TOTEM_ENERGIZE, &damage, 0, 0, true, 0, 0, GetOriginalCaster()->GetGUID());
+ GetCaster()->ToPlayer()->RemoveSpellCooldown(SPELL_SHAMAN_LAVA_BURST, true);
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_sha_mana_spring_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_sha_lava_surge_proc_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_sha_mana_spring_totem_SpellScript();
+ return new spell_sha_lava_surge_proc_SpellScript();
}
};
-// 39610 - Mana Tide Totem
+// 16191 - Mana Tide
+/// Updated 4.3.4
class spell_sha_mana_tide_totem : public SpellScriptLoader
{
public:
spell_sha_mana_tide_totem() : SpellScriptLoader("spell_sha_mana_tide_totem") { }
- class spell_sha_mana_tide_totem_SpellScript : public SpellScript
+ class spell_sha_mana_tide_totem_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_mana_tide_totem_AuraScript);
+
+ void CalculateAmount(AuraEffect const* aurEff, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ ///@TODO: Exclude the "short term" buffs from the stat value
+ if (Unit* caster = GetCaster())
+ if (Unit* owner = caster->GetOwner())
+ amount = CalculatePct(owner->GetStat(STAT_SPIRIT), aurEff->GetAmount());
+ }
+
+ void Register() OVERRIDE
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_mana_tide_totem_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_mana_tide_totem_AuraScript();
+ }
+};
+
+// -30881 - Nature's Guardian
+class spell_sha_nature_guardian : public SpellScriptLoader
+{
+ public:
+ spell_sha_nature_guardian() : SpellScriptLoader("spell_sha_nature_guardian") { }
+
+ class spell_sha_nature_guardian_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_sha_mana_tide_totem_SpellScript);
+ PrepareAuraScript(spell_sha_nature_guardian_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE) || !sSpellMgr->GetSpellInfo(SPELL_SHAMAN_MANA_TIDE_TOTEM))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_NATURE_GUARDIAN))
return false;
return true;
}
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ bool CheckProc(ProcEventInfo& eventInfo)
{
- if (Unit* caster = GetCaster())
- if (Unit* unitTarget = GetHitUnit())
- {
- if (unitTarget->getPowerType() == POWER_MANA)
- {
- int32 effValue = GetEffectValue();
- // Glyph of Mana Tide
- if (Unit* owner = caster->GetOwner())
- if (AuraEffect* dummy = owner->GetAuraEffect(SPELL_SHAMAN_GLYPH_OF_MANA_TIDE, 0))
- effValue += dummy->GetAmount();
- // Regenerate 6% of Total Mana Every 3 secs
- int32 effBasePoints0 = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), effValue));
- caster->CastCustomSpell(unitTarget, SPELL_SHAMAN_MANA_TIDE_TOTEM, &effBasePoints0, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID());
- }
- }
+ //! HACK due to currenct proc system implementation
+ if (Player* player = GetTarget()->ToPlayer())
+ if (player->HasSpellCooldown(GetSpellInfo()->Id))
+ return false;
+
+ return GetTarget()->HealthBelowPctDamaged(30, eventInfo.GetDamageInfo()->GetDamage());
+ }
+
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 basePoints0 = GetTarget()->CountPctFromMaxHealth(aurEff->GetAmount());
+
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_NATURE_GUARDIAN, &basePoints0, NULL, NULL, true);
+
+ if (eventInfo.GetProcTarget() && eventInfo.GetProcTarget()->IsAlive())
+ eventInfo.GetProcTarget()->getThreatManager().modifyThreatPercent(GetTarget(), -10);
+
+ if (Player* player = GetTarget()->ToPlayer())
+ player->AddSpellCooldown(GetSpellInfo()->Id, 0, time(NULL) + aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue());
}
void Register() OVERRIDE
{
- OnEffectHitTarget += SpellEffectFn(spell_sha_mana_tide_totem_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ DoCheckProc += AuraCheckProcFn(spell_sha_nature_guardian_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_sha_nature_guardian_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
}
};
- SpellScript* GetSpellScript() const OVERRIDE
+ AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_sha_mana_tide_totem_SpellScript();
+ return new spell_sha_nature_guardian_AuraScript();
}
};
-// 6495 - Sentry Totem
-class spell_sha_sentry_totem : public SpellScriptLoader
+// 88756 - Rolling Thunder
+class spell_sha_rolling_thunder : public SpellScriptLoader
{
public:
- spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { }
+ spell_sha_rolling_thunder() : SpellScriptLoader("spell_sha_rolling_thunder") { }
- class spell_sha_sentry_totem_AuraScript : public AuraScript
+ class spell_sha_rolling_thunder_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_sha_sentry_totem_AuraScript);
+ PrepareAuraScript(spell_sha_rolling_thunder_AuraScript);
- bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_BIND_SIGHT))
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_LIGHTNING_SHIELD))
return false;
return true;
}
- void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
- if (Unit* caster = GetCaster())
- if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4]))
- if (totem->IsTotem())
- caster->CastSpell(totem, SPELL_SHAMAN_BIND_SIGHT, true);
+ if (Aura* aura = GetTarget()->GetAura(SPELL_SHAMAN_LIGHTNING_SHIELD))
+ {
+ aura->SetCharges(std::min(aura->GetCharges() + 1, aurEff->GetAmount()));
+ aura->RefreshDuration();
+ }
}
- void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void Register() OVERRIDE
{
- if (Unit* caster = GetCaster())
- if (caster->GetTypeId() == TYPEID_PLAYER)
- caster->ToPlayer()->StopCastingBindSight();
+ OnEffectProc += AuraEffectProcFn(spell_sha_rolling_thunder_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_rolling_thunder_AuraScript();
+ }
+};
+
+// 82984 - Telluric Currents
+class spell_sha_telluric_currents : public SpellScriptLoader
+{
+ public:
+ spell_sha_telluric_currents() : SpellScriptLoader("spell_sha_telluric_currents") { }
+
+ class spell_sha_telluric_currents_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_telluric_currents_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TELLURIC_CURRENTS))
+ return false;
+ return true;
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ PreventDefaultAction();
+ int32 basePoints0 = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount());
+
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_TELLURIC_CURRENTS, &basePoints0, NULL, NULL, true);
}
void Register() OVERRIDE
{
- AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
- AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectProc += AuraEffectProcFn(spell_sha_telluric_currents_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_sha_sentry_totem_AuraScript();
+ return new spell_sha_telluric_currents_AuraScript();
}
};
-// -51490 - Thunderstorm
+// 51490 - Thunderstorm
class spell_sha_thunderstorm : public SpellScriptLoader
{
public:
@@ -972,26 +1140,70 @@ class spell_sha_thunderstorm : public SpellScriptLoader
}
};
+// 51562 - Tidal Waves
+class spell_sha_tidal_waves : public SpellScriptLoader
+{
+ public:
+ spell_sha_tidal_waves() : SpellScriptLoader("spell_sha_tidal_waves") { }
+
+ class spell_sha_tidal_waves_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_tidal_waves_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHAMAN_TIDAL_WAVES))
+ return false;
+ return true;
+ }
+
+ void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ int32 basePoints0 = -aurEff->GetAmount();
+ int32 basePoints1 = aurEff->GetAmount();
+
+ GetTarget()->CastCustomSpell(GetTarget(), SPELL_SHAMAN_TIDAL_WAVES, &basePoints0, &basePoints1, NULL, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_sha_tidal_waves_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_sha_tidal_waves_AuraScript();
+ }
+};
+
void AddSC_shaman_spell_scripts()
{
+ new spell_sha_ancestral_awakening();
new spell_sha_ancestral_awakening_proc();
- new spell_sha_astral_shift();
new spell_sha_bloodlust();
new spell_sha_chain_heal();
- new spell_sha_cleansing_totem_pulse();
new spell_sha_earth_shield();
new spell_sha_earthbind_totem();
new spell_sha_earthen_power();
+ 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();
new spell_sha_item_lightning_shield();
new spell_sha_item_lightning_shield_trigger();
new spell_sha_item_mana_surge();
new spell_sha_lava_lash();
- new spell_sha_mana_spring_totem();
+ new spell_sha_lava_surge();
+ new spell_sha_lava_surge_proc();
new spell_sha_mana_tide_totem();
- new spell_sha_sentry_totem();
+ new spell_sha_nature_guardian();
+ new spell_sha_rolling_thunder();
+ new spell_sha_telluric_currents();
new spell_sha_thunderstorm();
+ new spell_sha_tidal_waves();
}
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 36e63b5a94e..9a374764949 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -25,33 +25,55 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
+#include "SpellAuras.h"
enum WarlockSpells
{
+ SPELL_WARLOCK_AFTERMATH_STUN = 85387,
+ SPELL_WARLOCK_BANE_OF_DOOM_EFFECT = 18662,
+ SPELL_WARLOCK_CREATE_HEALTHSTONE = 34130,
SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT = 18662,
+ SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388,
SPELL_WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018,
SPELL_WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020,
- SPELL_WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388,
- SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435,
- SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443,
SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELGUARD = 54508,
SPELL_WARLOCK_DEMONIC_EMPOWERMENT_FELHUNTER = 54509,
SPELL_WARLOCK_DEMONIC_EMPOWERMENT_IMP = 54444,
+ SPELL_WARLOCK_DEMONIC_EMPOWERMENT_SUCCUBUS = 54435,
+ SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER = 54443,
+ SPELL_WARLOCK_DEMON_SOUL_IMP = 79459,
+ SPELL_WARLOCK_DEMON_SOUL_FELHUNTER = 79460,
+ SPELL_WARLOCK_DEMON_SOUL_FELGUARD = 79452,
+ SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS = 79453,
+ SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER = 79454,
SPELL_WARLOCK_FEL_SYNERGY_HEAL = 54181,
SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME = 63311,
SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE = 63106,
+ SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP = 56226,
+ SPELL_WARLOCK_GLYPH_OF_SUCCUBUS = 56250,
SPELL_WARLOCK_HAUNT = 48181,
SPELL_WARLOCK_HAUNT_HEAL = 48210,
- SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1 = 18692,
- SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2 = 18693,
- SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703,
- SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704,
+ SPELL_WARLOCK_IMMOLATE = 348,
SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R1 = 60955,
SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2 = 60956,
+ SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R1 = 18703,
+ SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_R2 = 18704,
+ SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT = 85383,
+ SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE = 85385,
SPELL_WARLOCK_LIFE_TAP_ENERGIZE = 31818,
SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2 = 32553,
- SPELL_WARLOCK_SOULSHATTER = 32835,
+ SPELL_WARLOCK_NETHER_WARD = 91711,
+ SPELL_WARLOCK_NETHER_TALENT = 91713,
+ SPELL_WARLOCK_RAIN_OF_FIRE = 42223,
+ SPELL_WARLOCK_SHADOW_TRANCE = 17941,
SPELL_WARLOCK_SIPHON_LIFE_HEAL = 63106,
+ SPELL_WARLOCK_SHADOW_WARD = 6229,
+ SPELL_WARLOCK_SOULSHATTER = 32835,
+ SPELL_WARLOCK_SOUL_SWAP_CD_MARKER = 94229,
+ SPELL_WARLOCK_SOUL_SWAP_OVERRIDE = 86211,
+ SPELL_WARLOCK_SOUL_SWAP_MOD_COST = 92794,
+ SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER = 92795,
+ SPELL_WARLOCK_UNSTABLE_AFFLICTION = 30108,
SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117
};
@@ -61,7 +83,53 @@ enum WarlockSpellIcons
WARLOCK_ICON_ID_MANA_FEED = 1982
};
-// -710 - Banish
+enum MiscSpells
+{
+ SPELL_GEN_REPLENISHMENT = 57669,
+ SPELL_PRIEST_SHADOW_WORD_DEATH = 32409
+};
+
+// -85113 - Aftermath
+class spell_warl_aftermath : public SpellScriptLoader
+{
+ public:
+ spell_warl_aftermath() : SpellScriptLoader("spell_warl_aftermath") { }
+
+ class spell_warl_aftermath_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_aftermath_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_AFTERMATH_STUN))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ {
+ if (eventInfo.GetDamageInfo()->GetSpellInfo()->Id == SPELL_WARLOCK_RAIN_OF_FIRE)
+ {
+ PreventDefaultAction();
+
+ if (eventInfo.GetProcTarget() && roll_chance_i(aurEff->GetAmount()))
+ GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARLOCK_AFTERMATH_STUN, true, NULL, aurEff);
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_warl_aftermath_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warl_aftermath_AuraScript();
+ }
+};
+
+// 710 - Banish
class spell_warl_banish : public SpellScriptLoader
{
public:
@@ -79,6 +147,8 @@ class spell_warl_banish : public SpellScriptLoader
void HandleBanish()
{
+ /// Casting Banish on a banished target will cancel the effect
+ /// Check if the target already has Banish, if so, do nothing.
if (Unit* target = GetHitUnit())
{
if (target->GetAuraEffect(SPELL_AURA_SCHOOL_IMMUNITY, SPELLFAMILY_WARLOCK, 0, 0x08000000, 0))
@@ -113,7 +183,42 @@ class spell_warl_banish : public SpellScriptLoader
}
};
-// 6201 - Create Healthstone (and ranks)
+// 17962 - Conflagrate - Updated to 4.3.4
+class spell_warl_conflagrate : public SpellScriptLoader
+{
+ public:
+ spell_warl_conflagrate() : SpellScriptLoader("spell_warl_conflagrate") { }
+
+ class spell_warl_conflagrate_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_conflagrate_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMMOLATE))
+ return false;
+ 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())));
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warl_conflagrate_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_conflagrate_SpellScript();
+ }
+};
+
+// 6201 - Create Healthstone
class spell_warl_create_healthstone : public SpellScriptLoader
{
public:
@@ -123,59 +228,26 @@ class spell_warl_create_healthstone : public SpellScriptLoader
{
PrepareSpellScript(spell_warl_create_healthstone_SpellScript);
- static uint32 const iTypes[8][3];
-
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1) || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_CREATE_HEALTHSTONE))
return false;
return true;
}
- SpellCastResult CheckCast()
+ bool Load() OVERRIDE
{
- if (Player* caster = GetCaster()->ToPlayer())
- {
- uint8 spellRank = GetSpellInfo()->GetRank();
- ItemPosCountVec dest;
- InventoryResult msg = caster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, iTypes[spellRank - 1][0], 1, NULL);
- if (msg != EQUIP_ERR_OK)
- return SPELL_FAILED_TOO_MANY_OF_ITEM;
- }
- return SPELL_CAST_OK;
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- void HandleScriptEffect(SpellEffIndex effIndex)
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- if (Unit* unitTarget = GetHitUnit())
- {
- uint32 rank = 0;
- // Improved Healthstone
- if (AuraEffect const* aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 284, 0))
- {
- switch (aurEff->GetId())
- {
- case SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R1:
- rank = 1;
- break;
- case SPELL_WARLOCK_IMPROVED_HEALTHSTONE_R2:
- rank = 2;
- break;
- default:
- TC_LOG_ERROR("spells", "Unknown rank of Improved Healthstone id: %d", aurEff->GetId());
- break;
- }
- }
- uint8 spellRank = GetSpellInfo()->GetRank();
- if (spellRank > 0 && spellRank <= 8)
- CreateItem(effIndex, iTypes[spellRank - 1][rank]);
- }
+ GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_CREATE_HEALTHSTONE, true);
}
void Register() OVERRIDE
{
OnEffectHitTarget += SpellEffectFn(spell_warl_create_healthstone_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- OnCheckCast += SpellCheckCastFn(spell_warl_create_healthstone_SpellScript::CheckCast);
}
};
@@ -185,22 +257,12 @@ class spell_warl_create_healthstone : public SpellScriptLoader
}
};
-uint32 const spell_warl_create_healthstone::spell_warl_create_healthstone_SpellScript::iTypes[8][3] = {
- { 5512, 19004, 19005}, // Minor Healthstone
- { 5511, 19006, 19007}, // Lesser Healthstone
- { 5509, 19008, 19009}, // Healthstone
- { 5510, 19010, 19011}, // Greater Healthstone
- { 9421, 19012, 19013}, // Major Healthstone
- {22103, 22104, 22105}, // Master Healthstone
- {36889, 36890, 36891}, // Demonic Healthstone
- {36892, 36893, 36894} // Fel Healthstone
-};
-
-// -603 - Curse of Doom
-class spell_warl_curse_of_doom : public SpellScriptLoader
+// 603 - Bane of Doom
+/// Updated 4.3.4
+class spell_warl_bane_of_doom : public SpellScriptLoader
{
public:
- spell_warl_curse_of_doom() : SpellScriptLoader("spell_warl_curse_of_doom") { }
+ spell_warl_bane_of_doom() : SpellScriptLoader("spell_warl_bane_of_doom") { }
class spell_warl_curse_of_doom_AuraScript : public AuraScript
{
@@ -208,7 +270,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_BANE_OF_DOOM_EFFECT))
return false;
return true;
}
@@ -228,7 +290,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader
return;
if (GetCaster()->ToPlayer()->isHonorOrXPTarget(GetTarget()))
- GetCaster()->CastSpell(GetTarget(), SPELL_WARLOCK_CURSE_OF_DOOM_EFFECT, true, NULL, aurEff);
+ GetCaster()->CastSpell(GetTarget(), SPELL_WARLOCK_BANE_OF_DOOM_EFFECT, true, NULL, aurEff);
}
void Register() OVERRIDE
@@ -244,6 +306,7 @@ class spell_warl_curse_of_doom : public SpellScriptLoader
};
// 48018 - Demonic Circle: Summon
+/// Updated 4.3.4
class spell_warl_demonic_circle_summon : public SpellScriptLoader
{
public:
@@ -296,6 +359,7 @@ class spell_warl_demonic_circle_summon : public SpellScriptLoader
};
// 48020 - Demonic Circle: Teleport
+/// Updated 4.3.4
class spell_warl_demonic_circle_teleport : public SpellScriptLoader
{
public:
@@ -329,7 +393,75 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader
}
};
+// 77801 - Demon Soul - Updated to 4.3.4
+class spell_warl_demon_soul : public SpellScriptLoader
+{
+ public:
+ spell_warl_demon_soul() : SpellScriptLoader("spell_warl_demon_soul") { }
+
+ class spell_warl_demon_soul_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_demon_soul_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_IMP))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELHUNTER))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_FELGUARD))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER))
+ return false;
+ return true;
+ }
+
+ void OnHitTarget(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ if (Creature* targetCreature = GetHitCreature())
+ {
+ if (targetCreature->IsPet())
+ {
+ CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(targetCreature->GetEntry());
+ switch (ci->family)
+ {
+ case CREATURE_FAMILY_SUCCUBUS:
+ caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_SUCCUBUS);
+ break;
+ case CREATURE_FAMILY_VOIDWALKER:
+ caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_VOIDWALKER);
+ break;
+ case CREATURE_FAMILY_FELGUARD:
+ caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELGUARD);
+ break;
+ case CREATURE_FAMILY_FELHUNTER:
+ caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_FELHUNTER);
+ break;
+ case CREATURE_FAMILY_IMP:
+ caster->CastSpell(caster, SPELL_WARLOCK_DEMON_SOUL_IMP);
+ break;
+ }
+ }
+ }
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warl_demon_soul_SpellScript::OnHitTarget, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_demon_soul_SpellScript;
+ }
+};
+
// 47193 - Demonic Empowerment
+/// Updated 4.3.4
class spell_warl_demonic_empowerment : public SpellScriptLoader
{
public:
@@ -363,7 +495,6 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER);
int32 hp = int32(targetCreature->CountPctFromMaxHealth(GetCaster()->CalculateSpellDamage(targetCreature, spellInfo, 0)));
targetCreature->CastCustomSpell(targetCreature, SPELL_WARLOCK_DEMONIC_EMPOWERMENT_VOIDWALKER, &hp, NULL, NULL, true);
- //unitTarget->CastSpell(unitTarget, 54441, true);
break;
}
case CREATURE_FAMILY_FELGUARD:
@@ -393,6 +524,7 @@ class spell_warl_demonic_empowerment : public SpellScriptLoader
};
// 47422 - Everlasting Affliction
+/// Updated 4.3.4
class spell_warl_everlasting_affliction : public SpellScriptLoader
{
public:
@@ -406,8 +538,8 @@ class spell_warl_everlasting_affliction : public SpellScriptLoader
{
if (Unit* unitTarget = GetHitUnit())
// Refresh corruption on target
- if (AuraEffect* aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID()))
- aur->GetBase()->RefreshDuration();
+ if (AuraEffect* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, GetCaster()->GetGUID()))
+ aurEff->GetBase()->RefreshDuration();
}
void Register() OVERRIDE
@@ -422,6 +554,43 @@ 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
{
@@ -482,7 +651,7 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader
return true;
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
PreventDefaultAction();
GetTarget()->CastSpell(eventInfo.GetProcTarget(), SPELL_WARLOCK_GLYPH_OF_SHADOWFLAME, true, NULL, aurEff);
@@ -490,7 +659,7 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader
void Register() OVERRIDE
{
- OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_shadowflame_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectProc += AuraEffectProcFn(spell_warl_glyph_of_shadowflame_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
}
};
@@ -500,7 +669,8 @@ class spell_warl_glyph_of_shadowflame : public SpellScriptLoader
}
};
-// -48181 - Haunt
+// 48181 - Haunt
+/// Updated 4.3.4
class spell_warl_haunt : public SpellScriptLoader
{
public:
@@ -560,7 +730,8 @@ class spell_warl_haunt : public SpellScriptLoader
}
};
-// -755 - Health Funnel
+// 755 - Health Funnel
+/// Updated 4.3.4
class spell_warl_health_funnel : public SpellScriptLoader
{
public:
@@ -590,10 +761,28 @@ class spell_warl_health_funnel : public SpellScriptLoader
target->RemoveAurasDueToSpell(SPELL_WARLOCK_IMPROVED_HEALTH_FUNNEL_BUFF_R2);
}
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+ //! HACK for self damage, is not blizz :/
+ uint32 damage = caster->CountPctFromMaxHealth(aurEff->GetBaseAmount());
+
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_COST, damage);
+
+ SpellNonMeleeDamage damageInfo(caster, caster, GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);
+ damageInfo.damage = damage;
+ caster->SendSpellNonMeleeDamageLog(&damageInfo);
+ caster->DealSpellDamage(&damageInfo, false);
+ }
+
void Register() OVERRIDE
{
- OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL);
- OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL);
+ OnEffectApply += AuraEffectApplyFn(spell_warl_health_funnel_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_warl_health_funnel_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH, AURA_EFFECT_HANDLE_REAL);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_warl_health_funnel_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_OBS_MOD_HEALTH);
}
};
@@ -603,7 +792,73 @@ class spell_warl_health_funnel : public SpellScriptLoader
}
};
-// -1454 - Life Tap
+// 6262 - Healthstone
+class spell_warl_healthstone_heal : public SpellScriptLoader
+{
+ public:
+ spell_warl_healthstone_heal() : SpellScriptLoader("spell_warl_healthstone_heal") { }
+
+ class spell_warl_healthstone_heal_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_healthstone_heal_SpellScript);
+
+ void HandleOnHit()
+ {
+ int32 heal = int32(CalculatePct(GetCaster()->GetCreateHealth(), GetHitHeal()));
+ SetHitHeal(heal);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnHit += SpellHitFn(spell_warl_healthstone_heal_SpellScript::HandleOnHit);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_healthstone_heal_SpellScript();
+ }
+};
+
+// -18119 - Improved Soul Fire
+class spell_warl_improved_soul_fire : public SpellScriptLoader
+{
+ public:
+ spell_warl_improved_soul_fire() : SpellScriptLoader("spell_warl_improved_soul_fire") { }
+
+ class spell_warl_improved_soul_fire_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_improved_soul_fire_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE))
+ return false;
+ return true;
+ }
+
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastCustomSpell(SPELL_WARLOCK_IMPROVED_SOUL_FIRE_PCT, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetTarget(), true, NULL, aurEff);
+ GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_IMPROVED_SOUL_FIRE_STATE, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_warl_improved_soul_fire_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warl_improved_soul_fire_AuraScript();
+ }
+};
+
+// 1454 - Life Tap
+/// Updated 4.3.4
class spell_warl_life_tap : public SpellScriptLoader
{
public:
@@ -618,9 +873,10 @@ class spell_warl_life_tap : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- bool Validate(SpellInfo const* /*spell*/) OVERRIDE
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE) || !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2))
return false;
return true;
}
@@ -630,8 +886,8 @@ class spell_warl_life_tap : public SpellScriptLoader
Player* caster = GetCaster()->ToPlayer();
if (Unit* target = GetHitUnit())
{
- int32 damage = GetEffectValue();
- int32 mana = int32(damage + (caster->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+SPELL_SCHOOL_SHADOW) * 0.5f));
+ int32 damage = caster->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue());
+ int32 mana = CalculatePct(damage, GetSpellInfo()->Effects[EFFECT_1].CalcValue());
// Shouldn't Appear in Combat Log
target->ModifyHealth(-damage);
@@ -643,12 +899,9 @@ class spell_warl_life_tap : public SpellScriptLoader
caster->CastCustomSpell(target, SPELL_WARLOCK_LIFE_TAP_ENERGIZE, &mana, NULL, NULL, false);
// Mana Feed
- int32 manaFeedVal = 0;
if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, WARLOCK_ICON_ID_MANA_FEED, 0))
- manaFeedVal = aurEff->GetAmount();
-
- if (manaFeedVal > 0)
{
+ int32 manaFeedVal = aurEff->GetAmount();
ApplyPct(manaFeedVal, mana);
caster->CastCustomSpell(caster, SPELL_WARLOCK_LIFE_TAP_ENERGIZE_2, &manaFeedVal, NULL, NULL, true, NULL);
}
@@ -657,7 +910,7 @@ class spell_warl_life_tap : public SpellScriptLoader
SpellCastResult CheckCast()
{
- if ((int32(GetCaster()->GetHealth()) > int32(GetSpellInfo()->Effects[EFFECT_0].CalcValue() + (6.3875 * GetSpellInfo()->BaseLevel))))
+ if (int32(GetCaster()->GetHealth()) > int32(GetCaster()->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue())))
return SPELL_CAST_OK;
return SPELL_FAILED_FIZZLE;
}
@@ -675,35 +928,92 @@ class spell_warl_life_tap : public SpellScriptLoader
}
};
-// 18541 - Ritual of Doom Effect
-class spell_warl_ritual_of_doom_effect : public SpellScriptLoader
+// 687 - Demon Armor
+// 28176 - Fel Armor
+class spell_warl_nether_ward_overrride : public SpellScriptLoader
{
public:
- spell_warl_ritual_of_doom_effect() : SpellScriptLoader("spell_warl_ritual_of_doom_effect") { }
+ spell_warl_nether_ward_overrride() : SpellScriptLoader("spell_warl_nether_ward_overrride") { }
- class spell_warl_ritual_of_doom_effect_SpellScript : public SpellScript
+ class spell_warl_nether_ward_overrride_AuraScript : public AuraScript
{
- PrepareSpellScript(spell_warl_ritual_of_doom_effect_SpellScript);
+ PrepareAuraScript(spell_warl_nether_ward_overrride_AuraScript);
- void HandleDummy(SpellEffIndex /*effIndex*/)
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_TALENT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_NETHER_WARD) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SHADOW_WARD))
+ return false;
+ return true;
+ }
+
+ void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (GetUnitOwner()->HasAura(SPELL_WARLOCK_NETHER_TALENT))
+ amount = SPELL_WARLOCK_NETHER_WARD;
+ else
+ amount = SPELL_WARLOCK_SHADOW_WARD;
+ }
+
+ void Register() OVERRIDE
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_nether_ward_overrride_AuraScript::CalculateAmount, EFFECT_2, SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warl_nether_ward_overrride_AuraScript();
+ }
+};
+
+// 6358 - Seduction (Special Ability)
+class spell_warl_seduction : public SpellScriptLoader
+{
+ public:
+ spell_warl_seduction() : SpellScriptLoader("spell_warl_seduction") { }
+
+ class spell_warl_seduction_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_seduction_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SUCCUBUS) ||
+ !sSpellMgr->GetSpellInfo(SPELL_PRIEST_SHADOW_WORD_DEATH))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
- caster->CastSpell(caster, GetEffectValue(), true);
+ if (Unit* target = GetHitUnit())
+ {
+ if (caster->GetOwner() && caster->GetOwner()->HasAura(SPELL_WARLOCK_GLYPH_OF_SUCCUBUS))
+ {
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE, 0, target->GetAura(SPELL_PRIEST_SHADOW_WORD_DEATH)); // SW:D shall not be removed.
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
+ target->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
+ }
+ }
}
void Register() OVERRIDE
{
- OnEffectHit += SpellEffectFn(spell_warl_ritual_of_doom_effect_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_warl_seduction_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
SpellScript* GetSpellScript() const OVERRIDE
{
- return new spell_warl_ritual_of_doom_effect_SpellScript();
+ return new spell_warl_seduction_SpellScript();
}
};
-// -27285 - Seed of Corruption
+// 27285 - Seed of Corruption
+/// Updated 4.3.4
class spell_warl_seed_of_corruption : public SpellScriptLoader
{
public:
@@ -731,6 +1041,42 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader
}
};
+// -18094 - Nightfall
+// 56218 - Glyph of Corruption
+class spell_warl_shadow_trance_proc : public SpellScriptLoader
+{
+ public:
+ spell_warl_shadow_trance_proc() : SpellScriptLoader("spell_warl_shadow_trance_proc") { }
+
+ class spell_warl_shadow_trance_proc_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_shadow_trance_proc_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SHADOW_TRANCE))
+ return false;
+ return true;
+ }
+
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), SPELL_WARLOCK_SHADOW_TRANCE, true, NULL, aurEff);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_warl_shadow_trance_proc_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warl_shadow_trance_proc_AuraScript();
+ }
+};
+
// -7235 - Shadow Ward
class spell_warl_shadow_ward : public SpellScriptLoader
{
@@ -768,56 +1114,246 @@ class spell_warl_shadow_ward : public SpellScriptLoader
}
};
-// 63108 - Siphon Life
-class spell_warl_siphon_life : public SpellScriptLoader
+// -30293 - Soul Leech
+class spell_warl_soul_leech : public SpellScriptLoader
{
public:
- spell_warl_siphon_life() : SpellScriptLoader("spell_warl_siphon_life") { }
+ spell_warl_soul_leech() : SpellScriptLoader("spell_warl_soul_leech") { }
- class spell_warl_siphon_life_AuraScript : public AuraScript
+ class spell_warl_soul_leech_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_warl_siphon_life_AuraScript);
+ PrepareAuraScript(spell_warl_soul_leech_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SIPHON_LIFE_HEAL))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE))
+ if (!sSpellMgr->GetSpellInfo(SPELL_GEN_REPLENISHMENT))
return false;
return true;
}
- bool CheckProc(ProcEventInfo& eventInfo)
+ void OnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
{
- return eventInfo.GetDamageInfo()->GetDamage() && GetTarget()->IsAlive();
+ GetTarget()->CastSpell((Unit*)NULL, SPELL_GEN_REPLENISHMENT, true, NULL, aurEff);
}
- void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
+ void Register() OVERRIDE
{
- PreventDefaultAction();
+ OnEffectProc += AuraEffectProcFn(spell_warl_soul_leech_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE);
+ }
+ };
- int32 amount = int32(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount()));
- // Glyph of Siphon Life
- if (AuraEffect const* glyph = GetTarget()->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_SIPHON_LIFE, EFFECT_0))
- AddPct(amount, glyph->GetAmount());
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warl_soul_leech_AuraScript();
+ }
+};
+
+// 86121 - Soul Swap
+class spell_warl_soul_swap : public SpellScriptLoader
+{
+ public:
+ spell_warl_soul_swap() : SpellScriptLoader("spell_warl_soul_swap") { }
+
+ class spell_warl_soul_swap_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_soul_swap_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_CD_MARKER) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
+ return false;
+ return true;
+ }
- GetTarget()->CastCustomSpell(SPELL_WARLOCK_SIPHON_LIFE_HEAL, SPELLVALUE_BASE_POINT0, amount, GetTarget(), true, NULL, aurEff);
+ void HandleHit(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_OVERRIDE, true);
+ GetHitUnit()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_DOT_MARKER, true);
}
void Register() OVERRIDE
{
- DoCheckProc += AuraCheckProcFn(spell_warl_siphon_life_AuraScript::CheckProc);
- OnEffectProc += AuraEffectProcFn(spell_warl_siphon_life_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_soul_swap_SpellScript();
+ }
+};
+
+// 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") { }
+
+ 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 { }
+
+ public:
+ void AddDot(uint32 id) { _dotList.push_back(id); }
+ std::list<uint32> const GetDotList() const { return _dotList; }
+ Unit* GetOriginalSwapSource() const { return _swapCaster; }
+ void SetOriginalSwapSource(Unit* victim) { _swapCaster = victim; }
+
+ private:
+ std::list<uint32> _dotList;
+ Unit* _swapCaster;
+ };
+
AuraScript* GetAuraScript() const OVERRIDE
{
- return new spell_warl_siphon_life_AuraScript();
+ return new spell_warl_soul_swap_override_AuraScript();
}
};
+typedef spell_warl_soul_swap_override::spell_warl_soul_swap_override_AuraScript SoulSwapOverrideAuraScript;
+
+//! Soul Swap Copy Spells - 92795 - Simply copies spell IDs.
+class spell_warl_soul_swap_dot_marker : public SpellScriptLoader
+{
+ public:
+ spell_warl_soul_swap_dot_marker() : SpellScriptLoader("spell_warl_soul_swap_dot_marker") { }
+
+ class spell_warl_soul_swap_dot_marker_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_soul_swap_dot_marker_SpellScript);
+
+ void HandleHit(SpellEffIndex effIndex)
+ {
+ Unit* swapVictim = GetCaster();
+ Unit* warlock = GetHitUnit();
+ if (!warlock || !swapVictim)
+ return;
+
+ flag96 classMask = GetSpellInfo()->Effects[effIndex].SpellClassMask;
+
+ Unit::AuraApplicationMap const& appliedAuras = swapVictim->GetAppliedAuras();
+ SoulSwapOverrideAuraScript* swapSpellScript = NULL;
+ if (Aura* swapOverrideAura = warlock->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
+ swapSpellScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverrideAura->GetScriptByName("spell_warl_soul_swap_override"));
+
+ if (swapSpellScript == NULL)
+ return;
+
+ for (Unit::AuraApplicationMap::const_iterator itr = appliedAuras.begin(); itr != appliedAuras.end(); ++itr)
+ {
+ SpellInfo const* spellProto = itr->second->GetBase()->GetSpellInfo();
+ if (itr->second->GetBase()->GetCaster() == warlock)
+ if (spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellProto->SpellFamilyFlags & classMask))
+ swapSpellScript->AddDot(itr->first);
+ }
+
+ swapSpellScript->SetOriginalSwapSource(swapVictim);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_dot_marker_SpellScript::HandleHit, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_soul_swap_dot_marker_SpellScript();
+ }
+};
+
+// 86213 - Soul Swap Exhale
+class spell_warl_soul_swap_exhale : public SpellScriptLoader
+{
+public:
+ spell_warl_soul_swap_exhale() : SpellScriptLoader("spell_warl_soul_swap_exhale") { }
+
+ class spell_warl_soul_swap_exhale_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_soul_swap_exhale_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_MOD_COST) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ Unit* currentTarget = GetExplTargetUnit();
+ Unit* swapTarget = NULL;
+ if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
+ if (SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override")))
+ swapTarget = swapScript->GetOriginalSwapSource();
+
+ // Soul Swap Exhale can't be cast on the same target than Soul Swap
+ if (swapTarget && currentTarget && swapTarget == currentTarget)
+ return SPELL_FAILED_BAD_TARGETS;
+
+ return SPELL_CAST_OK;
+ }
+
+ void OnEffectHit(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_MOD_COST, true);
+ bool hasGlyph = GetCaster()->HasAura(SPELL_WARLOCK_GLYPH_OF_SOUL_SWAP);
+
+ std::list<uint32> dotList;
+ Unit* swapSource = NULL;
+ if (Aura const* swapOverride = GetCaster()->GetAura(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE))
+ {
+ SoulSwapOverrideAuraScript* swapScript = dynamic_cast<SoulSwapOverrideAuraScript*>(swapOverride->GetScriptByName("spell_warl_soul_swap_override"));
+ if (!swapScript)
+ return;
+ dotList = swapScript->GetDotList();
+ swapSource = swapScript->GetOriginalSwapSource();
+ }
+
+ if (dotList.empty())
+ return;
+
+ for (std::list<uint32>::const_iterator itr = dotList.begin(); itr != dotList.end(); ++itr)
+ {
+ GetCaster()->AddAura(*itr, GetHitUnit());
+ if (!hasGlyph && swapSource)
+ swapSource->RemoveAurasDueToSpell(*itr);
+ }
+
+ // Remove Soul Swap Exhale buff
+ GetCaster()->RemoveAurasDueToSpell(SPELL_WARLOCK_SOUL_SWAP_OVERRIDE);
+
+ if (hasGlyph) // Add a cooldown on Soul Swap if caster has the glyph
+ GetCaster()->CastSpell(GetCaster(), SPELL_WARLOCK_SOUL_SWAP_CD_MARKER, false);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnCheckCast += SpellCheckCastFn(spell_warl_soul_swap_exhale_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_warl_soul_swap_exhale_SpellScript::OnEffectHit, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warl_soul_swap_exhale_SpellScript();
+ }
+};
+
// 29858 - Soulshatter
+/// Updated 4.3.4
class spell_warl_soulshatter : public SpellScriptLoader
{
public:
@@ -838,10 +1374,8 @@ class spell_warl_soulshatter : public SpellScriptLoader
{
Unit* caster = GetCaster();
if (Unit* target = GetHitUnit())
- {
if (target->CanHaveThreatList() && target->getThreatManager().getThreat(caster) > 0.0f)
caster->CastSpell(target, SPELL_WARLOCK_SOULSHATTER, true);
- }
}
void Register() OVERRIDE
@@ -856,7 +1390,8 @@ class spell_warl_soulshatter : public SpellScriptLoader
}
};
-// -30108 - Unstable Affliction
+// 30108, 34438, 34439, 35183 - Unstable Affliction
+/// Updated 4.3.4
class spell_warl_unstable_affliction : public SpellScriptLoader
{
public:
@@ -876,7 +1411,7 @@ class spell_warl_unstable_affliction : public SpellScriptLoader
void HandleDispel(DispelInfo* dispelInfo)
{
if (Unit* caster = GetCaster())
- if (AuraEffect const* aurEff = GetEffect(EFFECT_0))
+ if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
{
int32 damage = aurEff->GetAmount() * 9;
// backfire damage and silence
@@ -898,22 +1433,34 @@ class spell_warl_unstable_affliction : public SpellScriptLoader
void AddSC_warlock_spell_scripts()
{
+ new spell_warl_aftermath();
+ new spell_warl_bane_of_doom();
new spell_warl_banish();
+ new spell_warl_conflagrate();
new spell_warl_create_healthstone();
- new spell_warl_curse_of_doom();
new spell_warl_demonic_circle_summon();
new spell_warl_demonic_circle_teleport();
new spell_warl_demonic_empowerment();
+ new spell_warl_demon_soul();
new spell_warl_everlasting_affliction();
+ 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_ritual_of_doom_effect();
+ new spell_warl_nether_ward_overrride();
+ new spell_warl_seduction();
new spell_warl_seed_of_corruption();
+ new spell_warl_shadow_trance_proc();
new spell_warl_shadow_ward();
- new spell_warl_siphon_life();
+ new spell_warl_soul_leech();
+ new spell_warl_soul_swap();
+ new spell_warl_soul_swap_dot_marker();
+ new spell_warl_soul_swap_exhale();
+ new spell_warl_soul_swap_override();
new spell_warl_soulshatter();
new spell_warl_unstable_affliction();
}
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 5a655a92996..3a8af5f0e17 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -31,19 +31,26 @@ enum WarriorSpells
SPELL_WARRIOR_BLOODTHIRST = 23885,
SPELL_WARRIOR_BLOODTHIRST_DAMAGE = 23881,
SPELL_WARRIOR_CHARGE = 34846,
- SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE = 59653,
+ SPELL_WARRIOR_COLOSSUS_SMASH = 86346,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_1 = 12162,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_2 = 12850,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_3 = 12868,
SPELL_WARRIOR_DEEP_WOUNDS_RANK_PERIODIC = 12721,
SPELL_WARRIOR_EXECUTE = 20647,
SPELL_WARRIOR_GLYPH_OF_EXECUTION = 58367,
- SPELL_WARRIOR_GLYPH_OF_VIGILANCE = 63326,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF = 65156,
SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT = 64976,
SPELL_WARRIOR_LAST_STAND_TRIGGERED = 12976,
+ SPELL_WARRIOR_MORTAL_STRIKE = 12294,
+ SPELL_WARRIOR_RALLYING_CRY = 97463,
+ SPELL_WARRIOR_REND = 94009,
SPELL_WARRIOR_RETALIATION_DAMAGE = 22858,
- SPELL_WARRIOR_SLAM = 50783,
+ SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1 = 29834,
+ SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2 = 29838,
+ SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1 = 29841,
+ SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2 = 29842,
+ SPELL_WARRIOR_SHIELD_SLAM = 23922,
+ SPELL_WARRIOR_SLAM = 50782,
SPELL_WARRIOR_SUNDER_ARMOR = 58567,
SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK = 26654,
SPELL_WARRIOR_TAUNT = 355,
@@ -52,7 +59,7 @@ enum WarriorSpells
SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_1 = 64849,
SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850,
SPELL_WARRIOR_VIGILANCE_PROC = 50725,
- SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665
+ SPELL_WARRIOR_VENGEANCE = 76691
};
enum WarriorSpellIcons
@@ -60,15 +67,15 @@ enum WarriorSpellIcons
WARRIOR_ICON_ID_SUDDEN_DEATH = 1989
};
+
enum MiscSpells
{
SPELL_PALADIN_BLESSING_OF_SANCTUARY = 20911,
SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY = 25899,
- SPELL_PRIEST_RENEWED_HOPE = 63944,
- SPELL_GEN_DAMAGE_REDUCTION_AURA = 68066,
+ SPELL_PRIEST_RENEWED_HOPE = 63944
};
-// 23881 - Bloodthirst
+/// Updated 4.3.4
class spell_warr_bloodthirst : public SpellScriptLoader
{
public:
@@ -110,7 +117,7 @@ class spell_warr_bloodthirst : public SpellScriptLoader
}
};
-// 23880 - Bloodthirst (Heal)
+/// Updated 4.3.4
class spell_warr_bloodthirst_heal : public SpellScriptLoader
{
public:
@@ -123,7 +130,7 @@ class spell_warr_bloodthirst_heal : public SpellScriptLoader
void HandleHeal(SpellEffIndex /*effIndex*/)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_WARRIOR_BLOODTHIRST_DAMAGE))
- SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())));
+ SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())) / 100);
}
void Register() OVERRIDE
@@ -138,7 +145,7 @@ class spell_warr_bloodthirst_heal : public SpellScriptLoader
}
};
-// -100 - Charge
+/// Updated 4.3.4
class spell_warr_charge : public SpellScriptLoader
{
public:
@@ -150,7 +157,9 @@ class spell_warr_charge : public SpellScriptLoader
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_TALENT) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_JUGGERNAUT_CRIT_BONUS_BUFF) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_CHARGE))
return false;
return true;
}
@@ -178,7 +187,7 @@ class spell_warr_charge : public SpellScriptLoader
}
};
-// 12809 - Concussion Blow
+/// Updated 4.3.4
class spell_warr_concussion_blow : public SpellScriptLoader
{
public:
@@ -205,44 +214,6 @@ class spell_warr_concussion_blow : public SpellScriptLoader
}
};
-// -58872 - Damage Shield
-class spell_warr_damage_shield : public SpellScriptLoader
-{
- public:
- spell_warr_damage_shield() : SpellScriptLoader("spell_warr_damage_shield") { }
-
- class spell_warr_damage_shield_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_warr_damage_shield_AuraScript);
-
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE))
- return false;
- return true;
- }
-
- void OnProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
- {
- PreventDefaultAction();
-
- // % of amount blocked
- int32 damage = CalculatePct(int32(GetTarget()->GetShieldBlockValue()), aurEff->GetAmount());
- GetTarget()->CastCustomSpell(SPELL_WARRIOR_DAMAGE_SHIELD_DAMAGE, SPELLVALUE_BASE_POINT0, damage, eventInfo.GetProcTarget(), true, NULL, aurEff);
- }
-
- void Register() OVERRIDE
- {
- OnEffectProc += AuraEffectProcFn(spell_warr_damage_shield_AuraScript::OnProc, EFFECT_0, SPELL_AURA_DUMMY);
- }
- };
-
- AuraScript* GetAuraScript() const OVERRIDE
- {
- return new spell_warr_damage_shield_AuraScript();
- }
-};
-
// -12162 - Deep Wounds
class spell_warr_deep_wounds : public SpellScriptLoader
{
@@ -255,7 +226,10 @@ class spell_warr_deep_wounds : public SpellScriptLoader
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))
+ 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_RANK_PERIODIC))
return false;
return true;
}
@@ -298,7 +272,7 @@ class spell_warr_deep_wounds : public SpellScriptLoader
}
};
-// -5308 - Execute
+/// Updated 4.3.4
class spell_warr_execute : public SpellScriptLoader
{
public:
@@ -308,43 +282,35 @@ class spell_warr_execute : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_execute_SpellScript);
- bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_EXECUTE) || !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_EXECUTION))
- return false;
- return true;
- }
-
- void HandleEffect(SpellEffIndex effIndex)
+ void HandleEffect(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
- if (Unit* target = GetHitUnit())
+ if (GetHitUnit())
{
SpellInfo const* spellInfo = GetSpellInfo();
- int32 rageUsed = std::min<int32>(300 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE));
+ int32 rageUsed = std::min<int32>(200 - spellInfo->CalcPowerCost(caster, SpellSchoolMask(spellInfo->SchoolMask)), caster->GetPower(POWER_RAGE));
int32 newRage = std::max<int32>(0, caster->GetPower(POWER_RAGE) - rageUsed);
// Sudden Death rage save
if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_GENERIC, WARRIOR_ICON_ID_SUDDEN_DEATH, EFFECT_0))
{
- int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue() * 10;
+ int32 ragesave = aurEff->GetSpellInfo()->Effects[EFFECT_0].CalcValue() * 10;
newRage = std::max(newRage, ragesave);
}
caster->SetPower(POWER_RAGE, uint32(newRage));
- // Glyph of Execution bonus
- if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_EXECUTION, EFFECT_0))
- rageUsed += aurEff->GetAmount() * 10;
-
- int32 bp = GetEffectValue() + int32(rageUsed * spellInfo->Effects[effIndex].DamageMultiplier + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.2f);
- caster->CastCustomSpell(target, SPELL_WARRIOR_EXECUTE, &bp, NULL, NULL, true, NULL, NULL, GetOriginalCaster()->GetGUID());
+ /// Formula taken from the DBC: "${10+$AP*0.437*$m1/100}"
+ int32 baseDamage = int32(10 + caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.437f * GetEffectValue() / 100.0f);
+ /// 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
{
- OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_warr_execute_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
}
};
@@ -446,6 +412,44 @@ class spell_warr_intimidating_shout : public SpellScriptLoader
}
};
+// -84583 Lambs to the Slaughter
+class spell_warr_lambs_to_the_slaughter : public SpellScriptLoader
+{
+ public:
+ spell_warr_lambs_to_the_slaughter() : SpellScriptLoader("spell_warr_lambs_to_the_slaughter") { }
+
+ class spell_warr_lambs_to_the_slaughter_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_lambs_to_the_slaughter_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_MORTAL_STRIKE) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_REND))
+ return false;
+ return true;
+ }
+
+ void OnProc(AuraEffect const* /*aurEff*/, ProcEventInfo& eventInfo)
+ {
+ if (Aura* aur = eventInfo.GetProcTarget()->GetAura(SPELL_WARRIOR_REND, GetTarget()->GetGUID()))
+ aur->SetDuration(aur->GetSpellInfo()->GetMaxDuration(), true);
+
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectProc += AuraEffectProcFn(spell_warr_lambs_to_the_slaughter_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_lambs_to_the_slaughter_AuraScript();
+ }
+};
+
+/// Updated 4.3.4
// 12975 - Last Stand
class spell_warr_last_stand : public SpellScriptLoader
{
@@ -472,6 +476,7 @@ class spell_warr_last_stand : public SpellScriptLoader
void Register() OVERRIDE
{
+ // add dummy effect spell handler to Last Stand
OnEffectHit += SpellEffectFn(spell_warr_last_stand_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -482,7 +487,7 @@ class spell_warr_last_stand : public SpellScriptLoader
}
};
-// 7384, 7887, 11584, 11585 - Overpower
+// 7384 - Overpower
class spell_warr_overpower : public SpellScriptLoader
{
public:
@@ -520,7 +525,48 @@ class spell_warr_overpower : public SpellScriptLoader
}
};
-// -772 - Rend
+// 97462 - Rallying Cry
+class spell_warr_rallying_cry : public SpellScriptLoader
+{
+ public:
+ spell_warr_rallying_cry() : SpellScriptLoader("spell_warr_rallying_cry") { }
+
+ class spell_warr_rallying_cry_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warr_rallying_cry_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_RALLYING_CRY))
+ return false;
+ return true;
+ }
+
+ bool Load() OVERRIDE
+ {
+ return GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ int32 basePoints0 = int32(GetHitUnit()->CountPctFromMaxHealth(GetEffectValue()));
+
+ GetCaster()->CastCustomSpell(GetHitUnit(), SPELL_WARRIOR_RALLYING_CRY, &basePoints0, NULL, NULL, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warr_rallying_cry_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_warr_rallying_cry_SpellScript();
+ }
+};
+
+// 94009 - Rend
class spell_warr_rend : public SpellScriptLoader
{
public:
@@ -536,21 +582,13 @@ class spell_warr_rend : public SpellScriptLoader
{
canBeRecalculated = false;
- // $0.2 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick
+ // $0.25 * (($MWB + $mwb) / 2 + $AP / 14 * $MWS) bonus per tick
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
int32 mws = caster->GetAttackTime(BASE_ATTACK);
float mwbMin = caster->GetWeaponDamageRange(BASE_ATTACK, MINDAMAGE);
float mwbMax = caster->GetWeaponDamageRange(BASE_ATTACK, MAXDAMAGE);
- float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.2f;
+ float mwb = ((mwbMin + mwbMax) / 2 + ap * mws / 14000) * 0.25f;
amount += int32(caster->ApplyEffectModifiers(GetSpellInfo(), aurEff->GetEffIndex(), mwb));
-
- // "If used while your target is above 75% health, Rend does 35% more damage."
- // as for 3.1.3 only ranks above 9 (wrong tooltip?)
- if (GetSpellInfo()->GetRank() >= 9)
- {
- if (GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, GetSpellInfo(), caster))
- AddPct(amount, GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster));
- }
}
}
@@ -586,7 +624,7 @@ class spell_warr_retaliation : public SpellScriptLoader
bool CheckProc(ProcEventInfo& eventInfo)
{
// check attack comes not from behind and warrior is not stunned
- return GetTarget()->isInFront(eventInfo.GetActor(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED);
+ return GetTarget()->isInFront(eventInfo.GetProcTarget(), M_PI) && !GetTarget()->HasUnitState(UNIT_STATE_STUNNED);
}
void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
@@ -639,7 +677,7 @@ class spell_warr_shattering_throw : public SpellScriptLoader
}
};
-// -1464 - Slam
+/// Updated 4.3.4
class spell_warr_slam : public SpellScriptLoader
{
public:
@@ -674,6 +712,126 @@ class spell_warr_slam : public SpellScriptLoader
}
};
+class spell_warr_second_wind_proc : public SpellScriptLoader
+{
+ public:
+ spell_warr_second_wind_proc() : SpellScriptLoader("spell_warr_second_wind_proc") { }
+
+ class spell_warr_second_wind_proc_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_second_wind_proc_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1) ||
+ !sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2))
+ return false;
+ return true;
+ }
+
+ bool CheckProc(ProcEventInfo& eventInfo)
+ {
+ if (eventInfo.GetProcTarget() == GetTarget())
+ return false;
+ if (!eventInfo.GetDamageInfo()->GetSpellInfo() || !(eventInfo.GetDamageInfo()->GetSpellInfo()->GetAllEffectsMechanicMask() & ((1 << MECHANIC_ROOT) | (1 << MECHANIC_STUN))))
+ return false;
+ return true;
+ }
+
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ uint32 spellId = 0;
+
+ if (GetSpellInfo()->Id == SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_1)
+ spellId = SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_1;
+ else if (GetSpellInfo()->Id == SPELL_WARRIOR_SECOUND_WIND_PROC_RANK_2)
+ spellId = SPELL_WARRIOR_SECOUND_WIND_TRIGGER_RANK_2;
+ if (!spellId)
+ return;
+
+ GetTarget()->CastSpell(GetTarget(), spellId, true, NULL, aurEff);
+
+ }
+
+ void Register() OVERRIDE
+ {
+ DoCheckProc += AuraCheckProcFn(spell_warr_second_wind_proc_AuraScript::CheckProc);
+ OnEffectProc += AuraEffectProcFn(spell_warr_second_wind_proc_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_second_wind_proc_AuraScript();
+ }
+};
+
+class spell_warr_second_wind_trigger : public SpellScriptLoader
+{
+ public:
+ spell_warr_second_wind_trigger() : SpellScriptLoader("spell_warr_second_wind_trigger") { }
+
+ class spell_warr_second_wind_trigger_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_second_wind_trigger_AuraScript);
+
+ void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ amount = int32(GetUnitOwner()->CountPctFromMaxHealth(amount));
+ }
+
+ void Register() OVERRIDE
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warr_second_wind_trigger_AuraScript::CalculateAmount, EFFECT_1, SPELL_AURA_PERIODIC_HEAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_second_wind_trigger_AuraScript();
+ }
+};
+
+// 52437 - Sudden Death
+class spell_warr_sudden_death : public SpellScriptLoader
+{
+ public:
+ spell_warr_sudden_death() : SpellScriptLoader("spell_warr_sudden_death") { }
+
+ class spell_warr_sudden_death_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_sudden_death_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_COLOSSUS_SMASH))
+ return false;
+ return true;
+ }
+
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ // Remove cooldown on Colossus Smash
+ if (Player* player = GetTarget()->ToPlayer())
+ player->RemoveSpellCooldown(SPELL_WARRIOR_COLOSSUS_SMASH, true);
+ }
+
+ void Register() OVERRIDE
+ {
+ AfterEffectApply += AuraEffectRemoveFn(spell_warr_sudden_death_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL); // correct?
+ }
+ };
+
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_sudden_death_AuraScript();
+ }
+};
+
// 12328, 18765, 35429 - Sweeping Strikes
class spell_warr_sweeping_strikes : public SpellScriptLoader
{
@@ -725,88 +883,123 @@ class spell_warr_sweeping_strikes : public SpellScriptLoader
}
};
-// 50720 - Vigilance
-class spell_warr_vigilance : public SpellScriptLoader
+// -46951 - Sword and Board
+class spell_warr_sword_and_board : public SpellScriptLoader
{
public:
- spell_warr_vigilance() : SpellScriptLoader("spell_warr_vigilance") { }
+ spell_warr_sword_and_board() : SpellScriptLoader("spell_warr_sword_and_board") { }
- class spell_warr_vigilance_AuraScript : public AuraScript
+ class spell_warr_sword_and_board_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_warr_vigilance_AuraScript);
+ PrepareAuraScript(spell_warr_sword_and_board_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_GLYPH_OF_VIGILANCE))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_PROC))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT))
- return false;
- if (!sSpellMgr->GetSpellInfo(SPELL_GEN_DAMAGE_REDUCTION_AURA))
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_SHIELD_SLAM))
return false;
return true;
}
- bool Load() OVERRIDE
+ void OnProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
{
- _procTarget = NULL;
- return true;
+ // Remove cooldown on Shield Slam
+ if (Player* player = GetTarget()->ToPlayer())
+ player->RemoveSpellCooldown(SPELL_WARRIOR_SHIELD_SLAM, true);
}
- void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void Register() OVERRIDE
{
- Unit* target = GetTarget();
- target->CastSpell(target, SPELL_GEN_DAMAGE_REDUCTION_AURA, true);
+ OnEffectProc += AuraEffectProcFn(spell_warr_sword_and_board_AuraScript::OnProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ }
+ };
- if (Unit* caster = GetCaster())
- target->CastSpell(caster, SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT, true);
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_sword_and_board_AuraScript();
+ }
+};
+
+// 32216 - Victorious
+// 82368 - Victorious
+class spell_warr_victorious : public SpellScriptLoader
+{
+ public:
+ spell_warr_victorious() : SpellScriptLoader("spell_warr_victorious") { }
+
+ class spell_warr_victorious_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_victorious_AuraScript);
+
+ void HandleEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo& /*eventInfo*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->RemoveAura(GetId());
}
- void HandleAfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ void Register() OVERRIDE
{
- //! WORKAROUND
- //! this glyph is a proc
- if (Unit* caster = GetCaster())
- {
- if (AuraEffect const* glyph = caster->GetAuraEffect(SPELL_WARRIOR_GLYPH_OF_VIGILANCE, EFFECT_0))
- GetTarget()->ModifyRedirectThreat(glyph->GetAmount());
- }
+ OnEffectProc += AuraEffectProcFn(spell_warr_victorious_AuraScript::HandleEffectProc, EFFECT_0, SPELL_AURA_DUMMY);
}
+ };
- void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ AuraScript* GetAuraScript() const OVERRIDE
+ {
+ return new spell_warr_victorious_AuraScript();
+ }
+};
+
+// 50720 - Vigilance
+class spell_warr_vigilance : public SpellScriptLoader
+{
+ public:
+ spell_warr_vigilance() : SpellScriptLoader("spell_warr_vigilance") { }
+
+ class spell_warr_vigilance_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warr_vigilance_AuraScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- Unit* target = GetTarget();
- if (target->HasAura(SPELL_GEN_DAMAGE_REDUCTION_AURA) &&
- !(target->HasAura(SPELL_PALADIN_BLESSING_OF_SANCTUARY) ||
- target->HasAura(SPELL_PALADIN_GREATER_BLESSING_OF_SANCTUARY) ||
- target->HasAura(SPELL_PRIEST_RENEWED_HOPE)))
- {
- target->RemoveAurasDueToSpell(SPELL_GEN_DAMAGE_REDUCTION_AURA);
- }
+ if (!sSpellMgr->GetSpellInfo(SPELL_WARRIOR_VENGEANCE))
+ return false;
+ return true;
+ }
- target->ResetRedirectThreat();
+ bool Load() OVERRIDE
+ {
+ _procTarget = NULL;
+ return true;
}
- bool CheckProc(ProcEventInfo& /*eventInfo*/)
+ bool CheckProc(ProcEventInfo& eventInfo)
{
_procTarget = GetCaster();
- return _procTarget;
+ return _procTarget && eventInfo.GetDamageInfo();
}
- void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
+ void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
{
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);
+ }
+
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ if (caster->HasAura(SPELL_WARRIOR_VENGEANCE))
+ caster->RemoveAurasDueToSpell(SPELL_WARRIOR_VENGEANCE);
+ }
}
void Register() OVERRIDE
{
- OnEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- AfterEffectApply += AuraEffectApplyFn(spell_warr_vigilance_AuraScript::HandleAfterApply, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
- OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
DoCheckProc += AuraCheckProcFn(spell_warr_vigilance_AuraScript::CheckProc);
OnEffectProc += AuraEffectProcFn(spell_warr_vigilance_AuraScript::HandleProc, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_warr_vigilance_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PROC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
private:
@@ -819,7 +1012,7 @@ class spell_warr_vigilance : public SpellScriptLoader
}
};
-// 50725 - Vigilance
+// 50725 Vigilance
class spell_warr_vigilance_trigger : public SpellScriptLoader
{
public:
@@ -856,19 +1049,25 @@ void AddSC_warrior_spell_scripts()
new spell_warr_bloodthirst_heal();
new spell_warr_charge();
new spell_warr_concussion_blow();
- new spell_warr_damage_shield();
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();
new spell_warr_last_stand();
new spell_warr_overpower();
+ new spell_warr_rallying_cry();
new spell_warr_rend();
new spell_warr_retaliation();
+ new spell_warr_second_wind_proc();
+ new spell_warr_second_wind_trigger();
new spell_warr_shattering_throw();
new spell_warr_slam();
+ new spell_warr_sudden_death();
new spell_warr_sweeping_strikes();
+ new spell_warr_sword_and_board();
+ new spell_warr_victorious();
new spell_warr_vigilance();
new spell_warr_vigilance_trigger();
}
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index ddb4cc4c8d1..886200ab84b 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -869,23 +869,6 @@ public:
## go_soulwell
######*/
-enum SoulWellData
-{
- GO_SOUL_WELL_R1 = 181621,
- GO_SOUL_WELL_R2 = 193169,
-
- SPELL_IMPROVED_HEALTH_STONE_R1 = 18692,
- SPELL_IMPROVED_HEALTH_STONE_R2 = 18693,
-
- SPELL_CREATE_MASTER_HEALTH_STONE_R0 = 34130,
- SPELL_CREATE_MASTER_HEALTH_STONE_R1 = 34149,
- SPELL_CREATE_MASTER_HEALTH_STONE_R2 = 34150,
-
- SPELL_CREATE_FEL_HEALTH_STONE_R0 = 58890,
- SPELL_CREATE_FEL_HEALTH_STONE_R1 = 58896,
- SPELL_CREATE_FEL_HEALTH_STONE_R2 = 58898,
-};
-
class go_soulwell : public GameObjectScript
{
public:
@@ -895,39 +878,6 @@ class go_soulwell : public GameObjectScript
{
go_soulwellAI(GameObject* go) : GameObjectAI(go)
{
- _stoneSpell = 0;
- _stoneId = 0;
- switch (go->GetEntry())
- {
- case GO_SOUL_WELL_R1:
- _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0;
- if (Unit* owner = go->GetOwner())
- {
- if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
- _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1;
- else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
- _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2;
- }
- break;
- case GO_SOUL_WELL_R2:
- _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0;
- if (Unit* owner = go->GetOwner())
- {
- if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1))
- _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1;
- else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2))
- _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2;
- }
- break;
- }
- if (_stoneSpell == 0) // Should never happen
- return;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell);
- if (!spellInfo)
- return;
-
- _stoneId = spellInfo->Effects[EFFECT_0].ItemType;
}
/// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE
@@ -937,31 +887,10 @@ class go_soulwell : public GameObjectScript
bool GossipHello(Player* player) OVERRIDE
{
Unit* owner = go->GetOwner();
- if (_stoneSpell == 0 || _stoneId == 0)
- return true;
-
if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer()))
return true;
-
- // Don't try to add a stone if we already have one.
- if (player->HasItemCount(_stoneId))
- {
- if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell))
- Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM);
- return true;
- }
-
- owner->CastSpell(player, _stoneSpell, true);
- // Item has to actually be created to remove a charge on the well.
- if (player->HasItemCount(_stoneId))
- go->AddUse();
-
return false;
}
-
- private:
- uint32 _stoneSpell;
- uint32 _stoneId;
};
GameObjectAI* GetAI(GameObject* go) const OVERRIDE
diff --git a/src/server/scripts/World/item_scripts.cpp b/src/server/scripts/World/item_scripts.cpp
index 545ee9f4b43..1eb9c304ec1 100644
--- a/src/server/scripts/World/item_scripts.cpp
+++ b/src/server/scripts/World/item_scripts.cpp
@@ -76,7 +76,7 @@ public:
return false;
// error
- player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
return true;
}
};
@@ -119,7 +119,7 @@ public:
targets.GetUnitTarget()->GetEntry() == 20748 && !targets.GetUnitTarget()->HasAura(32578))
return false;
- player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
return true;
}
};
@@ -268,15 +268,13 @@ class item_petrov_cluster_bombs : public ItemScript
public:
item_petrov_cluster_bombs() : ItemScript("item_petrov_cluster_bombs") { }
- bool OnUse(Player* player, Item* item, const SpellCastTargets & /*targets*/) OVERRIDE
+ bool OnUse(Player* player, Item* /*item*/, const SpellCastTargets & /*targets*/) OVERRIDE
{
if (player->GetZoneId() != ZONE_ID_HOWLING)
return false;
if (!player->GetTransport() || player->GetAreaId() != AREA_ID_SHATTERED_STRAITS)
{
- player->SendEquipError(EQUIP_ERR_NONE, item, NULL);
-
if (const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(SPELL_PETROV_BOMB))
Spell::SendCastResult(player, spellInfo, 1, SPELL_FAILED_NOT_HERE);
@@ -381,7 +379,7 @@ public:
} else
player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, item, NULL);
} else
- player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
return true;
}
};
@@ -407,7 +405,7 @@ public:
player->SendEquipError(EQUIP_ERR_OUT_OF_RANGE, item, NULL);
}
else
- player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, item, NULL);
return true;
}
};
diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp
index 5cbc54923e0..f08930026cf 100644
--- a/src/server/scripts/World/npc_professions.cpp
+++ b/src/server/scripts/World/npc_professions.cpp
@@ -214,7 +214,7 @@ int32 DoLowUnlearnCost(Player* player) //blacksmith
void ProcessCastaction(Player* player, Creature* creature, uint32 spellId, uint32 triggeredSpellId, int32 cost)
{
- if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney(cost))
+ if (!(spellId && player->HasSpell(spellId)) && player->HasEnoughMoney((int64)cost))
{
player->CastSpell(player, triggeredSpellId, true);
player->ModifyMoney(-cost);
@@ -352,11 +352,11 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui
{
if (EquippedOk(player, spellId))
{
- if (player->HasEnoughMoney(cost))
+ if (player->HasEnoughMoney(int64(cost)))
{
player->CastSpell(player, spellId, true);
ProfessionUnlearnSpells(player, spellId);
- player->ModifyMoney(-cost);
+ player->ModifyMoney(-int64(cost));
if (alternativeSpellId)
creature->CastSpell(player, alternativeSpellId, true);
}
@@ -364,7 +364,7 @@ void ProcessUnlearnAction(Player* player, Creature* creature, uint32 spellId, ui
player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, creature, 0, 0);
}
else
- player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, NULL, NULL);
+ player->SendEquipError(EQUIP_ERR_CLIENT_LOCKED_OUT, NULL, NULL);
player->CLOSE_GOSSIP_MENU();
}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index ac30f6f1e80..a8f4360483d 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -440,9 +440,6 @@ public:
me->Relocate(x, y, z + 0.94f);
me->SetDisableGravity(true);
me->HandleEmoteCommand(EMOTE_ONESHOT_DANCE);
- WorldPacket data; //send update position to client
- me->BuildHeartBeatMsg(&data);
- me->SendMessageToSet(&data, true);
}
void UpdateAI(uint32 diff) OVERRIDE
@@ -469,9 +466,6 @@ public:
me->SetInFront(player);
Active = false;
- WorldPacket data;
- me->BuildHeartBeatMsg(&data);
- me->SendMessageToSet(&data, true);
switch (emote)
{
case TEXT_EMOTE_KISS:
@@ -1238,7 +1232,6 @@ public:
}
};
-
/*######
## npc_sayge
######*/
@@ -1962,11 +1955,11 @@ public:
}
if (doSwitch)
{
- if (!player->HasEnoughMoney(EXP_COST))
+ if (!player->HasEnoughMoney(uint64(EXP_COST)))
player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
else if (noXPGain)
{
- player->ModifyMoney(-EXP_COST);
+ player->ModifyMoney(-int64(EXP_COST));
player->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_NO_XP_GAIN);
}
else if (!noXPGain)
diff --git a/src/server/shared/Common.h b/src/server/shared/Common.h
index 5dea589da25..36c186a7a34 100644
--- a/src/server/shared/Common.h
+++ b/src/server/shared/Common.h
@@ -182,6 +182,23 @@ LocaleConstant GetLocaleByName(const std::string& name);
typedef std::vector<std::string> StringVector;
+#if defined(__GNUC__)
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+struct LocalizedString
+{
+ char const* Str[TOTAL_LOCALES];
+};
+
+#if defined(__GNUC__)
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
// we always use stdlibc++ std::max/std::min, undefine some not C++ standard defines (Win API and some other platforms)
#ifdef max
#undef max
diff --git a/src/server/shared/DataStores/DB2FileLoader.cpp b/src/server/shared/DataStores/DB2FileLoader.cpp
new file mode 100644
index 00000000000..7a27072dd20
--- /dev/null
+++ b/src/server/shared/DataStores/DB2FileLoader.cpp
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 "Common.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "DB2FileLoader.h"
+
+DB2FileLoader::DB2FileLoader()
+{
+ data = NULL;
+ fieldsOffset = NULL;
+}
+
+bool DB2FileLoader::Load(const char *filename, const char *fmt)
+{
+ if (data)
+ {
+ delete [] data;
+ data = NULL;
+ }
+
+ FILE* f = fopen(filename, "rb");
+ if (!f)
+ return false;
+
+ uint32 header;
+ if (fread(&header, 4, 1, f) != 1) // Signature
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(header);
+
+ if (header != 0x32424457)
+ {
+ fclose(f);
+ return false; //'WDB2'
+ }
+
+ if (fread(&recordCount, 4, 1, f) != 1) // Number of records
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(recordCount);
+
+ if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(fieldCount);
+
+ if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(recordSize);
+
+ if (fread(&stringSize, 4, 1, f) != 1) // String size
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(stringSize);
+
+ /* NEW WDB2 FIELDS*/
+ if (fread(&tableHash, 4, 1, f) != 1) // Table hash
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(tableHash);
+
+ if (fread(&build, 4, 1, f) != 1) // Build
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(build);
+
+ if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(unk1);
+
+ if (build > 12880)
+ {
+ if (fread(&minIndex, 4, 1, f) != 1) // MinIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(minIndex);
+
+ if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(maxIndex);
+
+ if (fread(&locale, 4, 1, f) != 1) // Locales
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(locale);
+
+ if (fread(&unk5, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+ EndianConvert(unk5);
+ }
+
+ if (maxIndex != 0)
+ {
+ int32 diff = maxIndex - minIndex + 1;
+ fseek(f, diff * 4 + diff * 2, SEEK_CUR); // diff * 4: an index for rows, diff * 2: a memory allocation bank
+ }
+
+ fieldsOffset = new uint32[fieldCount];
+ fieldsOffset[0] = 0;
+ for (uint32 i = 1; i < fieldCount; i++)
+ {
+ fieldsOffset[i] = fieldsOffset[i - 1];
+ if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X')
+ fieldsOffset[i] += 1;
+ else
+ fieldsOffset[i] += 4;
+ }
+
+ data = new unsigned char[recordSize*recordCount+stringSize];
+ stringTable = data + recordSize*recordCount;
+
+ if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+
+ fclose(f);
+ return true;
+}
+
+DB2FileLoader::~DB2FileLoader()
+{
+ if (data)
+ delete [] data;
+ if (fieldsOffset)
+ delete [] fieldsOffset;
+}
+
+DB2FileLoader::Record DB2FileLoader::getRecord(size_t id)
+{
+ assert(data);
+ return Record(*this, data + id*recordSize);
+}
+
+uint32 DB2FileLoader::GetFormatRecordSize(const char * format, int32* index_pos)
+{
+ uint32 recordsize = 0;
+ int32 i = -1;
+ for (uint32 x=0; format[x]; ++x)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_INT:
+ recordsize += 4;
+ break;
+ case FT_STRING:
+ recordsize += sizeof(char*);
+ break;
+ case FT_SORT:
+ i = x;
+ break;
+ case FT_IND:
+ i = x;
+ recordsize += 4;
+ break;
+ case FT_BYTE:
+ recordsize += 1;
+ break;
+ }
+ }
+
+ if (index_pos)
+ *index_pos = i;
+
+ return recordsize;
+}
+
+uint32 DB2FileLoader::GetFormatStringsFields(const char * format)
+{
+ uint32 stringfields = 0;
+ for (uint32 x=0; format[x]; ++x)
+ if (format[x] == FT_STRING)
+ ++stringfields;
+
+ return stringfields;
+}
+
+char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable)
+{
+
+ typedef char * ptr;
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ //get struct size and index pos
+ int32 i;
+ uint32 recordsize=GetFormatRecordSize(format, &i);
+
+ if (i >= 0)
+ {
+ uint32 maxi = 0;
+ //find max index
+ for (uint32 y = 0; y < recordCount; y++)
+ {
+ uint32 ind=getRecord(y).getUInt(i);
+ if (ind>maxi)
+ maxi = ind;
+ }
+
+ ++maxi;
+ records = maxi;
+ indexTable = new ptr[maxi];
+ memset(indexTable, 0, maxi * sizeof(ptr));
+ }
+ else
+ {
+ records = recordCount;
+ indexTable = new ptr[recordCount];
+ }
+
+ char* dataTable = new char[recordCount * recordsize];
+
+ uint32 offset=0;
+
+ for (uint32 y =0; y < recordCount; y++)
+ {
+ if (i>=0)
+ {
+ indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
+ }
+ else
+ indexTable[y] = &dataTable[offset];
+
+ for (uint32 x = 0; x < fieldCount; x++)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = getRecord(y).getFloat(x);
+ offset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
+ offset += 1;
+ break;
+ case FT_STRING:
+ *((char**)(&dataTable[offset])) = NULL; // will be replaces non-empty or "" strings in AutoProduceStrings
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ return dataTable;
+}
+
+static char const* const nullStr = "";
+
+char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable)
+{
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ // we store flat holders pool as single memory block
+ size_t stringFields = GetFormatStringsFields(format);
+ // each string field at load have array of string for each locale
+ size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+ size_t stringHoldersRecordPoolSize = stringFields * stringHolderSize;
+ size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * recordCount;
+
+ char* stringHoldersPool = new char[stringHoldersPoolSize];
+
+ // DB2 strings expected to have at least empty string
+ for (size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i)
+ ((char const**)stringHoldersPool)[i] = nullStr;
+
+ uint32 offset=0;
+
+ // assign string holders to string field slots
+ for (uint32 y = 0; y < recordCount; y++)
+ {
+ uint32 stringFieldNum = 0;
+
+ for (uint32 x = 0; x < fieldCount; x++)
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_STRING:
+ {
+ // init db2 string field slots by pointers to string holders
+ char const*** slot = (char const***)(&dataTable[offset]);
+ *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * y + stringHolderSize*stringFieldNum]);
+ ++stringFieldNum;
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_NA:
+ case FT_NA_BYTE:
+ case FT_SORT:
+ break;
+ default:
+ assert(false && "unknown format character");
+ }
+ }
+
+ //send as char* for store in char* pool list for free at unload
+ return stringHoldersPool;
+}
+
+char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uint32 locale)
+{
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ char* stringPool= new char[stringSize];
+ memcpy(stringPool, stringTable, stringSize);
+
+ uint32 offset = 0;
+
+ for (uint32 y =0; y < recordCount; y++)
+ {
+ for (uint32 x = 0; x < fieldCount; x++)
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_STRING:
+ {
+ // fill only not filled entries
+ LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]);
+ if (db2str->Str[locale] == nullStr)
+ {
+ const char * st = getRecord(y).getString(x);
+ db2str->Str[locale] = stringPool + (st - (const char*)stringTable);
+ }
+
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ return stringPool;
+}
diff --git a/src/server/shared/DataStores/DB2FileLoader.h b/src/server/shared/DataStores/DB2FileLoader.h
new file mode 100644
index 00000000000..86350ebf1d6
--- /dev/null
+++ b/src/server/shared/DataStores/DB2FileLoader.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 DB2_FILE_LOADER_H
+#define DB2_FILE_LOADER_H
+
+#include "Define.h"
+#include "Utilities/ByteConverter.h"
+#include <cassert>
+
+class DB2FileLoader
+{
+ public:
+ DB2FileLoader();
+ ~DB2FileLoader();
+
+ bool Load(const char *filename, const char *fmt);
+
+ class Record
+ {
+ public:
+ float getFloat(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ float val = *reinterpret_cast<float*>(offset+file.GetOffset(field));
+ EndianConvert(val);
+ return val;
+ }
+ uint32 getUInt(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ uint32 val = *reinterpret_cast<uint32*>(offset+file.GetOffset(field));
+ EndianConvert(val);
+ return val;
+ }
+ uint8 getUInt8(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ return *reinterpret_cast<uint8*>(offset+file.GetOffset(field));
+ }
+
+ const char *getString(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ size_t stringOffset = getUInt(field);
+ assert(stringOffset < file.stringSize);
+ return reinterpret_cast<char*>(file.stringTable + stringOffset);
+ }
+
+ private:
+ Record(DB2FileLoader &file_, unsigned char *offset_): offset(offset_), file(file_) {}
+ unsigned char *offset;
+ DB2FileLoader &file;
+
+ friend class DB2FileLoader;
+ };
+
+ // Get record by id
+ Record getRecord(size_t id);
+ /// Get begin iterator over records
+
+ uint32 GetNumRows() const { return recordCount;}
+ uint32 GetCols() const { return fieldCount; }
+ uint32 GetOffset(size_t id) const { return (fieldsOffset != NULL && id < fieldCount) ? fieldsOffset[id] : 0; }
+ uint32 GetHash() const { return tableHash; }
+ bool IsLoaded() const { return (data != NULL); }
+ char* AutoProduceData(const char* fmt, uint32& count, char**& indexTable);
+ char* AutoProduceStringsArrayHolders(const char* fmt, char* dataTable);
+ char* AutoProduceStrings(const char* fmt, char* dataTable, uint32 locale);
+ static uint32 GetFormatRecordSize(const char * format, int32 * index_pos = NULL);
+ static uint32 GetFormatStringsFields(const char * format);
+private:
+
+ uint32 recordSize;
+ uint32 recordCount;
+ uint32 fieldCount;
+ uint32 stringSize;
+ uint32 *fieldsOffset;
+ unsigned char *data;
+ unsigned char *stringTable;
+
+ // WDB2 / WCH2 fields
+ uint32 tableHash; // WDB2
+ uint32 build; // WDB2
+
+ int unk1; // WDB2 (Unix time in WCH2)
+ int minIndex; // WDB2
+ int maxIndex; // WDB2 (index table)
+ int locale; // WDB2
+ int unk5; // WDB2
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
new file mode 100644
index 00000000000..77d6c4144e5
--- /dev/null
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2011 TrintiyCore <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 DB2STORE_H
+#define DB2STORE_H
+
+#include "DB2FileLoader.h"
+#include "Common.h"
+#include "ByteBuffer.h"
+#include <vector>
+
+/// Interface class for common access
+class DB2StorageBase
+{
+public:
+ virtual ~DB2StorageBase() { }
+
+ uint32 GetHash() const { return tableHash; }
+
+ virtual bool HasRecord(uint32 id) const = 0;
+
+ virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const = 0;
+
+protected:
+ uint32 tableHash;
+};
+
+template<class T>
+class DB2Storage;
+
+template<class T>
+bool DB2StorageHasEntry(DB2Storage<T> const& store, uint32 id)
+{
+ return store.LookupEntry(id) != NULL;
+}
+
+template<class T>
+void WriteDB2RecordToPacket(DB2Storage<T> const& store, uint32 id, uint32 locale, ByteBuffer& buffer)
+{
+ uint8 const* entry = (uint8 const*)store.LookupEntry(id);
+ ASSERT(entry);
+
+ std::string format = store.GetFormat();
+ for (uint32 i = 0; i < format.length(); ++i)
+ {
+ switch (format[i])
+ {
+ case FT_IND:
+ case FT_INT:
+ buffer << *(uint32*)entry;
+ entry += 4;
+ break;
+ case FT_FLOAT:
+ buffer << *(float*)entry;
+ entry += 4;
+ break;
+ case FT_BYTE:
+ buffer << *(uint8*)entry;
+ entry += 1;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString* locStr = *(LocalizedString**)entry;
+ if (locStr->Str[locale][0] == '\0')
+ locale = 0;
+
+ char const* str = locStr->Str[locale];
+ size_t len = strlen(str);
+ buffer << uint16(len);
+ if (len)
+ buffer << str;
+ entry += sizeof(char*);
+ break;
+ }
+ case FT_NA:
+ case FT_SORT:
+ buffer << uint32(0);
+ break;
+ case FT_NA_BYTE:
+ buffer << uint8(0);
+ break;
+ }
+ }
+}
+
+template<class T>
+class DB2Storage : public DB2StorageBase
+{
+ typedef std::list<char*> StringPoolList;
+ typedef std::vector<T*> DataTableEx;
+ typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32);
+ typedef void(*PacketWriter)(DB2Storage<T> const&, uint32, uint32, ByteBuffer&);
+public:
+ DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) :
+ nCount(0), fieldCount(0), fmt(f), m_dataTable(NULL)
+ {
+ indexTable.asT = NULL;
+ CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>;
+ WritePacket = writePacket ? writePacket : (PacketWriter)&WriteDB2RecordToPacket<T>;
+ }
+
+ ~DB2Storage() { Clear(); }
+
+ bool HasRecord(uint32 id) const { return CheckEntry(*this, id); }
+ T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable.asT[id]; }
+ uint32 GetNumRows() const { return nCount; }
+ char const* GetFormat() const { return fmt; }
+ uint32 GetFieldCount() const { return fieldCount; }
+ void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const
+ {
+ WritePacket(*this, id, locale, buffer);
+ }
+
+ T* CreateEntry(uint32 id, bool evenIfExists = false)
+ {
+ if (evenIfExists && LookupEntry(id))
+ return NULL;
+
+ if (id >= nCount)
+ {
+ // reallocate index table
+ char** tmpIdxTable = new char*[id + 1];
+ memset(tmpIdxTable, 0, (id + 1) * sizeof(char*));
+ memcpy(tmpIdxTable, indexTable.asChar, nCount * sizeof(char*));
+ delete[] reinterpret_cast<char*>(indexTable.asT);
+ nCount = id + 1;
+ indexTable.asChar = tmpIdxTable;
+ }
+
+ T* entryDst = new T;
+ m_dataTableEx.push_back(entryDst);
+ indexTable.asT[id] = entryDst;
+ return entryDst;
+ }
+
+ void EraseEntry(uint32 id) { indexTable.asT[id] = NULL; }
+
+ bool Load(char const* fn, uint32 locale)
+ {
+ DB2FileLoader db2;
+ // Check if load was sucessful, only then continue
+ if (!db2.Load(fn, fmt))
+ return false;
+
+ fieldCount = db2.GetCols();
+ tableHash = db2.GetHash();
+
+ // load raw non-string data
+ m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar));
+
+ // create string holders for loaded string fields
+ m_stringPoolList.push_back(db2.AutoProduceStringsArrayHolders(fmt, (char*)m_dataTable));
+
+ // load strings from dbc data
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
+
+ // error in dbc file at loading if NULL
+ return indexTable.asT != NULL;
+ }
+
+ bool LoadStringsFrom(char const* fn, uint32 locale)
+ {
+ // DBC must be already loaded using Load
+ if (!indexTable.asT)
+ return false;
+
+ DB2FileLoader db2;
+ // Check if load was successful, only then continue
+ if (!db2.Load(fn, fmt))
+ return false;
+
+ // load strings from another locale dbc data
+ m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
+
+ return true;
+ }
+
+ void Clear()
+ {
+ if (!indexTable.asT)
+ return;
+
+ delete[] reinterpret_cast<char*>(indexTable.asT);
+ indexTable.asT = NULL;
+
+ delete[] reinterpret_cast<char*>(m_dataTable);
+ m_dataTable = NULL;
+
+ for (typename DataTableEx::iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr)
+ delete *itr;
+ m_dataTableEx.clear();
+
+ while (!m_stringPoolList.empty())
+ {
+ delete[] m_stringPoolList.front();
+ m_stringPoolList.pop_front();
+ }
+
+ nCount = 0;
+ }
+
+ EntryChecker CheckEntry;
+ PacketWriter WritePacket;
+
+private:
+ uint32 nCount;
+ uint32 fieldCount;
+ char const* fmt;
+ union
+ {
+ T** asT;
+ char** asChar;
+ } indexTable;
+ T* m_dataTable;
+ DataTableEx m_dataTableEx;
+ StringPoolList m_stringPoolList;
+};
+
+#endif
diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp
index d027d7539ad..ab46bca9b72 100644
--- a/src/server/shared/DataStores/DBCFileLoader.cpp
+++ b/src/server/shared/DataStores/DBCFileLoader.cpp
@@ -155,9 +155,6 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos)
case FT_NA:
case FT_NA_BYTE:
break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
default:
ASSERT(false && "Unknown field format character in DBCfmt.h");
break;
@@ -249,9 +246,6 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**
*((char**)(&dataTable[offset])) = NULL; // will replace non-empty or "" strings in AutoProduceStrings
offset += sizeof(char*);
break;
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
case FT_NA:
case FT_NA_BYTE:
case FT_SORT:
@@ -306,9 +300,6 @@ char* DBCFileLoader::AutoProduceStrings(const char* format, char* dataTable)
offset += sizeof(char*);
break;
}
- case FT_LOGIC:
- ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
- break;
case FT_NA:
case FT_NA_BYTE:
case FT_SORT:
diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/server/shared/DataStores/DBCFileLoader.h
index c5194d20530..0084e3b9381 100644
--- a/src/server/shared/DataStores/DBCFileLoader.h
+++ b/src/server/shared/DataStores/DBCFileLoader.h
@@ -22,21 +22,6 @@
#include "Utilities/ByteConverter.h"
#include <cassert>
-enum DbcFieldFormat
-{
- FT_NA='x', //not used or unknown, 4 byte size
- FT_NA_BYTE='X', //not used or unknown, byte
- FT_STRING='s', //char*
- FT_FLOAT='f', //float
- FT_INT='i', //uint32
- FT_BYTE='b', //uint8
- FT_SORT='d', //sorted by this field, field is not included
- FT_IND='n', //the same, but parsed to data
- FT_LOGIC='l', //Logical (boolean)
- FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
- FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
-};
-
class DBCFileLoader
{
public:
diff --git a/src/server/shared/DataStores/DBCStore.h b/src/server/shared/DataStores/DBCStore.h
index 78f7bb28580..5f252318c8d 100644
--- a/src/server/shared/DataStores/DBCStore.h
+++ b/src/server/shared/DataStores/DBCStore.h
@@ -20,7 +20,7 @@
#define DBCSTORE_H
#include "DBCFileLoader.h"
-#include "Logging/Log.h"
+#include "Log.h"
#include "Field.h"
#include "DatabaseWorkerPool.h"
#include "Implementation/WorldDatabase.h"
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index aa7c2e96fba..eeda7b0a619 100644
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -43,14 +43,14 @@ void CharacterDatabaseConnection::DoPrepareStatements()
"subject, deliver_time, expire_time, money, has_items FROM mail WHERE receiver = ? ", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_MAIL_LIST_ITEMS, "SELECT itemEntry,count FROM item_instance WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_ENUM, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, c.position_x, c.position_y, c.position_z, "
- "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid "
+ "gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, cb.guid, c.slot "
"FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
- "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
+ "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_ENUM_DECLINED_NAME, "SELECT c.guid, c.name, c.race, c.class, c.gender, c.playerBytes, c.playerBytes2, c.level, c.zone, c.map, "
"c.position_x, c.position_y, c.position_z, gm.guildid, c.playerFlags, c.at_login, cp.entry, cp.modelid, cp.level, c.equipmentCache, "
- "cb.guid, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? "
+ "cb.guid, c.slot, cd.genitive FROM characters AS c LEFT JOIN character_pet AS cp ON c.guid = cp.owner AND cp.slot = ? "
"LEFT JOIN character_declinedname AS cd ON c.guid = cd.guid LEFT JOIN guild_member AS gm ON c.guid = gm.guid "
- "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL ORDER BY c.guid", CONNECTION_ASYNC);
+ "LEFT JOIN character_banned AS cb ON c.guid = cb.guid AND cb.active = 1 WHERE c.account = ? AND c.deleteInfos_Name IS NULL", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_FREE_NAME, "SELECT guid, name FROM characters WHERE guid = ? AND account = ? AND (at_login & ?) = ? AND NOT EXISTS (SELECT NULL FROM characters WHERE name = ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GUID_RACE_ACC_BY_NAME, "SELECT guid, race, account FROM characters WHERE name = ?", CONNECTION_BOTH);
PrepareStatement(CHAR_SEL_CHAR_RACE, "SELECT race FROM characters WHERE guid = ?", CONNECTION_SYNCH);
@@ -73,9 +73,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// Start LoginQueryHolder content
PrepareStatement(CHAR_SEL_CHARACTER, "SELECT guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, "
- "resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
- "arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, "
- "health, power1, power2, power3, power4, power5, power6, power7, instance_id, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels "
+ "resettalents_time, talentTree, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, instance_mode_mask, "
+ "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, "
+ "health, power1, power2, power3, power4, power5, instance_id, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels "
"FROM characters WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_GROUP_MEMBER, "SELECT guid FROM group_member WHERE memberGuid = ?", CONNECTION_BOTH);
@@ -113,7 +113,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_EQUIPMENTSETS, "SELECT setguid, setindex, name, iconname, ignore_mask, item0, item1, item2, item3, item4, item5, item6, item7, item8, "
"item9, item10, item11, item12, item13, item14, item15, item16, item17, item18 FROM character_equipmentsets WHERE guid = ? ORDER BY setindex", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_BGDATA, "SELECT instanceId, team, joinX, joinY, joinZ, joinO, joinMapId, taxiStart, taxiEnd, mountSpell FROM character_battleground_data WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_GLYPHS, "SELECT spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9 FROM character_glyphs WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_TALENTS, "SELECT spell, spec FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SKILLS, "SELECT skill, value, max FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_RANDOMBG, "SELECT guid FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC);
@@ -181,7 +181,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// 0: uint32, 1: uint8, 3: string, 4: uint32, 5: uint32
PrepareStatement(CHAR_INS_GUILD_RANK, "INSERT INTO guild_rank (guildid, rid, rname, rights, BankMoneyPerDay) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_RANKS, "DELETE FROM guild_rank WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
- PrepareStatement(CHAR_DEL_GUILD_LOWEST_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid >= ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
+ PrepareStatement(CHAR_DEL_GUILD_RANK, "DELETE FROM guild_rank WHERE guildid = ? AND rid = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_INS_GUILD_BANK_TAB, "INSERT INTO guild_bank_tab (guildid, TabId) VALUES (?, ?)", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_DEL_GUILD_BANK_TAB, "DELETE FROM guild_bank_tab WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8
PrepareStatement(CHAR_DEL_GUILD_BANK_TABS, "DELETE FROM guild_bank_tab WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
@@ -221,12 +221,24 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_GUILD_BANK_TAB_TEXT, "UPDATE guild_bank_tab SET TabText = ? WHERE guildid = ? AND TabId = ?", CONNECTION_ASYNC); // 0: string, 1: uint32, 2: uint8
PrepareStatement(CHAR_INS_GUILD_MEMBER_WITHDRAW,
- "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?) "
- "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5)", CONNECTION_ASYNC);
+ "INSERT INTO guild_member_withdraw (guid, tab0, tab1, tab2, tab3, tab4, tab5, tab6, tab7, money) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) "
+ "ON DUPLICATE KEY UPDATE tab0 = VALUES (tab0), tab1 = VALUES (tab1), tab2 = VALUES (tab2), tab3 = VALUES (tab3), tab4 = VALUES (tab4), tab5 = VALUES (tab5), tab6 = VALUES (tab6), tab7 = VALUES (tab7), money = VALUES (money)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_MEMBER_WITHDRAW, "TRUNCATE guild_member_withdraw", CONNECTION_ASYNC);
// 0: uint32, 1: uint32, 2: uint32
PrepareStatement(CHAR_SEL_CHAR_DATA_FOR_GUILD, "SELECT name, level, class, zone, account FROM characters WHERE guid = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT, "DELETE FROM guild_achievement WHERE guildId = ? AND achievement = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_ACHIEVEMENT, "INSERT INTO guild_achievement (guildId, achievement, date, guids) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ? AND criteria = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA, "INSERT INTO guild_achievement_progress (guildId, criteria, counter, date, completedGuid) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENTS, "DELETE FROM guild_achievement WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA, "DELETE FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT, "SELECT achievement, date, guids FROM guild_achievement WHERE guildId = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA, "SELECT criteria, counter, date, completedGuid FROM guild_achievement_progress WHERE guildId = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_UPD_GUILD_EXPERIENCE, "UPDATE guild SET level = ?, experience = ?, todayExperience = ? WHERE guildId = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE, "UPDATE guild SET todayExperience = 0", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_GUILD_NEWS, "INSERT INTO guild_newslog (guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)"
+ " ON DUPLICATE KEY UPDATE LogGuid = VALUES (LogGuid), EventType = VALUES (EventType), PlayerGuid = VALUES (PlayerGuid), Flags = VALUES (Flags), Value = VALUES (Value), Timestamp = VALUES (Timestamp)", CONNECTION_ASYNC);
// Chat channel handling
PrepareStatement(CHAR_SEL_CHANNEL, "SELECT announce, ownership, password, bannedList FROM channels WHERE name = ? AND team = ?", CONNECTION_SYNCH);
@@ -249,6 +261,11 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_AURA, "INSERT INTO character_aura (guid, caster_guid, item_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ // Currency
+ PrepareStatement(CHAR_SEL_PLAYER_CURRENCY, "SELECT currency, week_count, total_count FROM character_currency WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_PLAYER_CURRENCY, "UPDATE character_currency SET week_count = ?, total_count = ? WHERE guid = ? AND currency = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_PLAYER_CURRENCY, "REPLACE INTO character_currency (guid, currency, week_count, total_count) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+
// Account data
PrepareStatement(CHAR_SEL_ACCOUNT_DATA, "SELECT type, time, data FROM account_data WHERE accountId = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_REP_ACCOUNT_DATA, "REPLACE INTO account_data (accountId, type, time, data) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
@@ -314,8 +331,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_PLAYER_HOMEBIND, "DELETE FROM character_homebind WHERE guid = ?", CONNECTION_ASYNC);
// Corpse
- PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH);
- PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CORPSES, "SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_INS_CORPSE, "INSERT INTO corpse (corpseGuid, guid, posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, flags, dynFlags, time, corpseType, instanceId, phaseMask) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CORPSE, "DELETE FROM corpse WHERE corpseGuid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PLAYER_CORPSES, "DELETE FROM corpse WHERE guid = ? AND corpseType <> 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC);
@@ -355,18 +372,18 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
"map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, "
"taximask, cinematic, "
- "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, "
+ "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, talentTree, "
"extra_flags, stable_slots, at_login, zone, "
- "death_expire_time, taxi_path, arenaPoints, totalHonorPoints, todayHonorPoints, yesterdayHonorPoints, totalKills, "
- "todayKills, yesterdayKills, chosenTitle, knownCurrencies, watchedFaction, drunk, health, power1, power2, power3, "
- "power4, power5, power6, power7, latency, speccount, activespec, exploredZones, equipmentCache, ammoId, knownTitles, actionBars, grantableLevels) VALUES "
- "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
+ "death_expire_time, taxi_path, totalKills, "
+ "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, "
+ "power4, power5, latency, speccount, activespec, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES "
+ "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,playerBytes=?,playerBytes2=?,playerFlags=?,"
"map=?,instance_id=?,instance_mode_mask=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?,"
- "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
- "arenaPoints=?,totalHonorPoints=?,todayHonorPoints=?,yesterdayHonorPoints=?,totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,knownCurrencies=?,"
- "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,power6=?,power7=?,latency=?,speccount=?,activespec=?,exploredZones=?,"
- "equipmentCache=?,ammoId=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC);
+ "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,talentTree=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?,"
+ "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?,"
+ "watchedFaction=?,drunk=?,health=?,power1=?,power2=?,power3=?,power4=?,power5=?,latency=?,speccount=?,activespec=?,exploredZones=?,"
+ "equipmentCache=?,knownTitles=?,actionBars=?,grantableLevels=?,online=? WHERE guid=?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG, "UPDATE characters SET at_login = at_login | ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_REM_AT_LOGIN_FLAG, "UPDATE characters set at_login = at_login & ~ ? WHERE guid = ?", CONNECTION_ASYNC);
@@ -393,6 +410,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_ZONE, "UPDATE characters SET zone = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_LEVEL, "UPDATE characters SET level = ?, xp = 0 WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA, "DELETE FROM character_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD, "DELETE FROM guild_achievement_progress WHERE criteria = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_ACHIEVMENT, "DELETE FROM character_achievement WHERE achievement = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ADDON, "INSERT INTO addons (name, crc) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_INVALID_PET_SPELL, "DELETE FROM pet_spell WHERE spell = ?", CONNECTION_ASYNC);
@@ -463,7 +481,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS, "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION, "DELETE FROM character_reputation WHERE guid = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION, "INSERT INTO character_reputation (guid, faction, standing, flags) VALUES (?, ?, ? , ?)", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UPD_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = (arenaPoints + ?) WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_REFUND_INSTANCE, "DELETE FROM item_refund_instance WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_ITEM_REFUND_INSTANCE, "INSERT INTO item_refund_instance (item_guid, player_guid, paidMoney, paidExtendedCost) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GROUP, "DELETE FROM groups WHERE guid = ?", CONNECTION_ASYNC);
@@ -518,8 +535,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_CHAR_QUESTSTATUS_DAILY, "DELETE FROM character_queststatus_daily WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TALENT, "DELETE FROM character_talent WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_SKILLS, "DELETE FROM character_skills WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UDP_CHAR_HONOR_POINTS, "UPDATE characters SET totalHonorPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_UDP_CHAR_ARENA_POINTS, "UPDATE characters SET arenaPoints = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UDP_CHAR_MONEY, "UPDATE characters SET money = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_ACTION, "INSERT INTO character_action (guid, spec, button, action, type) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_ACTION, "UPDATE character_action SET action = ?, type = ? WHERE guid = ? AND button = ? AND spec = ?", CONNECTION_ASYNC);
@@ -539,17 +554,34 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UDP_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, spirit, "
+ PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, strength, agility, stamina, intellect, spirit, "
"armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, "
- "spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ "spellPower, resilience) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER, "DELETE FROM petition WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER, "DELETE FROM petition_sign WHERE ownerguid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_BY_OWNER_AND_TYPE, "DELETE FROM petition WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_PETITION_SIGNATURE_BY_OWNER_AND_TYPE, "DELETE FROM petition_sign WHERE ownerguid = ? AND type = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs VALUES(?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_GLYPHS, "INSERT INTO character_glyphs (guid, spec, glyph1, glyph2, glyph3, glyph4, glyph5, glyph6, glyph7, glyph8, glyph9) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC, "DELETE FROM character_talent WHERE guid = ? and spell = ? and spec = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_TALENT, "INSERT INTO character_talent (guid, spell, spec) VALUES (?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC, "DELETE FROM character_action WHERE spec<>? AND guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_UPD_CHAR_LIST_SLOT, "UPDATE characters SET slot = ? WHERE guid = ?", CONNECTION_ASYNC);
+
+ // Void Storage
+ PrepareStatement(CHAR_SEL_CHAR_VOID_STORAGE, "SELECT itemId, itemEntry, slot, creatorGuid, randomProperty, suffixFactor FROM character_void_storage WHERE playerGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_CHAR_VOID_STORAGE_ITEM, "REPLACE INTO character_void_storage (itemId, playerGuid, itemEntry, slot, creatorGuid, randomProperty, suffixFactor) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT, "DELETE FROM character_void_storage WHERE slot = ? AND playerGuid = ?", CONNECTION_ASYNC);
+
+ // CompactUnitFrame profiles
+ PrepareStatement(CHAR_SEL_CHAR_CUF_PROFILES, "SELECT id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154 FROM character_cuf_profiles WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_CHAR_CUF_PROFILES, "REPLACE INTO character_cuf_profiles (guid, id, name, frameHeight, frameWidth, sortBy, healthText, boolOptions, unk146, unk147, unk148, unk150, unk152, unk154) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_CUF_PROFILES, "DELETE FROM character_cuf_profiles WHERE guid = ? and id = ?", CONNECTION_ASYNC);
+
+ // Guild Finder
+ PrepareStatement(CHAR_REP_GUILD_FINDER_APPLICANT, "REPLACE INTO guild_finder_applicant (guildId, playerGuid, availability, classRole, interests, comment, submitTime) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_FINDER_APPLICANT, "DELETE FROM guild_finder_applicant WHERE guildId = ? AND playerGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_REP_GUILD_FINDER_GUILD_SETTINGS, "REPLACE INTO guild_finder_guild_settings (guildId, availability, classRoles, interests, level, listed, comment) VALUES(?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS, "DELETE FROM guild_finder_guild_settings WHERE guildId = ?", CONNECTION_ASYNC);
// Items that hold loot or money
PrepareStatement(CHAR_SEL_ITEMCONTAINER_ITEMS, "SELECT item_id, item_count, follow_rules, ffa, blocked, counted, under_threshold, needs_quest, rnd_prop, rnd_suffix FROM item_loot_items WHERE container_id = ?", CONNECTION_SYNCH);
@@ -589,10 +621,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_PET_SPELL, "INSERT INTO pet_spell (guid, spell, active) VALUES (?, ?, ?)", CONNECTION_BOTH);
PrepareStatement(CHAR_INS_PET_AURA, "INSERT INTO pet_aura (guid, caster_guid, spell, effect_mask, recalculate_mask, stackcount, amount0, amount1, amount2, "
"base_amount0, base_amount1, base_amount2, maxduration, remaintime, remaincharges) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_BOTH);
- PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND id = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT_2, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND entry = ? AND (slot = ? OR slot > ?)", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_PET_BY_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND (slot = ? OR slot > ?) ", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_CHAR_PET_BY_ENTRY_AND_SLOT, "SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, abdata, savetime, CreatedBySpell, PetType FROM character_pet WHERE owner = ? AND slot = ?", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_CHAR_PET_BY_OWNER, "DELETE FROM character_pet WHERE owner = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_PET_NAME, "UPDATE character_pet SET name = ?, renamed = 1 WHERE owner = ? AND id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UDP_CHAR_PET_SLOT_BY_SLOT_EXCLUDE_ID, "UPDATE character_pet SET slot = ? WHERE owner = ? AND slot = ? AND id <> ?", CONNECTION_ASYNC);
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 6768e4a197f..7f815c9f2f1 100644..100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -173,7 +173,7 @@ enum CharacterDatabaseStatements
CHAR_DEL_GUILD_MEMBERS,
CHAR_INS_GUILD_RANK,
CHAR_DEL_GUILD_RANKS,
- CHAR_DEL_GUILD_LOWEST_RANK,
+ CHAR_DEL_GUILD_RANK,
CHAR_INS_GUILD_BANK_TAB,
CHAR_DEL_GUILD_BANK_TAB,
CHAR_DEL_GUILD_BANK_TABS,
@@ -206,6 +206,17 @@ enum CharacterDatabaseStatements
CHAR_INS_GUILD_MEMBER_WITHDRAW,
CHAR_DEL_GUILD_MEMBER_WITHDRAW,
CHAR_SEL_CHAR_DATA_FOR_GUILD,
+ CHAR_DEL_GUILD_ACHIEVEMENT,
+ CHAR_INS_GUILD_ACHIEVEMENT,
+ CHAR_DEL_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_INS_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_DEL_ALL_GUILD_ACHIEVEMENTS,
+ CHAR_DEL_ALL_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_SEL_GUILD_ACHIEVEMENT,
+ CHAR_SEL_GUILD_ACHIEVEMENT_CRITERIA,
+ CHAR_UPD_GUILD_EXPERIENCE,
+ CHAR_UPD_GUILD_RESET_TODAY_EXPERIENCE,
+ CHAR_INS_GUILD_NEWS,
CHAR_SEL_CHANNEL,
CHAR_INS_CHANNEL,
@@ -220,6 +231,10 @@ enum CharacterDatabaseStatements
CHAR_INS_AURA,
+ CHAR_SEL_PLAYER_CURRENCY,
+ CHAR_UPD_PLAYER_CURRENCY,
+ CHAR_REP_PLAYER_CURRENCY,
+
CHAR_SEL_ACCOUNT_DATA,
CHAR_REP_ACCOUNT_DATA,
CHAR_DEL_ACCOUNT_DATA,
@@ -330,6 +345,7 @@ enum CharacterDatabaseStatements
CHAR_UPD_ZONE,
CHAR_UPD_LEVEL,
CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA,
+ CHAR_DEL_INVALID_ACHIEV_PROGRESS_CRITERIA_GUILD,
CHAR_DEL_INVALID_ACHIEVMENT,
CHAR_INS_ADDON,
CHAR_DEL_INVALID_PET_SPELL,
@@ -399,7 +415,6 @@ enum CharacterDatabaseStatements
CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS,
CHAR_DEL_CHAR_REPUTATION_BY_FACTION,
CHAR_INS_CHAR_REPUTATION_BY_FACTION,
- CHAR_UPD_CHAR_ARENA_POINTS,
CHAR_DEL_ITEM_REFUND_INSTANCE,
CHAR_INS_ITEM_REFUND_INSTANCE,
CHAR_DEL_GROUP,
@@ -454,8 +469,6 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHAR_QUESTSTATUS_DAILY,
CHAR_DEL_CHAR_TALENT,
CHAR_DEL_CHAR_SKILLS,
- CHAR_UDP_CHAR_HONOR_POINTS,
- CHAR_UDP_CHAR_ARENA_POINTS,
CHAR_UDP_CHAR_MONEY,
CHAR_INS_CHAR_ACTION,
CHAR_UPD_CHAR_ACTION,
@@ -484,6 +497,20 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC,
CHAR_INS_CHAR_TALENT,
CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC,
+ CHAR_UPD_CHAR_LIST_SLOT,
+
+ CHAR_SEL_CHAR_VOID_STORAGE,
+ CHAR_REP_CHAR_VOID_STORAGE_ITEM,
+ CHAR_DEL_CHAR_VOID_STORAGE_ITEM_BY_SLOT,
+
+ CHAR_SEL_CHAR_CUF_PROFILES,
+ CHAR_REP_CHAR_CUF_PROFILES,
+ CHAR_DEL_CHAR_CUF_PROFILES,
+
+ CHAR_REP_GUILD_FINDER_APPLICANT,
+ CHAR_DEL_GUILD_FINDER_APPLICANT,
+ CHAR_REP_GUILD_FINDER_GUILD_SETTINGS,
+ CHAR_DEL_GUILD_FINDER_GUILD_SETTINGS,
CHAR_REP_CALENDAR_EVENT,
CHAR_DEL_CALENDAR_EVENT,
diff --git a/src/server/shared/Database/Implementation/WorldDatabase.cpp b/src/server/shared/Database/Implementation/WorldDatabase.cpp
index 644d3b330fb..f64ad558e74 100644
--- a/src/server/shared/Database/Implementation/WorldDatabase.cpp
+++ b/src/server/shared/Database/Implementation/WorldDatabase.cpp
@@ -34,9 +34,9 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_DEL_GRAVEYARD_ZONE, "DELETE FROM game_graveyard_zone WHERE id = ? AND ghost_zone = ? AND faction = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_INS_GAME_TELE, "INSERT INTO game_tele (id, position_x, position_y, position_z, orientation, map, name) VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(WORLD_DEL_GAME_TELE, "DELETE FROM game_tele WHERE name = ?", CONNECTION_ASYNC);
- PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost) VALUES(?, ?, ?, ?, ?)", CONNECTION_ASYNC);
- PrepareStatement(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ?", CONNECTION_ASYNC);
- PrepareStatement(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost FROM npc_vendor WHERE entry = ? ORDER BY slot ASC", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_INS_NPC_VENDOR, "INSERT INTO npc_vendor (entry, item, maxcount, incrtime, extendedcost, type) VALUES(?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_DEL_NPC_VENDOR, "DELETE FROM npc_vendor WHERE entry = ? AND item = ? AND type = ?", CONNECTION_ASYNC);
+ PrepareStatement(WORLD_SEL_NPC_VENDOR_REF, "SELECT item, maxcount, incrtime, ExtendedCost, type FROM npc_vendor WHERE entry = ? AND type = ? ORDER BY slot ASC", CONNECTION_SYNCH);
PrepareStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE, "UPDATE creature SET MovementType = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_FACTION, "UPDATE creature_template SET faction_A = ?, faction_H = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_UPD_CREATURE_NPCFLAG, "UPDATE creature_template SET npcflag = ? WHERE entry = ?", CONNECTION_ASYNC);
@@ -76,7 +76,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
- PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
+ PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
diff --git a/src/server/shared/Define.h b/src/server/shared/Define.h
index 27973694818..a7fbfda641c 100644
--- a/src/server/shared/Define.h
+++ b/src/server/shared/Define.h
@@ -95,4 +95,18 @@ typedef ACE_UINT32 uint32;
typedef ACE_UINT16 uint16;
typedef ACE_UINT8 uint8;
+enum DBCFormer
+{
+ FT_NA='x', //not used or unknown, 4 byte size
+ FT_NA_BYTE='X', //not used or unknown, byte
+ FT_STRING='s', //char*
+ FT_FLOAT='f', //float
+ FT_INT='i', //uint32
+ FT_BYTE='b', //uint8
+ FT_SORT='d', //sorted by this field, field is not included
+ FT_IND='n', //the same, but parsed to data
+ FT_SQL_PRESENT='p', //Used in sql format to mark column present in sql dbc
+ FT_SQL_ABSENT='a' //Used in sql format to mark column absent in sql dbc
+};
+
#endif //TRINITY_DEFINE_H
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index 33d33519c8f..a1369b005b7 100644
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -69,19 +69,19 @@ class ByteBuffer
const static size_t DEFAULT_SIZE = 0x1000;
// constructor
- ByteBuffer() : _rpos(0), _wpos(0)
+ ByteBuffer() : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0)
{
_storage.reserve(DEFAULT_SIZE);
}
- ByteBuffer(size_t reserve) : _rpos(0), _wpos(0)
+ ByteBuffer(size_t reserve) : _rpos(0), _wpos(0), _bitpos(8), _curbitval(0)
{
_storage.reserve(reserve);
}
// copy constructor
ByteBuffer(const ByteBuffer &buf) : _rpos(buf._rpos), _wpos(buf._wpos),
- _storage(buf._storage)
+ _bitpos(buf._bitpos), _curbitval(buf._curbitval), _storage(buf._storage)
{
}
@@ -93,16 +93,115 @@ class ByteBuffer
template <typename T> void append(T value)
{
+ FlushBits();
EndianConvert(value);
append((uint8 *)&value, sizeof(value));
}
+ void FlushBits()
+ {
+ if (_bitpos == 8)
+ return;
+
+ append((uint8 *)&_curbitval, sizeof(uint8));
+ _curbitval = 0;
+ _bitpos = 8;
+ }
+
+ bool WriteBit(uint32 bit)
+ {
+ --_bitpos;
+ if (bit)
+ _curbitval |= (1 << (_bitpos));
+
+ if (_bitpos == 0)
+ {
+ _bitpos = 8;
+ append((uint8 *)&_curbitval, sizeof(_curbitval));
+ _curbitval = 0;
+ }
+
+ return (bit != 0);
+ }
+
+ bool ReadBit()
+ {
+ ++_bitpos;
+ if (_bitpos > 7)
+ {
+ _bitpos = 0;
+ _curbitval = read<uint8>();
+ }
+
+ return ((_curbitval >> (7-_bitpos)) & 1) != 0;
+ }
+
+ template <typename T> void WriteBits(T value, size_t bits)
+ {
+ for (int32 i = bits-1; i >= 0; --i)
+ WriteBit((value >> i) & 1);
+ }
+
+ uint32 ReadBits(size_t bits)
+ {
+ uint32 value = 0;
+ for (int32 i = bits-1; i >= 0; --i)
+ if (ReadBit())
+ value |= (1 << (i));
+
+ return value;
+ }
+
+ // Reads a byte (if needed) in-place
+ void ReadByteSeq(uint8& b)
+ {
+ if (b != 0)
+ b ^= read<uint8>();
+ }
+
+ void WriteByteSeq(uint8 b)
+ {
+ if (b != 0)
+ append<uint8>(b ^ 1);
+ }
+
template <typename T> void put(size_t pos, T value)
{
EndianConvert(value);
put(pos, (uint8 *)&value, sizeof(value));
}
+ /**
+ * @name PutBits
+ * @brief Places specified amount of bits of value at specified position in packet.
+ * To ensure all bits are correctly written, only call this method after
+ * bit flush has been performed
+
+ * @param pos Position to place the value at, in bits. The entire value must fit in the packet
+ * It is advised to obtain the position using bitwpos() function.
+
+ * @param value Data to write.
+ * @param bitCount Number of bits to store the value on.
+ */
+ template <typename T> void PutBits(size_t pos, T value, uint32 bitCount)
+ {
+ if (!bitCount)
+ throw ByteBufferSourceException((pos + bitCount) / 8, size(), 0);
+
+ if (pos + bitCount > size() * 8)
+ throw ByteBufferPositionException(false, (pos + bitCount) / 8, size(), (bitCount - 1) / 8 + 1);
+
+ for (uint32 i = 0; i < bitCount; ++i)
+ {
+ size_t wp = (pos + i) / 8;
+ size_t bit = (pos + i) % 8;
+ if ((value >> (bitCount - i - 1)) & 1)
+ _storage[wp] |= 1 << (7 - bit);
+ else
+ _storage[wp] &= ~(1 << (7 - bit));
+ }
+ }
+
ByteBuffer &operator<<(uint8 value)
{
append<uint8>(value);
@@ -296,6 +395,16 @@ class ByteBuffer
return _wpos;
}
+ /// Returns position of last written bit
+ size_t bitwpos() const { return _wpos * 8 + 8 - _bitpos; }
+
+ size_t bitwpos(size_t newPos)
+ {
+ _wpos = newPos / 8;
+ _bitpos = 8 - (newPos % 8);
+ return _wpos * 8 + 8 - _bitpos;
+ }
+
template<typename T>
void read_skip() { read_skip(sizeof(T)); }
@@ -354,6 +463,25 @@ class ByteBuffer
}
}
+ std::string ReadString(uint32 length)
+ {
+ if (!length)
+ return std::string();
+ char* buffer = new char[length + 1]();
+ read((uint8*)buffer, length);
+ std::string retval = buffer;
+ delete[] buffer;
+ return retval;
+ }
+
+ //! Method for writing strings that have their length sent separately in packet
+ //! without null-terminating the string
+ void WriteString(std::string const& str)
+ {
+ if (size_t len = str.length())
+ append(str.c_str(), len);
+ }
+
uint32 ReadPackedTime()
{
uint32 packedDate = read<uint32>();
@@ -481,7 +609,8 @@ class ByteBuffer
void hexlike() const;
protected:
- size_t _rpos, _wpos;
+ size_t _rpos, _wpos, _bitpos;
+ uint8 _curbitval;
std::vector<uint8> _storage;
};
diff --git a/src/server/shared/Utilities/Util.cpp b/src/server/shared/Utilities/Util.cpp
index 499ad0502b7..2149956c19f 100644
--- a/src/server/shared/Utilities/Util.cpp
+++ b/src/server/shared/Utilities/Util.cpp
@@ -150,9 +150,9 @@ std::string secsToTimeString(uint64 timeInSecs, bool shortText, bool hoursOnly)
return ss.str();
}
-int32 MoneyStringToMoney(const std::string& moneyString)
+int64 MoneyStringToMoney(const std::string& moneyString)
{
- int32 money = 0;
+ int64 money = 0;
if (!(std::count(moneyString.begin(), moneyString.end(), 'g') == 1 ||
std::count(moneyString.begin(), moneyString.end(), 's') == 1 ||
@@ -169,7 +169,7 @@ int32 MoneyStringToMoney(const std::string& moneyString)
if (gCount + sCount + cCount != 1)
return 0;
- uint32 amount = atoi(*itr);
+ uint64 amount = atol(*itr);
if (gCount == 1)
money += amount * 100 * 100;
else if (sCount == 1)
diff --git a/src/server/shared/Utilities/Util.h b/src/server/shared/Utilities/Util.h
index b086a28134c..236670e5cf1 100644
--- a/src/server/shared/Utilities/Util.h
+++ b/src/server/shared/Utilities/Util.h
@@ -68,7 +68,7 @@ private:
void stripLineInvisibleChars(std::string &src);
-int32 MoneyStringToMoney(const std::string& moneyString);
+int64 MoneyStringToMoney(const std::string& moneyString);
std::string secsToTimeString(uint64 timeInSecs, bool shortText = false, bool hoursOnly = false);
uint32 TimeStringToSecs(const std::string& timestring);
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index d1d2ef11848..af76cac3fb5 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -84,6 +84,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/DataStores
${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding
${CMAKE_SOURCE_DIR}/src/server/game/Entities
+ ${CMAKE_SOURCE_DIR}/src/server/game/Entities/AreaTrigger
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature
${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse
${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject
@@ -113,6 +114,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous
${CMAKE_SOURCE_DIR}/src/server/game/Movement
${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators
+ ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Spline
${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints
${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP
${CMAKE_SOURCE_DIR}/src/server/game/Pools
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 2a47c8f989e..6d0caa707ac 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -28,6 +28,7 @@
# CHARACTER DELETE OPTIONS
# CUSTOM SERVER OPTIONS
# LOGGING SYSTEM SETTINGS
+# CURRENCIES SETTINGS
# PACKET SPOOF PROTECTION SETTINGS
#
###################################################################################################
@@ -581,8 +582,7 @@ StrictPetNames = 0
#
# DBC.Locale
# Description: DBC language settings.
-# Default: 255 - (Auto Detect)
-# 0 - (English)
+# Default: 0 - (English)
# 1 - (Korean)
# 2 - (French)
# 3 - (German)
@@ -592,7 +592,7 @@ StrictPetNames = 0
# 7 - (Spanish Mexico)
# 8 - (Russian)
-DBC.Locale = 255
+DBC.Locale = 0
#
# DeclinedNames
@@ -606,11 +606,12 @@ DeclinedNames = 0
# Expansion
# Description: Allow server to use content from expansions. Checks for expansion-related
# map files, client compatibility and class/race character creation.
-# Default: 2 - (Expansion 2)
+# Default: 3 - (Expansion 3)
+# 2 - (Expansion 2)
# 1 - (Expansion 1)
# 0 - (Disabled, Ignore and disable expansion content (maps, races, classes)
-Expansion = 2
+Expansion = 3
#
# MinPlayerName
@@ -738,16 +739,16 @@ SkipCinematics = 0
# Description: Maximum level that can be reached by players.
# Important: Levels beyond 100 are not recommended at all.
# Range: 1-255
-# Default: 80
+# Default: 85
-MaxPlayerLevel = 80
+MaxPlayerLevel = 85
#
# MinDualSpecLevel
# Description: Level requirement for Dual Talent Specialization.
-# Default: 40
+# Default: 30
-MinDualSpecLevel = 40
+MinDualSpecLevel = 30
#
# StartPlayerLevel
@@ -774,40 +775,12 @@ StartHeroicPlayerLevel = 55
StartPlayerMoney = 0
#
-# MaxHonorPoints
-# Description: Maximum honor points a character can have.
-# Default: 75000
-
-MaxHonorPoints = 75000
-
-#
-# StartHonorPoints
-# Description: Amount of honor points that characters have after creation.
-# Default: 0
-
-StartHonorPoints = 0
-
-#
-# MaxArenaPoints
-# Description: Maximum arena points a character can have.
-# Default: 10000
-
-MaxArenaPoints = 10000
-
-#
-# StartArenaPoints
-# Description: Amount of arena points that characters has after creation.
-# Default: 0
-
-StartArenaPoints = 0
-
-#
# RecruitAFriend.MaxLevel
# Description: Highest level up to which a character can benefit from the Recruit-A-Friend
# experience multiplier.
-# Default: 60
+# Default: 80
-RecruitAFriend.MaxLevel = 60
+RecruitAFriend.MaxLevel = 80
#
# RecruitAFriend.MaxDifference
@@ -846,15 +819,6 @@ AllFlightPaths = 0
InstantFlightPaths = 0
#
-# AlwaysMaxSkillForLevel
-# Description: Players will automatically gain max skill level when logging in or leveling
-# up.
-# Default: 0 - (Disabled)
-# 1 - (Enabled)
-
-AlwaysMaxSkillForLevel = 0
-
-#
# ActivateWeather
# Description: Activate the weather system.
# Default: 1 - (Enabled)
@@ -985,6 +949,16 @@ Guild.ResetHour = 6
Guild.BankEventLogRecordsCount = 25
#
+# Guild.NewsLogRecordsCount
+# Description: Number of log entries for guild news that are stored per guild. Old
+# entries will be overwritten if the number of log entries exceed the
+# configured value. High numbers prevent this behavior but may have performance
+# impacts.
+# Default: 250
+
+Guild.NewsLogRecordsCount = 250
+
+#
# MaxPrimaryTradeSkill
# Description: Maximum number of primary professions a character can learn.
# Range: 0-10
@@ -995,10 +969,10 @@ MaxPrimaryTradeSkill = 2
#
# MinPetitionSigns
# Description: Number of required signatures on charters to create a guild.
-# Range: 0-9
-# Default: 9
+# Range: 0-4
+# Default: 4
-MinPetitionSigns = 9
+MinPetitionSigns = 4
#
# MaxGroupXPDistance
@@ -1883,19 +1857,13 @@ Rate.InstanceResetTime = 1
#
# SkillGain.Crafting
-# SkillGain.Defense
# SkillGain.Gathering
-# SkillGain.Weapon
# Description: Crafting/defense/gathering/weapon skills gain rate.
# Default: 1 - (SkillGain.Crafting)
-# 1 - (SkillGain.Defense)
# 1 - (SkillGain.Gathering)
-# 1 - (SkillGain.Weapon)
SkillGain.Crafting = 1
-SkillGain.Defense = 1
SkillGain.Gathering = 1
-SkillGain.Weapon = 1
#
# SkillChance.Orange
@@ -2137,9 +2105,9 @@ Battleground.Random.ResetHour = 6
#
# Battleground.RewardWinnerHonorFirst
-# Battleground.RewardWinnerArenaFirst
+# Battleground.RewardWinnerConquestFirst
# Battleground.RewardWinnerHonorLast
-# Battleground.RewardWinnerArenaLast
+# Battleground.RewardWinnerConquestLast
# Battleground.RewardLoserHonorFirst
# Battleground.RewardLoserHonorLast
# Description: Random Battlegrounds / call to the arms rewards.
@@ -2151,12 +2119,12 @@ Battleground.Random.ResetHour = 6
# 5 - Battleground.RewardLoserHonorLast
#
-Battleground.RewardWinnerHonorFirst = 30
-Battleground.RewardWinnerArenaFirst = 25
-Battleground.RewardWinnerHonorLast = 15
-Battleground.RewardWinnerArenaLast = 0
-Battleground.RewardLoserHonorFirst = 5
-Battleground.RewardLoserHonorLast = 5
+Battleground.RewardWinnerHonorFirst = 27000
+Battleground.RewardWinnerConquestFirst = 10000
+Battleground.RewardWinnerHonorLast = 13500
+Battleground.RewardWinnerConquestLast = 5000
+Battleground.RewardLoserHonorFirst = 4500
+Battleground.RewardLoserHonorLast = 3500
#
###################################################################################################
@@ -2801,6 +2769,150 @@ Log.Async.Enable = 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
+# How often should currency week count reset (days)
+# Default: 7 (weekly)
+#
+
+Currency.ResetInterval = 7
+
+#
+# Currency.ResetWeekDay
+# Week day when currency week count is reset (0..6) 0 == Sunday
+# Default: 3 (Wednesday)
+#
+
+Currency.ResetWeekDay = 3
+
+#
+# Currency.ResetHour
+# Hour of a day when currency week count is reset (0..23)
+# Default: 6
+#
+
+Currency.ResetHour = 6
+
+#
+# Currency.StartHonorPoints
+# Amount of honor points that new players will start with
+# Default: 0 (with precision)
+#
+
+Currency.StartHonorPoints = 0
+
+#
+# Currency.MaxHonorPoints
+# Amount honor points a player can have
+# Default: 4000
+#
+
+Currency.MaxHonorPoints = 4000
+
+#
+# Currency.StartJusticePoints
+# Amount of justice points that new players will start with
+# Default: 0 (with precision)
+#
+
+Currency.StartJusticePoints = 0
+
+#
+# Currency.MaxJusticePoints
+# Amount justice points a player can have
+# Default: 4000
+#
+
+Currency.MaxJusticePoints = 4000
+
+#
+# Currency.StartConquestPoints
+# Amount of conquest points that new players will start with
+# Default: 0 (with precision)
+#
+
+Currency.StartConquestPoints = 0
+
+#
+# Currency.ConquestPointsDefaultWeekCap
+# Amount of conquest points that player can earn per week
+# Default: 1350
+#
+
+Currency.ConquestPointsDefaultWeekCap = 1350
+
+#
+# Currency.ConquestPointsArenaReward
+# Amount of conquest points rewarded by winning arenas
+# Default: 180
+#
+
+Currency.ConquestPointsArenaReward = 180
+
+#
+###################################################################################################
# PACKET SPOOF PROTECTION SETTINGS
#
# These settings determine which action to take when harmful packet spoofing is detected.
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index c2ea8a85926..0267f17fd6c 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -11,7 +11,9 @@
add_subdirectory(map_extractor)
add_subdirectory(vmap4_assembler)
add_subdirectory(vmap4_extractor)
-add_subdirectory(mmaps_generator)
-if (WITH_MESHEXTRACTOR)
- add_subdirectory(mesh_extractor)
-endif()
+
+#if (WITH_MESHEXTRACTOR)
+# add_subdirectory(mesh_extractor)
+#else()
+# add_subdirectory(mmaps_generator)
+#endif()
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index f05424d6bbe..664b80c292d 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -11,20 +11,13 @@
file(GLOB_RECURSE sources *.cpp *.h)
-set(include_Dirs
- ${CMAKE_SOURCE_DIR}/src/server/shared
- ${CMAKE_SOURCE_DIR}/dep/libmpq
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/loadlib
+include_directories (
+ ${CMAKE_SOURCE_DIR}/src/server/shared
+ ${CMAKE_SOURCE_DIR}/dep/StormLib/src
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/loadlib
)
-if( WIN32 )
- set(include_Dirs
- ${include_Dirs}
- ${CMAKE_SOURCE_DIR}/dep/libmpq/win
- )
-endif()
-
include_directories(${include_Dirs})
add_executable(mapextractor
@@ -32,11 +25,13 @@ add_executable(mapextractor
)
target_link_libraries(mapextractor
- mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
+ storm
)
+add_dependencies(mapextractor storm)
+
if( UNIX )
install(TARGETS mapextractor DESTINATION bin)
elseif( WIN32 )
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index ca04e5a2081..9eafb68ca15 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -20,18 +20,20 @@
#include <stdio.h>
#include <deque>
-#include <set>
+#include <list>
#include <cstdlib>
+#include <cstring>
#ifdef _WIN32
#include "direct.h"
#else
#include <sys/stat.h>
#include <unistd.h>
+#define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND
#endif
+#include "StormLib.h"
#include "dbcfile.h"
-#include "mpq_libmpq04.h"
#include "adt.h"
#include "wdt.h"
@@ -48,11 +50,13 @@
#endif
#ifdef O_LARGEFILE
- #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE)
+ #define OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE)
#else
#define OPEN_FLAGS (O_RDONLY | O_BINARY)
#endif
-extern ArchiveSet gOpenArchives;
+
+HANDLE WorldMpq = NULL;
+HANDLE LocaleMpq = NULL;
typedef struct
{
@@ -78,6 +82,7 @@ enum Extract
// Select data for extract
int CONF_extract = EXTRACT_MAP | EXTRACT_DBC;
+
// This option allow limit minimum height to some value (Allow save some memory)
bool CONF_allow_height_limit = true;
float CONF_use_minHeight = -500.0f;
@@ -89,46 +94,63 @@ float CONF_float_to_int16_limit = 2048.0f; // Max accuracy = val/65536
float CONF_flat_height_delta_limit = 0.005f; // If max - min less this value - surface is flat
float CONF_flat_liquid_delta_limit = 0.001f; // If max - min less this value - liquid surface is flat
-// List MPQ for extract from
-const char *CONF_mpq_list[]={
- "common.MPQ",
- "common-2.MPQ",
- "lichking.MPQ",
- "expansion.MPQ",
- "patch.MPQ",
- "patch-2.MPQ",
- "patch-3.MPQ",
- "patch-4.MPQ",
- "patch-5.MPQ",
+uint32 CONF_TargetBuild = 15595; // 4.3.4.15595
+
+// List MPQ for extract maps from
+char const* CONF_mpq_list[]=
+{
+ "world.MPQ",
+ "art.MPQ",
+ "world2.MPQ",
+ "expansion1.MPQ",
+ "expansion2.MPQ",
+ "expansion3.MPQ",
+};
+
+uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0};
+#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder
+#define NEW_BASE_SET_BUILD 15211
+
+char const* Locales[] =
+{
+ "enGB", "enUS",
+ "deDE", "esES",
+ "frFR", "koKR",
+ "zhCN", "zhTW",
+ "enCN", "enTW",
+ "esMX", "ruRU"
+};
+
+TCHAR const* LocalesT[] =
+{
+ _T("enGB"), _T("enUS"),
+ _T("deDE"), _T("esES"),
+ _T("frFR"), _T("koKR"),
+ _T("zhCN"), _T("zhTW"),
+ _T("enCN"), _T("enTW"),
+ _T("esMX"), _T("ruRU"),
};
-static const char* const langs[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU" };
-#define LANG_COUNT 12
+#define LOCALES_COUNT 12
-void CreateDir( const std::string& Path )
+void CreateDir(std::string const& path)
{
- if(chdir(Path.c_str()) == 0)
+ if (chdir(path.c_str()) == 0)
{
chdir("../");
return;
}
- int ret;
- #ifdef _WIN32
- ret = _mkdir( Path.c_str());
- #else
- ret = mkdir( Path.c_str(), 0777 );
- #endif
- if (ret != 0)
- {
- printf("Fatal Error: Could not create directory %s check your permissions", Path.c_str());
- exit(1);
- }
+#ifdef _WIN32
+ _mkdir(path.c_str());
+#else
+ mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO); // 0777
+#endif
}
-bool FileExists( const char* FileName )
+bool FileExists(TCHAR const* fileName)
{
- int fp = _open(FileName, OPEN_FLAGS);
+ int fp = _open(fileName, OPEN_FLAGS);
if(fp != -1)
{
_close(fp);
@@ -138,7 +160,7 @@ bool FileExists( const char* FileName )
return false;
}
-void Usage(char* prg)
+void Usage(char const* prg)
{
printf(
"Usage:\n"\
@@ -147,52 +169,62 @@ void Usage(char* prg)
"-o set output path\n"\
"-e extract only MAP(1)/DBC(2) - standard: both(3)\n"\
"-f height stored as int (less map size but lost some accuracy) 1 by default\n"\
- "Example: %s -f 0 -i \"c:\\games\\game\"", prg, prg);
+ "-b target build (default %u)\n"\
+ "Example: %s -f 0 -i \"c:\\games\\game\"", prg, CONF_TargetBuild, prg);
exit(1);
}
-void HandleArgs(int argc, char * arg[])
+void HandleArgs(int argc, char* arg[])
{
- for(int c = 1; c < argc; ++c)
+ for (int c = 1; c < argc; ++c)
{
// i - input path
// o - output path
// e - extract only MAP(1)/DBC(2) - standard both(3)
// f - use float to int conversion
// h - limit minimum height
- if(arg[c][0] != '-')
+ // b - target client build
+ if (arg[c][0] != '-')
Usage(arg[0]);
- switch(arg[c][1])
+ switch (arg[c][1])
{
case 'i':
- if(c + 1 < argc) // all ok
- strcpy(input_path, arg[(c++) + 1]);
+ if (c + 1 < argc) // all ok
+ strcpy(input_path, arg[c++ + 1]);
else
Usage(arg[0]);
break;
case 'o':
- if(c + 1 < argc) // all ok
- strcpy(output_path, arg[(c++) + 1]);
+ if (c + 1 < argc) // all ok
+ strcpy(output_path, arg[c++ + 1]);
else
Usage(arg[0]);
break;
case 'f':
- if(c + 1 < argc) // all ok
- CONF_allow_float_to_int=atoi(arg[(c++) + 1])!=0;
+ if (c + 1 < argc) // all ok
+ CONF_allow_float_to_int = atoi(arg[c++ + 1])!=0;
else
Usage(arg[0]);
break;
case 'e':
- if(c + 1 < argc) // all ok
+ if (c + 1 < argc) // all ok
{
- CONF_extract=atoi(arg[(c++) + 1]);
- if(!(CONF_extract > 0 && CONF_extract < 4))
+ CONF_extract = atoi(arg[c++ + 1]);
+ if (!(CONF_extract > 0 && CONF_extract < 4))
Usage(arg[0]);
}
else
Usage(arg[0]);
break;
+ case 'b':
+ if (c + 1 < argc) // all ok
+ CONF_TargetBuild = atoi(arg[c++ + 1]);
+ else
+ Usage(arg[0]);
+ break;
+ default:
+ break;
}
}
}
@@ -200,22 +232,31 @@ void HandleArgs(int argc, char * arg[])
uint32 ReadBuild(int locale)
{
// include build info file also
- std::string filename = std::string("component.wow-")+langs[locale]+".txt";
+ std::string filename = std::string("component.wow-") + Locales[locale] + ".txt";
//printf("Read %s file... ", filename.c_str());
- MPQFile m(filename.c_str());
- if(m.isEof())
+ HANDLE dbcFile;
+ if (!SFileOpenFileEx(LocaleMpq, filename.c_str(), SFILE_OPEN_PATCHED_FILE, &dbcFile))
{
printf("Fatal error: Not found %s file!\n", filename.c_str());
exit(1);
}
- std::string text = std::string(m.getPointer(), m.getSize());
- m.close();
+ char buff[512];
+ DWORD readBytes = 0;
+ SFileReadFile(dbcFile, buff, 512, &readBytes, NULL);
+ if (!readBytes)
+ {
+ printf("Fatal error: Not found %s file!\n", filename.c_str());
+ exit(1);
+ }
+
+ std::string text = buff;
+ SFileCloseFile(dbcFile);
size_t pos = text.find("version=\"");
size_t pos1 = pos + strlen("version=\"");
- size_t pos2 = text.find("\"",pos1);
+ size_t pos2 = text.find("\"", pos1);
if (pos == text.npos || pos2 == text.npos || pos1 >= pos2)
{
printf("Fatal error: Invalid %s file format!\n", filename.c_str());
@@ -237,9 +278,16 @@ uint32 ReadBuild(int locale)
uint32 ReadMapDBC()
{
printf("Read Map.dbc file... ");
- DBCFile dbc("DBFilesClient\\Map.dbc");
- if(!dbc.open())
+ HANDLE dbcFile;
+ if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\Map.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile))
+ {
+ printf("Fatal error: Cannot find Map.dbc in archive!\n");
+ exit(1);
+ }
+
+ DBCFile dbc(dbcFile);
+ if (!dbc.open())
{
printf("Fatal error: Invalid Map.dbc file format!\n");
exit(1);
@@ -252,15 +300,23 @@ uint32 ReadMapDBC()
map_ids[x].id = dbc.getRecord(x).getUInt(0);
strcpy(map_ids[x].name, dbc.getRecord(x).getString(1));
}
- printf("Done! (%u maps loaded)\n", (uint32)map_count);
+
+ SFileCloseFile(dbcFile);
+ printf("Done! (%u maps loaded)\n", uint32(map_count));
return map_count;
}
void ReadAreaTableDBC()
{
printf("Read AreaTable.dbc file...");
- DBCFile dbc("DBFilesClient\\AreaTable.dbc");
+ HANDLE dbcFile;
+ if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\AreaTable.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile))
+ {
+ printf("Fatal error: Cannot find AreaTable.dbc in archive!\n");
+ exit(1);
+ }
+ DBCFile dbc(dbcFile);
if(!dbc.open())
{
printf("Fatal error: Invalid AreaTable.dbc file format!\n");
@@ -268,22 +324,27 @@ void ReadAreaTableDBC()
}
size_t area_count = dbc.getRecordCount();
- size_t maxid = dbc.getMaxId();
- areas = new uint16[maxid + 1];
- memset(areas, 0xff, (maxid + 1) * sizeof(uint16));
+ maxAreaId = dbc.getMaxId();
+ areas = new uint16[maxAreaId + 1];
- for(uint32 x = 0; x < area_count; ++x)
+ for (uint32 x = 0; x < area_count; ++x)
areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
- maxAreaId = dbc.getMaxId();
-
- printf("Done! (%u areas loaded)\n", (uint32)area_count);
+ SFileCloseFile(dbcFile);
+ printf("Done! (%u areas loaded)\n", uint32(area_count));
}
void ReadLiquidTypeTableDBC()
{
printf("Read LiquidType.dbc file...");
- DBCFile dbc("DBFilesClient\\LiquidType.dbc");
+ HANDLE dbcFile;
+ if (!SFileOpenFileEx(LocaleMpq, "DBFilesClient\\LiquidType.dbc", SFILE_OPEN_PATCHED_FILE, &dbcFile))
+ {
+ printf("Fatal error: Cannot find LiquidType.dbc in archive!\n");
+ exit(1);
+ }
+
+ DBCFile dbc(dbcFile);
if(!dbc.open())
{
printf("Fatal error: Invalid LiquidType.dbc file format!\n");
@@ -298,6 +359,7 @@ void ReadLiquidTypeTableDBC()
for(uint32 x = 0; x < liqTypeCount; ++x)
LiqType[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
+ SFileCloseFile(dbcFile);
printf("Done! (%u LiqTypes loaded)\n", (uint32)liqTypeCount);
}
@@ -401,16 +463,9 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
{
ADT_file adt;
- if (!adt.loadFile(filename))
+ if (!adt.loadFile(WorldMpq, filename))
return false;
- adt_MCIN *cells = adt.a_grid->getMCIN();
- if (!cells)
- {
- printf("Can't find cells in '%s'\n", filename);
- return false;
- }
-
memset(liquid_show, 0, sizeof(liquid_show));
memset(liquid_flags, 0, sizeof(liquid_flags));
memset(liquid_entry, 0, sizeof(liquid_entry));
@@ -422,24 +477,27 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
map.buildMagic = build;
// Get area flags data
- for (int i=0;i<ADT_CELLS_PER_GRID;i++)
+ for (int i = 0; i < ADT_CELLS_PER_GRID; ++i)
{
- for(int j=0;j<ADT_CELLS_PER_GRID;j++)
+ for (int j = 0; j < ADT_CELLS_PER_GRID; ++j)
{
- adt_MCNK * cell = cells->getMCNK(i,j);
+ adt_MCNK* cell = adt.cells[i][j];
uint32 areaid = cell->areaid;
- if(areaid && areaid <= maxAreaId)
+ if (areaid && areaid <= maxAreaId)
{
- if(areas[areaid] != 0xffff)
+ if (areas[areaid] != 0xFFFF)
{
area_flags[i][j] = areas[areaid];
continue;
}
+
printf("File: %s\nCan't find area flag for areaid %u [%d, %d].\n", filename, areaid, cell->ix, cell->iy);
}
+
area_flags[i][j] = 0xffff;
}
}
+
//============================================
// Try pack area data
//============================================
@@ -481,7 +539,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
{
for(int j=0;j<ADT_CELLS_PER_GRID;j++)
{
- adt_MCNK * cell = cells->getMCNK(i,j);
+ adt_MCNK * cell = adt.cells[i][j];
if (!cell)
continue;
// Height values for triangles stored in order:
@@ -652,7 +710,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
{
for(int j = 0; j < ADT_CELLS_PER_GRID; j++)
{
- adt_MCNK *cell = cells->getMCNK(i, j);
+ adt_MCNK *cell = adt.cells[i][j];
if (!cell)
continue;
@@ -752,7 +810,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
// Dark water detect
if (LiqType[h->liquidType] == LIQUID_TYPE_OCEAN)
{
- uint8 *lm = h2o->getLiquidLightMap(h);
+ uint8* lm = h2o->getLiquidLightMap(h);
if (!lm)
liquid_flags[i][j] |= MAP_LIQUID_TYPE_DARK_WATER;
}
@@ -760,34 +818,37 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
if (!count && liquid_flags[i][j])
printf("Wrong liquid detect in MH2O chunk");
- float *height = h2o->getLiquidHeightMap(h);
+ float* height = h2o->getLiquidHeightMap(h);
int pos = 0;
- for (int y=0; y<=h->height;y++)
+ for (int y = 0; y <= h->height; y++)
{
- int cy = i*ADT_CELL_SIZE + y + h->yOffset;
- for (int x=0; x<= h->width; x++)
+ int cy = i * ADT_CELL_SIZE + y + h->yOffset;
+ for (int x = 0; x <= h->width; x++)
{
- int cx = j*ADT_CELL_SIZE + x + h->xOffset;
+ int cx = j * ADT_CELL_SIZE + x + h->xOffset;
+
if (height)
liquid_height[cy][cx] = height[pos];
else
liquid_height[cy][cx] = h->heightLevel1;
+
pos++;
}
}
}
}
}
+
//============================================
// Pack liquid data
//============================================
uint8 type = liquid_flags[0][0];
bool fullType = false;
- for (int y=0;y<ADT_CELLS_PER_GRID;y++)
+ for (int y = 0; y < ADT_CELLS_PER_GRID; y++)
{
- for(int x=0;x<ADT_CELLS_PER_GRID;x++)
+ for (int x = 0; x < ADT_CELLS_PER_GRID; x++)
{
- if (liquid_flags[y][x]!=type)
+ if (liquid_flags[y][x] != type)
{
fullType = true;
y = ADT_CELLS_PER_GRID;
@@ -874,7 +935,7 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
{
for (int j = 0; j < ADT_CELLS_PER_GRID; ++j)
{
- adt_MCNK * cell = cells->getMCNK(i,j);
+ adt_MCNK * cell = adt.cells[i][j];
if (!cell)
continue;
holes[i][j] = cell->holes;
@@ -926,15 +987,16 @@ bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/,
if (map.liquidMapOffset)
{
fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
- if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE))
+ if (!(liquidHeader.flags & MAP_LIQUID_NO_TYPE))
{
fwrite(liquid_entry, sizeof(liquid_entry), 1, output);
fwrite(liquid_flags, sizeof(liquid_flags), 1, output);
}
- if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT))
+
+ if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
{
- for (int y=0; y<liquidHeader.height;y++)
- fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
+ for (int y = 0; y < liquidHeader.height; y++)
+ fwrite(&liquid_height[y + liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
}
}
@@ -965,186 +1027,330 @@ void ExtractMapsFromMpq(uint32 build)
CreateDir(path);
printf("Convert map files\n");
- for(uint32 z = 0; z < map_count; ++z)
+ for (uint32 z = 0; z < map_count; ++z)
{
printf("Extract %s (%d/%u) \n", map_ids[z].name, z+1, map_count);
// Loadup map grid data
sprintf(mpq_map_name, "World\\Maps\\%s\\%s.wdt", map_ids[z].name, map_ids[z].name);
WDT_file wdt;
- if (!wdt.loadFile(mpq_map_name, false))
- {
-// printf("Error loading %s map wdt data\n", map_ids[z].name);
+ if (!wdt.loadFile(WorldMpq, mpq_map_name, false))
continue;
- }
- for(uint32 y = 0; y < WDT_MAP_SIZE; ++y)
+ for (uint32 y = 0; y < WDT_MAP_SIZE; ++y)
{
- for(uint32 x = 0; x < WDT_MAP_SIZE; ++x)
+ for (uint32 x = 0; x < WDT_MAP_SIZE; ++x)
{
- if (!wdt.main->adt_list[y][x].exist)
+ if (!(wdt.main->adt_list[y][x].flag & 0x1))
continue;
+
sprintf(mpq_filename, "World\\Maps\\%s\\%s_%u_%u.adt", map_ids[z].name, map_ids[z].name, x, y);
sprintf(output_filename, "%s/maps/%03u%02u%02u.map", output_path, map_ids[z].id, y, x);
ConvertADT(mpq_filename, output_filename, y, x, build);
}
+
// draw progress bar
printf("Processing........................%d%%\r", (100 * (y+1)) / WDT_MAP_SIZE);
}
}
+
printf("\n");
delete [] areas;
delete [] map_ids;
}
-bool ExtractFile( char const* mpq_name, std::string const& filename )
+bool ExtractFile(HANDLE fileInArchive, char const* filename)
{
- FILE *output = fopen(filename.c_str(), "wb");
+ FILE* output = fopen(filename, "wb");
if(!output)
{
- printf("Can't create the output file '%s'\n", filename.c_str());
+ printf("Can't create the output file '%s'\n", filename);
return false;
}
- MPQFile m(mpq_name);
- if(!m.isEof())
- fwrite(m.getPointer(), 1, m.getSize(), output);
+
+ char buffer[0x10000];
+ DWORD readBytes = 1;
+
+ while (readBytes > 0)
+ {
+ SFileReadFile(fileInArchive, buffer, sizeof(buffer), &readBytes, NULL);
+ if (readBytes > 0)
+ fwrite(buffer, 1, readBytes, output);
+ }
fclose(output);
return true;
}
-void ExtractDBCFiles(int locale, bool basicLocale)
+void ExtractDBCFiles(int l, bool basicLocale)
{
printf("Extracting dbc files...\n");
- std::set<std::string> dbcfiles;
-
- // get DBC file list
- for(ArchiveSet::iterator i = gOpenArchives.begin(); i != gOpenArchives.end();++i)
+ SFILE_FIND_DATA foundFile;
+ memset(&foundFile, 0, sizeof(foundFile));
+ HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*dbc", &foundFile, NULL);
+ HANDLE dbcFile = NULL;
+ uint32 count = 0;
+ if (listFile)
{
- vector<string> files;
- (*i)->GetFileListTo(files);
- for (vector<string>::iterator iter = files.begin(); iter != files.end(); ++iter)
- if (iter->rfind(".dbc") == iter->length() - strlen(".dbc"))
- dbcfiles.insert(*iter);
+ std::string outputPath = output_path;
+ outputPath += "/dbc/";
+
+ CreateDir(outputPath);
+ if (!basicLocale)
+ {
+ outputPath += Locales[l];
+ outputPath += "/";
+ CreateDir(outputPath);
+ }
+
+ std::string filename;
+
+ do
+ {
+ if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile))
+ {
+ printf("Unable to open file %s in the archive\n", foundFile.cFileName);
+ continue;
+ }
+
+ filename = foundFile.cFileName;
+ filename = outputPath + filename.substr(filename.rfind('\\'));
+
+ if (FileExists(filename.c_str()))
+ continue;
+
+ if (ExtractFile(dbcFile, filename.c_str()))
+ ++count;
+
+ SFileCloseFile(dbcFile);
+ } while (SFileFindNextFile(listFile, &foundFile));
+
+ SFileFindClose(listFile);
}
- std::string path = output_path;
- path += "/dbc/";
- CreateDir(path);
- if(!basicLocale)
+ printf("Extracted %u DBC files\n\n", count);
+}
+
+void ExtractDB2Files(int l, bool basicLocale)
+{
+ printf("Extracting db2 files...\n");
+
+ SFILE_FIND_DATA foundFile;
+ memset(&foundFile, 0, sizeof(foundFile));
+ HANDLE listFile = SFileFindFirstFile(LocaleMpq, "DBFilesClient\\*db2", &foundFile, NULL);
+ HANDLE dbcFile = NULL;
+ uint32 count = 0;
+ if (listFile)
{
- path += langs[locale];
- path += "/";
- CreateDir(path);
+ std::string outputPath = output_path;
+ outputPath += "/dbc/";
+ if (!basicLocale)
+ {
+ outputPath += Locales[l];
+ outputPath += "/";
+ }
+
+ std::string filename;
+
+ do
+ {
+ if (!SFileOpenFileEx(LocaleMpq, foundFile.cFileName, SFILE_OPEN_PATCHED_FILE, &dbcFile))
+ {
+ printf("Unable to open file %s in the archive\n", foundFile.cFileName);
+ continue;
+ }
+
+ filename = foundFile.cFileName;
+ filename = outputPath + filename.substr(filename.rfind('\\'));
+ if (ExtractFile(dbcFile, filename.c_str()))
+ ++count;
+
+ SFileCloseFile(dbcFile);
+ } while (SFileFindNextFile(listFile, &foundFile));
+
+ SFileFindClose(listFile);
}
- // extract Build info file
- {
- string mpq_name = std::string("component.wow-") + langs[locale] + ".txt";
- string filename = path + mpq_name;
+ printf("Extracted %u DB2 files\n\n", count);
+}
- ExtractFile(mpq_name.c_str(), filename);
+bool LoadLocaleMPQFile(int locale)
+{
+ TCHAR buff[512];
+ memset(buff, 0, sizeof(buff));
+ _stprintf(buff, _T("%s/Data/%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]);
+ if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ {
+ _tprintf(_T("\nLoading %s locale MPQs\n"), LocalesT[locale]);
+ _tprintf(_T("Cannot open archive %s\n"), buff);
+ }
+ return false;
}
- // extract DBCs
- uint32 count = 0;
- for (set<string>::iterator iter = dbcfiles.begin(); iter != dbcfiles.end(); ++iter)
+ _tprintf(_T("\nLoading %s locale MPQs\n"), LocalesT[locale]);
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
{
- string filename = path;
- filename += (iter->c_str() + strlen("DBFilesClient\\"));
-
- if(FileExists(filename.c_str()))
+ // Do not attempt to read older MPQ patch archives past this build, they were merged with base
+ // and trying to read them together with new base will not end well
+ if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD)
continue;
- if (ExtractFile(iter->c_str(), filename))
- ++count;
+ memset(buff, 0, sizeof(buff));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(buff, _T("%s/Data/%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]);
+ }
+ else
+ {
+ prefix = Locales[locale];
+ _stprintf(buff, _T("%s/Data/wow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0))
+ {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), buff);
+ continue;
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), buff);
}
- printf("Extracted %u DBC files\n\n", count);
+
+ printf("\n");
+ return true;
}
-void LoadLocaleMPQFiles(int const locale)
+void LoadCommonMPQFiles(uint32 build)
{
- char filename[512];
-
- sprintf(filename,"%s/Data/%s/locale-%s.MPQ", input_path, langs[locale], langs[locale]);
- new MPQArchive(filename);
+ TCHAR filename[512];
+ _stprintf(filename, _T("%s/Data/world.MPQ"), input_path);
+ _tprintf(_T("Loading common MPQ files\n"));
+ if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ return;
+ }
- for(int i = 1; i < 5; ++i)
+ int count = sizeof(CONF_mpq_list) / sizeof(char*);
+ for (int i = 1; i < count; ++i)
{
- char ext[3] = "";
- if(i > 1)
- sprintf(ext, "-%i", i);
+ if (build < NEW_BASE_SET_BUILD && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ
+ continue;
+
+ _stprintf(filename, _T("%s/Data/%s"), input_path, CONF_mpq_list[i]);
+ if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
- sprintf(filename,"%s/Data/%s/patch-%s%s.MPQ", input_path, langs[locale], langs[locale], ext);
- if(FileExists(filename))
- new MPQArchive(filename);
}
-}
-void LoadCommonMPQFiles()
-{
- char filename[512];
- int count = sizeof(CONF_mpq_list)/sizeof(char*);
- for(int i = 0; i < count; ++i)
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
{
- sprintf(filename, "%s/Data/%s", input_path, CONF_mpq_list[i]);
- if(FileExists(filename))
- new MPQArchive(filename);
+ // Do not attempt to read older MPQ patch archives past this build, they were merged with base
+ // and trying to read them together with new base will not end well
+ if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD)
+ continue;
+
+ memset(filename, 0, sizeof(filename));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(filename, _T("%s/Data/wow-update-base-%u.MPQ"), input_path, Builds[i]);
+ }
+ else
+ {
+ prefix = "base";
+ _stprintf(filename, _T("%s/Data/wow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ continue;
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
}
-}
-inline void CloseMPQFiles()
-{
- for(ArchiveSet::iterator j = gOpenArchives.begin(); j != gOpenArchives.end();++j) (*j)->close();
- gOpenArchives.clear();
+ printf("\n");
}
int main(int argc, char * arg[])
{
printf("Map & DBC Extractor\n");
- printf("===================\n\n");
+ printf("===================\n");
HandleArgs(argc, arg);
int FirstLocale = -1;
uint32 build = 0;
- for (int i = 0; i < LANG_COUNT; i++)
+ for (int i = 0; i < LOCALES_COUNT; ++i)
{
- char tmp1[512];
- sprintf(tmp1, "%s/Data/%s/locale-%s.MPQ", input_path, langs[i], langs[i]);
- if (FileExists(tmp1))
+ //Open MPQs
+ if (!LoadLocaleMPQFile(i))
{
- printf("Detected locale: %s\n", langs[i]);
-
- //Open MPQs
- LoadLocaleMPQFiles(i);
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ printf("Unable to load %s locale archives!\n", Locales[i]);
+ continue;
+ }
- if((CONF_extract & EXTRACT_DBC) == 0)
+ printf("Detected locale: %s\n", Locales[i]);
+ if ((CONF_extract & EXTRACT_DBC) == 0)
+ {
+ FirstLocale = i;
+ build = ReadBuild(i);
+ if (build > CONF_TargetBuild)
{
- FirstLocale = i;
- build = ReadBuild(FirstLocale);
- printf("Detected client build: %u\n", build);
- break;
+ printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], build, CONF_TargetBuild);
+ return 0;
}
- //Extract DBC files
- if(FirstLocale < 0)
- {
- FirstLocale = i;
- build = ReadBuild(FirstLocale);
- printf("Detected client build: %u\n", build);
- ExtractDBCFiles(i, true);
- }
- else
- ExtractDBCFiles(i, false);
+ printf("Detected client build: %u\n", build);
+ printf("\n");
+ break;
+ }
+
+ //Extract DBC files
+ uint32 tempBuild = ReadBuild(i);
+ printf("Detected client build %u for locale %s\n", tempBuild, Locales[i]);
+ if (tempBuild > CONF_TargetBuild)
+ {
+ SFileCloseArchive(LocaleMpq);
+ printf("Base locale-%s.MPQ has build higher than target build (%u > %u), nothing extracted!\n", Locales[i], tempBuild, CONF_TargetBuild);
+ continue;
+ }
+
+ printf("\n");
+ ExtractDBCFiles(i, FirstLocale < 0);
+ ExtractDB2Files(i, FirstLocale < 0);
- //Close MPQs
- CloseMPQFiles();
+ if (FirstLocale < 0)
+ {
+ FirstLocale = i;
+ build = tempBuild;
}
+
+ //Close MPQs
+ SFileCloseArchive(LocaleMpq);
}
- if(FirstLocale < 0)
+ if (FirstLocale < 0)
{
printf("No locales detected\n");
return 0;
@@ -1152,17 +1358,18 @@ int main(int argc, char * arg[])
if (CONF_extract & EXTRACT_MAP)
{
- printf("Using locale: %s\n", langs[FirstLocale]);
+ printf("Using locale: %s\n", Locales[FirstLocale]);
// Open MPQs
- LoadLocaleMPQFiles(FirstLocale);
- LoadCommonMPQFiles();
+ LoadLocaleMPQFile(FirstLocale);
+ LoadCommonMPQFiles(build);
// Extract maps
ExtractMapsFromMpq(build);
// Close MPQs
- CloseMPQFiles();
+ SFileCloseArchive(WorldMpq);
+ SFileCloseArchive(LocaleMpq);
}
return 0;
diff --git a/src/tools/map_extractor/adt.cpp b/src/tools/map_extractor/adt.cpp
index 095f598501a..9260828fd41 100644
--- a/src/tools/map_extractor/adt.cpp
+++ b/src/tools/map_extractor/adt.cpp
@@ -19,6 +19,7 @@
#define _CRT_SECURE_NO_DEPRECATE
#include "adt.h"
+#include <cstring>
// Helper
int holetab_h[4] = {0x1111, 0x2222, 0x4444, 0x8888};
@@ -69,10 +70,31 @@ bool ADT_file::prepareLoadedData()
return false;
// Check and prepare MHDR
- a_grid = (adt_MHDR *)(GetData()+8+version->size);
+ a_grid = (adt_MHDR*)(GetData()+8+version->size);
if (!a_grid->prepareLoadedData())
return false;
+ // funny offsets calculations because there is no mapping for them and they have variable lengths
+ uint8* ptr = (uint8*)a_grid + a_grid->size + 8;
+ uint32 mcnk_count = 0;
+ memset(cells, 0, ADT_CELLS_PER_GRID * ADT_CELLS_PER_GRID * sizeof(adt_MCNK*));
+ while (ptr < GetData() + GetDataSize())
+ {
+ uint32 header = *(uint32*)ptr;
+ uint32 size = *(uint32*)(ptr + 4);
+ if (header == MCNKMagic.fcc)
+ {
+ cells[mcnk_count / ADT_CELLS_PER_GRID][mcnk_count % ADT_CELLS_PER_GRID] = (adt_MCNK*)ptr;
+ ++mcnk_count;
+ }
+
+ // move to next chunk
+ ptr += size + 8;
+ }
+
+ if (mcnk_count != ADT_CELLS_PER_GRID * ADT_CELLS_PER_GRID)
+ return false;
+
return true;
}
diff --git a/src/tools/map_extractor/adt.h b/src/tools/map_extractor/adt.h
index 5cb45d488d5..2395bdd1cff 100644
--- a/src/tools/map_extractor/adt.h
+++ b/src/tools/map_extractor/adt.h
@@ -263,15 +263,18 @@ public:
//
// Adt file header chunk
//
+class ADT_file;
class adt_MHDR
{
+ friend class ADT_file;
+
union{
uint32 fcc;
char fcc_txt[4];
};
uint32 size;
- uint32 pad;
+ uint32 flags;
uint32 offsMCIN; // MCIN
uint32 offsTex; // MTEX
uint32 offsModels; // MMDX
@@ -289,9 +292,8 @@ class adt_MHDR
uint32 data5;
public:
bool prepareLoadedData();
- adt_MCIN *getMCIN(){ return (adt_MCIN *)((uint8 *)&pad+offsMCIN);}
- adt_MH2O *getMH2O(){ return offsMH2O ? (adt_MH2O *)((uint8 *)&pad+offsMH2O) : 0;}
-
+ adt_MCIN* getMCIN() { return offsMCIN ? (adt_MCIN *)((uint8 *)&flags+offsMCIN) : NULL; }
+ adt_MH2O* getMH2O() { return offsMH2O ? (adt_MH2O *)((uint8 *)&flags+offsMH2O) : NULL; }
};
class ADT_file : public FileLoader{
@@ -301,7 +303,8 @@ public:
~ADT_file();
void free();
- adt_MHDR *a_grid;
+ adt_MHDR* a_grid;
+ adt_MCNK* cells[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
};
#endif
diff --git a/src/tools/map_extractor/dbcfile.cpp b/src/tools/map_extractor/dbcfile.cpp
index 653b48ff949..fc7d8d25d05 100644
--- a/src/tools/map_extractor/dbcfile.cpp
+++ b/src/tools/map_extractor/dbcfile.cpp
@@ -19,83 +19,91 @@
#define _CRT_SECURE_NO_DEPRECATE
#include "dbcfile.h"
-#include "mpq_libmpq04.h"
-DBCFile::DBCFile(const std::string& filename):
- filename(filename), recordSize(0), recordCount(0), fieldCount(0), stringSize(0), data(NULL), stringTable(NULL)
+DBCFile::DBCFile(HANDLE file) :
+ _file(file), _data(NULL), _stringTable(NULL)
{
-
}
bool DBCFile::open()
{
- MPQFile f(filename.c_str());
char header[4];
- unsigned int na,nb,es,ss;
+ unsigned int na, nb, es, ss;
- if(f.read(header,4)!=4) // Number of records
+ DWORD readBytes = 0;
+ SFileReadFile(_file, header, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of records
return false;
- if(header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3]!='C')
+ if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C')
return false;
- if(f.read(&na,4)!=4) // Number of records
+ SFileReadFile(_file, &na, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of records
return false;
- if(f.read(&nb,4)!=4) // Number of fields
+
+ SFileReadFile(_file, &nb, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of fields
return false;
- if(f.read(&es,4)!=4) // Size of a record
+
+ SFileReadFile(_file, &es, 4, &readBytes, NULL);
+ if (readBytes != 4) // Size of a record
return false;
- if(f.read(&ss,4)!=4) // String size
+
+ SFileReadFile(_file, &ss, 4, &readBytes, NULL);
+ if (readBytes != 4) // String size
return false;
- recordSize = es;
- recordCount = na;
- fieldCount = nb;
- stringSize = ss;
- if(fieldCount*4 != recordSize)
+ _recordSize = es;
+ _recordCount = na;
+ _fieldCount = nb;
+ _stringSize = ss;
+ if (_fieldCount * 4 != _recordSize)
return false;
- data = new unsigned char[recordSize*recordCount+stringSize];
- stringTable = data + recordSize*recordCount;
+ _data = new unsigned char[_recordSize * _recordCount + _stringSize];
+ _stringTable = _data + _recordSize*_recordCount;
- size_t data_size = recordSize*recordCount+stringSize;
- if(f.read(data,data_size)!=data_size)
+ size_t data_size = _recordSize * _recordCount + _stringSize;
+ SFileReadFile(_file, _data, data_size, &readBytes, NULL);
+ if (readBytes != data_size)
return false;
- f.close();
+
return true;
}
+
DBCFile::~DBCFile()
{
- delete [] data;
+ delete [] _data;
}
DBCFile::Record DBCFile::getRecord(size_t id)
{
- assert(data);
- return Record(*this, data + id*recordSize);
+ assert(_data);
+ return Record(*this, _data + id*_recordSize);
}
size_t DBCFile::getMaxId()
{
- assert(data);
+ assert(_data);
size_t maxId = 0;
for(size_t i = 0; i < getRecordCount(); ++i)
- {
- if(maxId < getRecord(i).getUInt(0))
+ if (maxId < getRecord(i).getUInt(0))
maxId = getRecord(i).getUInt(0);
- }
+
return maxId;
}
DBCFile::Iterator DBCFile::begin()
{
- assert(data);
- return Iterator(*this, data);
+ assert(_data);
+ return Iterator(*this, _data);
}
+
DBCFile::Iterator DBCFile::end()
{
- assert(data);
- return Iterator(*this, stringTable);
+ assert(_data);
+ return Iterator(*this, _stringTable);
}
diff --git a/src/tools/map_extractor/dbcfile.h b/src/tools/map_extractor/dbcfile.h
index 526c553e0f0..3c71b615cc9 100644
--- a/src/tools/map_extractor/dbcfile.h
+++ b/src/tools/map_extractor/dbcfile.h
@@ -20,118 +20,125 @@
#define DBCFILE_H
#include <cassert>
#include <string>
+#include "StormLib.h"
class DBCFile
{
-public:
- DBCFile(const std::string &filename);
- ~DBCFile();
+ public:
+ DBCFile(HANDLE file);
+ ~DBCFile();
- // Open database. It must be openened before it can be used.
- bool open();
+ // Open database. It must be openened before it can be used.
+ bool open();
- // Database exceptions
- class Exception
- {
- public:
- Exception(const std::string &message): message(message)
- { }
- virtual ~Exception()
- { }
- const std::string &getMessage() {return message;}
- private:
- std::string message;
- };
- class NotFound: public Exception
- {
- public:
- NotFound(): Exception("Key was not found")
- { }
- };
- // Iteration over database
- class Iterator;
- class Record
- {
- public:
- float getFloat(size_t field) const
- {
- assert(field < file.fieldCount);
- return *reinterpret_cast<float*>(offset+field*4);
- }
- unsigned int getUInt(size_t field) const
+ // Database exceptions
+ class Exception
{
- assert(field < file.fieldCount);
- return *reinterpret_cast<unsigned int*>(offset+field*4);
- }
- int getInt(size_t field) const
- {
- assert(field < file.fieldCount);
- return *reinterpret_cast<int*>(offset+field*4);
- }
- const char *getString(size_t field) const
+ public:
+ Exception(const std::string &message) : message(message) { }
+ virtual ~Exception() { }
+ const std::string &getMessage() { return message; }
+ private:
+ std::string message;
+ };
+
+ class NotFound: public Exception
{
- assert(field < file.fieldCount);
- size_t stringOffset = getUInt(field);
- assert(stringOffset < file.stringSize);
- return reinterpret_cast<char*>(file.stringTable + stringOffset);
- }
- private:
- Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {}
- DBCFile &file;
- unsigned char *offset;
-
- friend class DBCFile;
- friend class DBCFile::Iterator;
- };
- /** Iterator that iterates over records
- */
- class Iterator
- {
- public:
- Iterator(DBCFile &file, unsigned char *offset):
- record(file, offset) {}
- /// Advance (prefix only)
- Iterator & operator++() {
- record.offset += record.file.recordSize;
- return *this;
- }
- /// Return address of current instance
- Record const & operator*() const { return record; }
- const Record* operator->() const {
- return &record;
- }
- /// Comparison
- bool operator==(const Iterator &b) const
+ public:
+ NotFound(): Exception("Key was not found") { }
+ };
+
+ // Iteration over database
+ class Iterator;
+ class Record
{
- return record.offset == b.record.offset;
- }
- bool operator!=(const Iterator &b) const
+ public:
+ float getFloat(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<float*>(offset + field * 4);
+ }
+
+ unsigned int getUInt(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<unsigned int*>(offset + field * 4);
+ }
+
+ int getInt(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<int*>(offset + field * 4);
+ }
+
+ char const* getString(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ size_t stringOffset = getUInt(field);
+ assert(stringOffset < file._stringSize);
+ return reinterpret_cast<char*>(file._stringTable + stringOffset);
+ }
+
+ private:
+ Record(DBCFile& file, unsigned char* offset): file(file), offset(offset) {}
+ DBCFile& file;
+ unsigned char* offset;
+
+ friend class DBCFile;
+ friend class DBCFile::Iterator;
+ };
+ /** Iterator that iterates over records
+ */
+ class Iterator
{
- return record.offset != b.record.offset;
- }
+ public:
+ Iterator(DBCFile &file, unsigned char* offset) : record(file, offset) { }
+
+ /// Advance (prefix only)
+ Iterator& operator++()
+ {
+ record.offset += record.file._recordSize;
+ return *this;
+ }
+
+ /// Return address of current instance
+ Record const& operator*() const { return record; }
+ Record const* operator->() const { return &record; }
+
+ /// Comparison
+ bool operator==(Iterator const& b) const
+ {
+ return record.offset == b.record.offset;
+ }
+
+ bool operator!=(Iterator const& b) const
+ {
+ return record.offset != b.record.offset;
+ }
+
+ private:
+ Record record;
+ };
+
+ // Get record by id
+ Record getRecord(size_t id);
+ /// Get begin iterator over records
+ Iterator begin();
+ /// Get begin iterator over records
+ Iterator end();
+ /// Trivial
+ size_t getRecordCount() const { return _recordCount; }
+ size_t getFieldCount() const { return _fieldCount; }
+ size_t getMaxId();
+
private:
- Record record;
- };
-
- // Get record by id
- Record getRecord(size_t id);
- /// Get begin iterator over records
- Iterator begin();
- /// Get begin iterator over records
- Iterator end();
- /// Trivial
- size_t getRecordCount() const { return recordCount;}
- size_t getFieldCount() const { return fieldCount; }
- size_t getMaxId();
-private:
- std::string filename;
- size_t recordSize;
- size_t recordCount;
- size_t fieldCount;
- size_t stringSize;
- unsigned char *data;
- unsigned char *stringTable;
+ HANDLE _file;
+ size_t _recordSize;
+ size_t _recordCount;
+ size_t _fieldCount;
+ size_t _stringSize;
+ unsigned char* _data;
+ unsigned char* _stringTable;
};
#endif
-
diff --git a/src/tools/map_extractor/loadlib.cpp b/src/tools/map_extractor/loadlib.cpp
index ebe1bd61b65..5d1742c224e 100644
--- a/src/tools/map_extractor/loadlib.cpp
+++ b/src/tools/map_extractor/loadlib.cpp
@@ -19,11 +19,8 @@
#define _CRT_SECURE_NO_DEPRECATE
#include "loadlib.h"
-#include "mpq_libmpq04.h"
#include <cstdio>
-class MPQFile;
-
u_map_fcc MverMagic = { {'R','E','V','M'} };
FileLoader::FileLoader()
@@ -38,28 +35,30 @@ FileLoader::~FileLoader()
free();
}
-bool FileLoader::loadFile(char *filename, bool log)
+bool FileLoader::loadFile(HANDLE mpq, char* filename, bool log)
{
free();
- MPQFile mf(filename);
- if(mf.isEof())
+ HANDLE file;
+ if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file))
{
if (log)
printf("No such file %s\n", filename);
return false;
}
- data_size = mf.getSize();
-
- data = new uint8 [data_size];
- mf.read(data, data_size);
- mf.close();
+ data_size = SFileGetFileSize(file, NULL);
+ data = new uint8[data_size];
+ SFileReadFile(file, data, data_size, NULL/*bytesRead*/, NULL);
if (prepareLoadedData())
+ {
+ SFileCloseFile(file);
return true;
+ }
- printf("Error loading %s", filename);
- mf.close();
+ printf("Error loading %s\n", filename);
+ SFileCloseFile(file);
free();
+
return false;
}
diff --git a/src/tools/map_extractor/loadlib/loadlib.h b/src/tools/map_extractor/loadlib/loadlib.h
index 724c41ef3c9..973d181f91a 100644
--- a/src/tools/map_extractor/loadlib/loadlib.h
+++ b/src/tools/map_extractor/loadlib/loadlib.h
@@ -19,6 +19,8 @@
#ifndef LOAD_LIB_H
#define LOAD_LIB_H
+#include "StormLib.h"
+
#ifdef _WIN32
typedef __int64 int64;
typedef __int32 int32;
@@ -66,6 +68,7 @@ struct file_MVER
uint32 ver;
};
+
class FileLoader{
uint8 *data;
uint32 data_size;
@@ -77,7 +80,7 @@ public:
file_MVER *version;
FileLoader();
~FileLoader();
- bool loadFile(char *filename, bool log = true);
+ bool loadFile(HANDLE mpq, char *filename, bool log = true);
virtual void free();
};
#endif
diff --git a/src/tools/map_extractor/mpq_libmpq.cpp b/src/tools/map_extractor/mpq_libmpq.cpp
deleted file mode 100644
index df9eb78fc65..00000000000
--- a/src/tools/map_extractor/mpq_libmpq.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * 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 "mpq_libmpq04.h"
-#include <deque>
-#include <cstdio>
-
-ArchiveSet gOpenArchives;
-
-MPQArchive::MPQArchive(const char* filename)
-{
- int result = libmpq__archive_open(&mpq_a, filename, -1);
- printf("Opening %s\n", filename);
- if(result) {
- switch(result) {
- case LIBMPQ_ERROR_OPEN :
- printf("Error opening archive '%s': Does file really exist?\n", filename);
- break;
- case LIBMPQ_ERROR_FORMAT : /* bad file format */
- printf("Error opening archive '%s': Bad file format\n", filename);
- break;
- case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
- printf("Error opening archive '%s': Seeking in file failed\n", filename);
- break;
- case LIBMPQ_ERROR_READ : /* Read error in archive */
- printf("Error opening archive '%s': Read error in archive\n", filename);
- break;
- case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
- printf("Error opening archive '%s': Maybe not enough memory\n", filename);
- break;
- default:
- printf("Error opening archive '%s': Unknown error\n", filename);
- break;
- }
- return;
- }
- gOpenArchives.push_front(this);
-}
-
-void MPQArchive::close()
-{
- //gOpenArchives.erase(erase(&mpq_a);
- libmpq__archive_close(mpq_a);
-}
-
-MPQFile::MPQFile(const char* filename):
- eof(false),
- buffer(0),
- pointer(0),
- size(0)
-{
- for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
- {
- mpq_archive *mpq_a = (*i)->mpq_a;
-
- uint32_t filenum;
- if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
- libmpq__off_t transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- // HACK: in patch.mpq some files don't want to open and give 1 for filesize
- if (size<=1) {
-// printf("warning: file %s has size %d; cannot read.\n", filename, size);
- eof = true;
- buffer = 0;
- return;
- }
- buffer = new char[size];
-
- //libmpq_file_getdata
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
- /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
- return;
-
- }
- eof = true;
- buffer = 0;
-}
-
-size_t MPQFile::read(void* dest, size_t bytes)
-{
- if (eof) return 0;
-
- size_t rpos = pointer + bytes;
- if (rpos > size_t(size)) {
- bytes = size - pointer;
- eof = true;
- }
-
- memcpy(dest, &(buffer[pointer]), bytes);
-
- pointer = rpos;
-
- return bytes;
-}
-
-void MPQFile::seek(int offset)
-{
- pointer = offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::seekRelative(int offset)
-{
- pointer += offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::close()
-{
- if (buffer) delete[] buffer;
- buffer = 0;
- eof = true;
-}
diff --git a/src/tools/map_extractor/mpq_libmpq04.h b/src/tools/map_extractor/mpq_libmpq04.h
deleted file mode 100644
index 76778c663a6..00000000000
--- a/src/tools/map_extractor/mpq_libmpq04.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * 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 MPQ_H
-#define MPQ_H
-
-#include "loadlib/loadlib.h"
-#include "libmpq/mpq.h"
-#include <string.h>
-#include <ctype.h>
-#include <vector>
-#include <iostream>
-#include <deque>
-
-using namespace std;
-
-class MPQArchive
-{
-
-public:
- mpq_archive_s *mpq_a;
-
- MPQArchive(const char* filename);
- ~MPQArchive() { close(); }
- void close();
-
- void GetFileListTo(vector<string>& filelist) {
- uint32_t filenum;
- if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return;
- libmpq__off_t size, transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- char *buffer = new char[size+1];
- buffer[size] = '\0';
-
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
-
- char seps[] = "\n";
- char *token;
-
- token = strtok( buffer, seps );
- uint32 counter = 0;
- while ((token != NULL) && (counter < size)) {
- //cout << token << endl;
- token[strlen(token) - 1] = 0;
- string s = token;
- filelist.push_back(s);
- counter += strlen(token) + 2;
- token = strtok(NULL, seps);
- }
-
- delete[] buffer;
- }
-};
-typedef std::deque<MPQArchive*> ArchiveSet;
-
-class MPQFile
-{
- //MPQHANDLE handle;
- bool eof;
- char *buffer;
- libmpq__off_t pointer,size;
-
- // disable copying
- MPQFile(const MPQFile& /*f*/) {}
- void operator=(const MPQFile& /*f*/) {}
-
-public:
- MPQFile(const char* filename); // filenames are not case sensitive
- ~MPQFile() { close(); }
- size_t read(void* dest, size_t bytes);
- size_t getSize() { return size; }
- size_t getPos() { return pointer; }
- char* getBuffer() { return buffer; }
- char* getPointer() { return buffer + pointer; }
- bool isEof() { return eof; }
- void seek(int offset);
- void seekRelative(int offset);
- void close();
-};
-
-inline void flipcc(char *fcc)
-{
- char t;
- t=fcc[0];
- fcc[0]=fcc[3];
- fcc[3]=t;
- t=fcc[1];
- fcc[1]=fcc[2];
- fcc[2]=t;
-}
-
-#endif
diff --git a/src/tools/map_extractor/wdt.cpp b/src/tools/map_extractor/wdt.cpp
index fbb0b78567b..59444b46b88 100644
--- a/src/tools/map_extractor/wdt.cpp
+++ b/src/tools/map_extractor/wdt.cpp
@@ -79,6 +79,6 @@ bool WDT_file::prepareLoadedData()
return false;
wmo = (wdt_MWMO *)((uint8*)main+ main->size+8);
if (!wmo->prepareLoadedData())
- return false;
+ wmo = NULL; // optional as of cataclysm
return true;
}
diff --git a/src/tools/map_extractor/wdt.h b/src/tools/map_extractor/wdt.h
index a55598105b3..3184b0727a3 100644
--- a/src/tools/map_extractor/wdt.h
+++ b/src/tools/map_extractor/wdt.h
@@ -63,7 +63,7 @@ public:
uint32 size;
struct adtData{
- uint32 exist;
+ uint32 flag;
uint32 data1;
} adt_list[64][64];
diff --git a/src/tools/mesh_extractor/ContinentBuilder.h b/src/tools/mesh_extractor/ContinentBuilder.h
index 7f0d23b0418..075265f2627 100644
--- a/src/tools/mesh_extractor/ContinentBuilder.h
+++ b/src/tools/mesh_extractor/ContinentBuilder.h
@@ -44,4 +44,5 @@ private:
int tileXMax;
int tileYMax;
};
+
#endif
diff --git a/src/tools/mesh_extractor/DBC.cpp b/src/tools/mesh_extractor/DBC.cpp
index d1b95076ecd..e38b9560533 100644
--- a/src/tools/mesh_extractor/DBC.cpp
+++ b/src/tools/mesh_extractor/DBC.cpp
@@ -52,6 +52,7 @@ DBC::DBC( FILE* stream ) : StringBlock(NULL), StringBlockSize(0), IsFaulty(true)
size += 4;
}
}
+
StringBlock = new uint8[StringBlockSize];
count = fread(StringBlock, sizeof(uint8), StringBlockSize, stream);
if (count != StringBlockSize)
diff --git a/src/tools/vmap4_assembler/CMakeLists.txt b/src/tools/vmap4_assembler/CMakeLists.txt
index 33e8188aee1..041d44e014c 100644
--- a/src/tools/vmap4_assembler/CMakeLists.txt
+++ b/src/tools/vmap4_assembler/CMakeLists.txt
@@ -21,10 +21,7 @@ include_directories(
)
add_executable(vmap4assembler VMapAssembler.cpp)
-
-if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
- set_target_properties(vmap4assembler PROPERTIES LINK_FLAGS "-framework Carbon")
-endif()
+add_dependencies(vmap4assembler storm)
target_link_libraries(vmap4assembler
collision
diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt
index 90d2c68977f..a98cc55666c 100644
--- a/src/tools/vmap4_extractor/CMakeLists.txt
+++ b/src/tools/vmap4_extractor/CMakeLists.txt
@@ -11,27 +11,30 @@
file(GLOB_RECURSE sources *.cpp *.h)
-set(include_Dirs
- ${CMAKE_SOURCE_DIR}/dep/libmpq
-)
+# uncomment next line to disable debug mode
+add_definitions("-DIOMAP_DEBUG")
-if( WIN32 )
- set(include_Dirs
- ${include_Dirs}
- ${CMAKE_SOURCE_DIR}/dep/libmpq/win
- )
+# build setup currently only supports libmpq 0.4.x
+if( NOT MSVC )
+ add_definitions("-Wall")
+ add_definitions("-ggdb")
+ add_definitions("-O3")
endif()
-include_directories(${include_Dirs})
+include_directories(
+ ${CMAKE_SOURCE_DIR}/dep/StormLib/src
+)
add_executable(vmap4extractor ${sources})
target_link_libraries(vmap4extractor
- mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
+ storm
)
+add_dependencies(vmap4extractor storm)
+
if( UNIX )
install(TARGETS vmap4extractor DESTINATION bin)
elseif( WIN32 )
diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp
index 246b448380a..15723e7d941 100644
--- a/src/tools/vmap4_extractor/adtfile.cpp
+++ b/src/tools/vmap4_extractor/adtfile.cpp
@@ -44,26 +44,29 @@ char* GetPlainName(char* FileName)
return FileName;
}
-void fixnamen(char* name, size_t len)
+void FixNameCase(char* name, size_t len)
{
- for (size_t i = 0; i < len-3; i++)
+ char* ptr = name + len - 1;
+
+ //extension in lowercase
+ for (; *ptr != '.'; --ptr)
+ *ptr |= 0x20;
+
+ for (; ptr >= name; --ptr)
{
- if (i > 0 && name[i] >= 'A' && name[i] <= 'Z' && isalpha(name[i-1]))
- name[i] |= 0x20;
- else if ((i == 0 || !isalpha(name[i-1])) && name[i]>='a' && name[i]<='z')
- name[i] &= ~0x20;
+ if (ptr > name && *ptr >= 'A' && *ptr <= 'Z' && isalpha(*(ptr - 1)))
+ *ptr |= 0x20;
+ else if ((ptr == name || !isalpha(*(ptr - 1))) && *ptr >= 'a' && *ptr <= 'z')
+ *ptr &= ~0x20;
}
- //extension in lowercase
- for (size_t i = len - 3; i < len; i++)
- name[i] |= 0x20;
}
-void fixname2(char* name, size_t len)
+void FixNameSpaces(char* name, size_t len)
{
for (size_t i=0; i<len-3; i++)
{
if(name[i] == ' ')
- name[i] = '_';
+ name[i] = '_';
}
}
@@ -74,7 +77,9 @@ char* GetExtension(char* FileName)
return NULL;
}
-ADTFile::ADTFile(char* filename): ADT(filename), nWMO(0), nMDX(0), WmoInstansName(NULL), ModelInstansName(NULL)
+extern HANDLE WorldMpq;
+
+ADTFile::ADTFile(char* filename) : ADT(WorldMpq, filename, false)
{
Adtfilename.append(filename);
}
@@ -130,23 +135,24 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
{
if (size)
{
- char *buf = new char[size];
+ char* buf = new char[size];
ADT.read(buf, size);
- char *p=buf;
- int t=0;
- ModelInstansName = new string[size];
- while (p<buf+size)
+ char* p = buf;
+ int t = 0;
+ ModelInstanceNames = new std::string[size];
+ while (p < buf + size)
{
- fixnamen(p,strlen(p));
+ std::string path(p);
+
char* s = GetPlainName(p);
- fixname2(s,strlen(s));
+ FixNameCase(s, strlen(s));
+ FixNameSpaces(s, strlen(s));
- ModelInstansName[t++] = s;
+ ModelInstanceNames[t++] = s;
- string path(p);
ExtractSingleModel(path);
- p = p+strlen(p)+1;
+ p += strlen(p) + 1;
}
delete[] buf;
}
@@ -157,16 +163,18 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
{
char* buf = new char[size];
ADT.read(buf, size);
- char* p=buf;
+ char* p = buf;
int q = 0;
- WmoInstansName = new string[size];
- while (p<buf+size)
+ WmoInstanceNames = new std::string[size];
+ while (p < buf + size)
{
char* s = GetPlainName(p);
- fixnamen(s, strlen(s));
- fixname2(s, strlen(s));
+ FixNameCase(s, strlen(s));
+ FixNameSpaces(s, strlen(s));
+
+ WmoInstanceNames[q++] = s;
+
p += strlen(p) + 1;
- WmoInstansName[q++] = s;
}
delete[] buf;
}
@@ -181,9 +189,10 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
{
uint32 id;
ADT.read(&id, 4);
- ModelInstance inst(ADT,ModelInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
+ ModelInstance inst(ADT, ModelInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile);
}
- delete[] ModelInstansName;
+ delete[] ModelInstanceNames;
+ ModelInstanceNames = NULL;
}
}
else if (!strcmp(fourcc,"MODF"))
@@ -195,14 +204,18 @@ bool ADTFile::init(uint32 map_num, uint32 tileX, uint32 tileY)
{
uint32 id;
ADT.read(&id, 4);
- WMOInstance inst(ADT,WmoInstansName[id].c_str(), map_num, tileX, tileY, dirfile);
+ WMOInstance inst(ADT, WmoInstanceNames[id].c_str(), map_num, tileX, tileY, dirfile);
}
- delete[] WmoInstansName;
+
+ delete[] WmoInstanceNames;
+ WmoInstanceNames = NULL;
}
}
+
//======================
ADT.seek(nextpos);
}
+
ADT.close();
fclose(dirfile);
return true;
diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h
index aafcb46ce84..1970686f30e 100644
--- a/src/tools/vmap4_extractor/adtfile.h
+++ b/src/tools/vmap4_extractor/adtfile.h
@@ -19,7 +19,7 @@
#ifndef ADT_H
#define ADT_H
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "wmo.h"
#include "model.h"
@@ -113,14 +113,14 @@ private:
//size_t mcnk_offsets[256], mcnk_sizes[256];
MPQFile ADT;
//mcell Mcell;
- string Adtfilename;
+ std::string Adtfilename;
public:
ADTFile(char* filename);
~ADTFile();
int nWMO;
int nMDX;
- string* WmoInstansName;
- string* ModelInstansName;
+ std::string* WmoInstanceNames;
+ std::string* ModelInstanceNames;
bool init(uint32 map_num, uint32 tileX, uint32 tileY);
//void LoadMapChunks();
@@ -133,11 +133,11 @@ public:
*/
};
-const char * GetPlainName(const char * FileName);
-char * GetPlainName(char * FileName);
-char * GetExtension(char * FileName);
-void fixnamen(char *name, size_t len);
-void fixname2(char *name, size_t len);
+char const* GetPlainName(char const* FileName);
+char* GetPlainName(char* FileName);
+char* GetExtension(char* FileName);
+void FixNameCase(char* name, size_t len);
+void FixNameSpaces(char* name, size_t len);
//void fixMapNamen(char *name, size_t len);
#endif
diff --git a/src/tools/vmap4_extractor/dbcfile.cpp b/src/tools/vmap4_extractor/dbcfile.cpp
index 66c5669b88b..a825fcacddd 100644
--- a/src/tools/vmap4_extractor/dbcfile.cpp
+++ b/src/tools/vmap4_extractor/dbcfile.cpp
@@ -16,81 +16,104 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "dbcfile.h"
-#include "mpq_libmpq04.h"
-#undef min
-#undef max
+#define _CRT_SECURE_NO_DEPRECATE
-#include <cstdio>
+#include "dbcfile.h"
-DBCFile::DBCFile(const std::string& filename):
- filename(filename), recordSize(0), recordCount(0), fieldCount(0), stringSize(0), data(NULL), stringTable(NULL)
+DBCFile::DBCFile(HANDLE mpq, const char* filename) :
+ _mpq(mpq), _filename(filename), _file(NULL), _data(NULL), _stringTable(NULL)
{
-
}
bool DBCFile::open()
{
- MPQFile f(filename.c_str());
+ if (!SFileOpenFileEx(_mpq, _filename, SFILE_OPEN_PATCHED_FILE, &_file))
+ return false;
+
+ char header[4];
+ unsigned int na, nb, es, ss;
+
+ DWORD readBytes = 0;
+ SFileReadFile(_file, header, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of records
+ return false;
+
+ if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C')
+ return false;
- // Need some error checking, otherwise an unhandled exception error occurs
- // if people screw with the data path.
- if (f.isEof() == true)
+ readBytes = 0;
+ SFileReadFile(_file, &na, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of records
return false;
- unsigned char header[4];
- unsigned int na,nb,es,ss;
+ readBytes = 0;
+ SFileReadFile(_file, &nb, 4, &readBytes, NULL);
+ if (readBytes != 4) // Number of fields
+ return false;
- f.read(header,4); // File Header
+ readBytes = 0;
+ SFileReadFile(_file, &es, 4, &readBytes, NULL);
+ if (readBytes != 4) // Size of a record
+ return false;
- if (header[0]!='W' || header[1]!='D' || header[2]!='B' || header[3] != 'C')
- {
- f.close();
- data = NULL;
- printf("Critical Error: An error occured while trying to read the DBCFile %s.", filename.c_str());
+ readBytes = 0;
+ SFileReadFile(_file, &ss, 4, &readBytes, NULL);
+ if (readBytes != 4) // String size
return false;
- }
-
- //assert(header[0]=='W' && header[1]=='D' && header[2]=='B' && header[3] == 'C');
-
- f.read(&na,4); // Number of records
- f.read(&nb,4); // Number of fields
- f.read(&es,4); // Size of a record
- f.read(&ss,4); // String size
-
- recordSize = es;
- recordCount = na;
- fieldCount = nb;
- stringSize = ss;
- //assert(fieldCount*4 == recordSize);
- assert(fieldCount*4 >= recordSize);
-
- data = new unsigned char[recordSize*recordCount+stringSize];
- stringTable = data + recordSize*recordCount;
- f.read(data,recordSize*recordCount+stringSize);
- f.close();
+
+ _recordSize = es;
+ _recordCount = na;
+ _fieldCount = nb;
+ _stringSize = ss;
+ if (_fieldCount * 4 != _recordSize)
+ return false;
+
+ _data = new unsigned char[_recordSize * _recordCount + _stringSize];
+ _stringTable = _data + _recordSize*_recordCount;
+
+ size_t data_size = _recordSize * _recordCount + _stringSize;
+ readBytes = 0;
+ SFileReadFile(_file, _data, data_size, &readBytes, NULL);
+ if (readBytes != data_size)
+ return false;
+
return true;
}
DBCFile::~DBCFile()
{
- delete [] data;
+ delete [] _data;
+ if (_file != NULL)
+ SFileCloseFile(_file);
}
DBCFile::Record DBCFile::getRecord(size_t id)
{
- assert(data);
- return Record(*this, data + id*recordSize);
+ assert(_data);
+ return Record(*this, _data + id*_recordSize);
+}
+
+size_t DBCFile::getMaxId()
+{
+ assert(_data);
+
+ size_t maxId = 0;
+ for(size_t i = 0; i < getRecordCount(); ++i)
+ if (maxId < getRecord(i).getUInt(0))
+ maxId = getRecord(i).getUInt(0);
+
+ return maxId;
}
DBCFile::Iterator DBCFile::begin()
{
- assert(data);
- return Iterator(*this, data);
+ assert(_data);
+ return Iterator(*this, _data);
}
DBCFile::Iterator DBCFile::end()
{
- assert(data);
- return Iterator(*this, stringTable);
+ assert(_data);
+ return Iterator(*this, _stringTable);
}
+
diff --git a/src/tools/vmap4_extractor/dbcfile.h b/src/tools/vmap4_extractor/dbcfile.h
index 7551de8594c..8e2edf951e1 100644
--- a/src/tools/vmap4_extractor/dbcfile.h
+++ b/src/tools/vmap4_extractor/dbcfile.h
@@ -18,138 +18,144 @@
#ifndef DBCFILE_H
#define DBCFILE_H
-
#include <cassert>
#include <string>
+#include "StormLib.h"
class DBCFile
{
-public:
- DBCFile(const std::string &filename);
- ~DBCFile();
-
- // Open database. It must be openened before it can be used.
- bool open();
-
- // TODO: Add a close function?
-
- // Database exceptions
- class Exception
- {
public:
- Exception(const std::string &message): message(message)
- { }
- virtual ~Exception()
- { }
- const std::string &getMessage() {return message;}
- private:
- std::string message;
- };
+ DBCFile(HANDLE mpq, const char* filename);
+ ~DBCFile();
- //
- class NotFound: public Exception
- {
- public:
- NotFound(): Exception("Key was not found")
- { }
- };
-
- // Iteration over database
- class Iterator;
- class Record
- {
- public:
- Record& operator= (const Record& r)
- {
- file = r.file;
- offset = r.offset;
- return *this;
- }
- float getFloat(size_t field) const
- {
- assert(field < file.fieldCount);
- return *reinterpret_cast<float*>(offset+field*4);
- }
- unsigned int getUInt(size_t field) const
- {
- assert(field < file.fieldCount);
- return *reinterpret_cast<unsigned int*>(offset+(field*4));
- }
- int getInt(size_t field) const
+ // Open database. It must be openened before it can be used.
+ bool open();
+
+ // Database exceptions
+ class Exception
{
- assert(field < file.fieldCount);
- return *reinterpret_cast<int*>(offset+field*4);
- }
- unsigned char getByte(size_t ofs) const
+ public:
+ Exception(const std::string &message) : message(message) { }
+ virtual ~Exception() { }
+ const std::string &getMessage() { return message; }
+ private:
+ std::string message;
+ };
+
+ class NotFound: public Exception
{
- assert(ofs < file.recordSize);
- return *reinterpret_cast<unsigned char*>(offset+ofs);
- }
- const char *getString(size_t field) const
+ public:
+ NotFound(): Exception("Key was not found") { }
+ };
+
+ // Iteration over database
+ class Iterator;
+ class Record
{
- assert(field < file.fieldCount);
- size_t stringOffset = getUInt(field);
- assert(stringOffset < file.stringSize);
- //char * tmp = (char*)file.stringTable + stringOffset;
- //unsigned char * tmp2 = file.stringTable + stringOffset;
- return reinterpret_cast<char*>(file.stringTable + stringOffset);
- }
- private:
- Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {}
- DBCFile &file;
- unsigned char *offset;
+ public:
+ float getFloat(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<float*>(offset + field * 4);
+ }
- friend class DBCFile;
- friend class Iterator;
- };
+ unsigned int getUInt(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<unsigned int*>(offset + field * 4);
+ }
- /* Iterator that iterates over records */
- class Iterator
- {
- public:
- Iterator(DBCFile &file, unsigned char *offset):
- record(file, offset) {}
- /// Advance (prefix only)
- Iterator & operator++() {
- record.offset += record.file.recordSize;
- return *this;
- }
- /// Return address of current instance
- Record const & operator*() const { return record; }
- const Record* operator->() const {
- return &record;
- }
- /// Comparison
- bool operator==(const Iterator &b) const
- {
- return record.offset == b.record.offset;
- }
- bool operator!=(const Iterator &b) const
+ int getInt(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ return *reinterpret_cast<int*>(offset + field * 4);
+ }
+
+ char const* getString(size_t field) const
+ {
+ assert(field < file._fieldCount);
+ size_t stringOffset = getUInt(field);
+ assert(stringOffset < file._stringSize);
+ return reinterpret_cast<char*>(file._stringTable + stringOffset);
+ }
+
+ private:
+ Record(DBCFile& file, unsigned char* offset): file(file), offset(offset) {}
+ DBCFile& file;
+ unsigned char* offset;
+
+ friend class DBCFile;
+ friend class DBCFile::Iterator;
+
+ Record& operator=(Record const&);
+ Record(Record const& right) : file(right.file), offset(right.offset)
+ {
+ }
+ };
+ /** Iterator that iterates over records
+ */
+ class Iterator
{
- return record.offset != b.record.offset;
- }
+ public:
+ Iterator(DBCFile &file, unsigned char* offset) : record(file, offset) { }
+
+ Iterator(Iterator const& right) : record(right.record)
+ {
+ }
+
+ /// Advance (prefix only)
+ Iterator& operator++()
+ {
+ record.offset += record.file._recordSize;
+ return *this;
+ }
+
+ /// Return address of current instance
+ Record const& operator*() const { return record; }
+ Record const* operator->() const { return &record; }
+
+ /// Comparison
+ bool operator==(Iterator const& b) const
+ {
+ return record.offset == b.record.offset;
+ }
+
+ bool operator!=(Iterator const& b) const
+ {
+ return record.offset != b.record.offset;
+ }
+
+ Iterator& operator=(Iterator const& right)
+ {
+ record.offset = right.record.offset;
+ return *this;
+ }
+ private:
+ Record record;
+
+ };
+
+ // Get record by id
+ Record getRecord(size_t id);
+ /// Get begin iterator over records
+ Iterator begin();
+ /// Get begin iterator over records
+ Iterator end();
+ /// Trivial
+ size_t getRecordCount() const { return _recordCount; }
+ size_t getFieldCount() const { return _fieldCount; }
+ size_t getMaxId();
+
private:
- Record record;
- };
-
- // Get record by id
- Record getRecord(size_t id);
- /// Get begin iterator over records
- Iterator begin();
- /// Get begin iterator over records
- Iterator end();
- /// Trivial
- size_t getRecordCount() const { return recordCount;}
- size_t getFieldCount() const { return fieldCount; }
-
-private:
- std::string filename;
- size_t recordSize;
- size_t recordCount;
- size_t fieldCount;
- size_t stringSize;
- unsigned char *data;
- unsigned char *stringTable;
+ HANDLE _mpq;
+ const char* _filename;
+ HANDLE _file;
+ size_t _recordSize;
+ size_t _recordCount;
+ size_t _fieldCount;
+ size_t _stringSize;
+ unsigned char *_data;
+ unsigned char* _stringTable;
};
#endif
diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp
index 59871012ea5..3bb0ac86901 100644
--- a/src/tools/vmap4_extractor/gameobject_extract.cpp
+++ b/src/tools/vmap4_extractor/gameobject_extract.cpp
@@ -26,18 +26,17 @@
bool ExtractSingleModel(std::string& fname)
{
- char * name = GetPlainName((char*)fname.c_str());
- char * ext = GetExtension(name);
-
- // < 3.1.0 ADT MMDX section store filename.mdx filenames for corresponded .m2 file
- if (!strcmp(ext, ".mdx"))
+ if (fname.substr(fname.length() - 4, 4) == ".mdx")
{
- // replace .mdx -> .m2
- fname.erase(fname.length()-2,2);
+ fname.erase(fname.length() - 2, 2);
fname.append("2");
}
- // >= 3.1.0 ADT MMDX section store filename.m2 filenames for corresponded .m2 file
- // nothing do
+
+ std::string originalName = fname;
+
+ char* name = GetPlainName((char*)fname.c_str());
+ FixNameCase(name, strlen(name));
+ FixNameSpaces(name, strlen(name));
std::string output(szWorkDirWmo);
output += "/";
@@ -46,17 +45,19 @@ bool ExtractSingleModel(std::string& fname)
if (FileExists(output.c_str()))
return true;
- Model mdl(fname);
+ Model mdl(originalName);
if (!mdl.open())
return false;
return mdl.ConvertToVMAPModel(output.c_str());
}
+extern HANDLE LocaleMpq;
+
void ExtractGameobjectModels()
{
printf("Extracting GameObject models...");
- DBCFile dbc("DBFilesClient\\GameObjectDisplayInfo.dbc");
+ DBCFile dbc(LocaleMpq, "DBFilesClient\\GameObjectDisplayInfo.dbc");
if(!dbc.open())
{
printf("Fatal error: Invalid GameObjectDisplayInfo.dbc file format!\n");
@@ -82,9 +83,9 @@ void ExtractGameobjectModels()
if (path.length() < 4)
continue;
- fixnamen((char*)path.c_str(), path.size());
+ FixNameCase((char*)path.c_str(), path.size());
char * name = GetPlainName((char*)path.c_str());
- fixname2(name, strlen(name));
+ FixNameSpaces(name, strlen(name));
char * ch_ext = GetExtension(name);
if (!ch_ext)
@@ -94,18 +95,11 @@ void ExtractGameobjectModels()
bool result = false;
if (!strcmp(ch_ext, ".wmo"))
- {
result = ExtractSingleWmo(path);
- }
- else if (!strcmp(ch_ext, ".mdl"))
- {
- // TODO: extract .mdl files, if needed
+ else if (!strcmp(ch_ext, ".mdl")) // TODO: extract .mdl files, if needed
continue;
- }
else //if (!strcmp(ch_ext, ".mdx") || !strcmp(ch_ext, ".m2"))
- {
result = ExtractSingleModel(path);
- }
if (result)
{
diff --git a/src/tools/vmap4_extractor/loadlib/loadlib.h b/src/tools/vmap4_extractor/loadlib/loadlib.h
deleted file mode 100644
index 1b44d13a9d3..00000000000
--- a/src/tools/vmap4_extractor/loadlib/loadlib.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * 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 LOAD_LIB_H
-#define LOAD_LIB_H
-
-#ifdef WIN32
-typedef __int64 int64;
-typedef __int32 int32;
-typedef __int16 int16;
-typedef __int8 int8;
-typedef unsigned __int64 uint64;
-typedef unsigned __int32 uint32;
-typedef unsigned __int16 uint16;
-typedef unsigned __int8 uint8;
-#else
-#include <stdint.h>
-#ifndef uint64_t
-#ifdef __linux__
-#include <linux/types.h>
-#endif
-#endif
-typedef int64_t int64;
-typedef int32_t int32;
-typedef int16_t int16;
-typedef int8_t int8;
-typedef uint64_t uint64;
-typedef uint32_t uint32;
-typedef uint16_t uint16;
-typedef uint8_t uint8;
-#endif
-
-#define FILE_FORMAT_VERSION 18
-
-//
-// File version chunk
-//
-struct file_MVER
-{
- union{
- uint32 fcc;
- char fcc_txt[4];
- };
- uint32 size;
- uint32 ver;
-};
-
-class FileLoader{
- uint8 *data;
- uint32 data_size;
-public:
- virtual bool prepareLoadedData();
- uint8 *GetData() {return data;}
- uint32 GetDataSize() {return data_size;}
-
- file_MVER *version;
- FileLoader();
- ~FileLoader();
- bool loadFile(char *filename, bool log = true);
- virtual void free();
-};
-#endif
diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp
index 825a2697c16..0f1bde7712d 100644
--- a/src/tools/vmap4_extractor/model.cpp
+++ b/src/tools/vmap4_extractor/model.cpp
@@ -19,11 +19,13 @@
#include "vmapexport.h"
#include "model.h"
#include "wmo.h"
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include <cassert>
#include <algorithm>
#include <cstdio>
+extern HANDLE WorldMpq;
+
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
{
memset(&header, 0, sizeof(header));
@@ -31,7 +33,7 @@ Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0
bool Model::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
if (f.isEof())
{
@@ -44,7 +46,7 @@ bool Model::open()
_unload();
memcpy(&header, f.getBuffer(), sizeof(ModelHeader));
- if(header.nBoundingTriangles > 0)
+ if (header.nBoundingTriangles > 0)
{
f.seek(0);
f.seekRelative(header.ofsBoundingVertices);
diff --git a/src/tools/vmap4_extractor/model.h b/src/tools/vmap4_extractor/model.h
index a1766ed0bb2..74df92efb3b 100644
--- a/src/tools/vmap4_extractor/model.h
+++ b/src/tools/vmap4_extractor/model.h
@@ -19,7 +19,6 @@
#ifndef MODEL_H
#define MODEL_H
-#include "loadlib/loadlib.h"
#include "vec3d.h"
#include "modelheaders.h"
#include <vector>
diff --git a/src/tools/vmap4_extractor/modelheaders.h b/src/tools/vmap4_extractor/modelheaders.h
index b0d729dd238..ce951d75f78 100644
--- a/src/tools/vmap4_extractor/modelheaders.h
+++ b/src/tools/vmap4_extractor/modelheaders.h
@@ -19,12 +19,7 @@
#ifndef MODELHEADERS_H
#define MODELHEADERS_H
-/* typedef unsigned char uint8;
-typedef char int8;
-typedef unsigned short uint16;
-typedef short int16;
-typedef unsigned int uint32;
-typedef int int32; */
+#include "mpqfile.h" // integer typedefs
#pragma pack(push,1)
diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp
deleted file mode 100644
index 265ae99528f..00000000000
--- a/src/tools/vmap4_extractor/mpq_libmpq.cpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * 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 "mpq_libmpq04.h"
-#include <deque>
-#include <cstdio>
-
-ArchiveSet gOpenArchives;
-
-MPQArchive::MPQArchive(const char* filename)
-{
- int result = libmpq__archive_open(&mpq_a, filename, -1);
- printf("Opening %s\n", filename);
- if(result) {
- switch(result) {
- case LIBMPQ_ERROR_OPEN :
- printf("Error opening archive '%s': Does file really exist?\n", filename);
- break;
- case LIBMPQ_ERROR_FORMAT : /* bad file format */
- printf("Error opening archive '%s': Bad file format\n", filename);
- break;
- case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
- printf("Error opening archive '%s': Seeking in file failed\n", filename);
- break;
- case LIBMPQ_ERROR_READ : /* Read error in archive */
- printf("Error opening archive '%s': Read error in archive\n", filename);
- break;
- case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
- printf("Error opening archive '%s': Maybe not enough memory\n", filename);
- break;
- default:
- printf("Error opening archive '%s': Unknown error\n", filename);
- break;
- }
- return;
- }
- gOpenArchives.push_front(this);
-}
-
-void MPQArchive::close()
-{
- //gOpenArchives.erase(erase(&mpq_a);
- libmpq__archive_close(mpq_a);
-}
-
-MPQFile::MPQFile(const char* filename):
- eof(false),
- buffer(0),
- pointer(0),
- size(0)
-{
- for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
- {
- mpq_archive *mpq_a = (*i)->mpq_a;
-
- uint32 filenum;
- if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
- libmpq__off_t transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- // HACK: in patch.mpq some files don't want to open and give 1 for filesize
- if (size<=1) {
- // printf("info: file %s has size %d; considered dummy file.\n", filename, size);
- eof = true;
- buffer = 0;
- return;
- }
- buffer = new char[size];
-
- //libmpq_file_getdata
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
- /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
- return;
-
- }
- eof = true;
- buffer = 0;
-}
-
-size_t MPQFile::read(void* dest, size_t bytes)
-{
- if (eof) return 0;
-
- size_t rpos = pointer + bytes;
- if (rpos > size_t(size)) {
- bytes = size - pointer;
- eof = true;
- }
-
- memcpy(dest, &(buffer[pointer]), bytes);
-
- pointer = rpos;
-
- return bytes;
-}
-
-void MPQFile::seek(int offset)
-{
- pointer = offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::seekRelative(int offset)
-{
- pointer += offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::close()
-{
- if (buffer) delete[] buffer;
- buffer = 0;
- eof = true;
-}
diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h
deleted file mode 100644
index d045abe307a..00000000000
--- a/src/tools/vmap4_extractor/mpq_libmpq04.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * 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 MPQ_H
-#define MPQ_H
-
-#include "loadlib/loadlib.h"
-#include "libmpq/mpq.h"
-#include <string.h>
-#include <ctype.h>
-#include <vector>
-#include <iostream>
-#include <deque>
-
-using namespace std;
-
-class MPQArchive
-{
-
-public:
- mpq_archive_s *mpq_a;
-
- MPQArchive(const char* filename);
- void close();
-
- void GetFileListTo(vector<string>& filelist) {
- uint32_t filenum;
- if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return;
- libmpq__off_t size, transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- char *buffer = new char[size + 1];
- buffer[size] = '\0';
-
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
-
- char seps[] = "\n";
- char *token;
-
- token = strtok( buffer, seps );
- uint32 counter = 0;
- while ((token != NULL) && (counter < size)) {
- //cout << token << endl;
- token[strlen(token) - 1] = 0;
- string s = token;
- filelist.push_back(s);
- counter += strlen(token) + 2;
- token = strtok(NULL, seps);
- }
-
- delete[] buffer;
- }
-};
-typedef std::deque<MPQArchive*> ArchiveSet;
-
-class MPQFile
-{
- //MPQHANDLE handle;
- bool eof;
- char *buffer;
- libmpq__off_t pointer,size;
-
- // disable copying
- MPQFile(const MPQFile& /*f*/) {}
- void operator=(const MPQFile& /*f*/) {}
-
-public:
- MPQFile(const char* filename); // filenames are not case sensitive
- ~MPQFile() { close(); }
- size_t read(void* dest, size_t bytes);
- size_t getSize() { return size; }
- size_t getPos() { return pointer; }
- char* getBuffer() { return buffer; }
- char* getPointer() { return buffer + pointer; }
- bool isEof() { return eof; }
- void seek(int offset);
- void seekRelative(int offset);
- void close();
-};
-
-inline void flipcc(char *fcc)
-{
- char t;
- t=fcc[0];
- fcc[0]=fcc[3];
- fcc[3]=t;
- t=fcc[1];
- fcc[1]=fcc[2];
- fcc[2]=t;
-}
-
-#endif
diff --git a/src/tools/vmap4_extractor/mpqfile.cpp b/src/tools/vmap4_extractor/mpqfile.cpp
new file mode 100644
index 00000000000..4e690aabee3
--- /dev/null
+++ b/src/tools/vmap4_extractor/mpqfile.cpp
@@ -0,0 +1,87 @@
+#include "mpqfile.h"
+#include <deque>
+#include <cstdio>
+#include "StormLib.h"
+
+MPQFile::MPQFile(HANDLE mpq, const char* filename, bool warnNoExist /*= true*/) :
+ eof(false),
+ buffer(0),
+ pointer(0),
+ size(0)
+{
+ HANDLE file;
+ if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file))
+ {
+ if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND)
+ fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError());
+ eof = true;
+ return;
+ }
+
+ DWORD hi = 0;
+ size = SFileGetFileSize(file, &hi);
+
+ if (hi)
+ {
+ fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, uint32(hi));
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ if (size <= 1)
+ {
+ fprintf(stderr, "Can't open %s, size = %u!\n", filename, uint32(size));
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ DWORD read = 0;
+ buffer = new char[size];
+ if (!SFileReadFile(file, buffer, size, &read) || size != read)
+ {
+ fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, uint32(size), uint32(read));
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ SFileCloseFile(file);
+}
+
+size_t MPQFile::read(void* dest, size_t bytes)
+{
+ if (eof) return 0;
+
+ size_t rpos = pointer + bytes;
+ if (rpos > size) {
+ bytes = size - pointer;
+ eof = true;
+ }
+
+ memcpy(dest, &(buffer[pointer]), bytes);
+
+ pointer = rpos;
+
+ return bytes;
+}
+
+void MPQFile::seek(int offset)
+{
+ pointer = offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::seekRelative(int offset)
+{
+ pointer += offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::close()
+{
+ if (buffer) delete[] buffer;
+ buffer = 0;
+ eof = true;
+}
diff --git a/src/tools/vmap4_extractor/mpqfile.h b/src/tools/vmap4_extractor/mpqfile.h
new file mode 100644
index 00000000000..e7379c4f7a0
--- /dev/null
+++ b/src/tools/vmap4_extractor/mpqfile.h
@@ -0,0 +1,81 @@
+#define _CRT_SECURE_NO_DEPRECATE
+#ifndef _CRT_SECURE_NO_WARNINGS // fuck the police^Wwarnings
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#ifndef MPQ_H
+#define MPQ_H
+
+#include <string.h>
+#include <ctype.h>
+#include <vector>
+#include <iostream>
+#include <deque>
+#include "StormLib.h"
+
+#ifdef _WIN32
+#include <Windows.h> // mainly only HANDLE definition is required
+typedef __int64 int64;
+typedef __int32 int32;
+typedef __int16 int16;
+typedef __int8 int8;
+typedef unsigned __int64 uint64;
+typedef unsigned __int32 uint32;
+typedef unsigned __int16 uint16;
+typedef unsigned __int8 uint8;
+#else
+#include <stdint.h>
+#ifndef uint64_t
+#ifdef __linux__
+#include <linux/types.h>
+#endif
+#endif
+typedef int64_t int64;
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+#endif
+
+using namespace std;
+
+class MPQFile
+{
+ //MPQHANDLE handle;
+ bool eof;
+ char *buffer;
+ size_t pointer,size;
+
+ // disable copying
+ MPQFile(const MPQFile &f);
+ void operator=(const MPQFile &f);
+
+public:
+ MPQFile(HANDLE mpq, const char* filename, bool warnNoExist = true); // filenames are not case sensitive
+ ~MPQFile() { close(); }
+ size_t read(void* dest, size_t bytes);
+ size_t getSize() { return size; }
+ size_t getPos() { return pointer; }
+ char* getBuffer() { return buffer; }
+ char* getPointer() { return buffer + pointer; }
+ bool isEof() { return eof; }
+ void seek(int offset);
+ void seekRelative(int offset);
+ void close();
+};
+
+inline void flipcc(char *fcc)
+{
+ char t;
+ t=fcc[0];
+ fcc[0]=fcc[3];
+ fcc[3]=t;
+ t=fcc[1];
+ fcc[1]=fcc[2];
+ fcc[2]=t;
+}
+
+#endif
diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp
index d75af79f379..fbb7cb87ebe 100644
--- a/src/tools/vmap4_extractor/vmapexport.cpp
+++ b/src/tools/vmap4_extractor/vmapexport.cpp
@@ -30,6 +30,7 @@
#define mkdir _mkdir
#else
#include <sys/stat.h>
+ #define ERROR_PATH_NOT_FOUND ERROR_FILE_NOT_FOUND
#endif
#undef min
@@ -45,7 +46,7 @@
#include "wdtfile.h"
#include "dbcfile.h"
#include "wmo.h"
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "vmapexport.h"
@@ -56,7 +57,47 @@
//-----------------------------------------------------------------------------
-extern ArchiveSet gOpenArchives;
+HANDLE WorldMpq = NULL;
+HANDLE LocaleMpq = NULL;
+
+uint32 CONF_TargetBuild = 15595; // 4.3.4.15595
+
+// List MPQ for extract maps from
+char const* CONF_mpq_list[]=
+{
+ "world.MPQ",
+ "art.MPQ",
+ "expansion1.MPQ",
+ "expansion2.MPQ",
+ "expansion3.MPQ",
+ "world2.MPQ",
+};
+
+uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0};
+#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder
+#define NEW_BASE_SET_BUILD 15211
+
+#define LOCALES_COUNT 12
+
+char const* Locales[LOCALES_COUNT] =
+{
+ "enGB", "enUS",
+ "deDE", "esES",
+ "frFR", "koKR",
+ "zhCN", "zhTW",
+ "enCN", "enTW",
+ "esMX", "ruRU"
+};
+
+TCHAR const* LocalesT[LOCALES_COUNT] =
+{
+ _T("enGB"), _T("enUS"),
+ _T("deDE"), _T("esES"),
+ _T("frFR"), _T("koKR"),
+ _T("zhCN"), _T("zhTW"),
+ _T("enCN"), _T("enTW"),
+ _T("esMX"), _T("ruRU"),
+};
typedef struct
{
@@ -69,7 +110,6 @@ uint16 *LiqType = 0;
uint32 map_count;
char output_path[128]=".";
char input_path[1024]=".";
-bool hasInputPathParam = false;
bool preciseVectorData = false;
// Constants
@@ -78,6 +118,120 @@ bool preciseVectorData = false;
const char* szWorkDirWmo = "./Buildings";
const char* szRawVMAPMagic = "VMAP041";
+bool LoadLocaleMPQFile(int locale)
+{
+ TCHAR buff[512];
+ memset(buff, 0, sizeof(buff));
+ _stprintf(buff, _T("%s%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]);
+ if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ {
+ _tprintf(_T("Loading %s locale MPQs\n"), LocalesT[locale]);
+ _tprintf(_T("Cannot open archive %s\n"), buff);
+ }
+ return false;
+ }
+
+ _tprintf(_T("Loading %s locale MPQs\n"), LocalesT[locale]);
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
+ {
+ // Do not attempt to read older MPQ patch archives past this build, they were merged with base
+ // and trying to read them together with new base will not end well
+ if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD)
+ continue;
+
+ memset(buff, 0, sizeof(buff));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(buff, _T("%s%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]);
+ }
+ else
+ {
+ prefix = Locales[locale];
+ _stprintf(buff, _T("%swow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0))
+ {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), buff);
+ continue;
+ }
+ }
+
+ printf("\n");
+ return true;
+}
+
+void LoadCommonMPQFiles(uint32 build)
+{
+ TCHAR filename[512];
+ _stprintf(filename, _T("%sworld.MPQ"), input_path);
+ _tprintf(_T("Loading common MPQ files\n"));
+ if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ return;
+ }
+
+ int count = sizeof(CONF_mpq_list) / sizeof(char*);
+ for (int i = 1; i < count; ++i)
+ {
+ if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ
+ continue;
+
+ _stprintf(filename, _T("%s%s"), input_path, CONF_mpq_list[i]);
+ if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
+ }
+
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
+ {
+ // Do not attempt to read older MPQ patch archives past this build, they were merged with base
+ // and trying to read them together with new base will not end well
+ if (CONF_TargetBuild >= NEW_BASE_SET_BUILD && Builds[i] < NEW_BASE_SET_BUILD)
+ continue;
+
+ memset(filename, 0, sizeof(filename));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(filename, _T("%swow-update-base-%u.MPQ"), input_path, Builds[i]);
+ }
+ else
+ {
+ prefix = "base";
+ _stprintf(filename, _T("%swow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ continue;
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
+ }
+
+ printf("\n");
+}
+
+
// Local testing functions
bool FileExists(const char* file)
@@ -103,7 +257,8 @@ void strToLower(char* str)
void ReadLiquidTypeTableDBC()
{
printf("Read LiquidType.dbc file...");
- DBCFile dbc("DBFilesClient\\LiquidType.dbc");
+
+ DBCFile dbc(LocaleMpq, "DBFilesClient\\LiquidType.dbc");
if(!dbc.open())
{
printf("Fatal error: Invalid LiquidType.dbc file format!\n");
@@ -123,21 +278,23 @@ void ReadLiquidTypeTableDBC()
bool ExtractWmo()
{
- bool success = true;
+ bool success = false;
//const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
- for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr)
+ SFILE_FIND_DATA data;
+ HANDLE find = SFileFindFirstFile(WorldMpq, "*.wmo", &data, NULL);
+ if (find != NULL)
{
- vector<string> filelist;
-
- (*ar_itr)->GetFileListTo(filelist);
- for (vector<string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname)
+ do
{
- if (fname->find(".wmo") != string::npos)
- success = ExtractSingleWmo(*fname);
+ std::string str = data.cFileName;
+ //printf("Extracting wmo %s\n", str.c_str());
+ success |= ExtractSingleWmo(str);
}
+ while (SFileFindNextFile(find, &data));
}
+ SFileFindClose(find);
if (success)
printf("\nExtract wmo complete (No (fatal) errors)\n");
@@ -152,7 +309,7 @@ bool ExtractSingleWmo(std::string& fname)
char szLocalFile[1024];
const char * plain_name = GetPlainName(fname.c_str());
sprintf(szLocalFile, "%s/%s", szWorkDirWmo, plain_name);
- fixnamen(szLocalFile,strlen(szLocalFile));
+ FixNameCase(szLocalFile,strlen(szLocalFile));
if (FileExists(szLocalFile))
return true;
@@ -203,7 +360,7 @@ bool ExtractSingleWmo(std::string& fname)
sprintf(groupFileName, "%s_%03u.wmo", temp, i);
//printf("Trying to open groupfile %s\n",groupFileName);
- string s = groupFileName;
+ std::string s = groupFileName;
WMOGroup fgroup(s);
if(!fgroup.open())
{
@@ -267,121 +424,10 @@ void getGamePath()
#endif
}
-bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames)
-{
- int i;
- char path[512];
-
- for (i = 1; i <= 99; i++)
- {
- if (i != 1)
- {
- sprintf(path, "%s-%d.MPQ", scanmatch, i);
- }
- else
- {
- sprintf(path, "%s.MPQ", scanmatch);
- }
-#ifdef __linux__
- if(FILE* h = fopen64(path, "rb"))
-#else
- if(FILE* h = fopen(path, "rb"))
-#endif
- {
- fclose(h);
- //matches.push_back(path);
- pArchiveNames.push_back(path);
- }
- }
-
- return(true);
-}
-
-bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames)
-{
- if(!hasInputPathParam)
- getGamePath();
-
- printf("\nGame path: %s\n", input_path);
-
- char path[512];
- string in_path(input_path);
- std::vector<std::string> locales, searchLocales;
-
- searchLocales.push_back("enGB");
- searchLocales.push_back("enUS");
- searchLocales.push_back("deDE");
- searchLocales.push_back("esES");
- searchLocales.push_back("frFR");
- searchLocales.push_back("koKR");
- searchLocales.push_back("zhCN");
- searchLocales.push_back("zhTW");
- searchLocales.push_back("enCN");
- searchLocales.push_back("enTW");
- searchLocales.push_back("esMX");
- searchLocales.push_back("ruRU");
-
- for (std::vector<std::string>::iterator i = searchLocales.begin(); i != searchLocales.end(); ++i)
- {
- std::string localePath = in_path + *i;
- // check if locale exists:
- struct stat status;
- if (stat(localePath.c_str(), &status))
- continue;
- if ((status.st_mode & S_IFDIR) == 0)
- continue;
- printf("Found locale '%s'\n", i->c_str());
- locales.push_back(*i);
- }
- printf("\n");
-
- // open locale expansion and common files
- printf("Adding data files from locale directories.\n");
- for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
- {
- pArchiveNames.push_back(in_path + *i + "/locale-" + *i + ".MPQ");
- pArchiveNames.push_back(in_path + *i + "/expansion-locale-" + *i + ".MPQ");
- pArchiveNames.push_back(in_path + *i + "/lichking-locale-" + *i + ".MPQ");
- }
-
- // open expansion and common files
- pArchiveNames.push_back(input_path + string("common.MPQ"));
- pArchiveNames.push_back(input_path + string("common-2.MPQ"));
- pArchiveNames.push_back(input_path + string("expansion.MPQ"));
- pArchiveNames.push_back(input_path + string("lichking.MPQ"));
-
- // now, scan for the patch levels in the core dir
- printf("Scanning patch levels from data directory.\n");
- sprintf(path, "%spatch", input_path);
- if (!scan_patches(path, pArchiveNames))
- return(false);
-
- // now, scan for the patch levels in locale dirs
- printf("Scanning patch levels from locale directories.\n");
- bool foundOne = false;
- for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
- {
- printf("Locale: %s\n", i->c_str());
- sprintf(path, "%s%s/patch-%s", input_path, i->c_str(), i->c_str());
- if(scan_patches(path, pArchiveNames))
- foundOne = true;
- }
-
- printf("\n");
-
- if(!foundOne)
- {
- printf("no locale found\n");
- return false;
- }
-
- return true;
-}
-
bool processArgv(int argc, char ** argv, const char *versionString)
{
bool result = true;
- hasInputPathParam = false;
+ bool hasInputPathParam = false;
preciseVectorData = false;
for(int i = 1; i < argc; ++i)
@@ -413,12 +459,18 @@ bool processArgv(int argc, char ** argv, const char *versionString)
{
preciseVectorData = true;
}
+ else if(strcmp("-b",argv[i]) == 0)
+ {
+ if (i + 1 < argc) // all ok
+ CONF_TargetBuild = atoi(argv[i++ + 1]);
+ }
else
{
result = false;
break;
}
}
+
if(!result)
{
printf("Extract %s.\n",versionString);
@@ -426,8 +478,13 @@ bool processArgv(int argc, char ** argv, const char *versionString)
printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n");
printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n");
printf(" -d <path>: Path to the vector data source folder.\n");
+ printf(" -b : target build (default %u)\n", CONF_TargetBuild);
printf(" -? : This message.\n");
}
+
+ if(!hasInputPathParam)
+ getGamePath();
+
return result;
}
@@ -465,7 +522,7 @@ int main(int argc, char ** argv)
}
}
- printf("Extract %s. Beginning work ....\n",versionString);
+ printf("Extract %s. Beginning work ....\n\n",versionString);
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// Create the working directory
if (mkdir(szWorkDirWmo
@@ -475,21 +532,22 @@ int main(int argc, char ** argv)
))
success = (errno == EEXIST);
- // prepare archive name list
- std::vector<std::string> archiveNames;
- fillArchiveNameVector(archiveNames);
- for (size_t i=0; i < archiveNames.size(); ++i)
- {
- MPQArchive *archive = new MPQArchive(archiveNames[i].c_str());
- if (gOpenArchives.empty() || gOpenArchives.front() != archive)
- delete archive;
- }
+ LoadCommonMPQFiles(CONF_TargetBuild);
- if (gOpenArchives.empty())
+ for (int i = 0; i < LOCALES_COUNT; ++i)
{
- printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path);
- return 1;
+ //Open MPQs
+ if (!LoadLocaleMPQFile(i))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ printf("Unable to load %s locale archives!\n", Locales[i]);
+ continue;
+ }
+
+ printf("Detected and using locale: %s\n", Locales[i]);
+ break;
}
+
ReadLiquidTypeTableDBC();
// extract data
@@ -500,7 +558,7 @@ int main(int argc, char ** argv)
//map.dbc
if (success)
{
- DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
+ DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc");
if (!dbc->open())
{
delete dbc;
@@ -521,10 +579,13 @@ int main(int argc, char ** argv)
ParsMapFiles();
delete [] map_ids;
//nError = ERROR_SUCCESS;
- // Extract models, listed in DameObjectDisplayInfo.dbc
+ // Extract models, listed in GameObjectDisplayInfo.dbc
ExtractGameobjectModels();
}
+ SFileCloseArchive(LocaleMpq);
+ SFileCloseArchive(WorldMpq);
+
printf("\n");
if (!success)
{
diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp
index 20bee313e70..6e17c80e187 100644
--- a/src/tools/vmap4_extractor/wdtfile.cpp
+++ b/src/tools/vmap4_extractor/wdtfile.cpp
@@ -30,7 +30,9 @@ char * wdtGetPlainName(char * FileName)
return FileName;
}
-WDTFile::WDTFile(char* file_name, char* file_name1) : WDT(file_name), gWmoInstansName(NULL), gnWMO(0)
+extern HANDLE WorldMpq;
+
+WDTFile::WDTFile(char* file_name, char* file_name1):WDT(WorldMpq, file_name)
{
filename.append(file_name1,strlen(file_name1));
}
@@ -81,7 +83,7 @@ bool WDTFile::init(char* /*map_id*/, unsigned int mapID)
while (p < buf + size)
{
char* s=wdtGetPlainName(p);
- fixnamen(s,strlen(s));
+ FixNameCase(s,strlen(s));
p=p+strlen(p)+1;
gWmoInstansName[q++] = s;
}
@@ -125,6 +127,6 @@ ADTFile* WDTFile::GetMap(int x, int z)
char name[512];
- sprintf(name,"World\\Maps\\%s\\%s_%d_%d.adt", filename.c_str(), filename.c_str(), x, z);
+ sprintf(name,"World\\Maps\\%s\\%s_%d_%d_obj0.adt", filename.c_str(), filename.c_str(), x, z);
return new ADTFile(name);
}
diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h
index 8545fd67560..637a2e0c24f 100644
--- a/src/tools/vmap4_extractor/wdtfile.h
+++ b/src/tools/vmap4_extractor/wdtfile.h
@@ -19,7 +19,7 @@
#ifndef WDTFILE_H
#define WDTFILE_H
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "wmo.h"
#include <string>
#include "stdlib.h"
diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp
index 8efdb899cab..fe79422c87e 100644
--- a/src/tools/vmap4_extractor/wmo.cpp
+++ b/src/tools/vmap4_extractor/wmo.cpp
@@ -26,7 +26,7 @@
#include <fstream>
#undef min
#undef max
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
using namespace std;
extern uint16 *LiqType;
@@ -39,9 +39,11 @@ WMORoot::WMORoot(std::string &filename)
memset(bbcorn2, 0, sizeof(bbcorn2));
}
+extern HANDLE WorldMpq;
+
bool WMORoot::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
if(f.isEof ())
{
printf("No such file.\n");
@@ -149,7 +151,7 @@ WMOGroup::WMOGroup(const std::string &filename) :
bool WMOGroup::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
if(f.isEof ())
{
printf("No such file.\n");
diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h
index 0f1f0772bd3..220bb607315 100644
--- a/src/tools/vmap4_extractor/wmo.h
+++ b/src/tools/vmap4_extractor/wmo.h
@@ -24,7 +24,7 @@
#include <string>
#include <set>
#include "vec3d.h"
-#include "loadlib/loadlib.h"
+#include "mpqfile.h"
// MOPY flags
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01